diff options
| author | Victor Stinner <victor.stinner@gmail.com> | 2016-01-20 11:12:38 +0100 | 
|---|---|---|
| committer | Victor Stinner <victor.stinner@gmail.com> | 2016-01-20 11:12:38 +0100 | 
| commit | bfd316e750bc3040c08d1b5872e2de188e8c1e5f (patch) | |
| tree | a0f5fc0ce8c171cd2b1f875c33b6089471c07447 /Python | |
| parent | aebb6d3682e08c93d8468a9291180c5cbdc2df1b (diff) | |
| download | cpython-git-bfd316e750bc3040c08d1b5872e2de188e8c1e5f.tar.gz | |
Add _PyThreadState_UncheckedGet()
Issue #26154: Add a new private _PyThreadState_UncheckedGet() function which
gets the current thread state, but don't call Py_FatalError() if it is NULL.
Python 3.5.1 removed the _PyThreadState_Current symbol from the Python C API to
no more expose complex and private atomic types. Atomic types depends on the
compiler or can even depend on compiler options. The new function
_PyThreadState_UncheckedGet() allows to get the variable value without having
to care of the exact implementation of atomic types.
Changes:
* Replace direct usage of the _PyThreadState_Current variable with a call to
  _PyThreadState_UncheckedGet().
* In pystate.c, replace direct usage of the _PyThreadState_Current variable
  with the PyThreadState_GET() macro for readability.
* Document also PyThreadState_Get() in pystate.h
Diffstat (limited to 'Python')
| -rw-r--r-- | Python/errors.c | 8 | ||||
| -rw-r--r-- | Python/pystate.c | 33 | ||||
| -rw-r--r-- | Python/sysmodule.c | 2 | 
3 files changed, 22 insertions, 21 deletions
diff --git a/Python/errors.c b/Python/errors.c index 7b67566727..5ff1e4c81a 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -152,13 +152,7 @@ PyErr_SetString(PyObject *exception, const char *string)  PyObject *  PyErr_Occurred(void)  { -    /* If there is no thread state, PyThreadState_GET calls -       Py_FatalError, which calls PyErr_Occurred.  To avoid the -       resulting infinite loop, we inline PyThreadState_GET here and -       treat no thread as no error. */ -    PyThreadState *tstate = -        ((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)); - +    PyThreadState *tstate = _PyThreadState_UncheckedGet();      return tstate == NULL ? NULL : tstate->curexc_type;  } diff --git a/Python/pystate.c b/Python/pystate.c index 7e0267ae1d..83f15fd671 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -3,6 +3,12 @@  #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 +  /* --------------------------------------------------------------------------  CAUTION @@ -423,7 +429,7 @@ tstate_delete_common(PyThreadState *tstate)  void  PyThreadState_Delete(PyThreadState *tstate)  { -    if (tstate == (PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)) +    if (tstate == PyThreadState_GET())          Py_FatalError("PyThreadState_Delete: tstate is still current");  #ifdef WITH_THREAD      if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate) @@ -437,8 +443,7 @@ PyThreadState_Delete(PyThreadState *tstate)  void  PyThreadState_DeleteCurrent()  { -    PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed( -        &_PyThreadState_Current); +    PyThreadState *tstate = PyThreadState_GET();      if (tstate == NULL)          Py_FatalError(              "PyThreadState_DeleteCurrent: no current tstate"); @@ -489,10 +494,16 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate)  PyThreadState * +_PyThreadState_UncheckedGet(void) +{ +    return PyThreadState_GET(); +} + + +PyThreadState *  PyThreadState_Get(void)  { -    PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed( -        &_PyThreadState_Current); +    PyThreadState *tstate = PyThreadState_GET();      if (tstate == NULL)          Py_FatalError("PyThreadState_Get: no current thread"); @@ -503,8 +514,7 @@ PyThreadState_Get(void)  PyThreadState *  PyThreadState_Swap(PyThreadState *newts)  { -    PyThreadState *oldts = (PyThreadState*)_Py_atomic_load_relaxed( -        &_PyThreadState_Current); +    PyThreadState *oldts = PyThreadState_GET();      _Py_atomic_store_relaxed(&_PyThreadState_Current, newts);      /* It should not be possible for more than one thread state @@ -535,8 +545,7 @@ PyThreadState_Swap(PyThreadState *newts)  PyObject *  PyThreadState_GetDict(void)  { -    PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed( -        &_PyThreadState_Current); +    PyThreadState *tstate = PyThreadState_GET();      if (tstate == NULL)          return NULL; @@ -682,7 +691,7 @@ PyThreadState_IsCurrent(PyThreadState *tstate)  {      /* Must be the tstate for this thread */      assert(PyGILState_GetThisThreadState()==tstate); -    return tstate == (PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current); +    return tstate == PyThreadState_GET();  }  /* Internal initialization/finalization functions called by @@ -774,9 +783,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 = PyThreadState_GET();      return tstate && (tstate == PyGILState_GetThisThreadState());  } diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 334f5d0c8e..8d7e05a465 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1397,7 +1397,7 @@ error:      Py_XDECREF(name);      Py_XDECREF(value);      /* No return value, therefore clear error state if possible */ -    if (_Py_atomic_load_relaxed(&_PyThreadState_Current)) +    if (_PyThreadState_UncheckedGet())          PyErr_Clear();  }  | 
