@@ -485,6 +485,23 @@ free_interpreter(PyInterpreterState *interp)
485485 }
486486}
487487
488+ static void
489+ _finalize_and_free_interpreter (PyInterpreterState * interp )
490+ {
491+ _Py_qsbr_fini (interp );
492+ _PyObject_FiniState (interp );
493+ free_interpreter (interp );
494+ }
495+
496+ static inline void
497+ _interp_release_owner (PyInterpreterState * interp )
498+ {
499+ Py_ssize_t prev = _Py_atomic_add_ssize (& interp -> _owners , -1 );
500+ if (prev == 1 ) {
501+ _finalize_and_free_interpreter (interp );
502+ }
503+ }
504+
488505#ifndef NDEBUG
489506static inline int check_interpreter_whence (long );
490507#endif
@@ -534,6 +551,7 @@ init_interpreter(PyInterpreterState *interp,
534551 interp -> id = id ;
535552
536553 interp -> id_refcount = 0 ;
554+ interp -> _owners = 1 ;
537555
538556 assert (runtime -> interpreters .head == interp );
539557 assert (next != NULL || (interp == runtime -> interpreters .main ));
@@ -955,11 +973,9 @@ PyInterpreterState_Delete(PyInterpreterState *interp)
955973 }
956974 HEAD_UNLOCK (runtime );
957975
958- _Py_qsbr_fini (interp );
959-
960- _PyObject_FiniState (interp );
976+ interp -> finalizing = 1 ;
961977
962- free_interpreter (interp );
978+ _interp_release_owner (interp );
963979}
964980
965981
@@ -1412,6 +1428,7 @@ static void
14121428free_threadstate (_PyThreadStateImpl * tstate )
14131429{
14141430 PyInterpreterState * interp = tstate -> base .interp ;
1431+
14151432 // The initial thread state of the interpreter is allocated
14161433 // as part of the interpreter state so should not be freed.
14171434 if (tstate == & interp -> _initial_thread ) {
@@ -1423,6 +1440,8 @@ free_threadstate(_PyThreadStateImpl *tstate)
14231440 else {
14241441 PyMem_RawFree (tstate );
14251442 }
1443+
1444+ _interp_release_owner (interp );
14261445}
14271446
14281447static void
@@ -1549,6 +1568,8 @@ new_threadstate(PyInterpreterState *interp, int whence)
15491568 uint64_t id = interp -> threads .next_unique_id ;
15501569 init_threadstate (tstate , interp , id , whence );
15511570
1571+ _Py_atomic_add_ssize (& interp -> _owners , 1 );
1572+
15521573 // Add the new thread state to the interpreter.
15531574 PyThreadState * old_head = interp -> threads .head ;
15541575 add_threadstate (interp , (PyThreadState * )tstate , old_head );
0 commit comments