Skip to content

Commit 994e31d

Browse files
committed
Fix thread
1 parent 90aeef1 commit 994e31d

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

crates/vm/src/stdlib/thread.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff 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

0 commit comments

Comments
 (0)