From c62ec3ae1aa5ac3b3f7f2756763a41c5703c06ca Mon Sep 17 00:00:00 2001 From: kosaki Date: Fri, 30 Nov 2012 18:55:28 +0000 Subject: * lib/sync.rb (Sync_m#sync_synchronize): add Thread.async_interrupt_timing for protecting from async interrupt. * lib/sync.rb (Sync_m#sync_lock): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38089 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/sync.rb | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) (limited to 'lib/sync.rb') diff --git a/lib/sync.rb b/lib/sync.rb index 524f3804e9..378c659b7b 100644 --- a/lib/sync.rb +++ b/lib/sync.rb @@ -135,25 +135,26 @@ module Sync_m def sync_lock(m = EX) return unlock if m == UN - - while true - @sync_mutex.synchronize do - begin - 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) + Thread.async_interrupt_timing(StandardError => :on_blocking) do + while true + @sync_mutex.synchronize do + begin + if sync_try_lock_sub(m) + return self else - unless sync_waiting.include?(Thread.current) || sync_upgrade_waiting.reverse_each.any?{|w| w.first == Thread.current } - 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 - ensure - sync_waiting.delete(Thread.current) end end end @@ -226,11 +227,13 @@ module Sync_m end def sync_synchronize(mode = EX) - sync_lock(mode) - begin - yield - ensure - sync_unlock + Thread.async_interrupt_timing(StandardError => :on_blocking) do + sync_lock(mode) + begin + yield + ensure + sync_unlock + end end end -- cgit v1.2.3