1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

new_cond before mon_initialize

MonitorMixin#new_cond can be called before mon_initialize, so we
need to initialize `@monitor` before it.

https://bugs.ruby-lang.org/issues/16255#note-4
This commit is contained in:
Koichi Sasada 2019-12-04 13:36:41 +09:00
parent f9e5c74cd2
commit c6e3db0c66
2 changed files with 23 additions and 2 deletions

View file

@ -208,6 +208,10 @@ module MonitorMixin
# Monitor object.
#
def new_cond
unless defined?(@mon_data)
mon_initialize
@mon_initialized_by_new_cond = true
end
return ConditionVariable.new(@mon_data)
end
@ -224,8 +228,12 @@ module MonitorMixin
# Initializes the MonitorMixin after being included in a class or when an
# object has been extended with the MonitorMixin
def mon_initialize
if defined?(@mon_data) && @mon_data_owner_object_id == self.object_id
raise ThreadError, "already initialized"
if defined?(@mon_data)
if defined?(@mon_initialized_by_new_cond)
return # already initalized.
elsif @mon_data_owner_object_id == self.object_id
raise ThreadError, "already initialized"
end
end
@mon_data = ::Monitor.new
@mon_data_owner_object_id = self.object_id

View file

@ -223,6 +223,19 @@ class TestMonitor < Test::Unit::TestCase
assert_join_threads([th, th2])
end
class NewCondTest
include MonitorMixin
attr_reader :cond
def initialize
@cond = new_cond
super # mon_initialize
end
end
def test_new_cond_before_initialize
assert NewCondTest.new.cond.instance_variable_get(:@monitor) != nil
end
def test_timedwait
cond = @monitor.new_cond
b = "foo"