summaryrefslogtreecommitdiffstats
path: root/tokio/src/io/driver/scheduled_io.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tokio/src/io/driver/scheduled_io.rs')
-rw-r--r--tokio/src/io/driver/scheduled_io.rs24
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,