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 2ac2fd5..24e20c3 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());  } | 
