Skip to content

Commit 77db337

Browse files
authored
bpo-43962: Fix _PyInterpreterState_IDIncref() (GH-25683) (GH-25686)
_PyInterpreterState_IDIncref() now calls _PyInterpreterState_IDInitref() and always increments id_refcount. (cherry picked from commit 32c5a17)
1 parent 7f7cfc4 commit 77db337

4 files changed

Lines changed: 22 additions & 10 deletions

File tree

‎Include/internal/pycore_pystate.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ struct _is {
140140
PyAPI_FUNC(struct _is*) _PyInterpreterState_LookUpID(PY_INT64_T);
141141

142142
PyAPI_FUNC(int) _PyInterpreterState_IDInitref(struct _is *);
143-
PyAPI_FUNC(void) _PyInterpreterState_IDIncref(struct _is *);
143+
PyAPI_FUNC(int) _PyInterpreterState_IDIncref(struct _is *);
144144
PyAPI_FUNC(void) _PyInterpreterState_IDDecref(struct _is *);
145145

146146

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
_PyInterpreterState_IDIncref() now calls _PyInterpreterState_IDInitref() and
2+
always increments id_refcount. Previously, calling
3+
_xxsubinterpreters.get_current() could create an id_refcount inconsistency
4+
when a _xxsubinterpreters.InterpreterID object was deallocated. Patch by
5+
Victor Stinner.

‎Objects/interpreteridobject.c‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,21 @@ newinterpid(PyTypeObject *cls, int64_t id, int force)
2323
}
2424
}
2525

26+
if (interp != NULL) {
27+
if (_PyInterpreterState_IDIncref(interp) < 0) {
28+
return NULL;
29+
}
30+
}
31+
2632
interpid *self = PyObject_New(interpid, cls);
2733
if (self == NULL) {
34+
if (interp != NULL) {
35+
_PyInterpreterState_IDDecref(interp);
36+
}
2837
return NULL;
2938
}
3039
self->id = id;
3140

32-
if (interp != NULL) {
33-
_PyInterpreterState_IDIncref(interp);
34-
}
3541
return self;
3642
}
3743

‎Python/pystate.c‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -473,24 +473,25 @@ _PyInterpreterState_IDInitref(PyInterpreterState *interp)
473473
}
474474

475475

476-
void
476+
int
477477
_PyInterpreterState_IDIncref(PyInterpreterState *interp)
478478
{
479-
if (interp->id_mutex == NULL) {
480-
return;
479+
if (_PyInterpreterState_IDInitref(interp) < 0) {
480+
return -1;
481481
}
482+
482483
PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK);
483484
interp->id_refcount += 1;
484485
PyThread_release_lock(interp->id_mutex);
486+
return 0;
485487
}
486488

487489

488490
void
489491
_PyInterpreterState_IDDecref(PyInterpreterState *interp)
490492
{
491-
if (interp->id_mutex == NULL) {
492-
return;
493-
}
493+
assert(interp->id_mutex != NULL);
494+
494495
struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate;
495496
PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK);
496497
assert(interp->id_refcount != 0);

0 commit comments

Comments
 (0)