diff options
Diffstat (limited to 'tokio/src/io/driver/scheduled_io.rs')
-rw-r--r-- | tokio/src/io/driver/scheduled_io.rs | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/tokio/src/io/driver/scheduled_io.rs b/tokio/src/io/driver/scheduled_io.rs index 3aefb376..ed3adc39 100644 --- a/tokio/src/io/driver/scheduled_io.rs +++ b/tokio/src/io/driver/scheduled_io.rs @@ -49,6 +49,8 @@ struct Waiters { } cfg_io_readiness! { + use crate::io::Interest; + #[derive(Debug)] struct Waiter { pointers: linked_list::Pointers<Waiter>, @@ -57,7 +59,7 @@ cfg_io_readiness! { waker: Option<Waker>, /// The interest this waiter is waiting on - interest: mio::Interest, + interest: Interest, is_ready: bool, @@ -283,7 +285,7 @@ impl ScheduledIo { /// These are to support `AsyncRead` and `AsyncWrite` polling methods, /// which cannot use the `async fn` version. This uses reserved reader /// and writer slots. - pub(in crate::io) fn poll_readiness( + pub(super) fn poll_readiness( &self, cx: &mut Context<'_>, direction: Direction, @@ -299,7 +301,19 @@ impl ScheduledIo { Direction::Read => &mut waiters.reader, Direction::Write => &mut waiters.writer, }; - *slot = Some(cx.waker().clone()); + + // Avoid cloning the waker if one is already stored that matches the + // current task. + match slot { + Some(existing) => { + if !existing.will_wake(cx.waker()) { + *existing = cx.waker().clone(); + } + } + None => { + *slot = Some(cx.waker().clone()); + } + } // Try again, in case the readiness was changed while we were // taking the waiters lock @@ -348,7 +362,7 @@ unsafe impl Sync for ScheduledIo {} cfg_io_readiness! { impl ScheduledIo { /// An async version of `poll_readiness` which uses a linked list of wakers - pub(crate) async fn readiness(&self, interest: mio::Interest) -> ReadyEvent { + pub(crate) async fn readiness(&self, interest: Interest) -> ReadyEvent { self.readiness_fut(interest).await } @@ -356,7 +370,7 @@ cfg_io_readiness! { // we are borrowing the `UnsafeCell` possibly over await boundaries. // // Go figure. - fn readiness_fut(&self, interest: mio::Interest) -> Readiness<'_> { + fn readiness_fut(&self, interest: Interest) -> Readiness<'_> { Readiness { scheduled_io: self, state: State::Init, |