# Should the standard library have a basic Future runtime?

**URL:** <https://internals.rust-lang.org/t/should-the-standard-library-have-a-basic-future-runtime/10705>\
**Category:** Uncategorized\
**Created:** [August 13, 2019, 11:10pm UTC](https://internals.rust-lang.org/t/should-the-standard-library-have-a-basic-future-runtime/10705 "2019-08-13T23:10:47Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![lachlansneff](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/lachlansneff/32/5924_2.png) [@lachlansneff](https://internals.rust-lang.org/u/lachlansneff)\
**Post date:** [August 13, 2019, 11:10pm UTC](https://internals.rust-lang.org/t/should-the-standard-library-have-a-basic-future-runtime/10705/1 "2019-08-13T23:10:47Z")

</div>

For discovery and user-friendliness reasons, should `std` include a basic, maybe multithreaded, future runtime? It seems strange to have to include a separate crate to even run a `Future`.

(As a separate note, that same argument applies to future combinators, which I personally believe should either be on the standardized `Future` trait, or at least in the standard library, but that's a separate discussion.)

_Poll ([view on site](https://internals.rust-lang.org/t/should-the-standard-library-have-a-basic-future-runtime/10705/1))_

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [August 14, 2019, 12:08am UTC](https://internals.rust-lang.org/t/should-the-standard-library-have-a-basic-future-runtime/10705/2 "2019-08-14T00:08:23Z")

</div>

No, don't, unless you mean [`future::block_on`](https://rust-lang-nursery.github.io/futures-api-docs/0.3.0-alpha.18/futures_executor/fn.block_on.html). The reasoning is that the futures runtime requires tradeoffs that the standard library doesn't want to have to make a choice. We can make e.g. runtime or similar a `rust-lang` crate, though, and potentially even distribute it with the standard distribution, depending on how things go.

But `std` shouldn't have anything beyond just a `block_on` runtime at most.

---

<div class="post-metadata">

**Author:** ![RustyYato](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rustyyato/32/13627_2.png) [@RustyYato](https://internals.rust-lang.org/u/RustyYato)\
**Post date:** [August 14, 2019, 12:09am UTC](https://internals.rust-lang.org/t/should-the-standard-library-have-a-basic-future-runtime/10705/3 "2019-08-14T00:09:46Z")

</div>

Putting an executor/runtime in the standard would put too much pressure on the maintainers, and they need to focus on more important things, like fixing the many soundness holes in Rust, or ICEs rather than dedicate time for a futures runtime. Executors can be very complex, and it would be best to leave it to the community to work things out.

But like @CAD97 said, having `block_on` should be fine, as that is quite small.

---

<div class="post-metadata">

**Author:** ![lachlansneff](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/lachlansneff/32/5924_2.png) [@lachlansneff](https://internals.rust-lang.org/u/lachlansneff)\
**Post date:** [August 14, 2019, 12:47am UTC](https://internals.rust-lang.org/t/should-the-standard-library-have-a-basic-future-runtime/10705/4 "2019-08-14T00:47:19Z")

</div>

Yeah, `block_on` is very simple. I wrote a quick implementation a week or two back on a plane when I had nothing better to do.

```
static VTABLE: RawWakerVTable = RawWakerVTable::new(
    raw::clone,
    raw::wake_by_ref,
    raw::wake_by_ref,
    raw::drop,
);

mod raw {
    use super::{VTABLE, RawWaker, Mutex, Condvar};
    pub unsafe fn clone(data: *const ()) -> RawWaker {
        RawWaker::new(data, &VTABLE)
    }

    pub unsafe fn wake_by_ref(data: *const ()) {
        let &(ref lock, ref cvar) = &*(data as *const (Mutex<bool>, Condvar));
        let mut started = lock.lock().unwrap();
        *started = true;
        cvar.notify_one();
    }

    pub unsafe fn drop(_data: *const ()) {}
}

pub fn block_on<F: Future>(future: F) -> F::Output {
    let pair = (Mutex::new(false), Condvar::new());
    let raw_waker = RawWaker::new(&pair as *const _ as *const (), &VTABLE);
    let waker = unsafe { Waker::from_raw(raw_waker) };
    let mut cx = Context::from_waker(&waker);

    let &(ref lock, ref cvar) = &pair;

    pin_mut!(future);

    loop {
        match future.as_mut().poll(&mut cx) {
            Poll::Pending => {},
            Poll::Ready(val) => break val,
        }

        let mut started = lock.lock().unwrap();
        while !*started {
            started = cvar.wait(started).unwrap();
        }
    }
}
```

---

<div class="post-metadata">

**Author:** ![Matthias247](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matthias247/32/5734_2.png) [@Matthias247](https://internals.rust-lang.org/u/Matthias247)\
**Post date:** [August 14, 2019, 5:51am UTC](https://internals.rust-lang.org/t/should-the-standard-library-have-a-basic-future-runtime/10705/5 "2019-08-14T05:51:45Z")

</div>

> [@lachlansneff](#):
>
> Yeah, `block_on` is very simple. I wrote a quick implementation a week or two back on a plane when I had nothing better to do.

That implementation isn't memory safe, since it's always valid to call a `Waker` - even if the associated `Future` already has been polled to completion. That means `Waker`s must in practice either be refcounted or use a `'static`/threadlocal object.

The implementation futures-rs uses `std::thread::park`, which satisfies the criteria and is probably as efficient as it gets.

---

<div class="post-metadata">

**Author:** ![lachlansneff](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/lachlansneff/32/5924_2.png) [@lachlansneff](https://internals.rust-lang.org/u/lachlansneff)\
**Post date:** [August 14, 2019, 2:13pm UTC](https://internals.rust-lang.org/t/should-the-standard-library-have-a-basic-future-runtime/10705/6 "2019-08-14T14:13:51Z")

</div>

Oops! Didn't realize that Waker could be called even after the completion of the Future.

---

<div class="post-metadata">

**Author:** ![orthoxerox](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/orthoxerox/32/5531_2.png) [@orthoxerox](https://internals.rust-lang.org/u/orthoxerox)\
**Post date:** [August 15, 2019, 6:46am UTC](https://internals.rust-lang.org/t/should-the-standard-library-have-a-basic-future-runtime/10705/7 "2019-08-15T06:46:27Z")

</div>

There should be a list of "blessed" runtimes for the most common use cases, so cargo/rustc can point users towards them when it fails to compile an async program.

---

<div class="post-metadata">

**Author:** ![DoumanAsh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/doumanash/32/5790_2.png) [@DoumanAsh](https://internals.rust-lang.org/u/DoumanAsh)\
**Post date:** [August 15, 2019, 11:20am UTC](https://internals.rust-lang.org/t/should-the-standard-library-have-a-basic-future-runtime/10705/8 "2019-08-15T11:20:06Z")

</div>

Rather than having runtime, std library should define common trait for executor and/or runtime

---

<div class="post-metadata">

**Author:** ![Nemo157](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nemo157/32/11585_2.png) [@Nemo157](https://internals.rust-lang.org/u/Nemo157)\
**Post date:** [August 15, 2019, 4:13pm UTC](https://internals.rust-lang.org/t/should-the-standard-library-have-a-basic-future-runtime/10705/9 "2019-08-15T16:13:11Z")

</div>

It does, `Future` along with the associated types in `std::task` are the interface between a future and the executor. The interface between an application and the executor doesn’t generally require abstraction as an application uses a single executor and can be written directly against it (and as far as I can think of the only “trait” that could be added is the equivalent of `for<F: Future> FnOnce(F) -> F::Output` which doesn’t provide much utility).

---

<div class="post-metadata">

**Author:** ![najamelan](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/najamelan/32/3162_2.png) [@najamelan](https://internals.rust-lang.org/u/najamelan)\
**Post date:** [August 16, 2019, 8:10am UTC](https://internals.rust-lang.org/t/should-the-standard-library-have-a-basic-future-runtime/10705/10 "2019-08-16T08:10:46Z")

</div>

Yes, in five years, when the dust has settled, and the backlog of RFC's to implement has gone down.

---

<div class="post-metadata">

**Author:** ![DoumanAsh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/doumanash/32/5790_2.png) [@DoumanAsh](https://internals.rust-lang.org/u/DoumanAsh)\
**Post date:** [August 16, 2019, 8:44am UTC](https://internals.rust-lang.org/t/should-the-standard-library-have-a-basic-future-runtime/10705/11 "2019-08-16T08:44:08Z")

</div>

That's not the same, so it doesn't.

Whether it is necessary is another question, but runtime != executor, runtime usually needs reactor also

---

<div class="post-metadata">

**Author:** ![najamelan](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/najamelan/32/3162_2.png) [@najamelan](https://internals.rust-lang.org/u/najamelan)\
**Post date:** [August 16, 2019, 3:00pm UTC](https://internals.rust-lang.org/t/should-the-standard-library-have-a-basic-future-runtime/10705/12 "2019-08-16T15:00:14Z")

</div>

I think there's some confusion. have published an async\_runtime for futures 0.3. It has no reactor. It allows you to set a thread global executor per thread to decide whether you want the globally available `rt::spawn` method to spawn on the current thread or in a threadpool.

It all works, and you can even spawn network related futures from romio, and even from tokio. Every future is responsible for waking up the task when progress can be made, but what exactly that means really depends on the specifics of the future, and I think libraries generating futures should take care of that themselves.

It's true that for operating system IO, rust libraries often use `mio`. And both `romio` and `tokio` have a reactor object for interfacing between mio and the task system.

It could be argued that it would be best if there was generic reactor crate, that different IO libraries could use rather than every library roll their own. However it's not in my opinion part of the runtime directly.

Since it's an interface to the OS, something like mio or a reactor could one day also be in stdlib, but I think a first step is to have it as a crate that is generic enough for different libraries, and not tied to specifics of one of them.

In any case both can be independently supported.

---

<div class="post-metadata">

**Author:** ![najamelan](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/najamelan/32/3162_2.png) [@najamelan](https://internals.rust-lang.org/u/najamelan)\
**Post date:** [August 16, 2019, 7:47pm UTC](https://internals.rust-lang.org/t/should-the-standard-library-have-a-basic-future-runtime/10705/13 "2019-08-16T19:47:28Z")

</div>

@lachlansneff Just saw this blog post:

> **[async-std - Announcing async-std](https://async.rs/blog/announcing-async-std/)**
>
> A Rust library for easy and understandable async programming

I haven't yet looked into how it works, but it has `task::spawn` as replacement for `thread::spawn`. There you have your standard library with a runtime!

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [November 14, 2019, 7:54pm UTC](https://internals.rust-lang.org/t/should-the-standard-library-have-a-basic-future-runtime/10705/14 "2019-11-14T19:54:02Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
