diff options
author | Antoine Pitrou <antoine@python.org> | 2023-11-04 13:59:24 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-04 13:59:24 (GMT) |
commit | 0e9c364f4ac18a2237bdbac702b96bcf8ef9cb09 (patch) | |
tree | 8febb8282c2c1ebd73a18205ec5b9229a99ac4fe /Include | |
parent | a28a3967ab9a189122f895d51d2551f7b3a273b0 (diff) | |
download | cpython-0e9c364f4ac18a2237bdbac702b96bcf8ef9cb09.zip cpython-0e9c364f4ac18a2237bdbac702b96bcf8ef9cb09.tar.gz cpython-0e9c364f4ac18a2237bdbac702b96bcf8ef9cb09.tar.bz2 |
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')
-rw-r--r-- | Include/cpython/pthread_stubs.h | 1 | ||||
-rw-r--r-- | Include/internal/pycore_pythread.h | 42 |
2 files changed, 43 insertions, 0 deletions
diff --git a/Include/cpython/pthread_stubs.h b/Include/cpython/pthread_stubs.h index 5246968..e542eaa 100644 --- a/Include/cpython/pthread_stubs.h +++ b/Include/cpython/pthread_stubs.h @@ -83,6 +83,7 @@ PyAPI_FUNC(int) pthread_create(pthread_t *restrict thread, void *(*start_routine)(void *), void *restrict arg); PyAPI_FUNC(int) pthread_detach(pthread_t thread); +PyAPI_FUNC(int) pthread_join(pthread_t thread, void** value_ptr); PyAPI_FUNC(pthread_t) pthread_self(void); PyAPI_FUNC(int) pthread_exit(void *retval) __attribute__ ((__noreturn__)); PyAPI_FUNC(int) pthread_attr_init(pthread_attr_t *attr); diff --git a/Include/internal/pycore_pythread.h b/Include/internal/pycore_pythread.h index d31ffc7..9c9a09f 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 } |