cpython/Modules
mpage 33da0e844c
gh-114271: Fix race in Thread.join() (#114839)
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]: 441affc9e7/Lib/threading.py (L1201)
[^2]: 441affc9e7/Lib/threading.py (L1115)
[^3]: 8194653279

---------

Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
Co-authored-by: Antoine Pitrou <antoine@python.org>
2024-03-16 13:56:30 +01:00
..
_blake2
_ctypes gh-108494: Fix Argument Clinic LIMITED_CAPI_REGEX (#116610) 2024-03-11 22:42:18 +00:00
_decimal
_hacl
_io
_multiprocessing gh-108494: Fix Argument Clinic LIMITED_CAPI_REGEX (#116610) 2024-03-11 22:42:18 +00:00
_sqlite
_sre
_ssl
_testcapi gh-116417: Move 4 limited C API test files to _testlimitedcapi (#116571) 2024-03-11 10:28:16 +00:00
_testinternalcapi
_testlimitedcapi gh-116417: Build _testinternalcapi with limited C API version 3.5 (#116598) 2024-03-11 15:20:04 +01:00
_xxtestfuzz
cjkcodecs
clinic gh-85283: Build pwd extension with the limited C API (#116841) 2024-03-15 08:49:58 +01:00
expat
_abc.c
_asynciomodule.c gh-116437: Use new C API PyDict_Pop() to simplify the code (GH-116438) 2024-03-07 11:21:08 +02:00
_bisectmodule.c
_bz2module.c
_codecsmodule.c
_collectionsmodule.c
_contextvarsmodule.c
_csv.c gh-116437: Use new C API PyDict_Pop() to simplify the code (GH-116438) 2024-03-07 11:21:08 +02:00
_curses_panel.c
_cursesmodule.c
_datetimemodule.c
_dbmmodule.c
_elementtree.c gh-116437: Use new C API PyDict_Pop() to simplify the code (GH-116438) 2024-03-07 11:21:08 +02:00
_functoolsmodule.c gh-111696, PEP 737: Add PyType_GetModuleName() function (#116824) 2024-03-14 18:17:43 +00:00
_gdbmmodule.c
_hashopenssl.c
_heapqmodule.c
_interpreters_common.h gh-76785: Minor Improvements to "interpreters" Module (gh-116328) 2024-03-05 08:54:46 -07:00
_json.c
_localemodule.c
_lsprof.c
_lzmamodule.c
_math.h
_opcode.c
_operator.c
_pickle.c
_posixsubprocess.c
_queuemodule.c
_randommodule.c
_scproxy.c gh-108494: Fix Argument Clinic LIMITED_CAPI_REGEX (#116610) 2024-03-11 22:42:18 +00:00
_ssl.c
_ssl.h
_ssl_data_31.h
_ssl_data_111.h
_ssl_data_300.h
_stat.c gh-108494: Fix Argument Clinic LIMITED_CAPI_REGEX (#116610) 2024-03-11 22:42:18 +00:00
_statisticsmodule.c
_struct.c
_suggestions.c
_sysconfig.c
_testbuffer.c
_testcapi_feature_macros.inc
_testcapimodule.c gh-111696, PEP 737: Add PyType_GetModuleName() function (#116824) 2024-03-14 18:17:43 +00:00
_testclinic.c
_testclinic_limited.c gh-116646: Add limited C API support to AC fildes converter (#116769) 2024-03-14 10:28:58 +01:00
_testexternalinspection.c gh-114099 - Add iOS testbed, plus Makefile target to invoke it. (gh-115930) 2024-03-06 23:24:52 -05:00
_testimportmultiple.c gh-108494: Fix Argument Clinic LIMITED_CAPI_REGEX (#116610) 2024-03-11 22:42:18 +00:00
_testinternalcapi.c gh-111696, PEP 737: Add PyType_GetModuleName() function (#116824) 2024-03-14 18:17:43 +00:00
_testlimitedcapi.c gh-116417: Move 4 limited C API test files to _testlimitedcapi (#116571) 2024-03-11 10:28:16 +00:00
_testmultiphase.c
_testsinglephase.c
_threadmodule.c gh-114271: Fix race in Thread.join() (#114839) 2024-03-16 13:56:30 +01:00
_tkinter.c
_tracemalloc.c
_typingmodule.c
_uuidmodule.c gh-108494: Fix Argument Clinic LIMITED_CAPI_REGEX (#116610) 2024-03-11 22:42:18 +00:00
_weakref.c
_winapi.c
_xxinterpchannelsmodule.c gh-76785: Minor Improvements to "interpreters" Module (gh-116328) 2024-03-05 08:54:46 -07:00
_xxinterpqueuesmodule.c gh-116386: Fix format string "%ld" warning in _xxinterpqueuesmodule (#116387) 2024-03-07 09:44:26 +03:00
_xxsubinterpretersmodule.c
_zoneinfo.c
addrinfo.h
arraymodule.c gh-116447: Fix possible UB in arraymodule and getargs (#116459) 2024-03-08 13:49:52 +03:00
atexitmodule.c
binascii.c
cmathmodule.c
config.c.in
errnomodule.c gh-108494: Fix Argument Clinic LIMITED_CAPI_REGEX (#116610) 2024-03-11 22:42:18 +00:00
faulthandler.c
fcntlmodule.c gh-85283: Build fcntl extension with the limited C API (#116791) 2024-03-14 12:01:13 +00:00
gc_weakref.txt
gcmodule.c
getaddrinfo.c
getbuildinfo.c
getnameinfo.c
getpath.c
getpath.py
getpath_noop.c
grpmodule.c gh-85283: Convert grp extension to the limited C API (#116611) 2024-03-12 00:46:53 +00:00
hashlib.h
itertoolsmodule.c
ld_so_aix.in
main.c
makesetup
makexp_aix
mathmodule.c
md5module.c
mmapmodule.c
overlapped.c
posixmodule.c gh-116195: Implements a fast path for nt.getppid (GH-116205) 2024-03-14 23:09:36 +00:00
posixmodule.h gh-85283: Convert grp extension to the limited C API (#116611) 2024-03-12 00:46:53 +00:00
pwdmodule.c gh-85283: Build pwd extension with the limited C API (#116841) 2024-03-15 08:49:58 +01:00
pyexpat.c
readline.c
README
resource.c gh-108494: Fix Argument Clinic LIMITED_CAPI_REGEX (#116610) 2024-03-11 22:42:18 +00:00
rotatingtree.c
rotatingtree.h
selectmodule.c
Setup
Setup.bootstrap.in
Setup.stdlib.in gh-116417: Move 4 limited C API test files to _testlimitedcapi (#116571) 2024-03-11 10:28:16 +00:00
sha1module.c
sha2module.c
sha3module.c
signalmodule.c
socketmodule.c gh-116616: Use relaxed atomic ops to access socket module defaulttimeout (#116623) 2024-03-12 14:44:39 +01:00
socketmodule.h
symtablemodule.c
syslogmodule.c
termios.c
timemodule.c gh-116437: Use new C API PyDict_Pop() to simplify the code (GH-116438) 2024-03-07 11:21:08 +02:00
tkappinit.c
tkinter.h
unicodedata.c
unicodedata_db.h
unicodename_db.h
winreparse.h
xxlimited.c gh-108494: Fix Argument Clinic LIMITED_CAPI_REGEX (#116610) 2024-03-11 22:42:18 +00:00
xxlimited_35.c gh-108494: Fix Argument Clinic LIMITED_CAPI_REGEX (#116610) 2024-03-11 22:42:18 +00:00
xxmodule.c
xxsubtype.c
zlibmodule.c

Source files for standard library extension modules,
and former extension modules that are now builtin modules.