summaryrefslogtreecommitdiffstats
path: root/tokio/src/time
diff options
context:
space:
mode:
authorThomas Whiteway <thomas.whiteway@metaswitch.com>2020-04-29 17:03:44 +0100
committerGitHub <noreply@github.com>2020-04-29 18:03:44 +0200
commit947045b9445f15fb9314ba0892efa2251076ae73 (patch)
treeb569e4b773308dbb558e21c7a1b9edc5eff851cb /tokio/src/time
parent2c53bebe56d584f1d6b710e9b39df6452d655a26 (diff)
time: notify when resetting a Delay to a time in the past (#2290)
If a Delay has been polled, then the task that polled it may be waiting for a notification. If the delay gets reset to a time in the past, then it immediately becomes elapsed, so it should notify the relevant task.
Diffstat (limited to 'tokio/src/time')
-rw-r--r--tokio/src/time/driver/entry.rs24
1 files changed, 12 insertions, 12 deletions
diff --git a/tokio/src/time/driver/entry.rs b/tokio/src/time/driver/entry.rs
index 20cc8240..8e1e6b2f 100644
--- a/tokio/src/time/driver/entry.rs
+++ b/tokio/src/time/driver/entry.rs
@@ -266,8 +266,9 @@ impl Entry {
let when = inner.normalize_deadline(deadline);
let elapsed = inner.elapsed();
+ let next = if when <= elapsed { ELAPSED } else { when };
+
let mut curr = entry.state.load(SeqCst);
- let mut notify;
loop {
// In these two cases, there is no work to do when resetting the
@@ -278,16 +279,6 @@ impl Entry {
return;
}
- let next;
-
- if when <= elapsed {
- next = ELAPSED;
- notify = !is_elapsed(curr);
- } else {
- next = when;
- notify = true;
- }
-
let actual = entry.state.compare_and_swap(curr, next, SeqCst);
if curr == actual {
@@ -297,7 +288,16 @@ impl Entry {
curr = actual;
}
- if notify {
+ // If the state has transitioned to 'elapsed' then wake the task as
+ // this entry is ready to be polled.
+ if !is_elapsed(curr) && is_elapsed(next) {
+ entry.waker.wake();
+ }
+
+ // The driver tracks all non-elapsed entries; notify the driver that it
+ // should update its state for this entry unless the entry had already
+ // elapsed and remains elapsed.
+ if !is_elapsed(curr) || !is_elapsed(next) {
let _ = inner.queue(entry);
}
}