Skip to content

Commit ff76625

Browse files
committed
Process timers set for exactly now
This fixes a bug wherein the first timer set for exactly `now` ends up in the `pending` list instead of the `ready` list, eventually resulting in polling with a timeout of 0. Under normal circumstances this bug would trigger very rarely, and when it did would only result in one spurious "loop", since the next time the timers are checked, time will have advanced. However, this bug can cause misbehavior and deadlock in emulated environments. e.g., in the Shadow emulator, time only moves forward when a blocking syscall is performed, so this bug causes deadlock: https://gitlab.torproject.org/tpo/core/arti/-/issues/174#note_2762399
1 parent 36ab1d2 commit ff76625

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

src/reactor.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,10 @@ impl Reactor {
187187
let now = Instant::now();
188188

189189
// Split timers into ready and pending timers.
190-
let pending = timers.split_off(&(now, 0));
190+
//
191+
// Careful to split just *after* `now`, so that a timer set for exactly `now` is considered
192+
// ready.
193+
let pending = timers.split_off(&(now + Duration::from_nanos(1), 0));
191194
let ready = mem::replace(&mut *timers, pending);
192195

193196
// Calculate the duration until the next event.

0 commit comments

Comments
 (0)