diff options
author | Mike Yu <yumike@google.com> | 2022-03-08 21:11:21 +0800 |
---|---|---|
committer | Mike Yu <yumike@google.com> | 2022-03-09 11:41:34 +0800 |
commit | a33e2c9d1ddafa6a9b98840dba95525fbf2a4ab7 (patch) | |
tree | 69a2fe49a08788b62bcdcb2cb1552d2204cc22e2 /doh | |
parent | b537dfdd39e6a57c73db121849dd13ffd2590f54 (diff) | |
download | DnsResolver-a33e2c9d1ddafa6a9b98840dba95525fbf2a4ab7.tar.gz |
Make boot_time::timeout() timeout immediately when passing zero duration
It's possible that the duration returned by Quiche timeout()
is Duration::ZERO. However, boot_time::sleep(Duration::ZERO).await
doesn't wake up immediately in tokio::select. This results in
missing one Quiche on_timeout() call.
Bug: 223356608
Test: cd packages/modules/DnsResolver && atest
Change-Id: Ib9d7fc9792158262d87a86f4e474e618efdbf408
Diffstat (limited to 'doh')
-rw-r--r-- | doh/boot_time.rs | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/doh/boot_time.rs b/doh/boot_time.rs index 1f6f97df..ff7462cf 100644 --- a/doh/boot_time.rs +++ b/doh/boot_time.rs @@ -123,6 +123,7 @@ impl TimerFd { } fn set(&self, duration: Duration) { + assert_ne!(duration, Duration::from_millis(0)); let timer = libc::itimerspec { it_interval: libc::timespec { tv_sec: 0, tv_nsec: 0 }, it_value: libc::timespec { @@ -147,6 +148,13 @@ pub async fn timeout<T>(duration: Duration, future: impl Future<Output = T>) -> // Ideally, all timeouts in a runtime would share a timerfd. That will be much more // straightforwards to implement when moving this functionality into `tokio`. + // According to timerfd_settime(), setting zero duration will disarm the timer, so + // we return immediate timeout here. + // Can't use is_zero() for now because sc-mainline-prod's Rust version is below 1.53. + if duration == Duration::from_millis(0) { + return Err(Elapsed(())); + } + // The failure conditions for this are rare (see `man 2 timerfd_create`) and the caller would // not be able to do much in response to them. When integrated into tokio, this would be called // during runtime setup. @@ -204,3 +212,11 @@ async fn timeout_drift() { assert!(drift < Duration::from_millis(5)); } } + +#[tokio::test] +async fn timeout_duration_zero() { + let start = BootTime::now(); + assert!(timeout(Duration::from_millis(0), pending::<()>()).await.is_err()); + let taken = start.elapsed(); + assert!(taken < Duration::from_millis(5)); +} |