diff --git a/lib/zk/install_fork_hooks.rb b/lib/zk/install_fork_hooks.rb index aeae126..68c5ad8 100644 --- a/lib/zk/install_fork_hooks.rb +++ b/lib/zk/install_fork_hooks.rb @@ -1,37 +1,51 @@ -module ::Kernel - def fork_with_zk_hooks(&block) - if block - new_block = proc do - ::ZK::ForkHook.fire_after_child_hooks! - block.call +module ZK + module ForkHook + module ModernCoreExt + def _fork + ::ZK::ForkHook.fire_prepare_hooks! + pid = super + if pid == 0 + ::ZK::ForkHook.fire_after_child_hooks! + else + ::ZK::ForkHook.fire_after_parent_hooks! + end + pid end + end - ::ZK::ForkHook.fire_prepare_hooks! - fork_without_zk_hooks(&new_block).tap do - ::ZK::ForkHook.fire_after_parent_hooks! - end - else - ::ZK::ForkHook.fire_prepare_hooks! - if pid = fork_without_zk_hooks - ::ZK::ForkHook.fire_after_parent_hooks! - # we're in the parent - return pid - else - # we're in the child - ::ZK::ForkHook.fire_after_child_hooks! - return nil + module CoreExt + def fork(*, **) + ::ZK::ForkHook.fire_prepare_hooks! + if block_given? + pid = super do + ::ZK::ForkHook.fire_after_child_hooks! + yield + end + ::ZK::ForkHook.fire_after_parent_hooks! + else + if pid = super + ZK::ForkHook.fire_after_parent_hooks! + else + ::ZK::ForkHook.fire_after_child_hooks! + end + end + + pid end end - end - if defined?(fork_without_zk_hooks) - remove_method :fork - alias fork fork_without_zk_hooks - remove_method :fork_without_zk_hooks + module CoreExtPrivate + include CoreExt + private :fork + end end - - alias fork_without_zk_hooks fork - alias fork fork_with_zk_hooks - module_function :fork end +if Process.respond_to?(:_fork) # Ruby 3.1+ + ::Process.singleton_class.prepend(ZK::ForkHook::ModernCoreExt) +elsif Process.respond_to?(:fork) + ::Object.prepend(ZK::ForkHook::CoreExtPrivate) if RUBY_VERSION < "3.0" + ::Kernel.prepend(ZK::ForkHook::CoreExtPrivate) + ::Kernel.singleton_class.prepend(ZK::ForkHook::CoreExt) + ::Process.singleton_class.prepend(ZK::ForkHook::CoreExt) +end