ruby-changes:73516
From: Takashi <ko1@a...>
Date: Sun, 11 Sep 2022 09:09:33 +0900 (JST)
Subject: [ruby-changes:73516] aa8a3b2358 (master): MJIT: Do not hang after forking with threads
https://git.ruby-lang.org/ruby.git/commit/?id=aa8a3b2358 From aa8a3b2358fbdc176c6bcfbcfd3ed1646d287d62 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun <takashikkbn@g...> Date: Sun, 11 Sep 2022 08:59:27 +0900 Subject: MJIT: Do not hang after forking with threads First, rb_mjit_fork should call rb_thread_atfork to stop threads after fork in the child process. Unfortunately, we cannot use rb_fork_ruby to prevent this kind of mistakes because MJIT needs special handling of waiting_pid and mjit_pause/resume. Second, mjit_waitpid_finished should be checked regardless of trap_interrupt. It doesn't seem like the flag is not set when SIGCHLD is handled for an MJIT child process. --- process.c | 1 + thread.c | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/process.c b/process.c index 405c7edcb3..4465b36c51 100644 --- a/process.c +++ b/process.c @@ -4222,6 +4222,7 @@ rb_mjit_fork(void) https://github.com/ruby/ruby/blob/trunk/process.c#L4222 after_fork_ruby(); disable_child_handler_fork_parent(&old); + if (pid == 0) rb_thread_atfork(); return pid; } diff --git a/thread.c b/thread.c index e50b2ce6ca..1364d73be2 100644 --- a/thread.c +++ b/thread.c @@ -2321,16 +2321,16 @@ rb_threadptr_execute_interrupts(rb_thread_t *th, int blocking_timing) https://github.com/ruby/ruby/blob/trunk/thread.c#L2321 ret |= rb_signal_exec(th, sig); } th->status = prev_status; + } #if USE_MJIT - // Handle waitpid_signal for MJIT issued by ruby_sigchld_handler. This needs to be done - // outside ruby_sigchld_handler to avoid recursively relying on the SIGCHLD handler. - if (mjit_waitpid_finished) { - mjit_waitpid_finished = false; - mjit_notify_waitpid(WIFEXITED(mjit_waitpid_status) ? WEXITSTATUS(mjit_waitpid_status) : -1); - } -#endif + // Handle waitpid_signal for MJIT issued by ruby_sigchld_handler. This needs to be done + // outside ruby_sigchld_handler to avoid recursively relying on the SIGCHLD handler. + if (mjit_waitpid_finished && th == th->vm->ractor.main_thread) { + mjit_waitpid_finished = false; + mjit_notify_waitpid(WIFEXITED(mjit_waitpid_status) ? WEXITSTATUS(mjit_waitpid_status) : -1); } +#endif /* exception from another thread */ if (pending_interrupt && threadptr_pending_interrupt_active_p(th)) { -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/