ruby-changes:59063
From: Koichi <ko1@a...>
Date: Wed, 4 Dec 2019 13:39:10 +0900 (JST)
Subject: [ruby-changes:59063] c6e3db0c66 (master): new_cond before mon_initialize
https://git.ruby-lang.org/ruby.git/commit/?id=c6e3db0c66 From c6e3db0c66312af1e932c21006437419efa9ac75 Mon Sep 17 00:00:00 2001 From: Koichi Sasada <ko1@a...> Date: Wed, 4 Dec 2019 13:36:41 +0900 Subject: 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 diff --git a/ext/monitor/lib/monitor.rb b/ext/monitor/lib/monitor.rb index 821dcca..1883cb7 100644 --- a/ext/monitor/lib/monitor.rb +++ b/ext/monitor/lib/monitor.rb @@ -208,6 +208,10 @@ module MonitorMixin https://github.com/ruby/ruby/blob/trunk/ext/monitor/lib/monitor.rb#L208 # 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 https://github.com/ruby/ruby/blob/trunk/ext/monitor/lib/monitor.rb#L228 # 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 diff --git a/test/monitor/test_monitor.rb b/test/monitor/test_monitor.rb index 950db91..721c848 100644 --- a/test/monitor/test_monitor.rb +++ b/test/monitor/test_monitor.rb @@ -223,6 +223,19 @@ class TestMonitor < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/monitor/test_monitor.rb#L223 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" -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/