@@ -176,11 +176,13 @@ ThreadHandle_get_os_handle(ThreadHandle *handle, PyThread_handle_t *os_handle)
176176}
177177
178178static void
179- add_to_shutdown_handles (thread_module_state * state , ThreadHandle * handle )
179+ add_to_shutdown_handles (thread_module_state * state , ThreadHandle * handle , PyInterpreterState * interp )
180180{
181+ _PyRWMutex_RLock (& interp -> prefini_mutex );
181182 HEAD_LOCK (& _PyRuntime );
182183 llist_insert_tail (& state -> shutdown_handles , & handle -> shutdown_node );
183184 HEAD_UNLOCK (& _PyRuntime );
185+ _PyRWMutex_RUnlock (& interp -> prefini_mutex );
184186}
185187
186188static void
@@ -195,13 +197,16 @@ clear_shutdown_handles(thread_module_state *state)
195197}
196198
197199static void
198- remove_from_shutdown_handles (ThreadHandle * handle )
200+ remove_from_shutdown_handles (ThreadHandle * handle , PyInterpreterState * interp )
199201{
202+ assert (interp != NULL );
203+ _PyRWMutex_RLock (& interp -> prefini_mutex );
200204 HEAD_LOCK (& _PyRuntime );
201205 if (handle -> shutdown_node .next != NULL ) {
202206 llist_remove (& handle -> shutdown_node );
203207 }
204208 HEAD_UNLOCK (& _PyRuntime );
209+ _PyRWMutex_RUnlock (& interp -> prefini_mutex );
205210}
206211
207212static ThreadHandle *
@@ -309,7 +314,7 @@ _PyThread_AfterFork(struct _pythread_runtime_state *state)
309314 handle -> mutex = (PyMutex ){_Py_UNLOCKED };
310315 _PyEvent_Notify (& handle -> thread_is_exiting );
311316 llist_remove (node );
312- remove_from_shutdown_handles (handle );
317+ remove_from_shutdown_handles (handle , _PyInterpreterState_GET () );
313318 }
314319}
315320
@@ -392,7 +397,7 @@ thread_run(void *boot_raw)
392397
393398exit :
394399 // Don't need to wait for this thread anymore
395- remove_from_shutdown_handles (handle );
400+ remove_from_shutdown_handles (handle , _PyInterpreterState_GET () );
396401
397402 _PyEvent_Notify (& handle -> thread_is_exiting );
398403 ThreadHandle_decref (handle );
@@ -1863,12 +1868,12 @@ do_start_new_thread(thread_module_state *state, PyObject *func, PyObject *args,
18631868 // Add the handle before starting the thread to avoid adding a handle
18641869 // to a thread that has already finished (i.e. if the thread finishes
18651870 // before the call to `ThreadHandle_start()` below returns).
1866- add_to_shutdown_handles (state , handle );
1871+ add_to_shutdown_handles (state , handle , interp );
18671872 }
18681873
18691874 if (ThreadHandle_start (handle , func , args , kwargs ) < 0 ) {
18701875 if (!daemon ) {
1871- remove_from_shutdown_handles (handle );
1876+ remove_from_shutdown_handles (handle , _PyInterpreterState_GET () );
18721877 }
18731878 return -1 ;
18741879 }
@@ -2345,7 +2350,6 @@ thread_shutdown(PyObject *self, PyObject *args)
23452350{
23462351 PyThread_ident_t ident = PyThread_get_thread_ident_ex ();
23472352 thread_module_state * state = get_thread_state (self );
2348- int found_thread = 0 ;
23492353
23502354 for (;;) {
23512355 ThreadHandle * handle = NULL ;
@@ -2354,7 +2358,6 @@ thread_shutdown(PyObject *self, PyObject *args)
23542358 HEAD_LOCK (& _PyRuntime );
23552359 struct llist_node * node ;
23562360 llist_for_each_safe (node , & state -> shutdown_handles ) {
2357- found_thread = 1 ;
23582361 ThreadHandle * cur = llist_data (node , ThreadHandle , shutdown_node );
23592362 if (cur -> ident != ident ) {
23602363 ThreadHandle_incref (cur );
@@ -2375,13 +2378,13 @@ thread_shutdown(PyObject *self, PyObject *args)
23752378 PyErr_FormatUnraisable ("Exception ignored while joining a thread "
23762379 "in _thread._shutdown()" );
23772380 ThreadHandle_decref (handle );
2378- return PyBool_FromLong ( found_thread ) ;
2381+ Py_RETURN_NONE ;
23792382 }
23802383
23812384 ThreadHandle_decref (handle );
23822385 }
23832386
2384- return PyBool_FromLong ( found_thread ) ;
2387+ Py_RETURN_NONE ;
23852388}
23862389
23872390PyDoc_STRVAR (shutdown_doc ,
0 commit comments