Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.3k
gh-137433: Fix deadlock with stop-the-world and daemon threads#137735
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
gh-137433: Fix deadlock with stop-the-world and daemon threads#137735
Uh oh!
There was an error while loading.Please reload this page.
Conversation
There was a deadlock originally seen by Memray when a daemon threadenabled or disabled profiling while the interpreter was shutting down.I think this could also happen with garbage collection, but I haven'tseen that in practice.The daemon thread could be hung while trying acquire the global rwmutexthat prevents overlapping global and per-interpreter stop-the-world events.Since it already held the main interpreter's stop-the-world lock, italso deadlocked the main thread, which is trying to perform interpreterfinalization.Swap the order of lock acquisition to prevent this deadlock.Additionally, refactor `_PyParkingLot_Park` so that the global bucketshashtable is left in a clean state if the thread is hung in`PyEval_AcquireThread`.
ZeroIntensity left a comment
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. I'm not a huge fan of usingPyEval_AcquireThread/PyEval_ReleaseThread over_PyThreadState_Attach/_PyThreadState_Detach, but since those were there already I'm not going to bother complaining about it.
90fe325 intopython:mainUh oh!
There was an error while loading.Please reload this page.
Thanks@colesbury for the PR 🌮🎉.. I'm working now to backport this PR to: 3.14. |
…ythongh-137735)There was a deadlock originally seen by Memray when a daemon threadenabled or disabled profiling while the interpreter was shutting down.I think this could also happen with garbage collection, but I haven'tseen that in practice.The daemon thread could be hung while trying acquire the global rwmutexthat prevents overlapping global and per-interpreter stop-the-world events.Since it already held the main interpreter's stop-the-world lock, italso deadlocked the main thread, which is trying to perform interpreterfinalization.Swap the order of lock acquisition to prevent this deadlock.Additionally, refactor `_PyParkingLot_Park` so that the global bucketshashtable is left in a clean state if the thread is hung in`PyEval_AcquireThread`.(cherry picked from commit90fe325)Co-authored-by: Sam Gross <colesbury@gmail.com>
GH-138965 is a backport of this pull request to the3.14 branch. |
…gh-137735) (GH-138965)There was a deadlock originally seen by Memray when a daemon threadenabled or disabled profiling while the interpreter was shutting down.I think this could also happen with garbage collection, but I haven'tseen that in practice.The daemon thread could be hung while trying acquire the global rwmutexthat prevents overlapping global and per-interpreter stop-the-world events.Since it already held the main interpreter's stop-the-world lock, italso deadlocked the main thread, which is trying to perform interpreterfinalization.Swap the order of lock acquisition to prevent this deadlock.Additionally, refactor `_PyParkingLot_Park` so that the global bucketshashtable is left in a clean state if the thread is hung in`PyEval_AcquireThread`.(cherry picked from commit90fe325)Co-authored-by: Sam Gross <colesbury@gmail.com>
Uh oh!
There was an error while loading.Please reload this page.
There was a deadlock originally seen by Memray when a daemon thread enabled or disabled profiling while the interpreter was shutting down. I think this could also happen with garbage collection, but I haven't seen that in practice.
The daemon thread could be hung while trying acquire the global rwmutex that prevents overlapping global and per-interpreter stop-the-world events. Since it already held the main interpreter's stop-the-world lock, it also deadlocked the main thread, which is trying to perform interpreter finalization.
Swap the order of lock acquisition to prevent this deadlock. Additionally, refactor
_PyParkingLot_Parkso that the global buckets hashtable is left in a clean state if the thread is hung inPyEval_AcquireThread.