Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Include/internal/pycore_lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ _PyMutex_at_fork_reinit(PyMutex *m)

typedef enum _PyLockFlags {
// Do not detach/release the GIL when waiting on the lock.
//
// Note that code executed while holding a mutex with this flag must
// not detach, reach a safepoint or initiate a stop-the-world pause.
// Otherwise, a non-detaching waiter may remain waiting for this mutex and
// prevent the pause from completing.
_Py_LOCK_DONT_DETACH = 0,

// Detach/release the GIL while waiting on the lock.
Expand Down
9 changes: 9 additions & 0 deletions Objects/unicodeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -14722,6 +14722,15 @@ intern_common(PyInterpreterState *interp, PyObject *s /* stolen */,
}
#endif

// Why _Py_LOCK_DONT_DETACH is used here: waiting for the interned mutex
// must not detach the thread state. Extension code is expected to
// detach before blocking on opaque external synchronization. However,
// the lock used for C++ static initialization is hidden, making
// that difficult, and it is common for C++ extensions to call
// PyUnicode_InternFromString() from static initializers. Detaching here
// can therefore deadlock: a stop-the-world pause may prevent the lock
// owner from reattaching while the pause waits for another attached
// thread blocked on the hidden lock.
FT_MUTEX_LOCK_FLAGS(INTERN_MUTEX, _Py_LOCK_DONT_DETACH);
PyObject *t;
{
Expand Down
Loading