Skip to content

Commit 078d7f8

Browse files
committed
add safe libc::clock_nanosleep wrapper
1 parent c8e8def commit 078d7f8

File tree

3 files changed

+60
-3
lines changed

3 files changed

+60
-3
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ exclude = [
1717
]
1818

1919
[dependencies]
20-
libc = { version = "0.2.78", features = [ "extra_traits" ] }
20+
libc = { version = "0.2.80", features = [ "extra_traits" ] }
2121
bitflags = "1.1"
2222
cfg-if = "0.1.10"
2323

src/time.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use crate::sys::time::TimeSpec;
1+
use bitflags::bitflags;
2+
use crate::sys::time::{TimeSpec, TimeValLike};
23
#[cfg(any(
34
target_os = "freebsd",
45
target_os = "dragonfly",
@@ -256,3 +257,46 @@ pub fn clock_getcpuclockid(pid: Pid) -> Result<ClockId> {
256257
Err(Error::Sys(Errno::from_i32(ret)))
257258
}
258259
}
260+
261+
bitflags! {
262+
/// Flags that are used for arming the timer.
263+
pub struct ClockNanosleepFlags: libc::c_int {
264+
const TIMER_ABSTIME = libc::TIMER_ABSTIME;
265+
}
266+
}
267+
268+
/// Suspend execution of this thread for the amount of time specified by rqtp
269+
/// and measured against the clock speficied by ClockId. If flags is
270+
/// TIMER_ABSTIME, this function will suspend execution until the time value of
271+
/// clock_id reaches the absolute time specified by rqtp. If a signal is caught
272+
/// by a signal-catching function, or a signal causes the process to terminate,
273+
/// this sleep is interrrupted.
274+
/// see also [man 3 clock_nanosleep](https://pubs.opengroup.org/onlinepubs/009695399/functions/clock_nanosleep.html)
275+
#[cfg(any(
276+
target_os = "freebsd",
277+
target_os = "netbsd",
278+
target_os = "linux",
279+
target_os = "android",
280+
target_os = "solaris",
281+
target_os = "illumos",
282+
))]
283+
pub fn clock_nanosleep(
284+
clock_id: ClockId,
285+
flags: ClockNanosleepFlags,
286+
rqtp: &TimeSpec,
287+
) -> Result<TimeSpec> {
288+
let mut rmtp: TimeSpec = TimeSpec::nanoseconds(0);
289+
let ret = unsafe {
290+
libc::clock_nanosleep(
291+
clock_id.as_raw(),
292+
flags.bits(),
293+
rqtp.as_ref() as *const _,
294+
rmtp.as_mut() as *mut _,
295+
)
296+
};
297+
if ret == 0 {
298+
Ok(rmtp)
299+
} else {
300+
Err(Error::Sys(Errno::from_i32(ret)))
301+
}
302+
}

test/test_time.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use nix::sys::time::{TimeSpec, TimeValLike};
12
#[cfg(any(
23
target_os = "freebsd",
34
target_os = "dragonfly",
@@ -6,7 +7,7 @@
67
target_os = "emscripten",
78
))]
89
use nix::time::clock_getcpuclockid;
9-
use nix::time::{clock_getres, clock_gettime, ClockId};
10+
use nix::time::{clock_getres, clock_gettime, clock_nanosleep, ClockId, ClockNanosleepFlags};
1011

1112
#[test]
1213
pub fn test_clock_getres() {
@@ -54,3 +55,15 @@ pub fn test_clock_id_pid_cpu_clock_id() {
5455
.map(ClockId::now)
5556
.is_ok());
5657
}
58+
59+
#[test]
60+
pub fn test_clock_nanosleep() {
61+
let sleep_time = TimeSpec::microseconds(1);
62+
let res = clock_nanosleep(
63+
ClockId::CLOCK_MONOTONIC,
64+
ClockNanosleepFlags::empty(),
65+
&sleep_time,
66+
);
67+
let expected = TimeSpec::microseconds(0);
68+
assert_eq!(res, Ok(expected));
69+
}

0 commit comments

Comments
 (0)