@@ -572,11 +572,18 @@ PyOS_BeforeFork(void)
572
572
run_at_forkers (_PyInterpreterState_GET ()-> before_forkers , 1 );
573
573
574
574
_PyImport_AcquireLock ();
575
+
576
+ // Stop all other threads still attached to the Python VM.
577
+ _PyRuntimeState_StopTheWorld (& _PyRuntime );
578
+ HEAD_LOCK (& _PyRuntime );
575
579
}
576
580
577
581
void
578
582
PyOS_AfterFork_Parent (void )
579
583
{
584
+ HEAD_UNLOCK (& _PyRuntime );
585
+ _PyRuntimeState_StartTheWorld (& _PyRuntime );
586
+
580
587
if (_PyImport_ReleaseLock () <= 0 )
581
588
Py_FatalError ("failed releasing import lock after fork" );
582
589
@@ -606,6 +613,12 @@ PyOS_AfterFork_Child(void)
606
613
tstate -> native_thread_id = PyThread_get_thread_native_id ();
607
614
#endif
608
615
616
+ // re-creates runtime->interpreters.mutex (HEAD_UNLOCK)
617
+ status = _PyRuntimeState_ReInitThreads (runtime );
618
+ if (_PyStatus_EXCEPTION (status )) {
619
+ goto fatal_error ;
620
+ }
621
+
609
622
status = _PyEval_ReInitThreads (tstate );
610
623
if (_PyStatus_EXCEPTION (status )) {
611
624
goto fatal_error ;
@@ -619,13 +632,10 @@ PyOS_AfterFork_Child(void)
619
632
_PySignal_AfterFork ();
620
633
_Py_queue_after_fork ();
621
634
622
- status = _PyRuntimeState_ReInitThreads (runtime );
623
- if (_PyStatus_EXCEPTION (status )) {
624
- goto fatal_error ;
625
- }
626
-
627
635
PyThreadState * garbage = _PyThreadState_UnlinkExcept (runtime , tstate , 1 );
628
636
637
+ _PyRuntimeState_StartTheWorld (runtime );
638
+
629
639
status = _PyInterpreterState_DeleteExceptMain (runtime );
630
640
if (_PyStatus_EXCEPTION (status )) {
631
641
goto fatal_error ;
0 commit comments