From aa8a3b2358fbdc176c6bcfbcfd3ed1646d287d62 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun 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. --- thread.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'thread.c') 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) 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.3