From 87a85550edd786665e081b355c6af62c4854b1d7 Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Thu, 8 Aug 2024 02:10:15 -0700 Subject: [PATCH] Re-initialize vm->ractor.sched.lock after fork Previously under certain conditions it was possible to encounter a deadlock in the forked child process if ractor.sched.lock was held. Co-authored-by: Nathan Froyd --- bootstraptest/test_fork.rb | 22 ++++++++++++++++++++++ thread_pthread.c | 1 + 2 files changed, 23 insertions(+) diff --git a/bootstraptest/test_fork.rb b/bootstraptest/test_fork.rb index 83923dad97..9e64f1d026 100644 --- a/bootstraptest/test_fork.rb +++ b/bootstraptest/test_fork.rb @@ -75,3 +75,25 @@ assert_equal '[1, 2]', %q{ end }, '[ruby-dev:44005] [Ruby 1.9 - Bug #4950]' +assert_equal 'ok', %q{ + def now = Process.clock_gettime(Process::CLOCK_MONOTONIC) + + Thread.new do + loop { sleep 0.0001 } + end + + 10.times do + pid = fork{ exit!(0) } + deadline = now + 1 + until Process.waitpid(pid, Process::WNOHANG) + if now > deadline + Process.kill(:KILL, pid) + raise "failed" + end + sleep 0.001 + end + rescue NotImplementedError + end + :ok +}, '[Bug #20670]' + diff --git a/thread_pthread.c b/thread_pthread.c index a4363aec48..3ebb67aaa3 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -1556,6 +1556,7 @@ thread_sched_atfork(struct rb_thread_sched *sched) } vm->ractor.sched.running_cnt = 0; + rb_native_mutex_initialize(&vm->ractor.sched.lock); // rb_native_cond_destroy(&vm->ractor.sched.cond); rb_native_cond_initialize(&vm->ractor.sched.cond); rb_native_cond_initialize(&vm->ractor.sched.barrier_complete_cond);