From: Eric Wong Date: 2018-06-24T12:15:38+00:00 Subject: [ruby-core:87621] Re: [Ruby trunk Bug#14867] Process.wait can wait for MJIT compiler process ``` > > File 0001-hijack-SIGCHLD-handler-for-internal-use.patch added > > Scratch that, slightly buggy. Will fix in a bit. Testing with this amendment: https://80x24.org/spew/20180624115501.19651-1-e@80x24.org/raw It's a bit tricky, and I introduced yet another sleep function (rb_thread_sleep_interruptible) to make it work. Original problem in my patch was holding a native mutex while forking is dangerous, so I went to normal ruby sleep methods (same as Mutex and autoload). However, it's impossible to resume main thread from signal handler because rb_threadptr_execute_interrupts always restores th->status after trap handlers. In other words, this doesn't work: main = Thread.current trap(:USR1) { main.run } Thread.new { sleep 0.1; Process.kill(:USR1, $$) } sleep So I tried moving rb_sigchld/rb_waitpid_all into timer-thread; but that's racy and not doable unless the Ruby thread holds a native mutex while sleeping on a native condvar (w/o GVL). And that brings us back to the original problem... (Well, I could use futex :P) Now, back to using the main thread to handle SIGCHLD... It seems to be working. I suspect there's an old bug here, since we lose wakeups when the timer-thread is stopped: --- a/process.c +++ b/process.c @@ -1348,6 +1348,9 @@ after_exec_non_async_signal_safe(void) { rb_thread_reset_timer_thread(); rb_thread_start_timer_thread(); + if (rb_signal_buff_size()) { + rb_thread_wakeup_timer_thread(); + } } static void ``` But maybe we can also block signals before stopping timer-thread. Unsubscribe: