Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.7k
Closed
Description
Bug report
Bug description:
There is a race between whenThread._tstate_lock is released1 inThread._wait_for_tstate_lock() and whenThread._stop() asserts2 that it is unlocked. Consider the following execution involving threads A, B, and C:
- A starts.
- B joins A, blocking on its
_tstate_lock. - C joins A, blocking on its
_tstate_lock. - A finishes and releases its
_tstate_lock. - B acquires A's
_tstate_lockin_wait_for_tstate_lock(), releases it, but is swapped out before calling_stop(). - C is scheduled, acquires A's
_tstate_lockin_wait_for_tstate_lock()but is swapped out before releasing it. - B is scheduled, calls
_stop(), which asserts that A's_tstate_lockis not held. However, C holds it, so the assertion fails.
The race can be reproduced3 by inserting sleeps at the appropriate points in the threading code. To do so, run therepro_join_race.py from the linked repo.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux