Skip to content

Commit

Permalink
Merge branch 'pythongh-116522-fork-shutdown' into nogil-integration
Browse files Browse the repository at this point in the history
  • Loading branch information
colesbury committed Mar 13, 2024
2 parents e4fb11c + b13d1e5 commit fda5574
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 3 deletions.
12 changes: 9 additions & 3 deletions Modules/posixmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -613,11 +613,16 @@ PyOS_BeforeFork(void)
run_at_forkers(interp->before_forkers, 1);

_PyImport_AcquireLock(interp);
_PyEval_StopTheWorldAll(&_PyRuntime);
HEAD_LOCK(&_PyRuntime);
}

void
PyOS_AfterFork_Parent(void)
{
HEAD_UNLOCK(&_PyRuntime);
_PyEval_StartTheWorldAll(&_PyRuntime);

PyInterpreterState *interp = _PyInterpreterState_GET();
if (_PyImport_ReleaseLock(interp) <= 0) {
Py_FatalError("failed releasing import lock after fork");
Expand All @@ -632,6 +637,7 @@ PyOS_AfterFork_Child(void)
PyStatus status;
_PyRuntimeState *runtime = &_PyRuntime;

// re-creates runtime->interpreters.mutex (HEAD_UNLOCK)
status = _PyRuntimeState_ReInitThreads(runtime);
if (_PyStatus_EXCEPTION(status)) {
goto fatal_error;
Expand Down Expand Up @@ -7858,9 +7864,9 @@ os_fork1_impl(PyObject *module)
/* child: this clobbers and resets the import lock. */
PyOS_AfterFork_Child();
} else {
warn_about_fork_with_threads("fork1");
/* parent: release the import lock. */
PyOS_AfterFork_Parent();
warn_about_fork_with_threads("fork1");
}
if (pid == -1) {
errno = saved_errno;
Expand Down Expand Up @@ -7906,9 +7912,9 @@ os_fork_impl(PyObject *module)
/* child: this clobbers and resets the import lock. */
PyOS_AfterFork_Child();
} else {
warn_about_fork_with_threads("fork");
/* parent: release the import lock. */
PyOS_AfterFork_Parent();
warn_about_fork_with_threads("fork");
}
if (pid == -1) {
errno = saved_errno;
Expand Down Expand Up @@ -8737,9 +8743,9 @@ os_forkpty_impl(PyObject *module)
/* child: this clobbers and resets the import lock. */
PyOS_AfterFork_Child();
} else {
warn_about_fork_with_threads("forkpty");
/* parent: release the import lock. */
PyOS_AfterFork_Parent();
warn_about_fork_with_threads("forkpty");
}
if (pid == -1) {
return posix_error();
Expand Down
3 changes: 3 additions & 0 deletions Python/pylifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -1911,6 +1911,9 @@ Py_FinalizeEx(void)
int malloc_stats = tstate->interp->config.malloc_stats;
#endif

/* Ensure that remaining threads are detached */
_PyEval_StopTheWorldAll(runtime);

/* Remaining daemon threads will automatically exit
when they attempt to take the GIL (ex: PyEval_RestoreThread()). */
_PyInterpreterState_SetFinalizing(tstate->interp, tstate);
Expand Down
6 changes: 6 additions & 0 deletions Python/pystate.c
Original file line number Diff line number Diff line change
Expand Up @@ -1693,6 +1693,10 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate)
PyInterpreterState *interp = tstate->interp;
_PyRuntimeState *runtime = interp->runtime;

#ifdef Py_GIL_DISABLED
assert(runtime->stoptheworld.world_stopped);
#endif

HEAD_LOCK(runtime);
/* Remove all thread states, except tstate, from the linked list of
thread states. This will allow calling PyThreadState_Clear()
Expand All @@ -1711,6 +1715,8 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate)
interp->threads.head = tstate;
HEAD_UNLOCK(runtime);

_PyEval_StartTheWorldAll(runtime);

/* Clear and deallocate all stale thread states. Even if this
executes Python code, we should be safe since it executes
in the current thread, not one of the stale threads. */
Expand Down

0 comments on commit fda5574

Please sign in to comment.