std1.0.0-beta-7 SafeC docs

Source async/host.h

View in the repository

// SafeC Standard Library — async: hosted parking and block_on
//
// HostPark is the Park source (std/async/executor.h) for a hosted program
// with no I/O to wait for: the OS monotonic clock, and a condition
// variable to sleep on until the next timer deadline or a wake from
// another thread. block_on(&fut) runs a future to completion on the
// calling thread with a fresh LocalExecutor and a HostPark — the usual way
// into async code from main() (Rust's futures::executor::block_on):
//
//   struct Fetch f = Fetch::new();
//   int n = block_on(&f);
//
// For async I/O use std/async/net.h's Runtime instead (its IoDriver parks
// in the OS readiness queue); for parallelism std/async/pool.h's
// ThreadPool. Hosted targets only (it uses std/thread.h and std/time.h).
#pragma once
#include <std/async/executor.h>
#include <std/thread.h>

namespace std {

struct HostPark {
    unsigned long long mu;       // std/thread.h mutex
    unsigned long long cv;       // and condition variable
    int                permit;   // an unpark() that no park() has consumed yet
    int                ok;       // mu/cv were created

    // Creates the mutex and condition variable; destroy() frees them.
    static struct HostPark new();
    void drop();
    void destroy() consume;   // = drop()
    long long now_ms();
    void park(long long timeout_ms);
    void unpark();
};

// Milliseconds of the OS monotonic clock.
long long async_mono_ms();

// Run 'fut' to completion on this thread and return its value. Tasks it
// spawns (async_spawn) run meanwhile, on the same thread; any still
// running when 'fut' finishes are abandoned with the executor.
generic<F: Future, T>
T block_on(&F fut) {
    struct LocalExecutor ex = LocalExecutor::new();
    struct HostPark park = HostPark::new();
    T r = ex.block_on(&park, fut);
    park.destroy();
    ex.drop();
    return r;
}

} // namespace std