diff options
author | Antoine Pitrou <antoine@python.org> | 2023-11-04 14:59:24 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-04 13:59:24 +0000 |
commit | 0e9c364f4ac18a2237bdbac702b96bcf8ef9cb09 (patch) | |
tree | 8febb8282c2c1ebd73a18205ec5b9229a99ac4fe /Include/internal/pycore_pythread.h | |
parent | a28a3967ab9a189122f895d51d2551f7b3a273b0 (diff) | |
download | cpython-0e9c364f4ac18a2237bdbac702b96bcf8ef9cb09.tar.gz cpython-0e9c364f4ac18a2237bdbac702b96bcf8ef9cb09.zip |
GH-110829: Ensure Thread.join() joins the OS thread (#110848)
Joining a thread now ensures the underlying OS thread has exited. This is required for safer fork() in multi-threaded processes.
---------
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
Diffstat (limited to 'Include/internal/pycore_pythread.h')
-rw-r--r-- | Include/internal/pycore_pythread.h | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/Include/internal/pycore_pythread.h b/Include/internal/pycore_pythread.h index d31ffc78130..9c9a09f60f3 100644 --- a/Include/internal/pycore_pythread.h +++ b/Include/internal/pycore_pythread.h @@ -106,6 +106,48 @@ PyAPI_FUNC(PyLockStatus) PyThread_acquire_lock_timed_with_retries( PyThread_type_lock, PY_TIMEOUT_T microseconds); +typedef unsigned long long PyThread_ident_t; +typedef Py_uintptr_t PyThread_handle_t; + +#define PY_FORMAT_THREAD_IDENT_T "llu" +#define Py_PARSE_THREAD_IDENT_T "K" + +PyAPI_FUNC(PyThread_ident_t) PyThread_get_thread_ident_ex(void); + +/* Thread joining APIs. + * + * These APIs have a strict contract: + * - Either PyThread_join_thread or PyThread_detach_thread must be called + * exactly once with the given handle. + * - Calling neither PyThread_join_thread nor PyThread_detach_thread results + * in a resource leak until the end of the process. + * - Any other usage, such as calling both PyThread_join_thread and + * PyThread_detach_thread, or calling them more than once (including + * simultaneously), results in undefined behavior. + */ +PyAPI_FUNC(int) PyThread_start_joinable_thread(void (*func)(void *), + void *arg, + PyThread_ident_t* ident, + PyThread_handle_t* handle); +/* + * Join a thread started with `PyThread_start_joinable_thread`. + * This function cannot be interrupted. It returns 0 on success, + * a non-zero value on failure. + */ +PyAPI_FUNC(int) PyThread_join_thread(PyThread_handle_t); +/* + * Detach a thread started with `PyThread_start_joinable_thread`, such + * that its resources are relased as soon as it exits. + * This function cannot be interrupted. It returns 0 on success, + * a non-zero value on failure. + */ +PyAPI_FUNC(int) PyThread_detach_thread(PyThread_handle_t); + +/* + * Obtain the new thread ident and handle in a forked child process. + */ +PyAPI_FUNC(void) PyThread_update_thread_after_fork(PyThread_ident_t* ident, + PyThread_handle_t* handle); #ifdef __cplusplus } |