From 0e427c6d159e86f17270770cd8dc37372e3c4004 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 25 Mar 2020 21:22:55 +0100 Subject: [PATCH] bpo-39947: Add _PyThreadState_GetDict() function (GH-19160) --- Include/cpython/pystate.h | 2 ++ Modules/_asynciomodule.c | 5 +++-- Python/pystate.c | 27 ++++++++++++++++++--------- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 4ea509dc6ee..27097270a0c 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -149,6 +149,8 @@ PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *); * if it is NULL. */ PyAPI_FUNC(PyThreadState *) _PyThreadState_UncheckedGet(void); +PyAPI_FUNC(PyObject *) _PyThreadState_GetDict(PyThreadState *tstate); + /* PyGILState */ /* Helper/diagnostic function - return 1 if the current thread diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index fa94a65f1ce..1092b084114 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -236,12 +236,13 @@ get_running_loop(PyObject **loop) rl = cached_running_holder; // borrowed } else { - if (ts->dict == NULL) { + PyObject *ts_dict = _PyThreadState_GetDict(ts); // borrowed + if (ts_dict == NULL) { goto not_found; } rl = _PyDict_GetItemIdWithError( - ts->dict, &PyId___asyncio_running_event_loop__); // borrowed + ts_dict, &PyId___asyncio_running_event_loop__); // borrowed if (rl == NULL) { if (PyErr_Occurred()) { goto error; diff --git a/Python/pystate.c b/Python/pystate.c index c7154ea7060..66a1d3b492d 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -4,9 +4,10 @@ #include "Python.h" #include "pycore_ceval.h" #include "pycore_initconfig.h" +#include "pycore_pyerrors.h" +#include "pycore_pylifecycle.h" #include "pycore_pymem.h" #include "pycore_pystate.h" -#include "pycore_pylifecycle.h" /* -------------------------------------------------------------------------- CAUTION @@ -979,20 +980,28 @@ PyThreadState_Swap(PyThreadState *newts) PyThreadState_GetDict() returns NULL, an exception has *not* been raised and the caller should assume no per-thread state is available. */ +PyObject * +_PyThreadState_GetDict(PyThreadState *tstate) +{ + assert(tstate != NULL); + if (tstate->dict == NULL) { + tstate->dict = PyDict_New(); + if (tstate->dict == NULL) { + _PyErr_Clear(tstate); + } + } + return tstate->dict; +} + + PyObject * PyThreadState_GetDict(void) { PyThreadState *tstate = _PyThreadState_GET(); - if (tstate == NULL) + if (tstate == NULL) { return NULL; - - if (tstate->dict == NULL) { - PyObject *d; - tstate->dict = d = PyDict_New(); - if (d == NULL) - PyErr_Clear(); } - return tstate->dict; + return _PyThreadState_GetDict(tstate); }