diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index e08f02b..ceb607c 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -98,6 +98,25 @@ jobs: command: test args: --all-features --examples + test-loom: + needs: check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{env.RUST_TOOLCHAIN}} + override: true + profile: minimal + - uses: Swatinem/rust-cache@v1 + - name: Run tests + uses: actions-rs/cargo@v1 + with: + command: test + args: test_loom --release + env: + RUSTFLAGS: --cfg loom + cargo-hack: needs: check runs-on: ubuntu-latest diff --git a/Cargo.toml b/Cargo.toml index 54c94c7..14cfa7e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,9 @@ 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" tokio = { version = "1", features = ["net", "rt-multi-thread", "io-util", "test-util"] } tracing-subscriber = { version = "0.3", features = ["env-filter"] } + +[target.'cfg(not(loom))'.dev-dependencies] +hyper = { version = "0.14", features = [ "server", "tcp", "http1", "http2" ] } diff --git a/src/lib.rs b/src/lib.rs index 8e847c3..2a00dbf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,7 +40,9 @@ mod guard; pub use guard::{ShutdownGuard, WeakShutdownGuard}; mod shutdown; -pub use shutdown::{default_signal, Shutdown}; +#[cfg(not(loom))] +pub use shutdown::default_signal; +pub use shutdown::Shutdown; pub(crate) mod sync; pub(crate) mod trigger; diff --git a/src/shutdown.rs b/src/shutdown.rs index 0fd09ff..1258be4 100644 --- a/src/shutdown.rs +++ b/src/shutdown.rs @@ -1,7 +1,7 @@ use std::{future::Future, time}; use crate::{ - sync::Arc, + sync::{Arc, JoinHandle}, trigger::{trigger, Receiver}, ShutdownGuard, WeakShutdownGuard, }; @@ -13,6 +13,8 @@ use crate::{ /// create a [`Shutdown`] with [`Shutdown::default`], which uses the default /// signal handler to trigger shutdown. See [`default_signal`] for more info. /// +/// > (NOTE: that these defaults are not available when compiling with --cfg loom) +/// /// See the [README] for more info on how to use this crate. /// /// [`Future`]: std::future::Future @@ -85,7 +87,7 @@ impl Shutdown { /// to wait for the spawned task to complete. See /// [`crate::sync::spawn`] for more information. #[inline] - pub fn spawn_task(&self, task: T) -> tokio::task::JoinHandle + pub fn spawn_task(&self, task: T) -> JoinHandle where T: Future + Send + 'static, T::Output: Send + 'static, @@ -97,7 +99,7 @@ impl Shutdown { /// to wait for the spawned task (fn) to complete. See /// [`crate::sync::spawn`] for more information. #[inline] - pub fn spawn_task_fn(&self, task: F) -> tokio::task::JoinHandle + pub fn spawn_task_fn(&self, task: F) -> JoinHandle where T: Future + Send + 'static, T::Output: Send + 'static, @@ -182,6 +184,7 @@ impl Shutdown { /// /// [`Future`]: std::future::Future /// [`tokio::time::sleep`]: https://docs.rs/tokio/*/tokio/time/fn.sleep.html +#[cfg(not(loom))] pub async fn default_signal() { let ctrl_c = tokio::signal::ctrl_c(); let signal = async { @@ -196,6 +199,7 @@ pub async fn default_signal() { } } +#[cfg(not(loom))] impl Default for Shutdown { fn default() -> Self { Self::new(default_signal()) diff --git a/src/sync/default.rs b/src/sync/default.rs index 7ccb73d..b4dd310 100644 --- a/src/sync/default.rs +++ b/src/sync/default.rs @@ -2,5 +2,3 @@ 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 index f79713c..d6b2a92 100644 --- a/src/sync/loom.rs +++ b/src/sync/loom.rs @@ -1,6 +1,4 @@ pub use loom::sync::{ atomic::{AtomicBool, AtomicUsize, Ordering}, - Arc, Mutex, Ordering, + Arc, Mutex, }; - -pub use loom::task::{spawn, JoinHandle}; diff --git a/src/sync/mod.rs b/src/sync/mod.rs index d3ac3e2..34c3590 100644 --- a/src/sync/mod.rs +++ b/src/sync/mod.rs @@ -1,9 +1,11 @@ #[cfg(loom)] mod loom; #[cfg(loom)] -pub use loom::*; +pub use self::loom::*; #[cfg(not(loom))] mod default; #[cfg(not(loom))] pub use default::*; + +pub use tokio::task::{spawn, JoinHandle}; diff --git a/src/trigger.rs b/src/trigger.rs index 1f675eb..313c788 100644 --- a/src/trigger.rs +++ b/src/trigger.rs @@ -213,3 +213,11 @@ pub fn trigger() -> (Sender, Receiver) { (sender, receiver) } + +#[cfg(all(test, loom))] +mod loom_tests { + use super::*; + + #[test] + fn test_loom_concurrent() {} +}