bpo-38733: PyErr_Occurred() caller must hold the GIL (GH-17080)
bpo-3605, bpo-38733: Optimize _PyErr_Occurred(): remove "tstate == NULL" test. Py_FatalError() no longer calls PyErr_Occurred() if called without holding the GIL. So PyErr_Occurred() no longer has to support tstate==NULL case. _Py_CheckFunctionResult(): use directly _PyErr_Occurred() to avoid explicit "!= NULL" test.
This commit is contained in:
parent
991b02dc87
commit
d12d0e7c0f
|
@ -374,6 +374,8 @@ Querying the error indicator
|
||||||
own a reference to the return value, so you do not need to :c:func:`Py_DECREF`
|
own a reference to the return value, so you do not need to :c:func:`Py_DECREF`
|
||||||
it.
|
it.
|
||||||
|
|
||||||
|
The caller must hold the GIL.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Do not compare the return value to a specific exception; use
|
Do not compare the return value to a specific exception; use
|
||||||
|
|
|
@ -10,7 +10,8 @@ extern "C" {
|
||||||
|
|
||||||
static inline PyObject* _PyErr_Occurred(PyThreadState *tstate)
|
static inline PyObject* _PyErr_Occurred(PyThreadState *tstate)
|
||||||
{
|
{
|
||||||
return tstate == NULL ? NULL : tstate->curexc_type;
|
assert(tstate != NULL);
|
||||||
|
return tstate->curexc_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,12 +30,10 @@ PyObject*
|
||||||
_Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable,
|
_Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable,
|
||||||
PyObject *result, const char *where)
|
PyObject *result, const char *where)
|
||||||
{
|
{
|
||||||
int err_occurred = (_PyErr_Occurred(tstate) != NULL);
|
|
||||||
|
|
||||||
assert((callable != NULL) ^ (where != NULL));
|
assert((callable != NULL) ^ (where != NULL));
|
||||||
|
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
if (!err_occurred) {
|
if (!_PyErr_Occurred(tstate)) {
|
||||||
if (callable)
|
if (callable)
|
||||||
_PyErr_Format(tstate, PyExc_SystemError,
|
_PyErr_Format(tstate, PyExc_SystemError,
|
||||||
"%R returned NULL without setting an error",
|
"%R returned NULL without setting an error",
|
||||||
|
@ -52,7 +50,7 @@ _Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (err_occurred) {
|
if (_PyErr_Occurred(tstate)) {
|
||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
|
|
||||||
if (callable) {
|
if (callable) {
|
||||||
|
|
|
@ -2313,12 +2313,13 @@ _PyMem_DebugRawRealloc(void *ctx, void *p, size_t nbytes)
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static inline void
|
||||||
_PyMem_DebugCheckGIL(void)
|
_PyMem_DebugCheckGIL(void)
|
||||||
{
|
{
|
||||||
if (!PyGILState_Check())
|
if (!PyGILState_Check()) {
|
||||||
Py_FatalError("Python memory allocator called "
|
Py_FatalError("Python memory allocator called "
|
||||||
"without holding the GIL");
|
"without holding the GIL");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
|
|
|
@ -218,6 +218,9 @@ PyErr_SetString(PyObject *exception, const char *string)
|
||||||
PyObject* _Py_HOT_FUNCTION
|
PyObject* _Py_HOT_FUNCTION
|
||||||
PyErr_Occurred(void)
|
PyErr_Occurred(void)
|
||||||
{
|
{
|
||||||
|
/* The caller must hold the GIL. */
|
||||||
|
assert(PyGILState_Check());
|
||||||
|
|
||||||
PyThreadState *tstate = _PyThreadState_GET();
|
PyThreadState *tstate = _PyThreadState_GET();
|
||||||
return _PyErr_Occurred(tstate);
|
return _PyErr_Occurred(tstate);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue