summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2021-04-28 13:46:57 (GMT)
committerGitHub <noreply@github.com>2021-04-28 13:46:57 (GMT)
commit77db337f1e69213e62ba79a797540cc4ac23492e (patch)
tree3c3807e1972611e7973abceca791498417d8834e
parent7f7cfc41185b651be9cb4d2759c40c3abf738485 (diff)
downloadcpython-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.h2
-rw-r--r--Misc/NEWS.d/next/C API/2021-04-28-13-13-07.bpo-43962.9Jzs5X.rst5
-rw-r--r--Objects/interpreteridobject.c12
-rw-r--r--Python/pystate.c13
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);