(vm: &VirtualMachine)
| 1052 | /// parking_lot-based locks in VmState are in unlocked state. |
| 1053 | #[cfg(unix)] |
| 1054 | pub fn after_fork_child(vm: &VirtualMachine) { |
| 1055 | let current_ident = get_ident(); |
| 1056 | |
| 1057 | // Update main thread ident - after fork, the current thread becomes the main thread |
| 1058 | vm.state.main_thread_ident.store(current_ident); |
| 1059 | |
| 1060 | // Reinitialize frame slot for current thread. |
| 1061 | // Locks are already reinit'd, so lock() is safe. |
| 1062 | crate::vm::thread::reinit_frame_slot_after_fork(vm); |
| 1063 | |
| 1064 | // Clean up thread handles. All VmState locks were reinit'd to unlocked, |
| 1065 | // so lock() won't deadlock. Per-thread Arc<Mutex<ThreadHandleInner>> |
| 1066 | // locks are also reinit'd below before use. |
| 1067 | { |
| 1068 | let mut handles = vm.state.thread_handles.lock(); |
| 1069 | handles.retain(|(inner_weak, done_event_weak): &HandleEntry| { |
| 1070 | let Some(inner) = inner_weak.upgrade() else { |
| 1071 | return false; |
| 1072 | }; |
| 1073 | let Some(done_event) = done_event_weak.upgrade() else { |
| 1074 | return false; |
| 1075 | }; |
| 1076 | |
| 1077 | // Reinit this per-handle lock in case a dead thread held it |
| 1078 | reinit_parking_lot_mutex(&inner); |
| 1079 | let mut inner_guard = inner.lock(); |
| 1080 | |
| 1081 | if inner_guard.ident == current_ident { |
| 1082 | return true; |
| 1083 | } |
| 1084 | if inner_guard.state == ThreadHandleState::NotStarted { |
| 1085 | return true; |
| 1086 | } |
| 1087 | |
| 1088 | inner_guard.state = ThreadHandleState::Done; |
| 1089 | inner_guard.join_handle = None; |
| 1090 | drop(inner_guard); |
| 1091 | |
| 1092 | // Reinit and set the done event |
| 1093 | let (lock, cvar) = &*done_event; |
| 1094 | reinit_parking_lot_mutex(lock); |
| 1095 | *lock.lock() = true; |
| 1096 | cvar.notify_all(); |
| 1097 | |
| 1098 | true |
| 1099 | }); |
| 1100 | } |
| 1101 | |
| 1102 | // Clean up shutdown_handles. |
| 1103 | { |
| 1104 | let mut handles = vm.state.shutdown_handles.lock(); |
| 1105 | handles.retain(|(inner_weak, done_event_weak): &ShutdownEntry| { |
| 1106 | let Some(inner) = inner_weak.upgrade() else { |
| 1107 | return false; |
| 1108 | }; |
| 1109 | let Some(done_event) = done_event_weak.upgrade() else { |
| 1110 | return false; |
| 1111 | }; |
no test coverage detected