[前][次][番号順一覧][スレッド一覧]

ruby-changes:41059

From: ngoto <ko1@a...>
Date: Wed, 16 Dec 2015 01:03:28 +0900 (JST)
Subject: [ruby-changes:41059] ngoto:r53134 (trunk): * lib/webrick/utils.rb (WEBrick::Utils::TimeoutHandler): Acquire

ngoto	2015-12-16 01:03:00 +0900 (Wed, 16 Dec 2015)

  New Revision: 53134

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=53134

  Log:
    * lib/webrick/utils.rb (WEBrick::Utils::TimeoutHandler): Acquire
      TimeoutMutex only when accessing @timeout_info for avoiding
      potential deadlock. [Bug #11742] [ruby-dev:49387]

  Modified files:
    trunk/ChangeLog
    trunk/lib/webrick/utils.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 53133)
+++ ChangeLog	(revision 53134)
@@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Wed Dec 16 00:53:45 2015  Naohisa Goto  <ngotogenome@g...>
+
+	* 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@g...>
 
 	* doc/extension.rdoc: [DOC] fix double-word typo.  [Fix GH-1153]
Index: lib/webrick/utils.rb
===================================================================
--- lib/webrick/utils.rb	(revision 53133)
+++ lib/webrick/utils.rb	(revision 53134)
@@ -135,24 +135,22 @@ module WEBrick https://github.com/ruby/ruby/blob/trunk/lib/webrick/utils.rb#L135
       # +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 https://github.com/ruby/ruby/blob/trunk/lib/webrick/utils.rb#L183
       ##
       # 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 https://github.com/ruby/ruby/blob/trunk/lib/webrick/utils.rb#L194
       # +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 https://github.com/ruby/ruby/blob/trunk/lib/webrick/utils.rb#L209
       ##
       # 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
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]