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

ruby-changes:26023

From: kosaki <ko1@a...>
Date: Sat, 1 Dec 2012 02:41:58 +0900 (JST)
Subject: [ruby-changes:26023] kosaki:r38080 (trunk): * lib/thread.rb (ConditionVariable#broadcast): protect from

kosaki	2012-12-01 02:39:36 +0900 (Sat, 01 Dec 2012)

  New Revision: 38080

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=38080

  Log:
    * lib/thread.rb (ConditionVariable#broadcast): protect from
      async interrupt by using Thread.async_interrupt_timing.
    * lib/thread.rb (ConditionVariable#signal): ditto.
    * lib/thread.rb (ConditionVariable#wait): ditto.

  Modified files:
    trunk/ChangeLog
    trunk/lib/thread.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 38079)
+++ ChangeLog	(revision 38080)
@@ -1,3 +1,10 @@
+Sat Dec  1 01:19:34 2012  KOSAKI Motohiro  <kosaki.motohiro@g...>
+
+	* lib/thread.rb (ConditionVariable#broadcast): protect from
+	  async interrupt by using Thread.async_interrupt_timing.
+	* lib/thread.rb (ConditionVariable#signal): ditto.
+	* lib/thread.rb (ConditionVariable#wait): ditto.
+
 Sat Dec  1 02:04:23 2012  Kazuhiro NISHIYAMA  <zn@m...>
 
 	* test/ruby/envutil.rb (Test::Unit::Assertions#assert_in_out_err):
Index: lib/thread.rb
===================================================================
--- lib/thread.rb	(revision 38079)
+++ lib/thread.rb	(revision 38080)
@@ -63,16 +63,19 @@
   # even if no other thread doesn't signal.
   #
   def wait(mutex, timeout=nil)
-    begin
-      # TODO: mutex should not be used
-      @waiters_mutex.synchronize do
-        @waiters.push(Thread.current)
+    Thread.async_interrupt_timing(StandardError => :defer) do
+      begin
+        Thread.async_interrupt_timing(StandardError => :on_blocking) do
+          @waiters_mutex.synchronize do
+            @waiters.push(Thread.current)
+          end
+          mutex.sleep timeout
+        end
+      ensure
+        @waiters_mutex.synchronize do
+          @waiters.delete(Thread.current)
+        end
       end
-      mutex.sleep timeout
-    ensure
-      @waiters_mutex.synchronize do
-        @waiters.delete(Thread.current)
-      end
     end
     self
   end
@@ -81,11 +84,13 @@
   # Wakes up the first thread in line waiting for this lock.
   #
   def signal
-    begin
-      t = @waiters_mutex.synchronize {@waiters.shift}
-      t.run if t
-    rescue ThreadError
-      retry
+    Thread.async_interrupt_timing(RuntimeError => :on_blocking) do
+      begin
+        t = @waiters_mutex.synchronize {@waiters.shift}
+        t.run if t
+      rescue ThreadError
+        retry # t was alread dead?
+      end
     end
     self
   end
@@ -94,17 +99,18 @@
   # Wakes up all threads waiting for this lock.
   #
   def broadcast
-    # TODO: incomplete
-    waiters0 = nil
-    @waiters_mutex.synchronize do
-      waiters0 = @waiters.dup
-      @waiters.clear
-    end
-    for t in waiters0
-      begin
-        t.run
-      rescue ThreadError
+    Thread.async_interrupt_timing(RuntimeError => :on_blocking) do
+      waiters0 = nil
+      @waiters_mutex.synchronize do
+        waiters0 = @waiters.dup
+        @waiters.clear
       end
+      for t in waiters0
+        begin
+          t.run
+        rescue ThreadError
+        end
+      end
     end
     self
   end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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