]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-43962: Fix _PyInterpreterState_IDIncref() (GH-25683) (GH-25686)
authorVictor Stinner <vstinner@python.org>
Wed, 28 Apr 2021 13:46:57 +0000 (15:46 +0200)
committerGitHub <noreply@github.com>
Wed, 28 Apr 2021 13:46:57 +0000 (15:46 +0200)
_PyInterpreterState_IDIncref() now calls
_PyInterpreterState_IDInitref() and always increments id_refcount.

(cherry picked from commit 32c5a174445ec93747240cd8472012276ed27acf)

Include/internal/pycore_pystate.h
Misc/NEWS.d/next/C API/2021-04-28-13-13-07.bpo-43962.9Jzs5X.rst [new file with mode: 0644]
Objects/interpreteridobject.c
Python/pystate.c

index 96d5e31d83a6e9485812efc71e8e22fb14ff7988..18105335363a45d04c86a758c81301e57e3e6ee5 100644 (file)
@@ -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 (file)
index 0000000..3216416
--- /dev/null
@@ -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.
index 94f5dd709bbda0906cb013712950bef5e928812b..19e86a2e0b0f77aa3b74c059b822fc1be69544a5 100644 (file)
@@ -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;
 }
 
index b1d0f1cbec428a1579b913d6167be913ca1901b2..56c184e43ae0ef9b2a08cec22909e55714a6917e 100644 (file)
@@ -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);