mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38080 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
a1d837ccc1
commit
6ca32179e6
2 changed files with 37 additions and 24 deletions
|
@ -1,3 +1,10 @@
|
|||
Sat Dec 1 01:19:34 2012 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
||||
|
||||
* 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@mbf.nifty.com>
|
||||
|
||||
* test/ruby/envutil.rb (Test::Unit::Assertions#assert_in_out_err):
|
||||
|
|
|
@ -63,15 +63,18 @@ class ConditionVariable
|
|||
# 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)
|
||||
end
|
||||
mutex.sleep timeout
|
||||
ensure
|
||||
@waiters_mutex.synchronize do
|
||||
@waiters.delete(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
|
||||
end
|
||||
self
|
||||
|
@ -81,11 +84,13 @@ class ConditionVariable
|
|||
# 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,16 +99,17 @@ class ConditionVariable
|
|||
# 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
|
||||
|
|
Loading…
Add table
Reference in a new issue