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/