aboutsummaryrefslogtreecommitdiffstats
path: root/lib/sync.rb
diff options
context:
space:
mode:
authorkosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-09-09 11:34:47 +0000
committerkosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-09-09 11:34:47 +0000
commit2248a8ce643509577dd29988f5ea1e662f4aaa65 (patch)
tree17385d76e32660ce60ebda88777e0cad6df50076 /lib/sync.rb
parent5dbbee86b616424ee9800488a381b02f9e7c65b3 (diff)
downloadruby-2248a8ce643509577dd29988f5ea1e662f4aaa65.tar.gz
* lib/sync.rb (Sync_m#sync_lock): Fixed wakeup/raise unsafe code.
Patched by Masaki Matsushita. [Bug #5355] [ruby-dev:44521] * test/thread/test_sync.rb (test_sync_lock_and_wakeup, test_sync_upgrade_and_wakeup, test_sync_lock_and_raise): new test. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36936 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/sync.rb')
-rw-r--r--lib/sync.rb22
1 files changed, 14 insertions, 8 deletions
diff --git a/lib/sync.rb b/lib/sync.rb
index a57b789d55..524f3804e9 100644
--- a/lib/sync.rb
+++ b/lib/sync.rb
@@ -138,16 +138,22 @@ module Sync_m
while true
@sync_mutex.synchronize do
- if sync_try_lock_sub(m)
- return self
- else
- if sync_sh_locker[Thread.current]
- sync_upgrade_waiting.push [Thread.current, sync_sh_locker[Thread.current]]
- sync_sh_locker.delete(Thread.current)
+ begin
+ if sync_try_lock_sub(m)
+ return self
else
- sync_waiting.push Thread.current
+ if sync_sh_locker[Thread.current]
+ sync_upgrade_waiting.push [Thread.current, sync_sh_locker[Thread.current]]
+ sync_sh_locker.delete(Thread.current)
+ else
+ unless sync_waiting.include?(Thread.current) || sync_upgrade_waiting.reverse_each.any?{|w| w.first == Thread.current }
+ sync_waiting.push Thread.current
+ end
+ end
+ @sync_mutex.sleep
end
- @sync_mutex.sleep
+ ensure
+ sync_waiting.delete(Thread.current)
end
end
end