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

ruby-changes:15457

From: mame <ko1@a...>
Date: Fri, 16 Apr 2010 20:10:24 +0900 (JST)
Subject: [ruby-changes:15457] Ruby:r27356 (trunk): * lib/thread.rb (Queue#push, #pop, SizedQueue#push, #pop): remove

mame	2010-04-16 20:10:08 +0900 (Fri, 16 Apr 2010)

  New Revision: 27356

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

  Log:
    * lib/thread.rb (Queue#push, #pop, SizedQueue#push, #pop): remove
      code that kicks waiting thread twice, which caused race and
      deadlock.  [ruby-core:25537]
    
    * test/thread/test_queue.rb: added.

  Added directories:
    trunk/test/thread/
  Added files:
    trunk/test/thread/test_queue.rb
  Modified files:
    trunk/ChangeLog
    trunk/lib/thread.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 27355)
+++ ChangeLog	(revision 27356)
@@ -1,3 +1,11 @@
+Fri Apr 16 20:05:24 2010  Yusuke Endoh  <mame@t...>
+
+	* lib/thread.rb (Queue#push, #pop, SizedQueue#push, #pop): remove
+	  code that kicks waiting thread twice, which caused race and
+	  deadlock.  [ruby-core:25537]
+
+	* test/thread/test_queue.rb: added.
+
 Fri Apr 16 20:01:47 2010  Yusuke Endoh  <mame@t...>
 
 	* .gitignore: updated.
Index: lib/thread.rb
===================================================================
--- lib/thread.rb	(revision 27355)
+++ lib/thread.rb	(revision 27356)
@@ -150,7 +150,6 @@
   # Pushes +obj+ to the queue.
   #
   def push(obj)
-    t = nil
     @mutex.synchronize{
       @que.push obj
       begin
@@ -160,10 +159,6 @@
         retry
       end
     }
-    begin
-      t.run if t
-    rescue ThreadError
-    end
   end
 
   #
@@ -182,8 +177,8 @@
   # thread isn't suspended, and an exception is raised.
   #
   def pop(non_block=false)
-    while true
-      @mutex.synchronize{
+    @mutex.synchronize{
+      while true
         if @que.empty?
           raise ThreadError, "queue empty" if non_block
           @waiting.push Thread.current
@@ -191,8 +186,8 @@
         else
           return @que.shift
         end
-      }
-    end
+      end
+    }
   end
 
   #
@@ -295,7 +290,6 @@
   # until space becomes available.
   #
   def push(obj)
-    t = nil
     @mutex.synchronize{
       while true
         break if @que.length < @max
@@ -311,11 +305,6 @@
         retry
       end
     }
-
-    begin
-      t.run if t
-    rescue ThreadError
-    end
   end
 
   #
@@ -333,7 +322,6 @@
   #
   def pop(*args)
     retval = super
-    t = nil
     @mutex.synchronize {
       if @que.length < @max
         begin
@@ -344,10 +332,6 @@
         end
       end
     }
-    begin
-      t.run if t
-    rescue ThreadError
-    end
     retval
   end
 
Index: test/thread/test_queue.rb
===================================================================
--- test/thread/test_queue.rb	(revision 0)
+++ test/thread/test_queue.rb	(revision 27356)
@@ -0,0 +1,38 @@
+require 'test/unit'
+require 'thread'
+
+class TestQueue < Test::Unit::TestCase
+  def test_queue
+    grind(5, 1000, 15, Queue)
+  end
+
+  def test_sized_queue
+    grind(5, 1000, 15, SizedQueue, 1000)
+  end
+
+  def grind(num_threads, num_objects, num_iterations, klass, *args)
+    from_workers = klass.new(*args)
+    to_workers = klass.new(*args)
+
+    workers = (1..num_threads).map {
+      Thread.new {
+        while object = to_workers.pop
+          from_workers.push object
+        end
+      }
+    }
+
+    Thread.new {
+      num_iterations.times {
+        num_objects.times { to_workers.push 99 }
+        num_objects.times { from_workers.pop }
+      }
+    }.join
+  
+    num_threads.times { to_workers.push nil }
+    workers.each { |t| t.join }
+
+    assert 0, from_workers.size
+    assert 0, to_workers.size
+  end
+end

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

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