diff options
Diffstat (limited to 'Python/pystate.c')
| -rw-r--r-- | Python/pystate.c | 69 | 
1 files changed, 42 insertions, 27 deletions
| diff --git a/Python/pystate.c b/Python/pystate.c index 83f15fd..e8026c5 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -3,11 +3,13 @@  #include "Python.h" -#ifndef Py_BUILD_CORE -/* ensure that PyThreadState_GET() is a macro, not an alias to - * PyThreadState_Get() */ -#  error "pystate.c must be compiled with Py_BUILD_CORE defined" -#endif +#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 @@ -32,6 +34,8 @@ to avoid the expense of doing their own locking).  extern "C" {  #endif +int _PyGILState_check_enabled = 1; +  #ifdef WITH_THREAD  #include "pythread.h"  static PyThread_type_lock head_mutex = NULL; /* Protects interp->tstate_head */ @@ -43,7 +47,7 @@ static PyThread_type_lock head_mutex = NULL; /* Protects interp->tstate_head */     GILState implementation  */  static PyInterpreterState *autoInterpreterState = NULL; -static int autoTLSkey = 0; +static int autoTLSkey = -1;  #else  #define HEAD_INIT() /* Nothing */  #define HEAD_LOCK() /* Nothing */ @@ -54,7 +58,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 @@ -260,7 +264,7 @@ 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; @@ -284,7 +288,7 @@ _PyState_AddModule(PyObject* module, struct PyModuleDef* def)                          "PyState_AddModule called on module with slots");          return -1;      } -    state = PyThreadState_GET()->interp; +    state = GET_INTERP_STATE();      if (!def)          return -1;      if (!state->modules_by_index) { @@ -304,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; @@ -331,7 +335,7 @@ PyState_RemoveModule(struct PyModuleDef* def)                          "PyState_RemoveModule called on module with slots");          return -1;      } -    state = PyThreadState_GET()->interp; +    state = GET_INTERP_STATE();      if (index == 0) {          Py_FatalError("PyState_RemoveModule: Module index invalid.");          return -1; @@ -351,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++) { @@ -429,7 +433,7 @@ tstate_delete_common(PyThreadState *tstate)  void  PyThreadState_Delete(PyThreadState *tstate)  { -    if (tstate == PyThreadState_GET()) +    if (tstate == GET_TSTATE())          Py_FatalError("PyThreadState_Delete: tstate is still current");  #ifdef WITH_THREAD      if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate) @@ -443,14 +447,14 @@ PyThreadState_Delete(PyThreadState *tstate)  void  PyThreadState_DeleteCurrent()  { -    PyThreadState *tstate = PyThreadState_GET(); +    PyThreadState *tstate = GET_TSTATE();      if (tstate == NULL)          Py_FatalError(              "PyThreadState_DeleteCurrent: no current tstate"); -    _Py_atomic_store_relaxed(&_PyThreadState_Current, NULL); +    tstate_delete_common(tstate);      if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)          PyThread_delete_key_value(autoTLSkey); -    tstate_delete_common(tstate); +    SET_TSTATE(NULL);      PyEval_ReleaseLock();  }  #endif /* WITH_THREAD */ @@ -496,14 +500,14 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate)  PyThreadState *  _PyThreadState_UncheckedGet(void)  { -    return PyThreadState_GET(); +    return GET_TSTATE();  }  PyThreadState *  PyThreadState_Get(void)  { -    PyThreadState *tstate = PyThreadState_GET(); +    PyThreadState *tstate = GET_TSTATE();      if (tstate == NULL)          Py_FatalError("PyThreadState_Get: no current thread"); @@ -514,9 +518,9 @@ PyThreadState_Get(void)  PyThreadState *  PyThreadState_Swap(PyThreadState *newts)  { -    PyThreadState *oldts = PyThreadState_GET(); +    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. @@ -545,7 +549,7 @@ PyThreadState_Swap(PyThreadState *newts)  PyObject *  PyThreadState_GetDict(void)  { -    PyThreadState *tstate = PyThreadState_GET(); +    PyThreadState *tstate = GET_TSTATE();      if (tstate == NULL)          return NULL; @@ -569,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 @@ -691,11 +694,11 @@ PyThreadState_IsCurrent(PyThreadState *tstate)  {      /* Must be the tstate for this thread */      assert(PyGILState_GetThisThreadState()==tstate); -    return tstate == PyThreadState_GET(); +    return tstate == GET_TSTATE();  }  /* Internal initialization/finalization functions called by -   Py_Initialize/Py_Finalize +   Py_Initialize/Py_FinalizeEx  */  void  _PyGILState_Init(PyInterpreterState *i, PyThreadState *t) @@ -715,6 +718,7 @@ void  _PyGILState_Fini(void)  {      PyThread_delete_key(autoTLSkey); +    autoTLSkey = -1;      autoInterpreterState = NULL;  } @@ -783,8 +787,19 @@ PyGILState_GetThisThreadState(void)  int  PyGILState_Check(void)  { -    PyThreadState *tstate = PyThreadState_GET(); -    return tstate && (tstate == PyGILState_GetThisThreadState()); +    PyThreadState *tstate; + +    if (!_PyGILState_check_enabled) +        return 1; + +    if (autoTLSkey == -1) +        return 1; + +    tstate = GET_TSTATE(); +    if (tstate == NULL) +        return 0; + +    return (tstate == PyGILState_GetThisThreadState());  }  PyGILState_STATE | 
