diff options
author | kosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-11-30 17:39:36 +0000 |
---|---|---|
committer | kosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-11-30 17:39:36 +0000 |
commit | 6ca32179e6d04cc6b22c4c2bbb55d3cc34127b3b (patch) | |
tree | 63be9e8857981d2e10a736a87ac90eabadfe1d19 /lib | |
parent | a1d837ccc1ff4b41f385fe0a167ae67cee1bcdd8 (diff) | |
download | ruby-6ca32179e6d04cc6b22c4c2bbb55d3cc34127b3b.tar.gz |
* 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
Diffstat (limited to 'lib')
-rw-r--r-- | lib/thread.rb | 54 |
1 files changed, 30 insertions, 24 deletions
diff --git a/lib/thread.rb b/lib/thread.rb index 0a5d1f41c1..f3dc9b15f9 100644 --- a/lib/thread.rb +++ b/lib/thread.rb @@ -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 |