diff -r bf997b22df06 Include/pystate.h --- a/Include/pystate.h Tue Jan 19 08:48:48 2016 +0100 +++ b/Include/pystate.h Tue Jan 19 13:24:38 2016 +0100 @@ -169,6 +169,11 @@ PyAPI_FUNC(void) _PyGILState_Reinit(void #endif PyAPI_FUNC(PyThreadState *) PyThreadState_Get(void); +#ifdef WITH_THREAD +/* Similar to PyThreadState_Get(), but don't call Py_FatalError() + * if it is NULL */ +PyAPI_FUNC(PyThreadState *) _PyThreadState_FastGet(void); +#endif PyAPI_FUNC(PyThreadState *) PyThreadState_Swap(PyThreadState *); PyAPI_FUNC(PyObject *) PyThreadState_GetDict(void); PyAPI_FUNC(int) PyThreadState_SetAsyncExc(long, PyObject *); diff -r bf997b22df06 Modules/faulthandler.c --- a/Modules/faulthandler.c Tue Jan 19 08:48:48 2016 +0100 +++ b/Modules/faulthandler.c Tue Jan 19 13:24:38 2016 +0100 @@ -490,7 +490,7 @@ faulthandler_thread(void *unused) assert(st == PY_LOCK_FAILURE); /* get the thread holding the GIL, NULL if no thread hold the GIL */ - current = (PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current); + current = _PyThreadState_FastGet(); _Py_write_noraise(thread.fd, thread.header, (int)thread.header_len); diff -r bf997b22df06 Objects/dictobject.c --- a/Objects/dictobject.c Tue Jan 19 08:48:48 2016 +0100 +++ b/Objects/dictobject.c Tue Jan 19 13:24:38 2016 +0100 @@ -1064,8 +1064,7 @@ PyDict_GetItem(PyObject *op, PyObject *k Let's just hope that no exception occurs then... This must be _PyThreadState_Current and not PyThreadState_GET() because in debug mode, the latter complains if tstate is NULL. */ - tstate = (PyThreadState*)_Py_atomic_load_relaxed( - &_PyThreadState_Current); + tstate = _PyThreadState_FastGet(); if (tstate != NULL && tstate->curexc_type != NULL) { /* preserve the existing exception */ PyObject *err_type, *err_value, *err_tb; @@ -1102,8 +1101,7 @@ PyObject * Let's just hope that no exception occurs then... This must be _PyThreadState_Current and not PyThreadState_GET() because in debug mode, the latter complains if tstate is NULL. */ - tstate = (PyThreadState*)_Py_atomic_load_relaxed( - &_PyThreadState_Current); + tstate = _PyThreadState_FastGet(); if (tstate != NULL && tstate->curexc_type != NULL) { /* preserve the existing exception */ PyObject *err_type, *err_value, *err_tb; diff -r bf997b22df06 Python/errors.c --- a/Python/errors.c Tue Jan 19 08:48:48 2016 +0100 +++ b/Python/errors.c Tue Jan 19 13:24:38 2016 +0100 @@ -152,13 +152,7 @@ PyErr_SetString(PyObject *exception, con 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_FastGet(); return tstate == NULL ? NULL : tstate->curexc_type; } diff -r bf997b22df06 Python/pystate.c --- a/Python/pystate.c Tue Jan 19 08:48:48 2016 +0100 +++ b/Python/pystate.c Tue Jan 19 13:24:38 2016 +0100 @@ -489,6 +489,13 @@ void PyThreadState * +_PyThreadState_FastGet(void) +{ + return (PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current); +} + + +PyThreadState * PyThreadState_Get(void) { PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed( diff -r bf997b22df06 Python/sysmodule.c --- a/Python/sysmodule.c Tue Jan 19 08:48:48 2016 +0100 +++ b/Python/sysmodule.c Tue Jan 19 13:24:38 2016 +0100 @@ -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_FastGet()) PyErr_Clear(); }