From 6f77b813394fcc2e67fbcd2e2b7240e45ded976f Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Tue, 12 Nov 2024 20:53:58 +0000 Subject: [PATCH] gh-126688: Reinit import lock after fork (GH-126692) The PyMutex implementation supports unlocking after fork because we clear the list of waiters in parking_lot.c. This doesn't work as well for _PyRecursiveMutex because on some systems, such as SerenityOS, the thread id is not preserved across fork(). (cherry picked from commit 5610860840aa71b186fc5639211dd268b817d65f) Co-authored-by: Sam Gross --- Include/internal/pycore_import.h | 1 + .../2024-11-11-17-02-48.gh-issue-126688.QiOXUi.rst | 2 ++ Modules/posixmodule.c | 1 + Python/import.c | 7 +++++++ 4 files changed, 11 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-11-11-17-02-48.gh-issue-126688.QiOXUi.rst diff --git a/Include/internal/pycore_import.h b/Include/internal/pycore_import.h index 3806e0d3cd0a95..55029abdd31b5a 100644 --- a/Include/internal/pycore_import.h +++ b/Include/internal/pycore_import.h @@ -21,6 +21,7 @@ extern int _PyImport_SetModuleString(const char *name, PyObject* module); extern void _PyImport_AcquireLock(PyInterpreterState *interp); extern void _PyImport_ReleaseLock(PyInterpreterState *interp); +extern void _PyImport_ReInitLock(PyInterpreterState *interp); // This is used exclusively for the sys and builtins modules: extern int _PyImport_FixupBuiltin( diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-11-11-17-02-48.gh-issue-126688.QiOXUi.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-11-17-02-48.gh-issue-126688.QiOXUi.rst new file mode 100644 index 00000000000000..30aa5722f0ea02 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-11-17-02-48.gh-issue-126688.QiOXUi.rst @@ -0,0 +1,2 @@ +Fix a crash when calling :func:`os.fork` on some operating systems, +including SerenityOS. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 5edc9dcc7ff3e5..a09305c91ecbba 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -678,6 +678,7 @@ PyOS_AfterFork_Child(void) _PyEval_StartTheWorldAll(&_PyRuntime); _PyThreadState_DeleteList(list); + _PyImport_ReInitLock(tstate->interp); _PyImport_ReleaseLock(tstate->interp); _PySignal_AfterFork(); diff --git a/Python/import.c b/Python/import.c index 1541d5a55b82ec..0f08e6dfc247bd 100644 --- a/Python/import.c +++ b/Python/import.c @@ -120,6 +120,13 @@ _PyImport_ReleaseLock(PyInterpreterState *interp) _PyRecursiveMutex_Unlock(&IMPORT_LOCK(interp)); } +void +_PyImport_ReInitLock(PyInterpreterState *interp) +{ + // gh-126688: Thread id may change after fork() on some operating systems. + IMPORT_LOCK(interp).thread = PyThread_get_thread_ident_ex(); +} + /***************/ /* sys.modules */