mirror of
https://github.com/python/cpython.git
synced 2025-12-31 04:23:37 +00:00
There is a race between when `Thread._tstate_lock` is released[^1] in `Thread._wait_for_tstate_lock()` and when `Thread._stop()` asserts[^2] that it is unlocked. Consider the following execution involving threads A, B, and C: 1. A starts. 2. B joins A, blocking on its `_tstate_lock`. 3. C joins A, blocking on its `_tstate_lock`. 4. A finishes and releases its `_tstate_lock`. 5. B acquires A's `_tstate_lock` in `_wait_for_tstate_lock()`, releases it, but is swapped out before calling `_stop()`. 6. C is scheduled, acquires A's `_tstate_lock` in `_wait_for_tstate_lock()` but is swapped out before releasing it. 7. B is scheduled, calls `_stop()`, which asserts that A's `_tstate_lock` is not held. However, C holds it, so the assertion fails. The race can be reproduced[^3] by inserting sleeps at the appropriate points in the threading code. To do so, run the `repro_join_race.py` from the linked repo. There are two main parts to this PR: 1. `_tstate_lock` is replaced with an event that is attached to `PyThreadState`. The event is set by the runtime prior to the thread being cleared (in the same place that `_tstate_lock` was released). `Thread.join()` blocks waiting for the event to be set. 2. `_PyInterpreterState_WaitForThreads()` provides the ability to wait for all non-daemon threads to exit. To do so, an `is_daemon` predicate was added to `PyThreadState`. This field is set each time a thread is created. `threading._shutdown()` now calls into `_PyInterpreterState_WaitForThreads()` instead of waiting on `_tstate_lock`s. [^1]: |
||
|---|---|---|
| .. | ||
| 2024-02-01-03-09-38.gh-issue-114271.raCkt5.rst | ||
| 2024-02-26-10-06-50.gh-issue-113308.MbvOFt.rst | ||
| 2024-03-01-20-23-57.gh-issue-90535.wXm-jC.rst | ||
| 2024-03-06-18-30-37.gh-issue-116401.3Wcda2.rst | ||
| 2024-03-08-11-31-49.gh-issue-116484.VMAsU7.rst | ||
| 2024-03-13-15-45-54.gh-issue-63283.OToJnG.rst | ||
| 2024-03-14-10-01-23.gh-issue-116811._h5iKP.rst | ||
| 2024-03-14-14-01-46.gh-issue-116764.moB3Lc.rst | ||
| 2024-03-14-17-24-59.gh-issue-106531.9ehywi.rst | ||
| 2024-03-14-20-59-28.gh-issue-90095.7UaJ1U.rst | ||
| README.rst | ||
Put news entry `blurb`_ files for the *Library* section in this directory. .. _blurb: https://pypi.org/project/blurb/