mod core; pub(crate) use self::core::Header; mod error; pub use self::error::Error; mod harness; mod join; pub(crate) use self::join::JoinHandle; mod list; pub(crate) use self::list::OwnedList; mod raw; mod stack; pub(crate) use self::stack::TransferStack; mod state; mod waker; /// Unit tests #[cfg(test)] mod tests; use self::raw::RawTask; use std::future::Future; use std::ptr::NonNull; use std::{fmt, mem}; /// An owned handle to the task, tracked by ref count pub(crate) struct Task { raw: RawTask, } unsafe impl Send for Task {} /// Task result sent back pub(crate) type Result = std::result::Result; pub(crate) trait Schedule: Send + Sync + Sized + 'static { /// Bind a task to the executor. /// /// Guaranteed to be called from the thread that called `poll` on the task. fn bind(&self, task: &Task); /// The task has completed work and is ready to be released. The scheduler /// is free to drop it whenever. fn release(&self, task: Task); /// The has been completed by the executor it was bound to. fn release_local(&self, task: &Task); /// Schedule the task fn schedule(&self, task: Task); } /// Create a new task without an associated join handle pub(crate) fn background(task: T) -> Task where T: Future + Send + 'static, S: Schedule, { let raw = RawTask::new_background(task); Task { raw } } /// Create a new task with an associated join handle pub(crate) fn joinable(task: T) -> (Task, JoinHandle) where T: Future + Send + 'static, S: Schedule, { let raw = RawTask::new_joinable(task); let task = Task { raw }; let join = JoinHandle::new(raw); (task, join) } impl Task { pub(crate) unsafe fn from_raw(ptr: NonNull>) -> Task { let raw = RawTask::from_raw(ptr); Task { raw } } pub(crate) fn header(&self) -> &Header { self.raw.header() } pub(crate) fn into_raw(self) -> NonNull> { let raw = self.raw.into_raw(); mem::forget(self); raw } } impl Task { /// Returns `self` when the task needs to be immediately re-scheduled pub(crate) fn run(self, executor: NonNull) -> Option { if unsafe { self.raw.poll(executor) } { Some(self) } else { // Cleaning up the `Task` instance is done from within the poll // function. mem::forget(self); None } } /// Pre-emptively cancel the task as part of the shutdown process. pub(crate) fn shutdown(self) { self.raw.cancel_from_queue(); mem::forget(self); } } impl Drop for Task { fn drop(&mut self) { self.raw.drop_task(); } } impl fmt::Debug for Task { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt.debug_struct("Task").finish() } }