#[cfg(feature = "blocking-default")]
mod default;
use std::fmt;
#[cfg(feature = "blocking-default")]
pub use default::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SpawnBlockingError;
impl fmt::Display for SpawnBlockingError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "failed to spawn blocking task")
}
}
impl std::error::Error for SpawnBlockingError {}
pub trait BlockingThreadPool: 'static {
fn spawn(&self, task: Box<dyn FnOnce() + Send + 'static>);
}
#[inline]
pub(crate) async fn spawn_blocking<T, F>(
pool: &dyn BlockingThreadPool,
f: F,
) -> Result<T, SpawnBlockingError>
where
T: Send + 'static,
F: FnOnce() -> T + Send + 'static,
{
let (tx, rx) = oneshot::async_channel::<T>();
let task: Box<dyn FnOnce() + Send + 'static> = Box::new(move || {
let _ = tx.send(f());
});
pool.spawn(task);
rx.await.map_err(|_| SpawnBlockingError)
}