Uh oh!
There was an error while loading. Please reload this page.
gh-118727: Don't drop the GIL in drop_gil() unless the current thread holds it - #118745
Conversation
Uh oh!
There was an error while loading. Please reload this page.
swtaarrs
commented
May 8, 2024
I realized while writing up an explanation of my changes that the commit I just pushed isn't quite right. I changed |
swtaarrs
commented
May 8, 2024
This should be ready now - I updated the description to reflect the changes. |
drop_gil() unless the current thread holds it
colesbury
left a comment
There was a problem hiding this comment.
Overall this LGTM. I think it's worth having tstate->_status.holds_gil in the default build as well.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
swtaarrs
commented
May 9, 2024
(moved from the issue where I accidentally posted this)
|
ericsnowcurrently
commented
May 10, 2024
Does applying |
colesbury
commented
May 10, 2024
@swtaarrs - I observed a hang when running I think there's an issue with
|
swtaarrs
commented
May 13, 2024
Thanks, good catch. I should probably pull |
swtaarrs
commented
May 13, 2024
The commit I just pushed should address the I'm running the tsan tests in a loop locally to see if it hangs again. |
colesbury
commented
May 21, 2024
@ericsnowcurrently - would you like to re-review this or should I go ahead and merge it? |
ericsnowcurrently
commented
May 21, 2024
I'll take a quick look tomorrow. |
swtaarrs
commented
May 23, 2024
@ericsnowcurrently will you have time to take a look today? |
ericsnowcurrently
commented
May 23, 2024
Sorry for the delay. I don't have any objections. If you both are confident about the solution then I'm on board. 😄 |
colesbury
commented
May 23, 2024
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_dyingargument 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