Skip to content

Commit bcb3865

Browse files
committed
Merge branch 'pythongh-116522-fork-shutdown' into nogil-integration
2 parents b45c98f + c2ebedb commit bcb3865

3 files changed

Lines changed: 18 additions & 3 deletions

File tree

‎Modules/posixmodule.c‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -613,11 +613,16 @@ PyOS_BeforeFork(void)
613613
run_at_forkers(interp->before_forkers, 1);
614614

615615
_PyImport_AcquireLock(interp);
616+
_PyEval_StopTheWorldAll(&_PyRuntime);
617+
HEAD_LOCK(&_PyRuntime);
616618
}
617619

618620
void
619621
PyOS_AfterFork_Parent(void)
620622
{
623+
HEAD_UNLOCK(&_PyRuntime);
624+
_PyEval_StartTheWorldAll(&_PyRuntime);
625+
621626
PyInterpreterState *interp = _PyInterpreterState_GET();
622627
if (_PyImport_ReleaseLock(interp) <= 0) {
623628
Py_FatalError("failed releasing import lock after fork");
@@ -632,6 +637,7 @@ PyOS_AfterFork_Child(void)
632637
PyStatus status;
633638
_PyRuntimeState *runtime = &_PyRuntime;
634639

640+
// re-creates runtime->interpreters.mutex (HEAD_UNLOCK)
635641
status = _PyRuntimeState_ReInitThreads(runtime);
636642
if (_PyStatus_EXCEPTION(status)) {
637643
goto fatal_error;
@@ -7858,9 +7864,9 @@ os_fork1_impl(PyObject *module)
78587864
/* child: this clobbers and resets the import lock. */
78597865
PyOS_AfterFork_Child();
78607866
} else {
7861-
warn_about_fork_with_threads("fork1");
78627867
/* parent: release the import lock. */
78637868
PyOS_AfterFork_Parent();
7869+
warn_about_fork_with_threads("fork1");
78647870
}
78657871
if (pid == -1) {
78667872
errno = saved_errno;
@@ -7906,9 +7912,9 @@ os_fork_impl(PyObject *module)
79067912
/* child: this clobbers and resets the import lock. */
79077913
PyOS_AfterFork_Child();
79087914
} else {
7909-
warn_about_fork_with_threads("fork");
79107915
/* parent: release the import lock. */
79117916
PyOS_AfterFork_Parent();
7917+
warn_about_fork_with_threads("fork");
79127918
}
79137919
if (pid == -1) {
79147920
errno = saved_errno;
@@ -8737,9 +8743,9 @@ os_forkpty_impl(PyObject *module)
87378743
/* child: this clobbers and resets the import lock. */
87388744
PyOS_AfterFork_Child();
87398745
} else {
8740-
warn_about_fork_with_threads("forkpty");
87418746
/* parent: release the import lock. */
87428747
PyOS_AfterFork_Parent();
8748+
warn_about_fork_with_threads("forkpty");
87438749
}
87448750
if (pid == -1) {
87458751
return posix_error();

‎Python/pylifecycle.c‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1918,6 +1918,9 @@ Py_FinalizeEx(void)
19181918
runtime->initialized = 0;
19191919
runtime->core_initialized = 0;
19201920

1921+
/* Ensure that remaining threads are detached */
1922+
_PyEval_StopTheWorldAll(runtime);
1923+
19211924
// XXX Call something like _PyImport_Disable() here?
19221925

19231926
/* Destroy the state of all threads of the interpreter, except of the

‎Python/pystate.c‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,6 +1692,10 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate)
16921692
PyInterpreterState *interp = tstate->interp;
16931693
_PyRuntimeState *runtime = interp->runtime;
16941694

1695+
#ifdef Py_GIL_DISABLED
1696+
assert(runtime->stoptheworld.world_stopped);
1697+
#endif
1698+
16951699
HEAD_LOCK(runtime);
16961700
/* Remove all thread states, except tstate, from the linked list of
16971701
thread states. This will allow calling PyThreadState_Clear()
@@ -1710,6 +1714,8 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate)
17101714
interp->threads.head = tstate;
17111715
HEAD_UNLOCK(runtime);
17121716

1717+
_PyEval_StartTheWorldAll(runtime);
1718+
17131719
/* Clear and deallocate all stale thread states. Even if this
17141720
executes Python code, we should be safe since it executes
17151721
in the current thread, not one of the stale threads. */

0 commit comments

Comments
 (0)