MCPcopy Index your code
hub / github.com/RustPython/RustPython / join_internal

Method join_internal

crates/vm/src/stdlib/_thread.rs:1204–1306  ·  view source on GitHub ↗
(
            inner: &Arc<parking_lot::Mutex<ThreadHandleInner>>,
            done_event: &Arc<(parking_lot::Mutex<bool>, parking_lot::Condvar)>,
            timeout_duration: Option<Duration>,
      

Source from the content-addressed store, hash-verified

1202 }
1203
1204 fn join_internal(
1205 inner: &Arc<parking_lot::Mutex<ThreadHandleInner>>,
1206 done_event: &Arc<(parking_lot::Mutex<bool>, parking_lot::Condvar)>,
1207 timeout_duration: Option<Duration>,
1208 vm: &VirtualMachine,
1209 ) -> PyResult<()> {
1210 Self::check_started(inner, vm)?;
1211
1212 let deadline =
1213 timeout_duration.and_then(|timeout| std::time::Instant::now().checked_add(timeout));
1214
1215 // Wait for thread completion using Condvar (supports timeout)
1216 // Loop to handle spurious wakeups
1217 let (lock, cvar) = &**done_event;
1218 let mut done = lock.lock();
1219
1220 // ThreadHandle_join semantics: self-join/finalizing checks
1221 // apply only while target thread has not reported it is exiting yet.
1222 if !*done {
1223 let inner_guard = inner.lock();
1224 let current_ident = get_ident();
1225 if inner_guard.ident == current_ident
1226 && inner_guard.state == ThreadHandleState::Running
1227 {
1228 return Err(vm.new_runtime_error("Cannot join current thread"));
1229 }
1230 if vm
1231 .state
1232 .finalizing
1233 .load(core::sync::atomic::Ordering::Acquire)
1234 {
1235 return Err(vm.new_exception_msg(
1236 vm.ctx.exceptions.python_finalization_error.to_owned(),
1237 "cannot join thread at interpreter shutdown"
1238 .to_owned()
1239 .into(),
1240 ));
1241 }
1242 }
1243
1244 while !*done {
1245 if let Some(timeout) = timeout_duration {
1246 let remaining = deadline.map_or(timeout, |deadline| {
1247 deadline.saturating_duration_since(std::time::Instant::now())
1248 });
1249 if remaining.is_zero() {
1250 return Ok(());
1251 }
1252 let result = vm.allow_threads(|| cvar.wait_for(&mut done, remaining));
1253 if result.timed_out() && !*done {
1254 // Timeout occurred and done is still false
1255 return Ok(());
1256 }
1257 } else {
1258 // Infinite wait
1259 vm.allow_threads(|| cvar.wait(&mut done));
1260 }
1261 }

Callers

nothing calls this directly

Calls 12

new_exception_msgMethod · 0.80
allow_threadsMethod · 0.80
get_identFunction · 0.70
ErrClass · 0.50
lockMethod · 0.45
loadMethod · 0.45
to_ownedMethod · 0.45
is_zeroMethod · 0.45
wait_forMethod · 0.45
waitMethod · 0.45
takeMethod · 0.45
joinMethod · 0.45

Tested by

no test coverage detected