-
-
Notifications
You must be signed in to change notification settings - Fork 30.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gh-118727: Don't drop the GIL in drop_gil()
unless the current thread holds it
#118745
Conversation
I realized while writing up an explanation of my changes that the commit I just pushed isn't quite right. I changed |
This should be ready now - I updated the description to reflect the changes. |
drop_gil()
unless the current thread holds it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall this LGTM. I think it's worth having tstate->_status.holds_gil
in the default build as well.
(moved from the issue where I accidentally posted this)
|
Does applying |
@swtaarrs - I observed a hang when running I think there's an issue with
|
Thanks, good catch. I should probably pull |
The commit I just pushed should address the I'm running the tsan tests in a loop locally to see if it hangs again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@ericsnowcurrently - would you like to re-review this or should I go ahead and merge it? |
I'll take a quick look tomorrow. |
@ericsnowcurrently will you have time to take a look today? |
Sorry for the delay. I don't have any objections. If you both are confident about the solution then I'm on board. 😄 |
Great! As a heads up, there is a different bug that affects the same test case (#119369). |
Thanks @swtaarrs for the PR, and @colesbury for merging it 🌮🎉.. I'm working now to backport this PR to: 3.13. |
…t thread holds it (pythonGH-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. (cherry picked from commit be1dfcc) Co-authored-by: Brett Simmers <swtaarrs@users.noreply.github.com>
GH-119474 is a backport of this pull request to the 3.13 branch. |
…nt 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 be1dfcc) Co-authored-by: Brett Simmers <swtaarrs@users.noreply.github.com>
…t thread holds it (python#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.
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, becausedetach_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 indrop_gil()
instead ofgil->enabled
. As part of this, add an explicitthread_dying
argument todrop_gil()
, separating that concept from whether or not it's safe to dereferencetstate
.This fixes a crash in
test_multiprocessing_pool_circular_import()
, so I've reenabled it.PyThreadState_DeleteCurrent
: drop_gil: GIL is not locked (free-threading) #118727