diff options
author | Thomas Whiteway <thomas.whiteway@metaswitch.com> | 2020-04-29 17:03:44 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-29 18:03:44 +0200 |
commit | 947045b9445f15fb9314ba0892efa2251076ae73 (patch) | |
tree | b569e4b773308dbb558e21c7a1b9edc5eff851cb /tokio/src/time | |
parent | 2c53bebe56d584f1d6b710e9b39df6452d655a26 (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.rs | 24 |
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); } } |