diff options
author | Victor Stinner <vstinner@python.org> | 2021-04-28 13:46:57 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-28 13:46:57 (GMT) |
commit | 77db337f1e69213e62ba79a797540cc4ac23492e (patch) | |
tree | 3c3807e1972611e7973abceca791498417d8834e | |
parent | 7f7cfc41185b651be9cb4d2759c40c3abf738485 (diff) | |
download | cpython-77db337f1e69213e62ba79a797540cc4ac23492e.zip cpython-77db337f1e69213e62ba79a797540cc4ac23492e.tar.gz cpython-77db337f1e69213e62ba79a797540cc4ac23492e.tar.bz2 |
bpo-43962: Fix _PyInterpreterState_IDIncref() (GH-25683) (GH-25686)
_PyInterpreterState_IDIncref() now calls
_PyInterpreterState_IDInitref() and always increments id_refcount.
(cherry picked from commit 32c5a174445ec93747240cd8472012276ed27acf)
-rw-r--r-- | Include/internal/pycore_pystate.h | 2 | ||||
-rw-r--r-- | Misc/NEWS.d/next/C API/2021-04-28-13-13-07.bpo-43962.9Jzs5X.rst | 5 | ||||
-rw-r--r-- | Objects/interpreteridobject.c | 12 | ||||
-rw-r--r-- | Python/pystate.c | 13 |
4 files changed, 22 insertions, 10 deletions
diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 96d5e31..1810533 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -140,7 +140,7 @@ struct _is { PyAPI_FUNC(struct _is*) _PyInterpreterState_LookUpID(PY_INT64_T); PyAPI_FUNC(int) _PyInterpreterState_IDInitref(struct _is *); -PyAPI_FUNC(void) _PyInterpreterState_IDIncref(struct _is *); +PyAPI_FUNC(int) _PyInterpreterState_IDIncref(struct _is *); PyAPI_FUNC(void) _PyInterpreterState_IDDecref(struct _is *); diff --git a/Misc/NEWS.d/next/C API/2021-04-28-13-13-07.bpo-43962.9Jzs5X.rst b/Misc/NEWS.d/next/C API/2021-04-28-13-13-07.bpo-43962.9Jzs5X.rst new file mode 100644 index 0000000..3216416 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2021-04-28-13-13-07.bpo-43962.9Jzs5X.rst @@ -0,0 +1,5 @@ +_PyInterpreterState_IDIncref() now calls _PyInterpreterState_IDInitref() and +always increments id_refcount. Previously, calling +_xxsubinterpreters.get_current() could create an id_refcount inconsistency +when a _xxsubinterpreters.InterpreterID object was deallocated. Patch by +Victor Stinner. diff --git a/Objects/interpreteridobject.c b/Objects/interpreteridobject.c index 94f5dd7..19e86a2 100644 --- a/Objects/interpreteridobject.c +++ b/Objects/interpreteridobject.c @@ -23,15 +23,21 @@ newinterpid(PyTypeObject *cls, int64_t id, int force) } } + if (interp != NULL) { + if (_PyInterpreterState_IDIncref(interp) < 0) { + return NULL; + } + } + interpid *self = PyObject_New(interpid, cls); if (self == NULL) { + if (interp != NULL) { + _PyInterpreterState_IDDecref(interp); + } return NULL; } self->id = id; - if (interp != NULL) { - _PyInterpreterState_IDIncref(interp); - } return self; } diff --git a/Python/pystate.c b/Python/pystate.c index b1d0f1c..56c184e 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -473,24 +473,25 @@ _PyInterpreterState_IDInitref(PyInterpreterState *interp) } -void +int _PyInterpreterState_IDIncref(PyInterpreterState *interp) { - if (interp->id_mutex == NULL) { - return; + if (_PyInterpreterState_IDInitref(interp) < 0) { + return -1; } + PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK); interp->id_refcount += 1; PyThread_release_lock(interp->id_mutex); + return 0; } void _PyInterpreterState_IDDecref(PyInterpreterState *interp) { - if (interp->id_mutex == NULL) { - return; - } + assert(interp->id_mutex != NULL); + struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK); assert(interp->id_refcount != 0); |