@@ -39,6 +39,7 @@ extern "C" {
3939
4040/* Forward declarations */
4141static PyThreadState * _PyGILState_GetThisThreadState (struct _gilstate_runtime_state * gilstate );
42+ static void _PyThreadState_Delete (PyThreadState * tstate , int check_current );
4243
4344
4445static PyStatus
@@ -295,13 +296,13 @@ PyInterpreterState_Clear(PyInterpreterState *interp)
295296
296297
297298static void
298- zapthreads (PyInterpreterState * interp )
299+ zapthreads (PyInterpreterState * interp , int check_current )
299300{
300- PyThreadState * p ;
301+ PyThreadState * tstate ;
301302 /* No need to lock the mutex here because this should only happen
302303 when the threads are all really dead (XXX famous last words). */
303- while ((p = interp -> tstate_head ) != NULL ) {
304- PyThreadState_Delete ( p );
304+ while ((tstate = interp -> tstate_head ) != NULL ) {
305+ _PyThreadState_Delete ( tstate , check_current );
305306 }
306307}
307308
@@ -311,7 +312,11 @@ PyInterpreterState_Delete(PyInterpreterState *interp)
311312{
312313 _PyRuntimeState * runtime = interp -> runtime ;
313314 struct pyinterpreters * interpreters = & runtime -> interpreters ;
314- zapthreads (interp );
315+ zapthreads (interp , 0 );
316+
317+ /* Delete current thread. After this, many C API calls become crashy. */
318+ _PyThreadState_Swap (& runtime -> gilstate , NULL );
319+
315320 HEAD_LOCK (runtime );
316321 PyInterpreterState * * p ;
317322 for (p = & interpreters -> head ; ; p = & (* p )-> next ) {
@@ -367,7 +372,7 @@ _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime)
367372 }
368373
369374 PyInterpreterState_Clear (interp ); // XXX must activate?
370- zapthreads (interp );
375+ zapthreads (interp , 1 );
371376 if (interp -> id_mutex != NULL ) {
372377 PyThread_free_lock (interp -> id_mutex );
373378 }
@@ -793,7 +798,8 @@ PyThreadState_Clear(PyThreadState *tstate)
793798
794799/* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */
795800static void
796- tstate_delete_common (PyThreadState * tstate )
801+ tstate_delete_common (PyThreadState * tstate ,
802+ struct _gilstate_runtime_state * gilstate )
797803{
798804 _PyRuntimeState * runtime = tstate -> interp -> runtime ;
799805 if (tstate == NULL ) {
@@ -815,22 +821,32 @@ tstate_delete_common(PyThreadState *tstate)
815821 tstate -> on_delete (tstate -> on_delete_data );
816822 }
817823 PyMem_RawFree (tstate );
818- }
819-
820824
821- void
822- PyThreadState_Delete (PyThreadState * tstate )
823- {
824- struct _gilstate_runtime_state * gilstate = & tstate -> interp -> runtime -> gilstate ;
825- if (tstate == _PyRuntimeGILState_GetThreadState (gilstate )) {
826- Py_FatalError ("PyThreadState_Delete: tstate is still current" );
827- }
828825 if (gilstate -> autoInterpreterState &&
829826 PyThread_tss_get (& gilstate -> autoTSSkey ) == tstate )
830827 {
831828 PyThread_tss_set (& gilstate -> autoTSSkey , NULL );
832829 }
833- tstate_delete_common (tstate );
830+ }
831+
832+
833+ static void
834+ _PyThreadState_Delete (PyThreadState * tstate , int check_current )
835+ {
836+ struct _gilstate_runtime_state * gilstate = & tstate -> interp -> runtime -> gilstate ;
837+ if (check_current ) {
838+ if (tstate == _PyRuntimeGILState_GetThreadState (gilstate )) {
839+ Py_FatalError ("PyThreadState_Delete: tstate is still current" );
840+ }
841+ }
842+ tstate_delete_common (tstate , gilstate );
843+ }
844+
845+
846+ void
847+ PyThreadState_Delete (PyThreadState * tstate )
848+ {
849+ _PyThreadState_Delete (tstate , 1 );
834850}
835851
836852
@@ -842,12 +858,7 @@ _PyThreadState_DeleteCurrent(_PyRuntimeState *runtime)
842858 if (tstate == NULL )
843859 Py_FatalError (
844860 "PyThreadState_DeleteCurrent: no current tstate" );
845- tstate_delete_common (tstate );
846- if (gilstate -> autoInterpreterState &&
847- PyThread_tss_get (& gilstate -> autoTSSkey ) == tstate )
848- {
849- PyThread_tss_set (& gilstate -> autoTSSkey , NULL );
850- }
861+ tstate_delete_common (tstate , gilstate );
851862 _PyRuntimeGILState_SetThreadState (gilstate , NULL );
852863 PyEval_ReleaseLock ();
853864}
0 commit comments