Added untested comm impl
This commit is contained in:
42
orchid-base/src/stash.rs
Normal file
42
orchid-base/src/stash.rs
Normal file
@@ -0,0 +1,42 @@
|
||||
//! A pattern for running async code from sync destructors and other
|
||||
//! unfortunately sync callbacks
|
||||
//!
|
||||
//! We create a task_local
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::pin::Pin;
|
||||
|
||||
use some_executor::task_local;
|
||||
|
||||
#[derive(Default)]
|
||||
struct StashedFutures {
|
||||
queue: VecDeque<Pin<Box<dyn Future<Output = ()>>>>,
|
||||
}
|
||||
|
||||
task_local! {
|
||||
static STASHED_FUTURES: StashedFutures;
|
||||
}
|
||||
|
||||
/// Complete the argument future, and any futures spawned from it via [stash].
|
||||
/// This is useful mostly to guarantee that messaging destructors have run.
|
||||
pub async fn with_stash<F: Future>(fut: F) -> F::Output {
|
||||
STASHED_FUTURES
|
||||
.scope(StashedFutures::default(), async {
|
||||
let val = fut.await;
|
||||
while let Some(fut) = STASHED_FUTURES.with_mut(|sf| sf.unwrap().queue.pop_front()) {
|
||||
fut.await;
|
||||
}
|
||||
val
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
/// Schedule a future to be run before the next [with_stash] guard ends. This is
|
||||
/// most useful for sending messages from destructors.
|
||||
pub fn stash<F: Future + 'static>(fut: F) {
|
||||
STASHED_FUTURES.with_mut(|sf| {
|
||||
sf.expect("No stash! Timely completion cannot be guaranteed").queue.push_back(Box::pin(async {
|
||||
fut.await;
|
||||
}))
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user