Skip to content

Commit b38230b

Browse files
committed
Add comments about _Py_LOCK_DONT_DETACH usage.
The need for _Py_LOCK_DONT_DETACH in intern_common() is not so obvious. Add some code comments explaining why we use that flag. Also, add a comment to the flag noting that you need extra care when writing code that holds a mutex with this flag set.
1 parent f62050d commit b38230b

2 files changed

Lines changed: 14 additions & 0 deletions

File tree

Include/internal/pycore_lock.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ _PyMutex_at_fork_reinit(PyMutex *m)
3434

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

3944
// Detach/release the GIL while waiting on the lock.

Objects/unicodeobject.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14722,6 +14722,15 @@ intern_common(PyInterpreterState *interp, PyObject *s /* stolen */,
1472214722
}
1472314723
#endif
1472414724

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

0 commit comments

Comments
 (0)