diff --git a/activesupport/lib/active_support/evented_file_update_checker.rb b/activesupport/lib/active_support/evented_file_update_checker.rb index 0518a36239536..29aa502ec0f2e 100644 --- a/activesupport/lib/active_support/evented_file_update_checker.rb +++ b/activesupport/lib/active_support/evented_file_update_checker.rb @@ -99,7 +99,7 @@ def initialize(files, dirs) def finalizer proc do stop - ActiveSupport::ForkTracker.unregister(@after_fork) + ActiveSupport::ForkTracker.unregister_after_fork(@after_fork) end end diff --git a/activesupport/lib/active_support/fork_tracker.rb b/activesupport/lib/active_support/fork_tracker.rb index 2ff8fc5bb754e..6718f043da51f 100644 --- a/activesupport/lib/active_support/fork_tracker.rb +++ b/activesupport/lib/active_support/fork_tracker.rb @@ -4,6 +4,7 @@ module ActiveSupport module ForkTracker # :nodoc: module CoreExt def _fork + ForkTracker.before_fork_callback pid = super if pid == 0 ForkTracker.after_fork_callback @@ -13,13 +14,18 @@ def _fork end @pid = Process.pid - @callbacks = [] + @before_callbacks = [] + @after_callbacks = [] class << self + def before_fork_callback + @before_callbacks.each(&:call) + end + def after_fork_callback new_pid = Process.pid if @pid != new_pid - @callbacks.each(&:call) + @after_callbacks.each(&:call) @pid = new_pid end end @@ -28,13 +34,22 @@ def hook! ::Process.singleton_class.prepend(CoreExt) end + def before_fork(&block) + @before_callbacks << block + block + end + def after_fork(&block) - @callbacks << block + @after_callbacks << block block end - def unregister(callback) - @callbacks.delete(callback) + def unregister_before_fork(callback) + @before_callbacks.delete(callback) + end + + def unregister_after_fork(callback) + @after_callbacks.delete(callback) end end end diff --git a/activesupport/test/fork_tracker_test.rb b/activesupport/test/fork_tracker_test.rb index 13b9a0aa95997..cc90ec88c8cfe 100644 --- a/activesupport/test/fork_tracker_test.rb +++ b/activesupport/test/fork_tracker_test.rb @@ -7,16 +7,22 @@ def setup super @read, @write = IO.pipe - @called = false + @before_called = false + @after_called = false - @handler = ActiveSupport::ForkTracker.after_fork do - @called = true + @before_handler = ActiveSupport::ForkTracker.before_fork do + @before_called = true + end + + @after_handler = ActiveSupport::ForkTracker.after_fork do + @after_called = true @write.write "forked" end end def teardown - ActiveSupport::ForkTracker.unregister(@handler) + ActiveSupport::ForkTracker.unregister_before_fork(@before_handler) + ActiveSupport::ForkTracker.unregister_after_fork(@after_handler) super end @@ -35,7 +41,8 @@ def test_object_fork assert_equal "forked", @read.read @read.close - assert_not @called + assert @before_called + assert_not @after_called end def test_object_fork_without_block @@ -44,7 +51,8 @@ def test_object_fork_without_block Process.waitpid(pid) assert_equal "forked", @read.read @read.close - assert_not @called + assert @before_called + assert_not @after_called else @read.close @write.close @@ -64,7 +72,8 @@ def test_process_fork Process.waitpid(pid) assert_equal "forked", @read.read @read.close - assert_not @called + assert @before_called + assert_not @after_called end def test_process_fork_without_block @@ -73,7 +82,8 @@ def test_process_fork_without_block Process.waitpid(pid) assert_equal "forked", @read.read @read.close - assert_not @called + assert @before_called + assert_not @after_called else @read.close @write.close @@ -93,7 +103,8 @@ def test_kernel_fork Process.waitpid(pid) assert_equal "forked", @read.read @read.close - assert_not @called + assert @before_called + assert_not @after_called end def test_kernel_fork_without_block @@ -102,7 +113,8 @@ def test_kernel_fork_without_block Process.waitpid(pid) assert_equal "forked", @read.read @read.close - assert_not @called + assert @before_called + assert_not @after_called else @read.close @write.close @@ -132,18 +144,21 @@ def fark(&block) assert_equal "forked", @read.read @read.close - assert_not @called + assert @before_called + assert_not @after_called end def test_unregister_callback - ActiveSupport::ForkTracker.unregister(@handler) + ActiveSupport::ForkTracker.unregister_before_fork(@before_handler) + ActiveSupport::ForkTracker.unregister_after_fork(@after_handler) if pid = Process.fork @write.close Process.waitpid(pid) assert_equal "", @read.read @read.close - assert_not @called + assert_not @before_called + assert_not @after_called else @read.close @write.close