Skip to content

Commit 7de833a

Browse files
Fix destroying a not-ready interpreter.
1 parent f7219ba commit 7de833a

File tree

2 files changed

+16
-13
lines changed

2 files changed

+16
-13
lines changed

Lib/test/test_interpreters/test_api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1494,7 +1494,7 @@ def test_whence(self):
14941494
self.assertEqual(whence, _interpreters.WHENCE_STDLIB)
14951495

14961496
for orig, name in {
1497-
# XXX Also check WHENCE_UNKNOWN.
1497+
_interpreters.WHENCE_UNKNOWN: 'not ready',
14981498
_interpreters.WHENCE_LEGACY_CAPI: 'legacy C-API',
14991499
_interpreters.WHENCE_CAPI: 'C-API',
15001500
_interpreters.WHENCE_XI: 'cross-interpreter C-API',

Python/crossinterp.c

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1872,6 +1872,20 @@ void
18721872
_PyXI_EndInterpreter(PyInterpreterState *interp,
18731873
PyThreadState *tstate, PyThreadState **p_save_tstate)
18741874
{
1875+
long whence = _PyInterpreterState_GetWhence(interp);
1876+
assert(whence != _PyInterpreterState_WHENCE_RUNTIME);
1877+
1878+
if (!_PyInterpreterState_IsReady(interp)) {
1879+
assert(whence == _PyInterpreterState_WHENCE_UNKNOWN);
1880+
// PyInterpreterState_Clear() requires the GIL,
1881+
// which a not-ready does not have, so we don't clear it.
1882+
// That means there may be leaks here until clearing the
1883+
// interpreter is fixed.
1884+
PyInterpreterState_Delete(interp);
1885+
return;
1886+
}
1887+
assert(whence != _PyInterpreterState_WHENCE_UNKNOWN);
1888+
18751889
PyThreadState *save_tstate = NULL;
18761890
PyThreadState *cur_tstate = PyThreadState_GET();
18771891
if (tstate == NULL) {
@@ -1893,18 +1907,7 @@ _PyXI_EndInterpreter(PyInterpreterState *interp,
18931907
}
18941908
}
18951909

1896-
long whence = _PyInterpreterState_GetWhence(interp);
1897-
assert(whence != _PyInterpreterState_WHENCE_RUNTIME);
1898-
if (whence == _PyInterpreterState_WHENCE_UNKNOWN) {
1899-
assert(!_PyInterpreterState_IsReady(interp));
1900-
PyThreadState *tstate = PyThreadState_New(interp);
1901-
save_tstate = PyThreadState_Swap(tstate);
1902-
_PyInterpreterState_Clear(tstate);
1903-
PyInterpreterState_Delete(interp);
1904-
}
1905-
else {
1906-
Py_EndInterpreter(tstate);
1907-
}
1910+
Py_EndInterpreter(tstate);
19081911

19091912
if (p_save_tstate != NULL) {
19101913
save_tstate = *p_save_tstate;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy