Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Discussion] Shared seems to wake up the same waker that was polling it #2852

Open
ZhennanWu opened this issue Apr 21, 2024 · 1 comment
Open

Comments

@ZhennanWu
Copy link
Contributor

ZhennanWu commented Apr 21, 2024

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.

// 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.

  1. 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

  2. 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.

@seanmonstar
Copy link
Contributor

Frankly, this line in the std docs appears wrong to me:

As long as the executor keeps running and the task is not finished, 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.

There's no way Waker can guarantee that. An executor probably would do that, but the strength of the sentence should reflect that level of certainty (read: not much).

Source: have implemented and maintained serious executors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants