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().
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(
--- /dev/null
+Fix a crash when calling :func:`os.fork` on some operating systems,
+including SerenityOS.
_PyEval_StartTheWorldAll(&_PyRuntime);
_PyThreadState_DeleteList(list);
+ _PyImport_ReInitLock(tstate->interp);
_PyImport_ReleaseLock(tstate->interp);
_PySignal_AfterFork();
_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 */