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

Please add more detail on Wakers and the RawWaker #146

Open
aboseley opened this issue Nov 13, 2021 · 1 comment
Open

Please add more detail on Wakers and the RawWaker #146

aboseley opened this issue Nov 13, 2021 · 1 comment

Comments

@aboseley
Copy link

aboseley commented Nov 13, 2021

I'd like to see a more detail on Wakers. A Waker is a wrapper around a RawWaker which looks to implement dynamic dispatch manually with lots of unsafe code, which seems odd when I would have expect this to be done via a 'traits object'

This is obviously done deliberately, and I'd like to read about the design rational for this. I'm not sure if this book is the best document for discussing such things - but I'd find helpful to better understanding the async mechanisms in rust.

@yeputons
Copy link

+1, would be very glad to see it in the book or somewhere.

My understanding is that it's done for optimization purposes, see Rust's RFC 2592's section "Waking up" (it's discussed at rust-lang/rfcs#2592):

This mechanism is chosen in favor of trait objects since it allows for more flexible memory management schemes. RawWaker can be implemented purely in terms of global functions and state, on top of reference counted objects, or in other ways. This strategy also makes it easier to provide different vtable functions that will perform different behaviors despite referencing the same underlying wakeable object type.

For example, one of the earlier designs actually specified trait Wake : Send + Sync and defined the fn wake(self: &Arc<Self>); method. That required a heap allocation for each waker. Looks like it is an issue for embedded systems, see this comment. It is also a more general issue: consider you have a struct File which contains fd: i32 inside it and has some async I/O methods. These methods are now not required to create a trait object for each File or make File implement Waker trait (especially considering there may be two wakers: one for reading, one for writing), you can simply store a pointer to the File (should be pinned, I guess?) in RawWaker and provide vtable.

More discussion is available here and in the following comment, e.g. whether it's enough to use usize as a waker ID instead of an arbitrary pointer. Same comments mention that all this discussion should probably end up somewhere in the docs :)

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