bpo-43962: Fix _PyInterpreterState_IDIncref() (GH-25683) (GH-25686)

_PyInterpreterState_IDIncref() now calls
_PyInterpreterState_IDInitref() and always increments id_refcount.

(cherry picked from commit 32c5a17444)
This commit is contained in:
Victor Stinner 2021-04-28 15:46:57 +02:00 committed by GitHub
parent 7f7cfc4118
commit 77db337f1e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 22 additions and 10 deletions

View 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 *);

View file

@ -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.

View 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;
}

View 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);