Some checks failed
Rust / build (push) Failing after 3m52s
terrified to start testing
66 lines
1.9 KiB
Rust
66 lines
1.9 KiB
Rust
use std::rc::Rc;
|
|
|
|
use crate::{ExtPort, ExtensionBuilder};
|
|
/// Run an extension inside a Tokio localset. Since the extension API does not
|
|
/// provide a forking mechanism, it can safely abort once the localset is
|
|
/// exhausted. If an extension absolutely needs a parallel thread, it can import
|
|
/// and call [tokio::task::spawn_local] which will keep alive the localset and
|
|
/// postpone the aggressive shutdown, and listen for the [Drop::drop] of the
|
|
/// value returned by [crate::system_ctor::SystemCtor::inst] to initiate
|
|
/// shutdown.
|
|
#[cfg(feature = "tokio")]
|
|
pub async fn __tokio_entrypoint(builder: ExtensionBuilder) {
|
|
use std::cell::RefCell;
|
|
|
|
use async_event::Event;
|
|
use tokio::io::{stderr, stdin, stdout};
|
|
use tokio::task::{LocalSet, spawn_local};
|
|
use tokio_util::compat::{TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt};
|
|
|
|
let cc = Rc::new(Event::new());
|
|
let c = Rc::new(RefCell::new(1));
|
|
LocalSet::new()
|
|
.run_until(async {
|
|
let counter = (c.clone(), cc.clone());
|
|
builder
|
|
.run(ExtPort {
|
|
input: Box::pin(stdin().compat()),
|
|
output: Box::pin(stdout().compat_write()),
|
|
log: Box::pin(stderr().compat_write()),
|
|
spawn: Rc::new(move |delay, fut| {
|
|
let (c, cc) = counter.clone();
|
|
if delay.is_zero() {
|
|
*c.borrow_mut() += 1;
|
|
cc.notify_all();
|
|
spawn_local(async move {
|
|
fut.await;
|
|
*c.borrow_mut() -= 1;
|
|
cc.notify_all();
|
|
});
|
|
} else {
|
|
let at = tokio::time::Instant::now() + delay;
|
|
spawn_local(async move {
|
|
tokio::time::sleep_until(at).await;
|
|
*c.borrow_mut() += 1;
|
|
cc.notify_all();
|
|
fut.await;
|
|
*c.borrow_mut() -= 1;
|
|
cc.notify_all();
|
|
});
|
|
}
|
|
}),
|
|
})
|
|
.await;
|
|
cc.wait_until(|| (*c.borrow() == 0).then_some(())).await;
|
|
})
|
|
.await;
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! tokio_main {
|
|
($builder:expr) => {
|
|
#[tokio::main]
|
|
pub async fn main() { $crate::__tokio_entrypoint($builder).await }
|
|
};
|
|
}
|