* lib/webrick/utils.rb (WEBrick::Utils::TimeoutHandler): Acquire
TimeoutMutex only when accessing @timeout_info for avoiding potential deadlock. [Bug #11742] [ruby-dev:49387] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53134 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
00f9a74bca
commit
e337dc6517
@ -1,3 +1,9 @@
|
|||||||
|
Wed Dec 16 00:53:45 2015 Naohisa Goto <ngotogenome@gmail.com>
|
||||||
|
|
||||||
|
* lib/webrick/utils.rb (WEBrick::Utils::TimeoutHandler): Acquire
|
||||||
|
TimeoutMutex only when accessing @timeout_info for avoiding
|
||||||
|
potential deadlock. [Bug #11742] [ruby-dev:49387]
|
||||||
|
|
||||||
Wed Dec 16 00:39:27 2015 Jake Worth <jakeworth82@gmail.com>
|
Wed Dec 16 00:39:27 2015 Jake Worth <jakeworth82@gmail.com>
|
||||||
|
|
||||||
* doc/extension.rdoc: [DOC] fix double-word typo. [Fix GH-1153]
|
* doc/extension.rdoc: [DOC] fix double-word typo. [Fix GH-1153]
|
||||||
|
@ -135,24 +135,22 @@ module WEBrick
|
|||||||
# +time+:: Timeout in seconds
|
# +time+:: Timeout in seconds
|
||||||
# +exception+:: Exception to raise when timeout elapsed
|
# +exception+:: Exception to raise when timeout elapsed
|
||||||
def TimeoutHandler.register(seconds, exception)
|
def TimeoutHandler.register(seconds, exception)
|
||||||
TimeoutMutex.synchronize{
|
instance.register(Thread.current, Time.now + seconds, exception)
|
||||||
instance.register(Thread.current, Time.now + seconds, exception)
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Cancels the timeout handler +id+
|
# Cancels the timeout handler +id+
|
||||||
def TimeoutHandler.cancel(id)
|
def TimeoutHandler.cancel(id)
|
||||||
TimeoutMutex.synchronize{
|
instance.cancel(Thread.current, id)
|
||||||
instance.cancel(Thread.current, id)
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Creates a new TimeoutHandler. You should use ::register and ::cancel
|
# Creates a new TimeoutHandler. You should use ::register and ::cancel
|
||||||
# instead of creating the timeout handler directly.
|
# instead of creating the timeout handler directly.
|
||||||
def initialize
|
def initialize
|
||||||
@timeout_info = Hash.new
|
TimeoutMutex.synchronize{
|
||||||
|
@timeout_info = Hash.new
|
||||||
|
}
|
||||||
@watcher = Thread.start{
|
@watcher = Thread.start{
|
||||||
to_interrupt = []
|
to_interrupt = []
|
||||||
while true
|
while true
|
||||||
@ -185,11 +183,9 @@ module WEBrick
|
|||||||
##
|
##
|
||||||
# Interrupts the timeout handler +id+ and raises +exception+
|
# Interrupts the timeout handler +id+ and raises +exception+
|
||||||
def interrupt(thread, id, exception)
|
def interrupt(thread, id, exception)
|
||||||
TimeoutMutex.synchronize{
|
if cancel(thread, id) && thread.alive?
|
||||||
if cancel(thread, id) && thread.alive?
|
thread.raise(exception, "execution timeout")
|
||||||
thread.raise(exception, "execution timeout")
|
end
|
||||||
end
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
@ -198,8 +194,11 @@ module WEBrick
|
|||||||
# +time+:: Timeout in seconds
|
# +time+:: Timeout in seconds
|
||||||
# +exception+:: Exception to raise when timeout elapsed
|
# +exception+:: Exception to raise when timeout elapsed
|
||||||
def register(thread, time, exception)
|
def register(thread, time, exception)
|
||||||
@timeout_info[thread] ||= Array.new
|
info = nil
|
||||||
@timeout_info[thread] << (info = [time, exception])
|
TimeoutMutex.synchronize{
|
||||||
|
@timeout_info[thread] ||= Array.new
|
||||||
|
@timeout_info[thread] << (info = [time, exception])
|
||||||
|
}
|
||||||
begin
|
begin
|
||||||
@watcher.wakeup
|
@watcher.wakeup
|
||||||
rescue ThreadError
|
rescue ThreadError
|
||||||
@ -210,14 +209,16 @@ module WEBrick
|
|||||||
##
|
##
|
||||||
# Cancels the timeout handler +id+
|
# Cancels the timeout handler +id+
|
||||||
def cancel(thread, id)
|
def cancel(thread, id)
|
||||||
if ary = @timeout_info[thread]
|
TimeoutMutex.synchronize{
|
||||||
ary.delete_if{|info| info.object_id == id }
|
if ary = @timeout_info[thread]
|
||||||
if ary.empty?
|
ary.delete_if{|info| info.object_id == id }
|
||||||
@timeout_info.delete(thread)
|
if ary.empty?
|
||||||
|
@timeout_info.delete(thread)
|
||||||
|
end
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
return true
|
return false
|
||||||
end
|
}
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user