@@ -904,41 +904,65 @@ pub(crate) mod _thread {
904904 // Update main thread ident - after fork, the current thread becomes the main thread
905905 MAIN_THREAD_IDENT . store ( current_ident) ;
906906
907- // Clean up THREAD_FRAMES - only keep current thread's frame slot
908- THREAD_FRAMES . lock ( ) . retain ( |& id, _| id == current_ident) ;
909-
910- let mut handles = THREAD_HANDLES . lock ( ) ;
907+ // Reinitialize THREAD_FRAMES for child process.
908+ // After fork, the old mutex/Arc state from parent threads is invalid.
909+ // We need to create a fresh slot for the current (only) thread.
910+ //
911+ // Note: We try_lock() because the mutex might have been held by a thread
912+ // that no longer exists in the child. If we can't acquire it, we still
913+ // reinitialize the thread-local which is sufficient for the child process.
914+ let new_slot = Arc :: new ( parking_lot:: Mutex :: new ( None ) ) ;
915+ if let Some ( mut registry) = THREAD_FRAMES . try_lock ( ) {
916+ registry. clear ( ) ;
917+ registry. insert ( current_ident, new_slot. clone ( ) ) ;
918+ }
919+ // Always update thread-local to point to the new slot
920+ CURRENT_FRAME_SLOT . with ( |s| {
921+ * s. borrow_mut ( ) = Some ( new_slot) ;
922+ } ) ;
911923
912- // Clean up dead weak refs and mark non-current threads as done
913- handles. retain ( |( inner_weak, done_event_weak) | {
914- let Some ( inner) = inner_weak. upgrade ( ) else {
915- return false ; // Remove dead entries
916- } ;
917- let Some ( done_event) = done_event_weak. upgrade ( ) else {
918- return false ;
919- } ;
924+ // Clean up thread handles if we can acquire the lock.
925+ // Use try_lock because the mutex might have been held during fork.
926+ // If we can't acquire it, just skip - the child process will work
927+ // correctly with new handles it creates.
928+ if let Some ( mut handles) = THREAD_HANDLES . try_lock ( ) {
929+ // Clean up dead weak refs and mark non-current threads as done
930+ handles. retain ( |( inner_weak, done_event_weak) | {
931+ let Some ( inner) = inner_weak. upgrade ( ) else {
932+ return false ; // Remove dead entries
933+ } ;
934+ let Some ( done_event) = done_event_weak. upgrade ( ) else {
935+ return false ;
936+ } ;
920937
921- let mut inner_guard = inner. lock ( ) ;
938+ // Try to lock the inner state - skip if we can't
939+ let Some ( mut inner_guard) = inner. try_lock ( ) else {
940+ return false ;
941+ } ;
922942
923- // Skip current thread and not-started threads
924- if inner_guard. ident == current_ident {
925- return true ;
926- }
927- if inner_guard. state == ThreadHandleState :: NotStarted {
928- return true ;
929- }
943+ // Skip current thread and not-started threads
944+ if inner_guard. ident == current_ident {
945+ return true ;
946+ }
947+ if inner_guard. state == ThreadHandleState :: NotStarted {
948+ return true ;
949+ }
930950
931- // Mark as done and notify waiters
932- inner_guard. state = ThreadHandleState :: Done ;
933- inner_guard. join_handle = None ; // Can't join OS thread from child
934- drop ( inner_guard) ;
951+ // Mark as done and notify waiters
952+ inner_guard. state = ThreadHandleState :: Done ;
953+ inner_guard. join_handle = None ; // Can't join OS thread from child
954+ drop ( inner_guard) ;
935955
936- let ( lock, cvar) = & * done_event;
937- * lock. lock ( ) = true ;
938- cvar. notify_all ( ) ;
956+ // Try to notify waiters - skip if we can't acquire the lock
957+ let ( lock, cvar) = & * done_event;
958+ if let Some ( mut done) = lock. try_lock ( ) {
959+ * done = true ;
960+ cvar. notify_all ( ) ;
961+ }
939962
940- true
941- } ) ;
963+ true
964+ } ) ;
965+ }
942966 }
943967
944968 // Thread handle state enum
0 commit comments