From 977e50a8e4307a5e63b1f03847378f667fb376cc Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Mon, 27 Oct 2025 18:30:23 -0400 Subject: [PATCH 1/6] Always assume the HAVE_THREAD_LOCAL macro is defined. --- Include/pyport.h | 7 ++----- Python/import.c | 14 -------------- Python/pystate.c | 3 --- 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/Include/pyport.h b/Include/pyport.h index 62db8d07701d1d..d4d98775a7e4d8 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -510,9 +510,7 @@ extern "C" { #ifdef WITH_THREAD # ifdef Py_BUILD_CORE -# ifdef HAVE_THREAD_LOCAL -# error "HAVE_THREAD_LOCAL is already defined" -# endif +// HAVE_THREAD_LOCAL is just defined here for compatibility's sake # define HAVE_THREAD_LOCAL 1 # ifdef thread_local # define _Py_thread_local thread_local @@ -523,8 +521,7 @@ extern "C" { # elif defined(__GNUC__) /* includes clang */ # define _Py_thread_local __thread # else - // fall back to the PyThread_tss_*() API, or ignore. -# undef HAVE_THREAD_LOCAL +# error "no supported thread-local variable storage classifier" # endif # endif #endif diff --git a/Python/import.c b/Python/import.c index 45206b46793846..d4b574a8828dc5 100644 --- a/Python/import.c +++ b/Python/import.c @@ -782,18 +782,13 @@ _PyImport_ClearModulesByIndex(PyInterpreterState *interp) substitute this (if the name actually matches). */ -#ifdef HAVE_THREAD_LOCAL _Py_thread_local const char *pkgcontext = NULL; # undef PKGCONTEXT # define PKGCONTEXT pkgcontext -#endif const char * _PyImport_ResolveNameWithPackageContext(const char *name) { -#ifndef HAVE_THREAD_LOCAL - PyMutex_Lock(&EXTENSIONS.mutex); -#endif if (PKGCONTEXT != NULL) { const char *p = strrchr(PKGCONTEXT, '.'); if (p != NULL && strcmp(name, p+1) == 0) { @@ -801,23 +796,14 @@ _PyImport_ResolveNameWithPackageContext(const char *name) PKGCONTEXT = NULL; } } -#ifndef HAVE_THREAD_LOCAL - PyMutex_Unlock(&EXTENSIONS.mutex); -#endif return name; } const char * _PyImport_SwapPackageContext(const char *newcontext) { -#ifndef HAVE_THREAD_LOCAL - PyMutex_Lock(&EXTENSIONS.mutex); -#endif const char *oldcontext = PKGCONTEXT; PKGCONTEXT = newcontext; -#ifndef HAVE_THREAD_LOCAL - PyMutex_Unlock(&EXTENSIONS.mutex); -#endif return oldcontext; } diff --git a/Python/pystate.c b/Python/pystate.c index 2141e842a37d2f..24681536797f94 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -67,9 +67,6 @@ to avoid the expense of doing their own locking). For each of these functions, the GIL must be held by the current thread. */ -#ifndef HAVE_THREAD_LOCAL -# error "no supported thread-local variable storage classifier" -#endif /* The attached thread state for the current thread. */ _Py_thread_local PyThreadState *_Py_tss_tstate = NULL; From 81b721787d82531945059050380899f8129a33d4 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Mon, 27 Oct 2025 19:10:31 -0400 Subject: [PATCH 2/6] Move _Py_thread_local to pycore_pystate.h This fixes extensions that define Py_BUILD_CORE after including Python.h, but before including pycore_pystate.h, such as mypyc. --- Include/internal/pycore_pystate.h | 15 +++++++++++++++ Include/pyport.h | 11 ----------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index cab458f84028e2..f4b71fd4fb60f4 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -85,6 +85,21 @@ _Py_ThreadCanHandleSignals(PyInterpreterState *interp) return (_Py_IsMainThread() && _Py_IsMainInterpreter(interp)); } +/* Definition of the _Py_thread_local macro. In reality, this should really be + * in pyport.h, but some extensions define Py_BUILD_CORE after including that. + * So, instead of breaking things, we just put this here for now. */ + +#ifdef thread_local +# define _Py_thread_local thread_local +#elif __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__) +# define _Py_thread_local _Thread_local +#elif defined(_MSC_VER) /* AKA NT_THREADS */ +# define _Py_thread_local __declspec(thread) +#elif defined(__GNUC__) /* includes clang */ +# define _Py_thread_local __thread +#else +# error "no supported thread-local variable storage classifier" +#endif /* Variable and static inline functions for in-line access to current thread and interpreter state */ diff --git a/Include/pyport.h b/Include/pyport.h index d4d98775a7e4d8..4dab4bacb0e2d3 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -512,17 +512,6 @@ extern "C" { # ifdef Py_BUILD_CORE // HAVE_THREAD_LOCAL is just defined here for compatibility's sake # define HAVE_THREAD_LOCAL 1 -# ifdef thread_local -# define _Py_thread_local thread_local -# elif __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__) -# define _Py_thread_local _Thread_local -# elif defined(_MSC_VER) /* AKA NT_THREADS */ -# define _Py_thread_local __declspec(thread) -# elif defined(__GNUC__) /* includes clang */ -# define _Py_thread_local __thread -# else -# error "no supported thread-local variable storage classifier" -# endif # endif #endif From 823f0e89b78c864db8fdb6757f7ce1bfb22b6082 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Tue, 28 Oct 2025 08:07:05 -0400 Subject: [PATCH 3/6] Remove `Py_BUILD_CORE` check in pyport.h --- Include/pyport.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Include/pyport.h b/Include/pyport.h index 4dab4bacb0e2d3..a1ad943aa09094 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -509,10 +509,8 @@ extern "C" { #endif #ifdef WITH_THREAD -# ifdef Py_BUILD_CORE // HAVE_THREAD_LOCAL is just defined here for compatibility's sake -# define HAVE_THREAD_LOCAL 1 -# endif +# define HAVE_THREAD_LOCAL 1 #endif #if defined(__ANDROID__) || defined(__VXWORKS__) From b2dde90f79579ac44b1fc6b2a19e01897a644f98 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Tue, 28 Oct 2025 08:33:37 -0400 Subject: [PATCH 4/6] Remove _Py_thread_local macro definition --- Include/internal/pycore_pystate.h | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index f4b71fd4fb60f4..bde0b9b9713c84 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -85,22 +85,6 @@ _Py_ThreadCanHandleSignals(PyInterpreterState *interp) return (_Py_IsMainThread() && _Py_IsMainInterpreter(interp)); } -/* Definition of the _Py_thread_local macro. In reality, this should really be - * in pyport.h, but some extensions define Py_BUILD_CORE after including that. - * So, instead of breaking things, we just put this here for now. */ - -#ifdef thread_local -# define _Py_thread_local thread_local -#elif __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__) -# define _Py_thread_local _Thread_local -#elif defined(_MSC_VER) /* AKA NT_THREADS */ -# define _Py_thread_local __declspec(thread) -#elif defined(__GNUC__) /* includes clang */ -# define _Py_thread_local __thread -#else -# error "no supported thread-local variable storage classifier" -#endif - /* Variable and static inline functions for in-line access to current thread and interpreter state */ From bb61072927e329268dec28c8c943b9d3a1e09924 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Tue, 28 Oct 2025 08:35:40 -0400 Subject: [PATCH 5/6] Move back to pyport.h --- Include/pyport.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Include/pyport.h b/Include/pyport.h index a1ad943aa09094..e77b39026a59c1 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -511,6 +511,17 @@ extern "C" { #ifdef WITH_THREAD // HAVE_THREAD_LOCAL is just defined here for compatibility's sake # define HAVE_THREAD_LOCAL 1 +# ifdef thread_local +# define _Py_thread_local thread_local +# elif __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__) +# define _Py_thread_local _Thread_local +# elif defined(_MSC_VER) /* AKA NT_THREADS */ +# define _Py_thread_local __declspec(thread) +# elif defined(__GNUC__) /* includes clang */ +# define _Py_thread_local __thread +# else +# error "no supported thread-local variable storage classifier" +# endif #endif #if defined(__ANDROID__) || defined(__VXWORKS__) From 5c85aefecad9909202535f94ecd333b188a94ec6 Mon Sep 17 00:00:00 2001 From: Peter Bierma Date: Tue, 28 Oct 2025 08:37:53 -0400 Subject: [PATCH 6/6] Fix stray newline change --- Include/internal/pycore_pystate.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index bde0b9b9713c84..cab458f84028e2 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -85,6 +85,7 @@ _Py_ThreadCanHandleSignals(PyInterpreterState *interp) return (_Py_IsMainThread() && _Py_IsMainInterpreter(interp)); } + /* Variable and static inline functions for in-line access to current thread and interpreter state */