mirror of
https://github.com/python/cpython.git
synced 2025-11-03 03:22:27 +00:00
gh-118727: Don't drop the GIL in drop_gil() unless the current thread holds it (#118745)
`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.
This commit is contained in:
parent
b30d30c747
commit
be1dfccdf2
5 changed files with 73 additions and 60 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue