diff --git a/Cargo.toml b/Cargo.toml index b90b0a4..54c94c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,14 +10,17 @@ keywords = ["io", "async", "non-blocking", "futures"] license = "MIT OR Apache-2.0" repository = "https://github.com/plabayo/tokio-graceful" +[target.'cfg(loom)'.dependencies] +loom = "0.7" + [dependencies] -pin-project-lite = "0.2.13" -slab = "0.4.9" +pin-project-lite = "0.2" +slab = "0.4" tokio = { version = "1", features = ["rt", "signal", "sync", "macros", "time"] } tracing = "0.1" [dev-dependencies] hyper = { version = "0.14", features = [ "server", "tcp", "http1", "http2" ] } -rand = "0.8.5" +rand = "0.8" tokio = { version = "1", features = ["net", "rt-multi-thread", "io-util", "test-util"] } tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/examples/waitgroup.rs b/examples/waitgroup.rs index 8cecd90..7c9b650 100644 --- a/examples/waitgroup.rs +++ b/examples/waitgroup.rs @@ -23,7 +23,7 @@ async fn main() { // NOTE: you can also manually create // a guard using `shutdown.guard()` and spawn // you async tasks manually in case you do not wish to run these - // using `tokio::spawn`. + // using `tokio_graceful::sync::spawn` (Tokio by default). let sleep = tokio::time::sleep(Duration::from_secs(countdown)); shutdown.spawn_task(async move { sleep.await; diff --git a/src/guard.rs b/src/guard.rs index 527015e..f8cc248 100644 --- a/src/guard.rs +++ b/src/guard.rs @@ -1,9 +1,7 @@ use std::{future::Future, mem::ManuallyDrop}; -use tokio::task::JoinHandle; - use crate::{ - sync::{Arc, AtomicUsize, Ordering}, + sync::{Arc, AtomicUsize, JoinHandle, Ordering}, trigger::{Receiver, Sender}, }; @@ -58,53 +56,44 @@ impl ShutdownGuard { self.0.cancelled().await } - /// Returns a Tokio [`JoinHandle`] that can be awaited on + /// Returns a [`crate::sync::JoinHandle`] that can be awaited on /// to wait for the spawned task to complete. See - /// [`tokio::spawn`] for more information. - /// - /// [`JoinHandle`]: https://docs.rs/tokio/*/tokio/task/struct.JoinHandle.html - /// [`tokio::spawn`]: https://docs.rs/tokio/*/tokio/task/fn.spawn.html + /// [`crate::sync::spawn`] for more information. pub fn spawn_task(&self, task: T) -> JoinHandle where T: Future + Send + 'static, T::Output: Send + 'static, { let guard = self.clone(); - tokio::spawn(async move { + crate::sync::spawn(async move { let output = task.await; drop(guard); output }) } - /// Returns a Tokio [`JoinHandle`] that can be awaited on + /// Returns a Tokio [`crate::sync::JoinHandle`] that can be awaited on /// to wait for the spawned task (future) to complete. See - /// [`tokio::spawn`] for more information. + /// [`crate::sync::spawn`] for more information. /// /// In contrast to [`ShutdownGuard::spawn_task`] this method consumes the guard, /// ensuring the guard is dropped once the task future is fulfilled. - /// - /// [`JoinHandle`]: https://docs.rs/tokio/*/tokio/task/struct.JoinHandle.html - /// [`tokio::spawn`]: https://docs.rs/tokio/*/tokio/task/fn.spawn.html /// [`ShutdownGuard::spawn_task`]: crate::ShutdownGuard::spawn_task pub fn into_spawn_task(self, task: T) -> JoinHandle where T: Future + Send + 'static, T::Output: Send + 'static, { - tokio::spawn(async move { + crate::sync::spawn(async move { let output = task.await; drop(self); output }) } - /// Returns a Tokio [`JoinHandle`] that can be awaited on + /// Returns a Tokio [`crate::sync::JoinHandle`] that can be awaited on /// to wait for the spawned task (fn) to complete. See - /// [`tokio::spawn`] for more information. - /// - /// [`JoinHandle`]: https://docs.rs/tokio/*/tokio/task/struct.JoinHandle.html - /// [`tokio::spawn`]: https://docs.rs/tokio/*/tokio/task/fn.spawn.html + /// [`crate::sync::spawn`] for more information. pub fn spawn_task_fn(&self, task: F) -> JoinHandle where F: FnOnce(ShutdownGuard) -> T + Send + 'static, @@ -112,18 +101,15 @@ impl ShutdownGuard { T::Output: Send + 'static, { let guard = self.clone(); - tokio::spawn(async move { task(guard).await }) + crate::sync::spawn(async move { task(guard).await }) } - /// Returns a Tokio [`JoinHandle`] that can be awaited on + /// Returns a Tokio [`crate::sync::JoinHandle`] that can be awaited on /// to wait for the spawned task (fn) to complete. See - /// [`tokio::spawn`] for more information. + /// [`crate::sync::spawn`] for more information. /// /// In contrast to [`ShutdownGuard::spawn_task_fn`] this method consumes the guard, /// ensuring the guard is dropped once the task future is fulfilled. - /// - /// [`JoinHandle`]: https://docs.rs/tokio/*/tokio/task/struct.JoinHandle.html - /// [`tokio::spawn`]: https://docs.rs/tokio/*/tokio/task/fn.spawn.html /// [`ShutdownGuard::spawn_task_fn`]: crate::ShutdownGuard::spawn_task_fn pub fn into_spawn_task_fn(self, task: F) -> JoinHandle where @@ -131,7 +117,7 @@ impl ShutdownGuard { T: Future + Send + 'static, T::Output: Send + 'static, { - tokio::spawn(async move { task(self).await }) + crate::sync::spawn(async move { task(self).await }) } /// Downgrades the guard to a [`WeakShutdownGuard`], diff --git a/src/lib.rs b/src/lib.rs index 102c54a..8e847c3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -63,7 +63,7 @@ mod tests { let shutdown = Shutdown::new(async { rx.await.unwrap(); }); - tokio::spawn(async move { + crate::sync::spawn(async move { tx.send(()).unwrap(); }); shutdown.shutdown().await; @@ -75,7 +75,7 @@ mod tests { let shutdown = Shutdown::new(async { rx.await.unwrap(); }); - tokio::spawn(async move { + crate::sync::spawn(async move { tx.send(()).unwrap(); }); shutdown diff --git a/src/shutdown.rs b/src/shutdown.rs index 1770c24..0fd09ff 100644 --- a/src/shutdown.rs +++ b/src/shutdown.rs @@ -34,7 +34,7 @@ impl Shutdown { let guard = ShutdownGuard::new(signal_rx, zero_tx, Arc::new(0usize.into())); - tokio::spawn(async move { + crate::sync::spawn(async move { signal.await; signal_tx.trigger(); }); @@ -81,12 +81,9 @@ impl Shutdown { self.guard.clone_weak() } - /// Returns a Tokio [`JoinHandle`] that can be awaited on + /// Returns a Tokio [`crate::sync::JoinHandle`] that can be awaited on /// to wait for the spawned task to complete. See - /// [`tokio::spawn`] for more information. - /// - /// [`JoinHandle`]: https://docs.rs/tokio/*/tokio/task/struct.JoinHandle.html - /// [`tokio::spawn`]: https://docs.rs/tokio/*/tokio/task/fn.spawn.html + /// [`crate::sync::spawn`] for more information. #[inline] pub fn spawn_task(&self, task: T) -> tokio::task::JoinHandle where @@ -96,12 +93,9 @@ impl Shutdown { self.guard.spawn_task(task) } - /// Returns a Tokio [`JoinHandle`] that can be awaited on + /// Returns a Tokio [`crate::sync::JoinHandle`] that can be awaited on /// to wait for the spawned task (fn) to complete. See - /// [`tokio::spawn`] for more information. - /// - /// [`JoinHandle`]: https://docs.rs/tokio/*/tokio/task/struct.JoinHandle.html - /// [`tokio::spawn`]: https://docs.rs/tokio/*/tokio/task/fn.spawn.html + /// [`crate::sync::spawn`] for more information. #[inline] pub fn spawn_task_fn(&self, task: F) -> tokio::task::JoinHandle where diff --git a/src/sync.rs b/src/sync.rs deleted file mode 100644 index 54a5ed6..0000000 --- a/src/sync.rs +++ /dev/null @@ -1,11 +0,0 @@ -#[cfg(loom)] -pub use loom::sync::{ - atomic::{AtomicBool, AtomicUsize, Ordering}, - Arc, Mutex, Ordering, -}; - -#[cfg(not(loom))] -pub use std::sync::{ - atomic::{AtomicBool, AtomicUsize, Ordering}, - Arc, Mutex, -}; diff --git a/src/sync/default.rs b/src/sync/default.rs new file mode 100644 index 0000000..7ccb73d --- /dev/null +++ b/src/sync/default.rs @@ -0,0 +1,6 @@ +pub use std::sync::{ + atomic::{AtomicBool, AtomicUsize, Ordering}, + Arc, Mutex, +}; + +pub use tokio::task::{spawn, JoinHandle}; diff --git a/src/sync/loom.rs b/src/sync/loom.rs new file mode 100644 index 0000000..f79713c --- /dev/null +++ b/src/sync/loom.rs @@ -0,0 +1,6 @@ +pub use loom::sync::{ + atomic::{AtomicBool, AtomicUsize, Ordering}, + Arc, Mutex, Ordering, +}; + +pub use loom::task::{spawn, JoinHandle}; diff --git a/src/sync/mod.rs b/src/sync/mod.rs new file mode 100644 index 0000000..d3ac3e2 --- /dev/null +++ b/src/sync/mod.rs @@ -0,0 +1,9 @@ +#[cfg(loom)] +mod loom; +#[cfg(loom)] +pub use loom::*; + +#[cfg(not(loom))] +mod default; +#[cfg(not(loom))] +pub use default::*;