forked from cloudflare/boringtun
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Be sure to count for system sleep in timers (cloudflare#317)
* Be sure to count for system sleep in timers Currently the timers in boringtun use std::time::Instant. This timer does not increment while the machine is asleep on macOS and Linux meaning the device does not know to properly handshake on wake from sleep. To solve this we use `CLOCK_BOOTTIME` on Linux/Android and `CLOCK_MONOTONIC` on macOS/iOS to get the actual duration since the last handshake. Fixes cloudflare#316 * Move sleepyinstant to module instead of crate * Moved Windows to new files Stopped using `path`
- Loading branch information
Matt Schulte
authored
Sep 13, 2022
1 parent
370a9ed
commit 6d4fb2e
Showing
9 changed files
with
141 additions
and
13 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
#![forbid(unsafe_code)] | ||
//! Attempts to provide the same functionality as std::time::Instant, except it | ||
//! uses a timer which accounts for time when the system is asleep | ||
use std::time::Duration; | ||
|
||
#[cfg(target_os = "windows")] | ||
mod windows; | ||
#[cfg(target_os = "windows")] | ||
use windows as inner; | ||
|
||
#[cfg(unix)] | ||
mod unix; | ||
#[cfg(unix)] | ||
use unix as inner; | ||
|
||
/// A measurement of a monotonically nondecreasing clock. | ||
/// Opaque and useful only with [`Duration`]. | ||
/// | ||
/// Instants are always guaranteed, barring [platform bugs], to be no less than any previously | ||
/// measured instant when created, and are often useful for tasks such as measuring | ||
/// benchmarks or timing how long an operation takes. | ||
/// | ||
/// Note, however, that instants are **not** guaranteed to be **steady**. In other | ||
/// words, each tick of the underlying clock might not be the same length (e.g. | ||
/// some seconds may be longer than others). An instant may jump forwards or | ||
/// experience time dilation (slow down or speed up), but it will never go | ||
/// backwards. | ||
/// | ||
/// Instants are opaque types that can only be compared to one another. There is | ||
/// no method to get "the number of seconds" from an instant. Instead, it only | ||
/// allows measuring the duration between two instants (or comparing two | ||
/// instants). | ||
/// | ||
/// The size of an `Instant` struct may vary depending on the target operating | ||
/// system. | ||
/// | ||
#[derive(Clone, Copy, Debug)] | ||
pub struct Instant { | ||
t: inner::Instant, | ||
} | ||
|
||
impl Instant { | ||
/// Returns an instant corresponding to "now". | ||
pub fn now() -> Self { | ||
Self { | ||
t: inner::Instant::now(), | ||
} | ||
} | ||
|
||
/// Returns the amount of time elapsed from another instant to this one, | ||
/// or zero duration if that instant is later than this one. | ||
/// | ||
/// # Panics | ||
/// | ||
/// panics when `earlier` was later than `self`. | ||
pub fn duration_since(&self, earlier: Instant) -> Duration { | ||
self.t.duration_since(earlier.t) | ||
} | ||
|
||
/// Returns the amount of time elapsed since this instant was created. | ||
pub fn elapsed(&self) -> Duration { | ||
Self::now().duration_since(*self) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn time_increments_after_sleep() { | ||
let sleep_time = Duration::from_millis(10); | ||
let start = Instant::now(); | ||
std::thread::sleep(sleep_time); | ||
assert!(start.elapsed() >= sleep_time); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
use std::time::Duration; | ||
|
||
use nix::sys::time::TimeSpec; | ||
use nix::time::{clock_gettime, ClockId}; | ||
|
||
#[cfg(any(target_os = "macos", target_os = "ios"))] | ||
const CLOCK_ID: ClockId = ClockId::CLOCK_MONOTONIC; | ||
#[cfg(not(any(target_os = "macos", target_os = "ios")))] | ||
const CLOCK_ID: ClockId = ClockId::CLOCK_BOOTTIME; | ||
|
||
#[derive(Clone, Copy, Debug)] | ||
pub(crate) struct Instant { | ||
t: TimeSpec, | ||
} | ||
|
||
impl Instant { | ||
pub(crate) fn now() -> Self { | ||
// std::time::Instant unwraps as well, so feel safe doing so here | ||
let t = clock_gettime(CLOCK_ID).unwrap(); | ||
Self { t } | ||
} | ||
|
||
fn checked_duration_since(&self, earlier: Instant) -> Option<Duration> { | ||
const NANOSECOND: nix::libc::c_long = 1_000_000_000; | ||
let (tv_sec, tv_nsec) = if self.t.tv_nsec() < earlier.t.tv_nsec() { | ||
( | ||
self.t.tv_sec() - earlier.t.tv_sec() - 1, | ||
self.t.tv_nsec() - earlier.t.tv_nsec() + NANOSECOND, | ||
) | ||
} else { | ||
( | ||
self.t.tv_sec() - earlier.t.tv_sec(), | ||
self.t.tv_nsec() - earlier.t.tv_nsec(), | ||
) | ||
}; | ||
|
||
if tv_sec < 0 { | ||
None | ||
} else { | ||
Some(Duration::new(tv_sec as _, tv_nsec as _)) | ||
} | ||
} | ||
|
||
pub(crate) fn duration_since(&self, earlier: Instant) -> Duration { | ||
self.checked_duration_since(earlier) | ||
.unwrap_or(Duration::ZERO) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub(crate) use std::time::Instant; |