-
Notifications
You must be signed in to change notification settings - Fork 669
Description
If I've not mistaken then Shared::poll will wake up the very same waker that was actually polling it, and return a Poll::Ready at the same time.
futures-rs/futures-util/src/future/future/shared.rs
Lines 347 to 352 in bb63c37
| // Wake all tasks and drop the slab | |
| let mut wakers_guard = inner.notifier.wakers.lock().unwrap(); | |
| let mut wakers = wakers_guard.take().unwrap(); | |
| for waker in wakers.drain().flatten() { | |
| waker.wake(); | |
| } |
Which is confusing considering what std doc was saying about Waker::wake protocol.
- https://doc.rust-lang.org/std/future/trait.Future.html#tymethod.poll
Once a task has been woken up, it should attempt to poll the future again
- https://doc.rust-lang.org/std/task/struct.Waker.html#method.wake
it is guaranteed that each invocation of wake() (or wake_by_ref()) will be followed by at least one poll() of the task to which this Waker belongs
According to std doc, when implementing an executor, I should call poll at least once whenever wake was called. But this is not the case for Shared: it can return a Poll::Ready and call wake at the same time. If I follow a poll afterwards, it will return Poll::Ready again. It seems the most correct thing to do then is to not poll at all and ignore this wake, which contradicts with the doc.
This behavior itself may not be a problem, but the doc is quite confusing.