pub mod traits;
pub(crate) mod io;
mod io_source;
pub use io_source::{Interest, IoSource};
mod async_drop;
pub use async_drop::AsyncDrop;
#[cfg(feature = "default-rt")]
pub(crate) mod zruntime;
#[cfg(feature = "default-rt")]
pub(crate) use self::zruntime::ZRuntime;
mod erased;
pub(crate) mod locks;
mod task;
pub(crate) use task::Task;
#[cfg(test)]
pub(crate) mod test_runtime;
mod timeout;
#[cfg(feature = "tokio")]
mod tokio_rt;
#[cfg(feature = "tokio")]
use tokio_rt::Tokio;
#[cfg(all(unix, any(feature = "unixexec", feature = "ibus", target_os = "macos")))]
pub(crate) mod process;
#[cfg(all(test, target_os = "linux", feature = "unixexec"))]
mod process_table;
#[cfg(any(unix, windows))]
use std::path::Path;
#[cfg(all(unix, any(feature = "unixexec", feature = "ibus", target_os = "macos")))]
use std::process::{Command, ExitStatus, Stdio};
use std::{borrow::Cow, future::Future, net::SocketAddr, pin::Pin, sync::Arc};
#[cfg(all(unix, any(feature = "unixexec", feature = "ibus", target_os = "macos")))]
use erased::BoxFuture;
use erased::ErasedRuntime;
use crate::Result;
#[derive(Clone, Debug)]
pub(crate) enum Runtime {
#[cfg(feature = "default-rt")]
ZRuntime(ZRuntime),
#[cfg(feature = "tokio")]
Tokio(Tokio),
External(Arc<dyn ErasedRuntime>),
}
impl Runtime {
pub(crate) fn default_for_build() -> Result<Self> {
#[cfg(feature = "tokio")]
if let Some(runtime) = Tokio::current() {
return Ok(Self::Tokio(runtime));
}
#[cfg(feature = "default-rt")]
{
Ok(Self::ZRuntime(ZRuntime::new()?))
}
#[cfg(not(feature = "default-rt"))]
{
Err(crate::Error::Unsupported)
}
}
pub(crate) fn from_external<R>(runtime: R) -> Self
where
R: traits::Runtime,
{
Self::External(Arc::new(runtime))
}
pub(crate) fn register_io_source(&self, source: IoSource) -> std::io::Result<io::Registration> {
match self {
#[cfg(feature = "default-rt")]
Self::ZRuntime(runtime) => {
traits::Runtime::register_io_source(runtime, source).map(io::Registration::ZRuntime)
}
#[cfg(feature = "tokio")]
Self::Tokio(runtime) => {
traits::Runtime::register_io_source(runtime, source).map(io::Registration::Tokio)
}
Self::External(runtime) => {
traits::Runtime::register_io_source(runtime, source).map(io::Registration::External)
}
}
}
pub(crate) fn spawn<T>(
&self,
name: impl Into<Cow<'static, str>>,
future: impl Future<Output = T> + Send + 'static,
) -> Task<T>
where
T: Send + 'static,
{
let name = name.into();
match self {
#[cfg(feature = "default-rt")]
Self::ZRuntime(runtime) => Task::ZRuntime(runtime.spawn_named(name, future)),
#[cfg(feature = "tokio")]
Self::Tokio(runtime) => Task::Tokio(traits::Runtime::spawn(runtime, &name, future)),
Self::External(runtime) => {
Task::External(traits::Runtime::spawn(runtime, &name, future))
}
}
}
pub(crate) async fn connect_tcp(&self, address: SocketAddr) -> std::io::Result<IoSource> {
match self {
#[cfg(feature = "default-rt")]
Self::ZRuntime(runtime) => traits::Runtime::connect_tcp(runtime, address).await,
#[cfg(feature = "tokio")]
Self::Tokio(runtime) => traits::Runtime::connect_tcp(runtime, address).await,
Self::External(runtime) => traits::Runtime::connect_tcp(runtime, address).await,
}
}
#[cfg(any(unix, windows))]
pub(crate) async fn connect_unix(&self, path: &Path) -> std::io::Result<IoSource> {
match self {
#[cfg(feature = "default-rt")]
Self::ZRuntime(runtime) => traits::Runtime::connect_unix(runtime, path).await,
#[cfg(feature = "tokio")]
Self::Tokio(runtime) => traits::Runtime::connect_unix(runtime, path).await,
Self::External(runtime) => traits::Runtime::connect_unix(runtime, path).await,
}
}
pub(crate) fn spawn_blocking<T>(
&self,
work: impl FnOnce() -> T + Send + 'static,
) -> Pin<Box<dyn Future<Output = T> + Send + 'static>>
where
T: Send + 'static,
{
match self {
#[cfg(feature = "default-rt")]
Self::ZRuntime(runtime) => traits::Runtime::spawn_blocking(runtime, work),
#[cfg(feature = "tokio")]
Self::Tokio(runtime) => traits::Runtime::spawn_blocking(runtime, work),
Self::External(runtime) => traits::Runtime::spawn_blocking(runtime, work),
}
}
#[cfg(all(unix, any(feature = "unixexec", feature = "ibus", target_os = "macos")))]
pub(crate) fn spawn_process(
&self,
command: Command,
stdin: Stdio,
stdout: Stdio,
stderr: Stdio,
) -> std::io::Result<BoxFuture<'static, std::io::Result<ExitStatus>>> {
match self {
#[cfg(feature = "default-rt")]
Self::ZRuntime(runtime) => {
traits::Runtime::spawn_process(runtime, command, stdin, stdout, stderr)
}
#[cfg(feature = "tokio")]
Self::Tokio(runtime) => {
traits::Runtime::spawn_process(runtime, command, stdin, stdout, stderr)
}
Self::External(runtime) => {
traits::Runtime::spawn_process(runtime, command, stdin, stdout, stderr)
}
}
}
}
#[cfg(test)]
mod tests;