Allow lock guards to be sent to other threads

But only if deadlock detection is not enabled.

Fixes #197
This commit is contained in:
Amanieu d'Antras 2020-05-28 00:07:18 +01:00
parent b5c69eb1e8
commit 358b35fd2f
5 changed files with 22 additions and 4 deletions

View File

@ -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"]

View File

@ -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`.

View File

@ -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};

View File

@ -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) {

View File

@ -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) {