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

Function sleep

crates/vm/src/stdlib/time.rs:99–152  ·  view source on GitHub ↗
(seconds: PyObjectRef, vm: &VirtualMachine)

Source from the content-addressed store, hash-verified

97
98 #[pyfunction]
99 fn sleep(seconds: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
100 let seconds_type_name = seconds.clone().class().name().to_owned();
101 let dur = seconds.try_into_value::<Duration>(vm).map_err(|e| {
102 if e.class().is(vm.ctx.exceptions.value_error)
103 && let Some(s) = e.args().first().and_then(|arg| arg.str(vm).ok())
104 && s.as_bytes() == b"negative duration"
105 {
106 return vm.new_value_error("sleep length must be non-negative");
107 }
108 if e.class().is(vm.ctx.exceptions.type_error) {
109 return vm.new_type_error(format!(
110 "'{seconds_type_name}' object cannot be interpreted as an integer or float"
111 ));
112 }
113 e
114 })?;
115
116 #[cfg(unix)]
117 {
118 // Loop on nanosleep, recomputing the
119 // remaining timeout after each EINTR so that signals don't
120 // shorten the requested sleep duration.
121 use std::time::Instant;
122 let deadline = Instant::now() + dur;
123 loop {
124 let remaining = deadline.saturating_duration_since(Instant::now());
125 if remaining.is_zero() {
126 break;
127 }
128 let ts = nix::sys::time::TimeSpec::from(remaining);
129 let (res, err) = vm.allow_threads(|| {
130 let r = unsafe { libc::nanosleep(ts.as_ref(), core::ptr::null_mut()) };
131 (r, nix::Error::last_raw())
132 });
133 if res == 0 {
134 break;
135 }
136 if err != libc::EINTR {
137 return Err(
138 vm.new_os_error(format!("nanosleep: {}", nix::Error::from_raw(err)))
139 );
140 }
141 // EINTR: run signal handlers, then retry with remaining time
142 vm.check_signals()?;
143 }
144 }
145
146 #[cfg(not(unix))]
147 {
148 vm.allow_threads(|| std::thread::sleep(dur));
149 }
150
151 Ok(())
152 }
153
154 #[pyfunction]
155 fn time_ns(vm: &VirtualMachine) -> PyResult<u64> {

Callers 4

writeMethod · 0.90
test_selectorMethod · 0.90
_fatal_error_c_threadFunction · 0.50
mainloopMethod · 0.50

Calls 15

isMethod · 0.80
okMethod · 0.80
allow_threadsMethod · 0.80
new_os_errorMethod · 0.80
check_signalsMethod · 0.80
ErrClass · 0.50
to_ownedMethod · 0.45
nameMethod · 0.45
classMethod · 0.45
cloneMethod · 0.45
firstMethod · 0.45
argsMethod · 0.45

Tested by 1

test_selectorMethod · 0.72