@@ -834,13 +834,11 @@ rb_ractor_terminate_all(void)
834834
835835 VM_ASSERT (cr == GET_RACTOR ()); // only main-ractor's main-thread should kick it.
836836
837- if (vm -> ractor .cnt > 1 ) {
838- RB_VM_LOCK ();
839- {
840- ractor_terminal_interrupt_all (vm ); // kill all ractors
841- }
842- RB_VM_UNLOCK ();
837+ RB_VM_LOCK ();
838+ {
839+ ractor_terminal_interrupt_all (vm ); // kill all ractors
843840 }
841+ RB_VM_UNLOCK ();
844842 rb_thread_terminate_all (GET_THREAD ()); // kill other threads in main-ractor and wait
845843
846844 RB_VM_LOCK ();
@@ -853,6 +851,17 @@ rb_ractor_terminate_all(void)
853851 rb_vm_ractor_blocking_cnt_inc (vm , cr , __FILE__ , __LINE__ );
854852 rb_del_running_thread (rb_ec_thread_ptr (cr -> threads .running_ec ));
855853 rb_vm_cond_timedwait (vm , & vm -> ractor .sync .terminate_cond , 1000 /* ms */ );
854+ #ifdef RUBY_THREAD_PTHREAD_H
855+ while (vm -> ractor .sched .barrier_waiting ) {
856+ // A barrier is waiting. Threads relinquish the VM lock before joining the barrier and
857+ // since we just acquired the VM lock back, we're blocking other threads from joining it.
858+ // We loop until the barrier is over. We can't join this barrier because our thread isn't added to
859+ // running_threads until the call below to `rb_add_running_thread`.
860+ RB_VM_UNLOCK ();
861+ unsigned int lev ;
862+ RB_VM_LOCK_ENTER_LEV_NB (& lev );
863+ }
864+ #endif
856865 rb_add_running_thread (rb_ec_thread_ptr (cr -> threads .running_ec ));
857866 rb_vm_ractor_blocking_cnt_dec (vm , cr , __FILE__ , __LINE__ );
858867
0 commit comments