@@ -488,6 +488,23 @@ free_interpreter(PyInterpreterState *interp)
488488 }
489489}
490490
491+ static void
492+ _finalize_and_free_interpreter (PyInterpreterState * interp )
493+ {
494+ _Py_qsbr_fini (interp );
495+ _PyObject_FiniState (interp );
496+ free_interpreter (interp );
497+ }
498+
499+ static inline void
500+ _interp_release_owner (PyInterpreterState * interp )
501+ {
502+ Py_ssize_t prev = _Py_atomic_add_ssize (& interp -> _owners , -1 );
503+ if (prev == 1 ) {
504+ _finalize_and_free_interpreter (interp );
505+ }
506+ }
507+
491508#ifndef NDEBUG
492509static inline int check_interpreter_whence (long );
493510#endif
@@ -537,6 +554,7 @@ init_interpreter(PyInterpreterState *interp,
537554 interp -> id = id ;
538555
539556 interp -> id_refcount = 0 ;
557+ interp -> _owners = 1 ;
540558
541559 assert (runtime -> interpreters .head == interp );
542560 assert (next != NULL || (interp == runtime -> interpreters .main ));
@@ -958,11 +976,9 @@ PyInterpreterState_Delete(PyInterpreterState *interp)
958976 }
959977 HEAD_UNLOCK (runtime );
960978
961- _Py_qsbr_fini (interp );
962-
963- _PyObject_FiniState (interp );
979+ interp -> finalizing = 1 ;
964980
965- free_interpreter (interp );
981+ _interp_release_owner (interp );
966982}
967983
968984
@@ -1415,6 +1431,7 @@ static void
14151431free_threadstate (_PyThreadStateImpl * tstate )
14161432{
14171433 PyInterpreterState * interp = tstate -> base .interp ;
1434+
14181435 // The initial thread state of the interpreter is allocated
14191436 // as part of the interpreter state so should not be freed.
14201437 if (tstate == & interp -> _initial_thread ) {
@@ -1426,6 +1443,8 @@ free_threadstate(_PyThreadStateImpl *tstate)
14261443 else {
14271444 PyMem_RawFree (tstate );
14281445 }
1446+
1447+ _interp_release_owner (interp );
14291448}
14301449
14311450static void
@@ -1552,6 +1571,8 @@ new_threadstate(PyInterpreterState *interp, int whence)
15521571 uint64_t id = interp -> threads .next_unique_id ;
15531572 init_threadstate (tstate , interp , id , whence );
15541573
1574+ _Py_atomic_add_ssize (& interp -> _owners , 1 );
1575+
15551576 // Add the new thread state to the interpreter.
15561577 PyThreadState * old_head = interp -> threads .head ;
15571578 add_threadstate (interp , (PyThreadState * )tstate , old_head );
0 commit comments