diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2024-05-23 21:27:38 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-23 21:27:38 (GMT) |
commit | d98d6b1776996484e05ec6b755a6770977a5000a (patch) | |
tree | efcafc59d80992ed2bd0964c04fef01a380beea4 /Include | |
parent | 8fd8cc564bea243e30cc8881a9981ab85e09fe81 (diff) | |
download | cpython-d98d6b1776996484e05ec6b755a6770977a5000a.zip cpython-d98d6b1776996484e05ec6b755a6770977a5000a.tar.gz cpython-d98d6b1776996484e05ec6b755a6770977a5000a.tar.bz2 |
[3.13] gh-118727: Don't drop the GIL in `drop_gil()` unless the current thread holds it (GH-118745) (#119474)
`drop_gil()` assumes that its caller is attached, which means that the current
thread holds the GIL if and only if the GIL is enabled, and the enabled-state
of the GIL won't change. This isn't true, though, because `detach_thread()`
calls `_PyEval_ReleaseLock()` after detaching and
`_PyThreadState_DeleteCurrent()` calls it after removing the current thread
from consideration for stop-the-world requests (effectively detaching it).
Fix this by remembering whether or not a thread acquired the GIL when it last
attached, in `PyThreadState._status.holds_gil`, and check this in `drop_gil()`
instead of `gil->enabled`.
This fixes a crash in `test_multiprocessing_pool_circular_import()`, so I've
reenabled it.
(cherry picked from commit be1dfccdf2c5c7671b8a549e969b8cf7d60d9936)
Co-authored-by: Brett Simmers <swtaarrs@users.noreply.github.com>
Diffstat (limited to 'Include')
-rw-r--r-- | Include/cpython/pystate.h | 4 | ||||
-rw-r--r-- | Include/internal/pycore_ceval.h | 7 |
2 files changed, 6 insertions, 5 deletions
diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 2df9ecd..ed3ee09 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -83,6 +83,8 @@ struct _ts { unsigned int bound_gilstate:1; /* Currently in use (maybe holds the GIL). */ unsigned int active:1; + /* Currently holds the GIL. */ + unsigned int holds_gil:1; /* various stages of finalization */ unsigned int finalizing:1; @@ -90,7 +92,7 @@ struct _ts { unsigned int finalized:1; /* padding to align to 4 bytes */ - unsigned int :24; + unsigned int :23; } _status; #ifdef Py_BUILD_CORE # define _PyThreadState_WHENCE_NOTSET -1 diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 48ad067..bd3ba12 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -131,11 +131,10 @@ extern int _PyEval_ThreadsInitialized(void); extern void _PyEval_InitGIL(PyThreadState *tstate, int own_gil); extern void _PyEval_FiniGIL(PyInterpreterState *interp); -// Acquire the GIL and return 1. In free-threaded builds, this function may -// return 0 to indicate that the GIL was disabled and therefore not acquired. -extern int _PyEval_AcquireLock(PyThreadState *tstate); +extern void _PyEval_AcquireLock(PyThreadState *tstate); -extern void _PyEval_ReleaseLock(PyInterpreterState *, PyThreadState *); +extern void _PyEval_ReleaseLock(PyInterpreterState *, PyThreadState *, + int final_release); #ifdef Py_GIL_DISABLED // Returns 0 or 1 if the GIL for the given thread's interpreter is disabled or |