File tree Expand file tree Collapse file tree 2 files changed +16
-4
lines changed Expand file tree Collapse file tree 2 files changed +16
-4
lines changed Original file line number Diff line number Diff line change @@ -1133,16 +1133,16 @@ Py_FinalizeEx(void)
1133
1133
return status ;
1134
1134
}
1135
1135
1136
+ /* Get current thread state and interpreter pointer */
1137
+ PyThreadState * tstate = _PyThreadState_GET ();
1138
+ PyInterpreterState * interp = tstate -> interp ;
1139
+
1136
1140
// Wrap up existing "threading"-module-created, non-daemon threads.
1137
1141
wait_for_thread_shutdown ();
1138
1142
1139
1143
// Make any remaining pending calls.
1140
1144
_Py_FinishPendingCalls ();
1141
1145
1142
- /* Get current thread state and interpreter pointer */
1143
- PyThreadState * tstate = _PyThreadState_GET ();
1144
- PyInterpreterState * interp = tstate -> interp ;
1145
-
1146
1146
/* The interpreter is still entirely intact at this point, and the
1147
1147
* exit funcs may be relying on that. In particular, if some thread
1148
1148
* or exit func is still waiting to do an import, the import machinery
@@ -2194,6 +2194,9 @@ wait_for_thread_shutdown(void)
2194
2194
Py_DECREF (result );
2195
2195
}
2196
2196
Py_DECREF (threading );
2197
+
2198
+ // All threading module threads are marked as "done" later
2199
+ // in PyThreadState_Clear().
2197
2200
}
2198
2201
2199
2202
#define NEXITFUNCS 32
Original file line number Diff line number Diff line change @@ -781,6 +781,13 @@ PyThreadState_Clear(PyThreadState *tstate)
781
781
Py_CLEAR (tstate -> async_gen_finalizer );
782
782
783
783
Py_CLEAR (tstate -> context );
784
+
785
+ if (tstate -> on_delete != NULL ) {
786
+ // This will unblock any joining threads.
787
+ tstate -> on_delete (tstate -> on_delete_data );
788
+ tstate -> on_delete = NULL ;
789
+ tstate -> on_delete_data = NULL ;
790
+ }
784
791
}
785
792
786
793
@@ -804,6 +811,8 @@ tstate_delete_common(_PyRuntimeState *runtime, PyThreadState *tstate)
804
811
tstate -> next -> prev = tstate -> prev ;
805
812
HEAD_UNLOCK (runtime );
806
813
if (tstate -> on_delete != NULL ) {
814
+ // This will unblock any joining threads.
815
+ // We also do this in PyThreadState_Clear(), but do it here to be sure.
807
816
tstate -> on_delete (tstate -> on_delete_data );
808
817
}
809
818
PyMem_RawFree (tstate );
You can’t perform that action at this time.
0 commit comments