aboutsummaryrefslogtreecommitdiff
path: root/doh
diff options
context:
space:
mode:
authorMike Yu <yumike@google.com>2022-03-08 21:11:21 +0800
committerMike Yu <yumike@google.com>2022-03-09 11:41:34 +0800
commita33e2c9d1ddafa6a9b98840dba95525fbf2a4ab7 (patch)
tree69a2fe49a08788b62bcdcb2cb1552d2204cc22e2 /doh
parentb537dfdd39e6a57c73db121849dd13ffd2590f54 (diff)
downloadDnsResolver-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.rs16
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));
+}