diff options
Diffstat (limited to 'Python/pystate.c')
-rw-r--r-- | Python/pystate.c | 78 |
1 files changed, 54 insertions, 24 deletions
diff --git a/Python/pystate.c b/Python/pystate.c index 2ac2fd5274..24e20c3e23 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -3,6 +3,14 @@ #include "Python.h" +#define GET_TSTATE() \ + ((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)) +#define SET_TSTATE(value) \ + _Py_atomic_store_relaxed(&_PyThreadState_Current, (Py_uintptr_t)(value)) +#define GET_INTERP_STATE() \ + (GET_TSTATE()->interp) + + /* -------------------------------------------------------------------------- CAUTION @@ -48,7 +56,7 @@ static PyInterpreterState *interp_head = NULL; /* Assuming the current thread holds the GIL, this is the PyThreadState for the current thread. */ -_Py_atomic_address _PyThreadState_Current = {NULL}; +_Py_atomic_address _PyThreadState_Current = {0}; PyThreadFrameGetter _PyThreadState_GetFrame = NULL; #ifdef WITH_THREAD @@ -212,6 +220,9 @@ new_threadstate(PyInterpreterState *interp, int init) tstate->on_delete = NULL; tstate->on_delete_data = NULL; + tstate->coroutine_wrapper = NULL; + tstate->in_coroutine_wrapper = 0; + if (init) _PyThreadState_Init(tstate); @@ -251,8 +262,11 @@ PyObject* PyState_FindModule(struct PyModuleDef* module) { Py_ssize_t index = module->m_base.m_index; - PyInterpreterState *state = PyThreadState_GET()->interp; + PyInterpreterState *state = GET_INTERP_STATE(); PyObject *res; + if (module->m_slots) { + return NULL; + } if (index == 0) return NULL; if (state->modules_by_index == NULL) @@ -266,9 +280,17 @@ PyState_FindModule(struct PyModuleDef* module) int _PyState_AddModule(PyObject* module, struct PyModuleDef* def) { - PyInterpreterState *state = PyThreadState_GET()->interp; - if (!def) + PyInterpreterState *state; + if (!def) { + assert(PyErr_Occurred()); + return -1; + } + if (def->m_slots) { + PyErr_SetString(PyExc_SystemError, + "PyState_AddModule called on module with slots"); return -1; + } + state = GET_INTERP_STATE(); if (!state->modules_by_index) { state->modules_by_index = PyList_New(0); if (!state->modules_by_index) @@ -286,7 +308,7 @@ int PyState_AddModule(PyObject* module, struct PyModuleDef* def) { Py_ssize_t index; - PyInterpreterState *state = PyThreadState_GET()->interp; + PyInterpreterState *state = GET_INTERP_STATE(); if (!def) { Py_FatalError("PyState_AddModule: Module Definition is NULL"); return -1; @@ -306,8 +328,14 @@ PyState_AddModule(PyObject* module, struct PyModuleDef* def) int PyState_RemoveModule(struct PyModuleDef* def) { + PyInterpreterState *state; Py_ssize_t index = def->m_base.m_index; - PyInterpreterState *state = PyThreadState_GET()->interp; + if (def->m_slots) { + PyErr_SetString(PyExc_SystemError, + "PyState_RemoveModule called on module with slots"); + return -1; + } + state = GET_INTERP_STATE(); if (index == 0) { Py_FatalError("PyState_RemoveModule: Module index invalid."); return -1; @@ -327,7 +355,7 @@ PyState_RemoveModule(struct PyModuleDef* def) void _PyState_ClearModules(void) { - PyInterpreterState *state = PyThreadState_GET()->interp; + PyInterpreterState *state = GET_INTERP_STATE(); if (state->modules_by_index) { Py_ssize_t i; for (i = 0; i < PyList_GET_SIZE(state->modules_by_index); i++) { @@ -372,6 +400,8 @@ PyThreadState_Clear(PyThreadState *tstate) tstate->c_tracefunc = NULL; Py_CLEAR(tstate->c_profileobj); Py_CLEAR(tstate->c_traceobj); + + Py_CLEAR(tstate->coroutine_wrapper); } @@ -403,7 +433,7 @@ tstate_delete_common(PyThreadState *tstate) void PyThreadState_Delete(PyThreadState *tstate) { - if (tstate == _Py_atomic_load_relaxed(&_PyThreadState_Current)) + if (tstate == GET_TSTATE()) Py_FatalError("PyThreadState_Delete: tstate is still current"); #ifdef WITH_THREAD if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate) @@ -417,12 +447,11 @@ PyThreadState_Delete(PyThreadState *tstate) void PyThreadState_DeleteCurrent() { - PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed( - &_PyThreadState_Current); + PyThreadState *tstate = GET_TSTATE(); if (tstate == NULL) Py_FatalError( "PyThreadState_DeleteCurrent: no current tstate"); - _Py_atomic_store_relaxed(&_PyThreadState_Current, NULL); + SET_TSTATE(NULL); if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate) PyThread_delete_key_value(autoTLSkey); tstate_delete_common(tstate); @@ -469,10 +498,16 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate) PyThreadState * +_PyThreadState_UncheckedGet(void) +{ + return GET_TSTATE(); +} + + +PyThreadState * PyThreadState_Get(void) { - PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed( - &_PyThreadState_Current); + PyThreadState *tstate = GET_TSTATE(); if (tstate == NULL) Py_FatalError("PyThreadState_Get: no current thread"); @@ -483,10 +518,9 @@ PyThreadState_Get(void) PyThreadState * PyThreadState_Swap(PyThreadState *newts) { - PyThreadState *oldts = (PyThreadState*)_Py_atomic_load_relaxed( - &_PyThreadState_Current); + PyThreadState *oldts = GET_TSTATE(); - _Py_atomic_store_relaxed(&_PyThreadState_Current, newts); + SET_TSTATE(newts); /* It should not be possible for more than one thread state to be used for a thread. Check this the best we can in debug builds. @@ -515,8 +549,7 @@ PyThreadState_Swap(PyThreadState *newts) PyObject * PyThreadState_GetDict(void) { - PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed( - &_PyThreadState_Current); + PyThreadState *tstate = GET_TSTATE(); if (tstate == NULL) return NULL; @@ -540,8 +573,7 @@ PyThreadState_GetDict(void) int PyThreadState_SetAsyncExc(long id, PyObject *exc) { - PyThreadState *tstate = PyThreadState_GET(); - PyInterpreterState *interp = tstate->interp; + PyInterpreterState *interp = GET_INTERP_STATE(); PyThreadState *p; /* Although the GIL is held, a few C API functions can be called @@ -662,7 +694,7 @@ PyThreadState_IsCurrent(PyThreadState *tstate) { /* Must be the tstate for this thread */ assert(PyGILState_GetThisThreadState()==tstate); - return tstate == _Py_atomic_load_relaxed(&_PyThreadState_Current); + return tstate == GET_TSTATE(); } /* Internal initialization/finalization functions called by @@ -754,9 +786,7 @@ PyGILState_GetThisThreadState(void) int PyGILState_Check(void) { - /* can't use PyThreadState_Get() since it will assert that it has the GIL */ - PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed( - &_PyThreadState_Current); + PyThreadState *tstate = GET_TSTATE(); return tstate && (tstate == PyGILState_GetThisThreadState()); } |