[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]