From b73d252dfaa5e4ac1fbbcb79e070ccbf21c5074b Mon Sep 17 00:00:00 2001 From: Nika Layzell Date: Sat, 4 Jul 2020 16:13:48 -0400 Subject: [PATCH 1/2] lock_api: Allow unsafely accessing data without a guard --- lock_api/src/mutex.rs | 16 ++++++++++++++++ lock_api/src/remutex.rs | 16 ++++++++++++++++ lock_api/src/rwlock.rs | 16 ++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/lock_api/src/mutex.rs b/lock_api/src/mutex.rs index 0f425781..3fac3d09 100644 --- a/lock_api/src/mutex.rs +++ b/lock_api/src/mutex.rs @@ -270,6 +270,22 @@ impl Mutex { pub unsafe fn raw(&self) -> &R { &self.raw } + + /// Returns a raw pointer to the underlying data. + /// + /// This is useful when combined with `mem::forget` to hold a lock without + /// the need to maintain a `MutexGuard` object alive, for example when + /// dealing with FFI. + /// + /// # Safety + /// + /// The returned pointer must only be dereferenced if the current thread + /// logically owns a `MutexGuard` but that guard has been discarded using + /// `mem::forget`. + #[inline] + pub fn data_ptr(&self) -> *mut T { + self.data.get() + } } impl Mutex { diff --git a/lock_api/src/remutex.rs b/lock_api/src/remutex.rs index 4de8c88e..fae78ab8 100644 --- a/lock_api/src/remutex.rs +++ b/lock_api/src/remutex.rs @@ -362,6 +362,22 @@ impl ReentrantMutex { pub unsafe fn raw(&self) -> &R { &self.raw.mutex } + + /// Returns a raw pointer to the underlying data. + /// + /// This is useful when combined with `mem::forget` to hold a lock without + /// the need to maintain a `ReentrantMutexGuard` object alive, for example + /// when dealing with FFI. + /// + /// # Safety + /// + /// The returned pointer must only be dereferenced if the current thread + /// logically owns a `ReentrantMutexGuard` but that guard has been discarded + /// using `mem::forget`. + #[inline] + pub fn data_ptr(&self) -> *mut T { + self.data.get() + } } impl ReentrantMutex { diff --git a/lock_api/src/rwlock.rs b/lock_api/src/rwlock.rs index 480245d7..55fab92b 100644 --- a/lock_api/src/rwlock.rs +++ b/lock_api/src/rwlock.rs @@ -540,6 +540,22 @@ impl RwLock { pub unsafe fn raw(&self) -> &R { &self.raw } + + /// Returns a raw pointer to the underlying data. + /// + /// This is useful when combined with `mem::forget` to hold a lock without + /// the need to maintain a `RwLockReadGuard` or `RwLockWriteGuard` object + /// alive, for example when dealing with FFI. + /// + /// # Safety + /// + /// The returned pointer must only be dereferenced if the current thread + /// logically owns a `RwLockReadGuard` or `RwLockWriteGuard` but that guard + /// has been discarded using `mem::forget`. + #[inline] + pub fn data_ptr(&self) -> *mut T { + self.data.get() + } } impl RwLock { From 0919affd8fdb6c2ae204500fa3ca4ff6569174c5 Mon Sep 17 00:00:00 2001 From: Nika Layzell Date: Sun, 5 Jul 2020 19:26:12 -0400 Subject: [PATCH 2/2] update doc comment for review changes --- lock_api/src/mutex.rs | 6 +++--- lock_api/src/remutex.rs | 7 ++++--- lock_api/src/rwlock.rs | 7 ++++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/lock_api/src/mutex.rs b/lock_api/src/mutex.rs index 3fac3d09..e435d8ae 100644 --- a/lock_api/src/mutex.rs +++ b/lock_api/src/mutex.rs @@ -279,9 +279,9 @@ impl Mutex { /// /// # Safety /// - /// The returned pointer must only be dereferenced if the current thread - /// logically owns a `MutexGuard` but that guard has been discarded using - /// `mem::forget`. + /// You must ensure that there are no data races when dereferencing the + /// returned pointer, for example if the current thread logically owns + /// a `MutexGuard` but that guard has been discarded using `mem::forget`. #[inline] pub fn data_ptr(&self) -> *mut T { self.data.get() diff --git a/lock_api/src/remutex.rs b/lock_api/src/remutex.rs index fae78ab8..09833b06 100644 --- a/lock_api/src/remutex.rs +++ b/lock_api/src/remutex.rs @@ -371,9 +371,10 @@ impl ReentrantMutex { /// /// # Safety /// - /// The returned pointer must only be dereferenced if the current thread - /// logically owns a `ReentrantMutexGuard` but that guard has been discarded - /// using `mem::forget`. + /// You must ensure that there are no data races when dereferencing the + /// returned pointer, for example if the current thread logically owns a + /// `ReentrantMutexGuard` but that guard has been discarded using + /// `mem::forget`. #[inline] pub fn data_ptr(&self) -> *mut T { self.data.get() diff --git a/lock_api/src/rwlock.rs b/lock_api/src/rwlock.rs index 55fab92b..a25c2f45 100644 --- a/lock_api/src/rwlock.rs +++ b/lock_api/src/rwlock.rs @@ -549,9 +549,10 @@ impl RwLock { /// /// # Safety /// - /// The returned pointer must only be dereferenced if the current thread - /// logically owns a `RwLockReadGuard` or `RwLockWriteGuard` but that guard - /// has been discarded using `mem::forget`. + /// You must ensure that there are no data races when dereferencing the + /// returned pointer, for example if the current thread logically owns a + /// `RwLockReadGuard` or `RwLockWriteGuard` but that guard has been discarded + /// using `mem::forget`. #[inline] pub fn data_ptr(&self) -> *mut T { self.data.get()