use std::future::Future;
use std::sync::{Arc, OnceLock};
use asupersync::cx::Cx;
use asupersync::runtime::reactor::create_reactor;
use asupersync::runtime::{IoDriverHandle, RuntimeBuilder};
use asupersync::types::{Budget, RegionId, TaskId};
struct RuntimeWithIo {
runtime: asupersync::runtime::Runtime,
io_driver: IoDriverHandle,
}
static RUNTIME: OnceLock<RuntimeWithIo> = OnceLock::new();
pub fn block_on<F: Future>(future: F) -> F::Output {
let rt = RUNTIME.get_or_init(|| {
let reactor = create_reactor().expect("failed to create platform I/O reactor");
let io_driver = IoDriverHandle::new(Arc::clone(&reactor));
let runtime = RuntimeBuilder::current_thread()
.with_reactor(reactor)
.build()
.expect("failed to build asupersync runtime");
RuntimeWithIo { runtime, io_driver }
});
let cx = Cx::new_with_observability(
RegionId::new_for_test(0, 0),
TaskId::new_for_test(0, 0),
Budget::INFINITE,
None, Some(rt.io_driver.clone()),
None, );
let _cx_guard = Cx::set_current(Some(cx));
rt.runtime.block_on(future)
}
#[cfg(test)]
mod tests {
use super::block_on;
#[test]
fn block_on_runs_async_blocks() {
let out = block_on(async { 1 + 1 });
assert_eq!(out, 2);
}
#[test]
fn block_on_can_be_called_multiple_times() {
let a = block_on(async { "a" });
let b = block_on(async { "b" });
assert_eq!(a, "a");
assert_eq!(b, "b");
}
}