* lib/thread.rb (ConditionVariable): use hash instead of array for

@waiters.
* test/thread/test_queue.rb (test_sized_queue_and_wakeup): remove
  a test because @waiters no longer have a chance to duplicated. Now it's
  a hash.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38109 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
kosaki 2012-12-01 08:28:44 +00:00
parent f9aef18497
commit 1f1db611b9
3 changed files with 15 additions and 25 deletions

View File

@ -1,3 +1,11 @@
Sat Dec 1 14:23:33 2012 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
* lib/thread.rb (ConditionVariable): use hash instead of array for
@waiters.
* test/thread/test_queue.rb (test_sized_queue_and_wakeup): remove
a test because @waiters no longer have a chance to duplicated. Now it's
a hash.
Sat Dec 1 17:16:54 2012 Nobuyoshi Nakada <nobu@ruby-lang.org> Sat Dec 1 17:16:54 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* misc/ruby-electric.el (ruby-electric-curlies): use kill-region * misc/ruby-electric.el (ruby-electric-curlies): use kill-region

View File

@ -52,7 +52,7 @@ class ConditionVariable
# Creates a new ConditionVariable # Creates a new ConditionVariable
# #
def initialize def initialize
@waiters = [] @waiters = {}
@waiters_mutex = Mutex.new @waiters_mutex = Mutex.new
end end
@ -67,7 +67,7 @@ class ConditionVariable
begin begin
Thread.async_interrupt_timing(StandardError => :on_blocking) do Thread.async_interrupt_timing(StandardError => :on_blocking) do
@waiters_mutex.synchronize do @waiters_mutex.synchronize do
@waiters.push(Thread.current) @waiters[Thread.current] = true
end end
mutex.sleep timeout mutex.sleep timeout
end end
@ -86,10 +86,10 @@ class ConditionVariable
def signal def signal
Thread.async_interrupt_timing(StandardError => :on_blocking) do Thread.async_interrupt_timing(StandardError => :on_blocking) do
begin begin
t = @waiters_mutex.synchronize {@waiters.shift} t, _ = @waiters_mutex.synchronize { @waiters.shift }
t.run if t t.run if t
rescue ThreadError rescue ThreadError
retry # t was alread dead? retry # t was already dead?
end end
end end
self self
@ -100,12 +100,12 @@ class ConditionVariable
# #
def broadcast def broadcast
Thread.async_interrupt_timing(StandardError => :on_blocking) do Thread.async_interrupt_timing(StandardError => :on_blocking) do
waiters0 = nil threads = nil
@waiters_mutex.synchronize do @waiters_mutex.synchronize do
waiters0 = @waiters.dup threads = @waiters.keys
@waiters.clear @waiters.clear
end end
for t in waiters0 for t in threads
begin begin
t.run t.run
rescue ThreadError rescue ThreadError

View File

@ -56,24 +56,6 @@ class TestQueue < Test::Unit::TestCase
assert_equal(1, q.max) assert_equal(1, q.max)
end end
def test_sized_queue_and_wakeup
sq = SizedQueue.new(1)
sq.push(0)
t1 = Thread.start { sq.push(1) ; sleep }
sleep 0.1 until t1.stop?
t1.wakeup
sleep 0.1 until t1.stop?
t2 = Thread.start { sq.push(2) }
sleep 0.1 until t1.stop? && t2.stop?
enque_cond = sq.instance_eval{ @enque_cond }
queue_wait = enque_cond.instance_eval { @waiters }
assert_equal(queue_wait.uniq, queue_wait)
end
def test_queue_pop_interrupt def test_queue_pop_interrupt
q = Queue.new q = Queue.new
t1 = Thread.new { q.pop } t1 = Thread.new { q.pop }