@@ -992,6 +992,26 @@ free_threadstate(PyThreadState *tstate)
992992 }
993993}
994994
995+ static void
996+ _PyThreadState_DecRef (PyThreadState * tstate )
997+ {
998+ if (tstate != & tstate -> interp -> _initial_thread .tstate ) {
999+ if (_Py_atomic_add_ssize (& tstate -> refcount , -1 ) == 1 ) {
1000+ free_threadstate (tstate );
1001+ }
1002+ }
1003+ }
1004+
1005+ void
1006+ _PyThreadState_Exit (PyThreadState * tstate )
1007+ {
1008+ if (_PyThreadState_GetStatus (tstate ) == _Py_THREAD_ATTACHED ) {
1009+ _Py_atomic_store_int (& tstate -> status , _Py_THREAD_DETACHED );
1010+ }
1011+ _PyThreadState_DecRef (tstate );
1012+ PyThread_exit_thread ();
1013+ }
1014+
9951015/* Get the thread state to a minimal consistent state.
9961016 Further init happens in pylifecycle.c before it can be used.
9971017 All fields not initialized here are expected to be zeroed out,
@@ -1061,6 +1081,7 @@ init_threadstate(PyThreadState *tstate,
10611081 if (_PyRuntime .stop_the_world_requested ) {
10621082 tstate -> status = _Py_THREAD_GC ;
10631083 }
1084+ tstate -> refcount = 2 ;
10641085 tstate -> _initialized = 1 ;
10651086}
10661087
@@ -1562,7 +1583,12 @@ void
15621583_PyThreadState_DeleteExcept (_PyRuntimeState * runtime , PyThreadState * tstate )
15631584{
15641585 PyThreadState * garbage = _PyThreadState_UnlinkExcept (runtime , tstate , 0 );
1565- _PyThreadState_DeleteGarbage (garbage );
1586+ PyThreadState * next ;
1587+ for (PyThreadState * p = garbage ; p ; p = next ) {
1588+ next = p -> next ;
1589+ PyThreadState_Clear (p );
1590+ _PyThreadState_DecRef (tstate );
1591+ }
15661592}
15671593
15681594PyThreadState *
0 commit comments