summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Gruber <luke.gruber@shopify.com>2025-11-26 17:14:55 -0500
committerGitHub <noreply@github.com>2025-11-26 17:14:55 -0500
commitbee02c41bc15780a45f47986ef638e17ca323ec3 (patch)
tree74c7299fe1e0b72e7bab35592ba5bcd3ce8e01fb
parent1660b8145c30f53771671dec343fa7025a953fb5 (diff)
Fix a ractor barrier issue during VM cleanup. (#15091)
-rw-r--r--ractor.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/ractor.c b/ractor.c
index 41c32b79de..8238d9a456 100644
--- a/ractor.c
+++ b/ractor.c
@@ -834,13 +834,11 @@ rb_ractor_terminate_all(void)
VM_ASSERT(cr == GET_RACTOR()); // only main-ractor's main-thread should kick it.
- if (vm->ractor.cnt > 1) {
- RB_VM_LOCK();
- {
- ractor_terminal_interrupt_all(vm); // kill all ractors
- }
- RB_VM_UNLOCK();
+ RB_VM_LOCK();
+ {
+ ractor_terminal_interrupt_all(vm); // kill all ractors
}
+ RB_VM_UNLOCK();
rb_thread_terminate_all(GET_THREAD()); // kill other threads in main-ractor and wait
RB_VM_LOCK();
@@ -853,6 +851,17 @@ rb_ractor_terminate_all(void)
rb_vm_ractor_blocking_cnt_inc(vm, cr, __FILE__, __LINE__);
rb_del_running_thread(rb_ec_thread_ptr(cr->threads.running_ec));
rb_vm_cond_timedwait(vm, &vm->ractor.sync.terminate_cond, 1000 /* ms */);
+#ifdef RUBY_THREAD_PTHREAD_H
+ while (vm->ractor.sched.barrier_waiting) {
+ // A barrier is waiting. Threads relinquish the VM lock before joining the barrier and
+ // since we just acquired the VM lock back, we're blocking other threads from joining it.
+ // We loop until the barrier is over. We can't join this barrier because our thread isn't added to
+ // running_threads until the call below to `rb_add_running_thread`.
+ RB_VM_UNLOCK();
+ unsigned int lev;
+ RB_VM_LOCK_ENTER_LEV_NB(&lev);
+ }
+#endif
rb_add_running_thread(rb_ec_thread_ptr(cr->threads.running_ec));
rb_vm_ractor_blocking_cnt_dec(vm, cr, __FILE__, __LINE__);