From 27674e4beb0391464fb97dcf15b884207789be2c Mon Sep 17 00:00:00 2001 From: Justin Collins Date: Wed, 1 Jan 2014 20:45:12 -0800 Subject: [PATCH] Wake waiting threads when SizedQueue#clear is called --- lib/thread.rb | 16 ++++++++++++++++ test/thread/test_queue.rb | 22 ++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/lib/thread.rb b/lib/thread.rb index 58c4f6b..494a5b3 100644 --- a/lib/thread.rb +++ b/lib/thread.rb @@ -355,6 +355,22 @@ class SizedQueue < Queue def num_waiting @waiting.size + @queue_wait.size end + + # + # Removes all objects from the queue and wakes waiting threads, if any. + # + def clear + @mutex.synchronize do + @que.clear + begin + until @queue_wait.empty? + @queue_wait.shift.wakeup + end + rescue ThreadError + retry + end + end + end end # Documentation comments: diff --git a/test/thread/test_queue.rb b/test/thread/test_queue.rb index b0ffe08..9d8d481 100644 --- a/test/thread/test_queue.rb +++ b/test/thread/test_queue.rb @@ -10,6 +10,28 @@ class TestQueue < Test::Unit::TestCase grind(5, 1000, 15, SizedQueue, 1000) end + def test_sized_queue_clear + # Fill queue, then test that SizedQueue#clear wakes up all waiting threads + sq = SizedQueue.new(2) + 2.times { sq << 1 } + + t1 = Thread.new do + sq << 1 + end + + t2 = Thread.new do + sq << 1 + end + + t3 = Thread.new do + Thread.pass + sq.clear + end + + [t3, t2, t1].each(&:join) + assert_equal sq.length, 2 + end + def grind(num_threads, num_objects, num_iterations, klass, *args) from_workers = klass.new(*args) to_workers = klass.new(*args) -- 1.8.3.2