We talked earlier about having block_on as a minimal executor available in std. It's pretty helpful for experimenting, bridging sync and async code, and does not seem like something that has a very controversial API. The implementation is also very minimal, and probably as efficient as it gets. The Waker is just something that calls
What needs to be done to get it into std? Does it need an RFC?
@Matthias247 maybe just make a PR at first to see how the implementation would look like and how much impl complexity it adds?
I support the idea that experimenting with async is pretty annoying atm since it requires so much setup
I wonder if that
static will be optimized out if unused
(some people may dislike the cost otherwise)
The CURRENT_THREAD_NOTIFY static? It seems to be unnecessary. The ENTERED one seems harder to avoid.
I have been using tokio’s current_thread_executor a lot even in my actual code where I know I don’t want/need to deal with multiple threads.
That one will probably be more complicated, but I would probably just use whatever alternative single_thread runtime if it existed in std.
@nagisa you'd probably know if unused statics are removed from the final binary? we have
#[used] precisely because they are stripped if unused, right?
Unused statics will get removed from the binary (removal is considered by both LLVM and linker independently), yes, but it is very easy for a lazy_static to become considered "used", even if it is overall not.
@nagisa right, but lazy_static is presumably not going to be used in libstd
Another caveat is that we might end up accidentally using this runtime to implement certain stdlib functions which otherwise look blocking
enter() is not necessarily needed - it just provides another error message if people would use block_on in recursive fashion. Not sure whether that is required - afaik rust also doesn't protect against other recursion issues.
CURRENT_THREAD_NOTIFY is also not necessarily required. We can either always create an
Arc<Thread>, or potentially create that lazily when the
Waker gets cloned. Both are just more overhead in case
block_on is used more than once.
would this live in
thread? I actually like
block_on_future/etc) - since it's the thread which gets blocked.
I started working on this. I think I have found a way on how to make this work pretty efficient without the thread-local variable. 2 tricks here:
- There is actually no need to get the
Thread handle until someone clones the Waker. For many primitive async/await examples that isn't necessary, and I can just check a local boolean flag for waking up.
- Thread in the stdlib is already an
Arc<ThreadInner> - which I can exploited
Hmm, when using async/await in unit-tests for libstd (in the source files directly) I get:
error[E0433]: failed to resolve: could not find `poll_with_tls_context` in `future` error[E0433]: failed to resolve: could not find `from_generator` in `future`
I guess at that compilation step some part for the generators is missing? Is there any way around it, e.g. by placing the test somewhere else? @centril?
nevermind. Got it running by moving the test into a file in the tests/ subfolder