Skip to content

Commit 5e86cca

Browse files
committed
pythongh-126688: Reinit import lock after fork
The PyMutex implementation supports unlocking after fork because we clear the list of watiers 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().
1 parent 8fa4dc4 commit 5e86cca

File tree

3 files changed

+11
-1
lines changed

3 files changed

+11
-1
lines changed

Include/internal/pycore_lock.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,13 @@ extern PyLockStatus _PyRecursiveMutex_LockTimed(_PyRecursiveMutex *m, PyTime_t t
164164
PyAPI_FUNC(void) _PyRecursiveMutex_Unlock(_PyRecursiveMutex *m);
165165
extern int _PyRecursiveMutex_TryUnlock(_PyRecursiveMutex *m);
166166

167+
static inline void
168+
_PyRecursiveMutex_at_fork_reinit(_PyRecursiveMutex *m)
169+
{
170+
memset(m, 0, sizeof(*m));
171+
}
172+
173+
167174
// A readers-writer (RW) lock. The lock supports multiple concurrent readers or
168175
// a single writer. The lock is write-preferring: if a writer is waiting while
169176
// the lock is read-locked then, new readers will be blocked. This avoids
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix a crash when calling :func:`os.fork` on some operating systems,
2+
including SerenityOS.

Modules/posixmodule.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,8 @@ PyOS_AfterFork_Child(void)
678678
_PyEval_StartTheWorldAll(&_PyRuntime);
679679
_PyThreadState_DeleteList(list);
680680

681-
_PyImport_ReleaseLock(tstate->interp);
681+
// gh-126688: Reinit lock because thread id may differ in child process.
682+
_PyRecursiveMutex_at_fork_reinit(&tstate->interp->imports.lock);
682683

683684
_PySignal_AfterFork();
684685

0 commit comments

Comments
 (0)