Skip to content
Merged
Prev Previous commit
Next Next commit
Fix pystate.c.
  • Loading branch information
ericsnowcurrently committed Apr 7, 2023
commit 3db400735ac2ce1a7814a2878fa3ec308e46dcfe
2 changes: 1 addition & 1 deletion Include/internal/pycore_pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ _Py_ThreadCanHandlePendingCalls(void)
and interpreter state */

#if defined(HAVE_THREAD_LOCAL) && !defined(Py_BUILD_CORE_MODULE)
extern thread_local PyThreadState *_Py_tss_tstate;
extern _Py_thread_local PyThreadState *_Py_tss_tstate;
#endif
PyAPI_DATA(PyThreadState *) _PyThreadState_GetCurrent(void);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the use case for this new _PyThreadState_GetCurrent() function? There is already PyThreadState_Get(). How is it different?

The API to get the current thread state is already complicated and has a complicated history: https://pythondev.readthedocs.io/pystate.html

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's there because I couldn't find a way to mix PyAPI_DATA with _Py_thread_local. Looks like that's the same issue you ran into in 2020.


Expand Down
31 changes: 24 additions & 7 deletions Python/pystate.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,38 +61,55 @@ extern "C" {
*/


thread_local PyThreadState *_Py_tss_tstate = NULL;

PyThreadState *
_PyThreadState_GetCurrent(void)
{
return _Py_tss_tstate;
}
#ifdef HAVE_THREAD_LOCAL
_Py_thread_local PyThreadState *_Py_tss_tstate = NULL;
#endif

static inline PyThreadState *
current_fast_get(_PyRuntimeState *Py_UNUSED(runtime))
{
#ifdef HAVE_THREAD_LOCAL
return _Py_tss_tstate;
#else
// XXX Fall back to the PyThread_tss_*() API.
# error "no supported thread-local variable storage classifier"
#endif
}

static inline void
current_fast_set(_PyRuntimeState *Py_UNUSED(runtime), PyThreadState *tstate)
{
assert(tstate != NULL);
#ifdef HAVE_THREAD_LOCAL
_Py_tss_tstate = tstate;
#else
// XXX Fall back to the PyThread_tss_*() API.
# error "no supported thread-local variable storage classifier"
#endif
}

static inline void
current_fast_clear(_PyRuntimeState *Py_UNUSED(runtime))
{
#ifdef HAVE_THREAD_LOCAL
_Py_tss_tstate = NULL;
#else
// XXX Fall back to the PyThread_tss_*() API.
# error "no supported thread-local variable storage classifier"
#endif
}

#define tstate_verify_not_active(tstate) \
if (tstate == current_fast_get((tstate)->interp->runtime)) { \
_Py_FatalErrorFormat(__func__, "tstate %p is still current", tstate); \
}

PyThreadState *
_PyThreadState_GetCurrent(void)
{
return current_fast_get(&_PyRuntime);
}


//------------------------------------------------
// the thread state bound to the current OS thread
Expand Down