Skip to main content

base_scheduler/
blocking.rs

1// Released under the MIT License.
2// Copyright, 2026, by Samuel Williams.
3
4use crate::{BlockingError, Cancellation, TaskError};
5use std::future::Future;
6
7/// Optional scheduler capability for owned synchronous work on blocking threads.
8pub trait Blocking {
9    /// The owning completion handle returned by [`spawn_blocking`](Self::spawn_blocking), resolving to the closure's output or a [`TaskError`].
10    type Handle<Output>: Future<Output = Result<Output, TaskError>> + Send + 'static
11    where
12        Output: Send + 'static;
13
14    /// Wait asynchronously for capacity and submit a closure, returning its owning completion handle.
15    ///
16    /// Admission is lazy: an unpolled future submits nothing. Cancellation before admission returns `BlockingError::Cancelled`. A worker checks cancellation again before starting; cancellation after that boundary does not replace the closure's result. The closure may capture a cancellation clone to cooperate while running.
17    ///
18    /// Moving the handle transfers ownership. Dropping it requests that queued work be skipped, but cannot interrupt a running closure. Queued cancellation need not complete until a worker reaches the job. Await the handle before shutting down services the closure needs.
19    ///
20    /// Implementations bound queued plus running jobs; waiting admission futures remain caller-owned. A running job retains its capacity until completion even if its handle is dropped. Job panics are reported as `TaskError::Panicked`.
21    fn spawn_blocking<F, Output>(
22        &self,
23        operation: F,
24        cancellation: &Cancellation,
25    ) -> impl Future<Output = Result<Self::Handle<Output>, BlockingError>> + Send
26    where
27        F: FnOnce() -> Output + Send + 'static,
28        Output: Send + 'static;
29}