From a4dd9cd1165a1e5cf864c06f634b426d9c88ebc9 Mon Sep 17 00:00:00 2001 From: Andrii Pohrebniak Date: Thu, 18 May 2023 12:25:39 +0100 Subject: [PATCH] timerfd: Add TFD_TIMER_CANCEL_ON_SET flag --- CHANGELOG.md | 2 ++ src/sys/time.rs | 1 + src/sys/timerfd.rs | 10 ++++++++++ 3 files changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index daa8b6d940..c87abc4b8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ This project adheres to [Semantic Versioning](https://semver.org/). - Added `mq_timedreceive` to `::nix::mqueue`. ([#1966])(https://github.com/nix-rust/nix/pull/1966) - Added `LocalPeerPid` to `nix::sys::socket::sockopt` for macOS. ([#1967](https://github.com/nix-rust/nix/pull/1967)) +- Added `TFD_TIMER_CANCEL_ON_SET` to `::nix::sys::time::TimerSetTimeFlags` on Linux and Android. + ([#2040](https://github.com/nix-rust/nix/pull/2040)) ### Changed diff --git a/src/sys/time.rs b/src/sys/time.rs index a1894e4d54..30ee5fd1b5 100644 --- a/src/sys/time.rs +++ b/src/sys/time.rs @@ -93,6 +93,7 @@ pub(crate) mod timer { /// Flags that are used for arming the timer. pub struct TimerSetTimeFlags: libc::c_int { const TFD_TIMER_ABSTIME = libc::TFD_TIMER_ABSTIME; + const TFD_TIMER_CANCEL_ON_SET = libc::TFD_TIMER_CANCEL_ON_SET; } } #[cfg(any( diff --git a/src/sys/timerfd.rs b/src/sys/timerfd.rs index 90a05a8ccd..c4337c9dfa 100644 --- a/src/sys/timerfd.rs +++ b/src/sys/timerfd.rs @@ -135,6 +135,13 @@ impl TimerFd { /// Then the one shot TimeSpec and the delay TimeSpec of the delayed /// interval are going to be interpreted as absolute. /// + /// # Cancel on a clock change + /// + /// If you set a `TFD_TIMER_CANCEL_ON_SET` alongside `TFD_TIMER_ABSTIME` + /// and the clock for this timer is `CLOCK_REALTIME` or `CLOCK_REALTIME_ALARM`, + /// then this timer is marked as cancelable if the real-time clock undergoes + /// a discontinuous change. + /// /// # Disabling alarms /// /// Note: Only one alarm can be set for any given timer. Setting a new alarm @@ -202,6 +209,9 @@ impl TimerFd { /// Note: If the alarm is unset, then you will wait forever. pub fn wait(&self) -> Result<()> { while let Err(e) = read(self.fd.as_fd().as_raw_fd(), &mut [0u8; 8]) { + if e == Errno::ECANCELED { + break; + } if e != Errno::EINTR { return Err(e); }