File tree Expand file tree Collapse file tree 1 file changed +44
-0
lines changed
Expand file tree Collapse file tree 1 file changed +44
-0
lines changed Original file line number Diff line number Diff line change @@ -936,6 +936,50 @@ pub(crate) mod _thread {
936936 true
937937 } ) ;
938938 }
939+
940+ // Clean up shutdown_handles as well.
941+ // This is critical to prevent _shutdown() from waiting on threads
942+ // that don't exist in the child process after fork.
943+ if let Some ( mut handles) = vm. state . shutdown_handles . try_lock ( ) {
944+ // Mark all non-current threads as done in shutdown_handles
945+ handles. retain ( |( inner_weak, done_event_weak) : & ShutdownEntry | {
946+ let Some ( inner) = inner_weak. upgrade ( ) else {
947+ return false ; // Remove dead entries
948+ } ;
949+ let Some ( done_event) = done_event_weak. upgrade ( ) else {
950+ return false ;
951+ } ;
952+
953+ // Try to lock the inner state - skip if we can't
954+ let Some ( mut inner_guard) = inner. try_lock ( ) else {
955+ return false ;
956+ } ;
957+
958+ // Skip current thread
959+ if inner_guard. ident == current_ident {
960+ return true ;
961+ }
962+
963+ // Keep handles for threads that have not been started yet.
964+ // They are safe to start in the child process.
965+ if inner_guard. state == ThreadHandleState :: NotStarted {
966+ return true ;
967+ }
968+
969+ // Mark as done so _shutdown() won't wait on it
970+ inner_guard. state = ThreadHandleState :: Done ;
971+ drop ( inner_guard) ;
972+
973+ // Notify waiters
974+ let ( lock, cvar) = & * done_event;
975+ if let Some ( mut done) = lock. try_lock ( ) {
976+ * done = true ;
977+ cvar. notify_all ( ) ;
978+ }
979+
980+ false // Remove from shutdown_handles - these threads don't exist in child
981+ } ) ;
982+ }
939983 }
940984
941985 // Thread handle state enum
You can’t perform that action at this time.
0 commit comments