summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorngoto <ngoto@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-12-15 16:03:00 +0000
committerngoto <ngoto@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-12-15 16:03:00 +0000
commite337dc65173f11b2be9e620acb34dc91a64fe520 (patch)
tree16bf47c07525bc661ded5b861b5525761dccbdea
parent00f9a74bcac20e25b69aae3a3beafddb18293abd (diff)
* 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
-rw-r--r--ChangeLog6
-rw-r--r--lib/webrick/utils.rb43
2 files changed, 28 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index eabfe46..ab7d04e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
* doc/extension.rdoc: [DOC] fix double-word typo. [Fix GH-1153]
diff --git a/lib/webrick/utils.rb b/lib/webrick/utils.rb
index dc7ce50..654d9de 100644
--- a/lib/webrick/utils.rb
+++ b/lib/webrick/utils.rb
@@ -135,24 +135,22 @@ module WEBrick
# +time+:: Timeout in seconds
# +exception+:: Exception to raise when timeout elapsed
def TimeoutHandler.register(seconds, exception)
- TimeoutMutex.synchronize{
- instance.register(Thread.current, Time.now + seconds, exception)
- }
+ instance.register(Thread.current, Time.now + seconds, exception)
end
##
# Cancels the timeout handler +id+
def TimeoutHandler.cancel(id)
- TimeoutMutex.synchronize{
- instance.cancel(Thread.current, id)
- }
+ instance.cancel(Thread.current, id)
end
##
# Creates a new TimeoutHandler. You should use ::register and ::cancel
# instead of creating the timeout handler directly.
def initialize
- @timeout_info = Hash.new
+ TimeoutMutex.synchronize{
+ @timeout_info = Hash.new
+ }
@watcher = Thread.start{
to_interrupt = []
while true
@@ -185,11 +183,9 @@ module WEBrick
##
# Interrupts the timeout handler +id+ and raises +exception+
def interrupt(thread, id, exception)
- TimeoutMutex.synchronize{
- if cancel(thread, id) && thread.alive?
- thread.raise(exception, "execution timeout")
- end
- }
+ if cancel(thread, id) && thread.alive?
+ thread.raise(exception, "execution timeout")
+ end
end
##
@@ -198,8 +194,11 @@ module WEBrick
# +time+:: Timeout in seconds
# +exception+:: Exception to raise when timeout elapsed
def register(thread, time, exception)
- @timeout_info[thread] ||= Array.new
- @timeout_info[thread] << (info = [time, exception])
+ info = nil
+ TimeoutMutex.synchronize{
+ @timeout_info[thread] ||= Array.new
+ @timeout_info[thread] << (info = [time, exception])
+ }
begin
@watcher.wakeup
rescue ThreadError
@@ -210,14 +209,16 @@ module WEBrick
##
# Cancels the timeout handler +id+
def cancel(thread, id)
- if ary = @timeout_info[thread]
- ary.delete_if{|info| info.object_id == id }
- if ary.empty?
- @timeout_info.delete(thread)
+ TimeoutMutex.synchronize{
+ if ary = @timeout_info[thread]
+ ary.delete_if{|info| info.object_id == id }
+ if ary.empty?
+ @timeout_info.delete(thread)
+ end
+ return true
end
- return true
- end
- return false
+ return false
+ }
end
end