Skip to content

Commit 829f96b

Browse files
committed
Close owned guards before deallocating the thread state, not after.
1 parent 331c0c9 commit 829f96b

2 files changed

Lines changed: 10 additions & 16 deletions

File tree

Modules/_testcapimodule.c

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2709,10 +2709,7 @@ test_thread_state_ensure_crossinterp(PyObject *self, PyObject *unused)
27092709
PyInterpreterGuard *guard = PyInterpreterGuard_FromCurrent();
27102710
PyThreadState *save_tstate = PyThreadState_Swap(NULL);
27112711
PyThreadState *interp_tstate = Py_NewInterpreter();
2712-
if (interp_tstate == NULL) {
2713-
PyInterpreterGuard_Close(guard);
2714-
return PyErr_NoMemory();
2715-
}
2712+
assert(interp_tstate != NULL);
27162713

27172714
/* This should create a new thread state for the calling interpreter, *not*
27182715
reactivate the old one. In a real-world scenario, this would arise in
@@ -2728,24 +2725,17 @@ test_thread_state_ensure_crossinterp(PyObject *self, PyObject *unused)
27282725
interp.exec(some_func)
27292726
*/
27302727
PyThreadState *thread_state = PyThreadState_Ensure(guard);
2731-
if (thread_state == NULL) {
2732-
PyInterpreterGuard_Close(guard);
2733-
return PyErr_NoMemory();
2734-
}
2728+
assert(thread_state != NULL);
27352729

27362730
PyThreadState *ensured_tstate = PyThreadState_Get();
27372731
assert(ensured_tstate != save_tstate);
27382732
assert(PyGILState_GetThisThreadState() == ensured_tstate);
27392733

27402734
// Now though, we should reactivate the thread state
27412735
PyThreadState *other_thread_state = PyThreadState_Ensure(guard);
2742-
if (other_thread_state == NULL) {
2743-
PyThreadState_Release(thread_state);
2744-
PyInterpreterGuard_Close(guard);
2745-
return PyErr_NoMemory();
2746-
}
2747-
2736+
assert(other_thread_state != NULL);
27482737
assert(PyThreadState_Get() == ensured_tstate);
2738+
27492739
PyThreadState_Release(other_thread_state);
27502740

27512741
// Ensure that we're restoring the prior thread state

Python/pystate.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3595,14 +3595,18 @@ PyThreadState_Release(PyThreadState *old_tstate)
35953595
assert(tstate->ensure.delete_on_release == 1 || tstate->ensure.delete_on_release == 0);
35963596
if (tstate->ensure.delete_on_release) {
35973597
PyThreadState_Clear(tstate);
3598-
PyThreadState_Swap(to_restore);
3599-
PyThreadState_Delete(tstate);
36003598
} else {
36013599
PyThreadState_Swap(to_restore);
36023600
}
36033601

3602+
PyThreadState_Swap(to_restore);
3603+
36043604
if (tstate->ensure.owned_guard != NULL) {
36053605
PyInterpreterGuard_Close(tstate->ensure.owned_guard);
36063606
tstate->ensure.owned_guard = NULL;
36073607
}
3608+
3609+
if (tstate->ensure.delete_on_release) {
3610+
PyThreadState_Delete(tstate);
3611+
}
36083612
}

0 commit comments

Comments
 (0)