Skip to content

Commit 82cf216

Browse files
committed
Merge branch 'pythongh-116522-fork-shutdown' into nogil-integration
2 parents 0cd9f9c + b13d1e5 commit 82cf216

File tree

3 files changed

+18
-3
lines changed

3 files changed

+18
-3
lines changed

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
@@ -1911,6 +1911,9 @@ Py_FinalizeEx(void)
19111911
int malloc_stats = tstate->interp->config.malloc_stats;
19121912
#endif
19131913

1914+
/* Ensure that remaining threads are detached */
1915+
_PyEval_StopTheWorldAll(runtime);
1916+
19141917
/* Remaining daemon threads will automatically exit
19151918
when they attempt to take the GIL (ex: PyEval_RestoreThread()). */
19161919
_PyInterpreterState_SetFinalizing(tstate->interp, tstate);

Python/pystate.c

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

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

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

0 commit comments

Comments
 (0)