diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-21-00-12-24.gh-issue-130115.mF-rP6.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-21-00-12-24.gh-issue-130115.mF-rP6.rst new file mode 100644 index 00000000000000..124da33f8836f6 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-21-00-12-24.gh-issue-130115.mF-rP6.rst @@ -0,0 +1 @@ +Fix an issue with thread identifiers being sign-extended on some platforms. diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index f588b4620da0d3..de95e733ce09f3 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -307,6 +307,24 @@ do_start_joinable_thread(void (*func)(void *), void *arg, pthread_t* out_id) return 0; } +/* Helper to convert pthread_t to PyThread_ident_t. POSIX allows pthread_t to be + non-arithmetic, e.g., musl typedefs it as a pointer. */ +static PyThread_ident_t +_pthread_t_to_ident(pthread_t value) { +// Cast through an integer type of the same size to avoid sign-extension. +#if SIZEOF_PTHREAD_T == SIZEOF_VOID_P + return (uintptr_t) value; +#elif SIZEOF_PTHREAD_T == SIZEOF_LONG + return (unsigned long) value; +#elif SIZEOF_PTHREAD_T == SIZEOF_INT + return (unsigned int) value; +#elif SIZEOF_PTHREAD_T == SIZEOF_LONG_LONG + return (unsigned long long) value; +#else +#error "Unsupported SIZEOF_PTHREAD_T value" +#endif +} + int PyThread_start_joinable_thread(void (*func)(void *), void *arg, PyThread_ident_t* ident, PyThread_handle_t* handle) { @@ -314,9 +332,8 @@ PyThread_start_joinable_thread(void (*func)(void *), void *arg, if (do_start_joinable_thread(func, arg, &th)) { return -1; } - *ident = (PyThread_ident_t) th; + *ident = _pthread_t_to_ident(th); *handle = (PyThread_handle_t) th; - assert(th == (pthread_t) *ident); assert(th == (pthread_t) *handle); return 0; } @@ -329,11 +346,7 @@ PyThread_start_new_thread(void (*func)(void *), void *arg) return PYTHREAD_INVALID_THREAD_ID; } pthread_detach(th); -#if SIZEOF_PTHREAD_T <= SIZEOF_LONG - return (unsigned long) th; -#else - return (unsigned long) *(unsigned long *) &th; -#endif + return (unsigned long) _pthread_t_to_ident(th);; } int @@ -358,8 +371,7 @@ PyThread_get_thread_ident_ex(void) { if (!initialized) PyThread_init_thread(); threadid = pthread_self(); - assert(threadid == (pthread_t) (PyThread_ident_t) threadid); - return (PyThread_ident_t) threadid; + return _pthread_t_to_ident(threadid); } unsigned long