summaryrefslogtreecommitdiffstats
path: root/Include
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2024-05-23 21:27:38 (GMT)
committerGitHub <noreply@github.com>2024-05-23 21:27:38 (GMT)
commitd98d6b1776996484e05ec6b755a6770977a5000a (patch)
treeefcafc59d80992ed2bd0964c04fef01a380beea4 /Include
parent8fd8cc564bea243e30cc8881a9981ab85e09fe81 (diff)
downloadcpython-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.h4
-rw-r--r--Include/internal/pycore_ceval.h7
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