mirror of
https://github.com/bertptrs/tracing-mutex.git
synced 2025-12-25 20:50:32 +01:00
Ensure BorrowedMutex is !Send
This commit is contained in:
@@ -6,6 +6,11 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Enforce that all internal mutex guards are `!Send`. They already should be according to other
|
||||||
|
reasons, but this adds extra security through the type system.
|
||||||
|
|
||||||
## [0.2.1] - 2022-05-23
|
## [0.2.1] - 2022-05-23
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
24
src/lib.rs
24
src/lib.rs
@@ -57,6 +57,7 @@ use std::ptr;
|
|||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
use std::sync::MutexGuard;
|
||||||
use std::sync::Once;
|
use std::sync::Once;
|
||||||
use std::sync::PoisonError;
|
use std::sync::PoisonError;
|
||||||
|
|
||||||
@@ -134,7 +135,10 @@ impl MutexId {
|
|||||||
/// This method panics if the new dependency would introduce a cycle.
|
/// This method panics if the new dependency would introduce a cycle.
|
||||||
pub fn get_borrowed(&self) -> BorrowedMutex {
|
pub fn get_borrowed(&self) -> BorrowedMutex {
|
||||||
self.mark_held();
|
self.mark_held();
|
||||||
BorrowedMutex(self)
|
BorrowedMutex {
|
||||||
|
id: self,
|
||||||
|
_not_send: PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mark this lock as held for the purposes of dependency tracking.
|
/// Mark this lock as held for the purposes of dependency tracking.
|
||||||
@@ -274,8 +278,22 @@ impl Drop for LazyMutexId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Borrowed mutex ID
|
||||||
|
///
|
||||||
|
/// This type should be used as part of a mutex guard wrapper. It can be acquired through
|
||||||
|
/// [`MutexId::get_borrowed`] and will automatically mark the mutex as not borrowed when it is
|
||||||
|
/// dropped.
|
||||||
|
///
|
||||||
|
/// This type intentionally is [`!Send`](std::marker::Send) because the ownership tracking is based
|
||||||
|
/// on a thread-local stack which doesn't work if a guard gets released in a different thread from
|
||||||
|
/// where they're acquired.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct BorrowedMutex<'a>(&'a MutexId);
|
struct BorrowedMutex<'a> {
|
||||||
|
/// Reference to the mutex we're borrowing from
|
||||||
|
id: &'a MutexId,
|
||||||
|
/// This value serves no purpose but to make the type [`!Send`](std::marker::Send)
|
||||||
|
_not_send: PhantomData<MutexGuard<'static, ()>>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Drop a lock held by the current thread.
|
/// Drop a lock held by the current thread.
|
||||||
///
|
///
|
||||||
@@ -286,7 +304,7 @@ struct BorrowedMutex<'a>(&'a MutexId);
|
|||||||
impl<'a> Drop for BorrowedMutex<'a> {
|
impl<'a> Drop for BorrowedMutex<'a> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
// Safety: the only way to get a BorrowedMutex is by locking the mutex.
|
// Safety: the only way to get a BorrowedMutex is by locking the mutex.
|
||||||
unsafe { self.0.mark_released() };
|
unsafe { self.id.mark_released() };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user