ruby-changes:41055
From: ngoto <ko1@a...>
Date: Wed, 16 Dec 2015 00:27:19 +0900 (JST)
Subject: [ruby-changes:41055] ngoto:r53130 (trunk): * lib/webrick/utils.rb (WEBrick::Utils::TimeoutHandler#initialize):
ngoto 2015-12-16 00:26:47 +0900 (Wed, 16 Dec 2015) New Revision: 53130 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=53130 Log: * lib/webrick/utils.rb (WEBrick::Utils::TimeoutHandler#initialize): TimeoutMutex should be acquired when accessing @timeout_info. To avoid deadlock, interrupt() calls are delayed. Due to the mutex, it is safe to treat ary without ary.dup. [Bug #11742] [ruby-dev:49387] Modified files: trunk/ChangeLog trunk/lib/webrick/utils.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 53129) +++ ChangeLog (revision 53130) @@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Wed Dec 16 00:25:41 2015 Naohisa Goto <ngotogenome@g...> + + * lib/webrick/utils.rb (WEBrick::Utils::TimeoutHandler#initialize): + TimeoutMutex should be acquired when accessing @timeout_info. + To avoid deadlock, interrupt() calls are delayed. + Due to the mutex, it is safe to treat ary without ary.dup. + [Bug #11742] [ruby-dev:49387] + Tue Dec 15 23:13:10 2015 Naohisa Goto <ngotogenome@g...> * gc.c: Delete excess semicolon after RUBY_ALIAS_FUNCTION(). Index: lib/webrick/utils.rb =================================================================== --- lib/webrick/utils.rb (revision 53129) +++ lib/webrick/utils.rb (revision 53130) @@ -154,20 +154,25 @@ module WEBrick https://github.com/ruby/ruby/blob/trunk/lib/webrick/utils.rb#L154 def initialize @timeout_info = Hash.new @watcher = Thread.start{ + to_interrupt = [] while true now = Time.now wakeup = nil - @timeout_info.each {|thread, ary| - next unless ary - ary.dup.each{|info| - time, exception = *info - if time < now - interrupt(thread, info.object_id, exception) - elsif !wakeup || time < wakeup - wakeup = time - end + to_interrupt.clear + TimeoutMutex.synchronize{ + @timeout_info.each {|thread, ary| + next unless ary + ary.each{|info| + time, exception = *info + if time < now + to_interrupt.push [thread, info.object_id, exception] + elsif !wakeup || time < wakeup + wakeup = time + end + } } } + to_interrupt.each {|arg| interrupt(*arg)} if !wakeup sleep elsif (wakeup -= now) > 0 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/