@@ -600,18 +600,6 @@ free_interpreter(PyInterpreterState *interp)
600600 }
601601}
602602
603- static Py_ssize_t
604- decref_interpreter (PyInterpreterState * interp )
605- {
606- assert (interp != NULL );
607- Py_ssize_t old_refcnt = _Py_atomic_add_ssize (& interp -> refcount , -1 );
608- if (old_refcnt == 1 ) {
609- free_interpreter (interp );
610- }
611-
612- return old_refcnt ;
613- }
614-
615603#ifndef NDEBUG
616604static inline int check_interpreter_whence (long );
617605#endif
@@ -805,7 +793,6 @@ _PyInterpreterState_New(PyThreadState *tstate, PyInterpreterState **pinterp)
805793 HEAD_UNLOCK (runtime );
806794
807795 if (interp != NULL ) {
808- assert (interp -> refcount == 1 );
809796 free_interpreter (interp );
810797 }
811798 return status ;
@@ -1056,7 +1043,7 @@ PyInterpreterState_Delete(PyInterpreterState *interp)
10561043
10571044 _PyObject_FiniState (interp );
10581045
1059- decref_interpreter (interp );
1046+ free_interpreter (interp );
10601047}
10611048
10621049
@@ -1092,7 +1079,7 @@ _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime)
10921079 zapthreads (interp );
10931080 PyInterpreterState * prev_interp = interp ;
10941081 interp = interp -> next ;
1095- decref_interpreter (prev_interp );
1082+ free_interpreter (prev_interp );
10961083 }
10971084 HEAD_UNLOCK (runtime );
10981085
@@ -1825,7 +1812,7 @@ decrement_daemon_count(PyInterpreterState *interp)
18251812{
18261813 assert (interp != NULL );
18271814 struct _Py_finalizing_threads * finalizing = & interp -> threads .finalizing ;
1828- if (-- finalizing -> countdown == 0 ) {
1815+ if (_Py_atomic_load_ssize_relaxed ( & finalizing -> countdown ) == 1 ) {
18291816 _PyEvent_Notify (& finalizing -> finished );
18301817 }
18311818}
@@ -3221,25 +3208,24 @@ Py_ssize_t
32213208_PyInterpreterState_Refcount (PyInterpreterState * interp )
32223209{
32233210 assert (interp != NULL );
3224- Py_ssize_t refcount = _Py_atomic_load_ssize_relaxed (& interp -> refcount );
3225- assert (refcount > 0 );
3211+ Py_ssize_t refcount = _Py_atomic_load_ssize_relaxed (& interp -> threads .finalizing .countdown );
32263212 return refcount ;
32273213}
32283214
32293215PyInterpreterState *
32303216PyInterpreterState_Hold (void )
32313217{
32323218 PyInterpreterState * interp = PyInterpreterState_Get ();
3233- assert (_Py_atomic_load_ssize_relaxed (& interp -> refcount ) > 0 );
3234- _Py_atomic_add_ssize (& interp -> refcount , 1 );
3219+ assert (_Py_atomic_load_ssize_relaxed (& interp -> threads . finalizing . countdown ) >= 0 );
3220+ _Py_atomic_add_ssize (& interp -> threads . finalizing . countdown , 1 );
32353221 return interp ;
32363222}
32373223
32383224void
32393225PyInterpreterState_Release (PyInterpreterState * interp )
32403226{
32413227 assert (interp != NULL );
3242- decref_interpreter (interp );
3228+ decrement_daemon_count (interp );
32433229}
32443230
32453231static int
@@ -3251,12 +3237,16 @@ tstate_set_daemon(PyThreadState *tstate, PyInterpreterState *interp, int daemon)
32513237 assert (daemon == 1 || daemon == 0 );
32523238 struct _Py_finalizing_threads * finalizing = & interp -> threads .finalizing ;
32533239 PyMutex_Lock (& finalizing -> mutex );
3240+ if (_Py_atomic_load_ssize_relaxed (& finalizing -> countdown ) == 0 ) {
3241+ PyMutex_Unlock (& finalizing -> mutex );
3242+ return -1 ;
3243+ }
32543244 if (_PyEvent_IsSet (& finalizing -> finished )) {
32553245 /* Native threads have already finalized */
32563246 PyMutex_Unlock (& finalizing -> mutex );
32573247 return -1 ;
32583248 }
3259- ++ finalizing -> countdown ;
3249+ _Py_atomic_add_ssize ( & finalizing -> countdown , 1 ) ;
32603250 PyMutex_Unlock (& finalizing -> mutex );
32613251 tstate -> daemon = daemon ;
32623252 return 1 ;
@@ -3271,7 +3261,7 @@ PyThreadState_SetDaemon(int daemon)
32713261 }
32723262 PyInterpreterState * interp = tstate -> interp ;
32733263 assert (interp != NULL );
3274- if (tstate == & interp -> _initial_thread ) {
3264+ if (tstate == ( PyThreadState * ) & interp -> _initial_thread ) {
32753265 Py_FatalError ("thread cannot be the main thread" );
32763266 }
32773267 if (tstate -> daemon == daemon ) {
@@ -3287,39 +3277,31 @@ PyThreadState_Ensure(PyInterpreterState *interp)
32873277 assert (interp != NULL );
32883278 _Py_ensured_tstate * entry = PyMem_RawMalloc (sizeof (_Py_ensured_tstate ));
32893279 if (entry == NULL ) {
3290- decref_interpreter (interp );
3280+ decrement_daemon_count (interp );
32913281 return -1 ;
32923282 }
32933283 PyThreadState * save = _PyThreadState_GET ();
32943284 if (save != NULL && save -> interp == interp ) {
3295- /* We already have a thread state that matches the
3296- interpreter. */
3297- Py_ssize_t refcnt = decref_interpreter (interp );
32983285 entry -> was_daemon = save -> daemon ;
32993286 entry -> next = save -> ensured ;
33003287 entry -> prior_tstate = NULL ;
3301- if (tstate_set_daemon (save , interp , 0 ) < 0 ) {
3302- PyMem_RawFree (entry );
3303- return -1 ;
3304- }
33053288 save -> ensured = entry ;
3289+ // Setting 'daemon' to 0 passes off the interpreter's reference
3290+ save -> daemon = 0 ;
33063291 return 0 ;
33073292 }
33083293
33093294 PyThreadState * tstate = PyThreadState_New (interp );
3310- decref_interpreter (interp );
33113295 if (tstate == NULL ) {
33123296 PyMem_RawFree (entry );
33133297 return -1 ;
33143298 }
3315- if (tstate_set_daemon (tstate , interp , 0 ) < 0 ) {
3316- PyMem_RawFree (entry );
3317- return -1 ;
3318- }
3299+ tstate -> daemon = 0 ;
33193300 entry -> was_daemon = 0 ;
33203301 entry -> prior_tstate = save ;
33213302 entry -> next = NULL ;
33223303 tstate -> ensured = entry ;
3304+ PyThreadState_Swap (tstate );
33233305
33243306 return 0 ;
33253307}
@@ -3342,8 +3324,11 @@ PyThreadState_Release(void)
33423324 return ;
33433325 }
33443326
3345- decrement_daemon_count (tstate -> interp );
33463327 tstate -> ensured = ensured -> next ;
33473328 tstate -> daemon = ensured -> was_daemon ;
33483329 PyMem_RawFree (ensured );
3330+ PyThreadState_Clear (tstate );
3331+ PyThreadState_Swap (NULL );
3332+ PyInterpreterState * interp = tstate -> interp ;
3333+ PyThreadState_Delete (tstate );
33493334}
0 commit comments