Skip to content

Commit

Permalink
Review feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
Firstyear committed Jan 15, 2025
1 parent a8dab00 commit 7593c0b
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 18 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ fdstore = ["dep:sendfd"]

[dependencies]
sendfd = { version = "0.4", optional = true }
libc = "^0.2.169"
libc = "0.2"
45 changes: 28 additions & 17 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ pub enum NotifyState<'a> {
WatchdogTrigger,
/// Resets the configured watchdog value.
WatchdogUsec(u32),
/// Tells the service manager to extend the service timeout.
/// Tells the service manager> to extend the service timeout.
ExtendTimeoutUsec(u32),
/// Tells the service manager to store attached file descriptors.
#[cfg(feature = "fdstore")]
Expand All @@ -71,8 +71,9 @@ pub enum NotifyState<'a> {
/// Tells the service manager to use this name for the attached file descriptor.
#[cfg(feature = "fdstore")]
FdName(&'a str),
/// Notify systemd of the current monotonic time in microseconds.
MonotonicUsec,
/// Notify systemd of the current monotonic time in microseconds. You should construct this
/// value by calling `NotifyState::monotonic_usec_now()`.
MonotonicUsec(i128),
/// Custom state.
Custom(&'a str),
}
Expand All @@ -97,15 +98,26 @@ impl Display for NotifyState<'_> {
NotifyState::FdStoreRemove => write!(f, "FDSTOREREMOVE=1"),
#[cfg(feature = "fdstore")]
NotifyState::FdName(name) => write!(f, "FDNAME={}", name),
NotifyState::MonotonicUsec => {
let usec = monotonic_time_usecs();
write!(f, "MONOTONIC_USEC={}", usec)
}
NotifyState::MonotonicUsec(usec) => write!(f, "MONOTONIC_USEC={}", usec),
NotifyState::Custom(state) => write!(f, "{}", state),
}
}
}

impl NotifyState<'_> {
/// Create a new NotifyState::MonotonicUsec using the current system monotonic time.
///
/// # Example
///
/// ```no_run
/// let _ = NotifyState::monotonic_usec_now()
/// .expect("Failed to access monotonic time");
/// ```
pub fn monotonic_usec_now() -> io::Result<Self> {
monotonic_time_usec().map(NotifyState::MonotonicUsec)
}
}

/// Checks whether the system has been booted by `systemd`.
///
/// This is implemented by verifying that a `/run/systemd/system` directory exists.
Expand Down Expand Up @@ -452,32 +464,31 @@ pub fn watchdog_enabled(unset_env: bool, usec: &mut u64) -> bool {
}
}

fn monotonic_time_usecs() -> io::Result<u128> {
use libc::{timespec, CLOCK_MONOTONIC, clock_gettime};
fn monotonic_time_usec() -> io::Result<i128> {
use libc::{clock_gettime, timespec, CLOCK_MONOTONIC};
use std::mem::MaybeUninit;

let mut c_time: MaybeUninit<timespec> = MaybeUninit::uninit();

let result = unsafe {
clock_gettime(CLOCK_MONOTONIC, c_time.as_mut_ptr())
};
let result = unsafe { clock_gettime(CLOCK_MONOTONIC, c_time.as_mut_ptr()) };

// WARNING - between the function that sets clock_gettime and last_os_error, you MUST NOT
// call any other function else the errno value MAY be reset.

if result != 0 {
// Should we return this as Result or Option?
return Err(io::last_os_error());
return Err(io::Error::last_os_error());
}

let monotonic_time = unsafe { c_time.assume_init() };

// First, nanosecond / 1000 -> microseconds.
// nanosecond / 1000 -> microseconds.
let lower_microseconds = (monotonic_time.tv_nsec / 1000) as i128;

// Now we have to shift the tv_sec to fit in our space.
// second * 1_000_000 -> microseconds
let upper_microseconds = (monotonic_time.tv_sec * 1_000_000) as i128;

Ok((upper_microseconds + lower_microseconds) as u128)
// combine
Ok(upper_microseconds + lower_microseconds)
}

#[cfg(test)]
Expand Down

0 comments on commit 7593c0b

Please sign in to comment.