File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -438,7 +438,30 @@ impl AsyncWrite for Mock {
438438 let until = Instant :: now ( ) + rem;
439439 self . inner . sleep = Some ( Box :: pin ( time:: sleep_until ( until) ) ) ;
440440 } else {
441- panic ! ( "unexpected WouldBlock {}" , self . pmsg( ) ) ;
441+ // A race condition (TOCTOU) can occur if the
442+ // timer expires between the `write()` call
443+ // and `remaining_wait()` due to preemption or other
444+ // delays. In this case, the `Wait` action is already popped by
445+ // `action()`, so we continue to the next one.
446+ //
447+ // Consider the following sequence:
448+ //
449+ // poll_write Inner action()
450+ // |--write()--->| |
451+ // | |--action()---->| (returns Wait)
452+ // |<-WouldBlk---| |
453+ // | | |
454+ // | <--- TIMEOUT! ---> |
455+ // | (due to preemption, etc.) |
456+ // | | |
457+ // |-rem_wait()->| |
458+ // | |--action()---->| (time's up, pop Wait)
459+ // |<--None------| |
460+ // | | |
461+ // |---continue->| (process next action)
462+ //
463+ // See <https://github.com/tokio-rs/tokio/issues/7881>.
464+ continue ;
442465 }
443466 }
444467 Ok ( 0 ) => {
You can’t perform that action at this time.
0 commit comments