Fix deadlock that can occur when child live thread tries to load a constant after writing to the stream.

This commit is contained in:
Alex Chinn 2016-08-15 17:08:46 -04:00
parent c8d9a11df2
commit 285d7cad6a
3 changed files with 30 additions and 1 deletions

View File

@ -205,7 +205,12 @@ module ActionController
private
def each_chunk(&block)
while str = @buf.pop
loop do
str = nil
ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
str = @buf.pop
end
break unless str
yield str
end
end

View File

@ -150,6 +150,20 @@ module ActionController
response.stream.close
end
def write_sleep_autoload
path = File.join(File.dirname(__FILE__), "../fixtures")
ActiveSupport::Dependencies.autoload_paths << path
response.headers["Content-Type"] = "text/event-stream"
response.stream.write "before load"
sleep 0.01
::LoadMe
response.stream.close
latch.count_down
ActiveSupport::Dependencies.autoload_paths.reject! {|p| p == path}
end
def thread_locals
tc.assert_equal "aaron", Thread.current[:setting]
@ -281,6 +295,14 @@ module ActionController
assert_equal "text/event-stream", @response.headers["Content-Type"]
end
def test_delayed_autoload_after_write_within_interlock_hook
# Simulate InterlockHook
ActiveSupport::Dependencies.interlock.start_running
res = get :write_sleep_autoload
res.each {}
ActiveSupport::Dependencies.interlock.done_running
end
def test_async_stream
rubinius_skip "https://github.com/rubinius/rubinius/issues/2934"

2
actionpack/test/fixtures/load_me.rb vendored Normal file
View File

@ -0,0 +1,2 @@
class LoadMe
end