Skip to content

Commit 538a842

Browse files
committed
gh-159485: Use the public interpreter guard API for the warnings lock
1 parent 3f35eeb commit 538a842

3 files changed

Lines changed: 18 additions & 35 deletions

File tree

‎Include/internal/pycore_interp_structs.h‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -652,8 +652,6 @@ struct _warnings_runtime_state {
652652
_PyRecursiveMutex lock;
653653
long filters_version;
654654
PyObject *context;
655-
// The lock owner's guard must outlive the mutex unlock.
656-
PyInterpreterGuard *lock_guard;
657655
};
658656

659657
struct _Py_mem_interp_free_queue {

‎Include/internal/pycore_tstate.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ typedef struct _PyThreadStateImpl {
5454
// Reused for the thread's lifetime; owns placeholders while they resolve.
5555
PyObject *lazy_imports;
5656

57+
// Held while this thread owns the warnings lock.
58+
PyInterpreterGuard *warnings_lock_guard;
59+
5760
// Distinguishes between yield and return from PyEval_EvalFrame().
5861
// See gen_send_ex2() in Objects/genobject.c
5962
enum {

‎Python/_warnings.c‎

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "pycore_long.h" // _PyLong_GetZero()
88
#include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing()
99
#include "pycore_pystate.h" // _PyThreadState_GET()
10+
#include "pycore_tstate.h" // _PyThreadStateImpl
1011
#include "pycore_traceback.h" // _Py_DisplaySourceLine()
1112
#include "pycore_tuple.h" // _PyTuple_FromPair
1213
#include "pycore_unicodeobject.h" // _PyUnicode_EqualToASCIIString()
@@ -255,38 +256,24 @@ get_warnings_attr(PyInterpreterState *interp, PyObject *attr, int try_import)
255256
return obj;
256257
}
257258

258-
static _Py_thread_local PyInterpreterGuard warnings_guard;
259-
260259
static inline int
261260
warnings_lock(PyInterpreterState *interp)
262261
{
263262
WarningsState *st = warnings_get_state(interp);
264263
assert(st != NULL);
265-
if (_PyRecursiveMutex_IsLockedByCurrentThread(&st->lock)) {
266-
_PyRecursiveMutex_Lock(&st->lock);
267-
return 0;
268-
}
269-
PyInterpreterGuard *guard = NULL;
270-
if (_PyInterpreterState_GetFinalizing(interp) != _PyThreadState_GET()) {
271-
guard = &warnings_guard;
272-
if (guard->interp != NULL) {
273-
guard = PyMem_RawMalloc(sizeof(*guard));
274-
if (guard == NULL) {
275-
PyErr_NoMemory();
276-
return -1;
277-
}
278-
}
279-
if (_PyInterpreterGuard_TryAcquire(interp, guard) < 0) {
280-
if (guard != &warnings_guard) {
281-
PyMem_RawFree(guard);
282-
}
283-
// Finalization has begun; this thread must stop before it takes
284-
// the lock.
285-
_PyThreadState_HangThread(_PyThreadState_GET());
264+
PyThreadState *tstate = _PyThreadState_GET();
265+
_PyThreadStateImpl *tstate_impl = (_PyThreadStateImpl *)tstate;
266+
if (!_PyRecursiveMutex_IsLockedByCurrentThread(&st->lock) &&
267+
_PyInterpreterState_GetFinalizing(interp) != tstate)
268+
{
269+
assert(tstate_impl->warnings_lock_guard == NULL);
270+
PyInterpreterGuard *guard = PyInterpreterGuard_FromCurrent();
271+
if (guard == NULL) {
272+
return -1;
286273
}
274+
tstate_impl->warnings_lock_guard = guard;
287275
}
288276
_PyRecursiveMutex_Lock(&st->lock);
289-
st->lock_guard = guard;
290277
return 0;
291278
}
292279

@@ -302,17 +289,12 @@ warnings_unlock(PyInterpreterState *interp)
302289
_PyRecursiveMutex_Unlock(&st->lock);
303290
return 0;
304291
}
305-
PyInterpreterGuard *guard = st->lock_guard;
306-
st->lock_guard = NULL;
292+
_PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET();
293+
PyInterpreterGuard *guard = tstate->warnings_lock_guard;
294+
tstate->warnings_lock_guard = NULL;
307295
_PyRecursiveMutex_Unlock(&st->lock);
308296
if (guard != NULL) {
309-
_PyInterpreterGuard_Release(guard);
310-
if (guard == &warnings_guard) {
311-
guard->interp = NULL;
312-
}
313-
else {
314-
PyMem_RawFree(guard);
315-
}
297+
PyInterpreterGuard_Close(guard);
316298
}
317299
return 0;
318300
}

0 commit comments

Comments
 (0)