gh-126688: Reinit import lock after fork (#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().
This commit is contained in:
Sam Gross 2024-11-12 20:53:58 +00:00 committed by GitHub
parent bf224bd7ce
commit 5610860840
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 11 additions and 0 deletions

View File

@ -21,6 +21,7 @@ extern int _PyImport_SetModuleString(const char *name, PyObject* module);
extern void _PyImport_AcquireLock(PyInterpreterState *interp); extern void _PyImport_AcquireLock(PyInterpreterState *interp);
extern void _PyImport_ReleaseLock(PyInterpreterState *interp); extern void _PyImport_ReleaseLock(PyInterpreterState *interp);
extern void _PyImport_ReInitLock(PyInterpreterState *interp);
// This is used exclusively for the sys and builtins modules: // This is used exclusively for the sys and builtins modules:
extern int _PyImport_FixupBuiltin( extern int _PyImport_FixupBuiltin(

View File

@ -0,0 +1,2 @@
Fix a crash when calling :func:`os.fork` on some operating systems,
including SerenityOS.

View File

@ -678,6 +678,7 @@ PyOS_AfterFork_Child(void)
_PyEval_StartTheWorldAll(&_PyRuntime); _PyEval_StartTheWorldAll(&_PyRuntime);
_PyThreadState_DeleteList(list); _PyThreadState_DeleteList(list);
_PyImport_ReInitLock(tstate->interp);
_PyImport_ReleaseLock(tstate->interp); _PyImport_ReleaseLock(tstate->interp);
_PySignal_AfterFork(); _PySignal_AfterFork();

View File

@ -122,6 +122,13 @@ _PyImport_ReleaseLock(PyInterpreterState *interp)
_PyRecursiveMutex_Unlock(&IMPORT_LOCK(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 */ /* sys.modules */