This is a fantastic write-up and it makes me even more hungry for generators! I really enjoyed the progressive walk from avec-io to sans-io, and I can’t say waker hacking never crossed my mind when writing manual poll implementations…
It’s also a nice little showcase in safe(ish) API design
That’s a load bearing “ish” when it comes to the API design side of things…!
I’ve actually realised that I can make things a little safer by changing the make_fut method so it instead returns a wrapper type which doesn’t allow access to the inner future. That way you can pass it back to step to drive the state machine but there’s no way to try to await the future in a normal async runtime.
Instead of using async to implement sans-io state machines, I’ve just started exploring the idea of simply having a async IO traits that can be implemented by both non-blocking stuff (like Tokio’s IO types) and blocking stuff (like the standard library IO types). In the latter case, .await would simply block until the IO was done, and then it would return Poll::Ready(result).
This is a fantastic write-up and it makes me even more hungry for generators! I really enjoyed the progressive walk from avec-io to sans-io, and I can’t say waker hacking never crossed my mind when writing manual poll implementations… It’s also a nice little showcase in safe(ish) API design
Thanks!
That’s a load bearing “ish” when it comes to the API design side of things…!
I’ve actually realised that I can make things a little safer by changing the
make_futmethod so it instead returns a wrapper type which doesn’t allow access to the inner future. That way you can pass it back tostepto drive the state machine but there’s no way to try to await the future in a normal async runtime.(Still a load bearing “ish” though I suspect)
Instead of using async to implement sans-io state machines, I’ve just started exploring the idea of simply having a async IO traits that can be implemented by both non-blocking stuff (like Tokio’s IO types) and blocking stuff (like the standard library IO types). In the latter case,
.awaitwould simply block until the IO was done, and then it would returnPoll::Ready(result).// SAFETY: Deliberately incorrect, the vtable is not inspected