[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 be1dfccdf2)

Co-authored-by: Brett Simmers <swtaarrs@users.noreply.github.com>
This commit is contained in:
Miss Islington (bot) 2024-05-23 23:27:38 +02:00 committed by GitHub
parent 8fd8cc564b
commit d98d6b1776
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 73 additions and 60 deletions

View file

@ -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