[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]