diff --git a/Cargo.toml b/Cargo.toml index 9e60c9a1..e78bf269 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ deadlock_detection = ["parking_lot_core/deadlock_detection"] serde = ["lock_api/serde"] stdweb = ["instant/stdweb"] wasm-bindgen = ["instant/wasm-bindgen"] +send_guard = [] [workspace] exclude = ["benchmark"] diff --git a/README.md b/README.md index d213572c..2c5c2d43 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,8 @@ in the Rust standard library: 18. Optional support for [serde](https://docs.serde.rs/serde/). Enable via the feature `serde`. **NOTE!** this support is for `Mutex`, `ReentrantMutex`, and `RwLock` only; `Condvar` and `Once` are not currently supported. +19. Lock guards can be sent to other threads when the `send_guard` geature is + enabled. ## The parking lot @@ -118,6 +120,12 @@ parking_lot = { version = "0.10", features = ["nightly"] } The experimental deadlock detector can be enabled with the `deadlock_detection` Cargo feature. +To allow sending `MutexGuard`s and `RwLock*Guard`s to other threads, enable the +`send_guard` option. + +Note that the `deadlock_detection` and `send_guard` features are incompatible +and cannot be used together. + The core parking lot API is provided by the `parking_lot_core` crate. It is separate from the synchronization primitives in the `parking_lot` crate so that changes to the core API do not cause breaking changes for users of `parking_lot`. diff --git a/src/lib.rs b/src/lib.rs index 73246c2e..7ff2c79d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,6 +30,15 @@ pub mod deadlock; #[cfg(not(feature = "deadlock_detection"))] mod deadlock; +// If deadlock detection is enabled, we cannot allow lock guards to be sent to +// other threads. +#[cfg(all(feature = "send_guard", feature = "deadlock_detection"))] +compile_error!("the `send_guard` and `deadlock_detection` features cannot be used together"); +#[cfg(feature = "send_guard")] +type GuardMarker = lock_api::GuardSend; +#[cfg(not(feature = "send_guard"))] +type GuardMarker = lock_api::GuardNoSend; + pub use self::condvar::{Condvar, WaitTimeoutResult}; pub use self::fair_mutex::{const_fair_mutex, FairMutex, FairMutexGuard, MappedFairMutexGuard}; pub use self::mutex::{const_mutex, MappedMutexGuard, Mutex, MutexGuard}; diff --git a/src/raw_mutex.rs b/src/raw_mutex.rs index 57f9318a..82591104 100644 --- a/src/raw_mutex.rs +++ b/src/raw_mutex.rs @@ -11,7 +11,7 @@ use core::{ time::Duration, }; use instant::Instant; -use lock_api::{GuardNoSend, RawMutex as RawMutex_}; +use lock_api::RawMutex as RawMutex_; use parking_lot_core::{self, ParkResult, SpinWait, UnparkResult, UnparkToken, DEFAULT_PARK_TOKEN}; // UnparkToken used to indicate that that the target thread should attempt to @@ -60,7 +60,7 @@ unsafe impl lock_api::RawMutex for RawMutex { state: AtomicU8::new(0), }; - type GuardMarker = GuardNoSend; + type GuardMarker = crate::GuardMarker; #[inline] fn lock(&self) { diff --git a/src/raw_rwlock.rs b/src/raw_rwlock.rs index e8c02242..6e54d4fc 100644 --- a/src/raw_rwlock.rs +++ b/src/raw_rwlock.rs @@ -13,7 +13,7 @@ use core::{ sync::atomic::{AtomicUsize, Ordering}, }; use instant::Instant; -use lock_api::{GuardNoSend, RawRwLock as RawRwLock_, RawRwLockUpgrade}; +use lock_api::{RawRwLock as RawRwLock_, RawRwLockUpgrade}; use parking_lot_core::{ self, deadlock, FilterOp, ParkResult, ParkToken, SpinWait, UnparkResult, UnparkToken, }; @@ -62,7 +62,7 @@ unsafe impl lock_api::RawRwLock for RawRwLock { state: AtomicUsize::new(0), }; - type GuardMarker = GuardNoSend; + type GuardMarker = crate::GuardMarker; #[inline] fn lock_exclusive(&self) {