about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
authorTrevor Gross <t.gross35@gmail.com>2025-05-28 10:28:07 -0400
committerGitHub <noreply@github.com>2025-05-28 10:28:07 -0400
commit5f17779a03746af581d8867449b1627404d8cd3f (patch)
tree3d3fd8a0cf752df68254482bae70eb5d9ce4b2e2 /library/std/src
parent77101febcc9662a076ff43887497cd5b30674d93 (diff)
parent20589bd6050ff9596348c751231ac84b7538adb4 (diff)
Rollup merge of #140369 - jplatte:mutex-rwlock-data-ptr, r=Amanieu
Add data_ptr method to Mutex and RwLock

Implementation of https://github.com/rust-lang/rust/issues/140368 / https://github.com/rust-lang/libs-team/issues/531.

I tried to write a useful safety section about when it is safe to read or write through the returned pointers, but couldn't come up with something nice. Hoping this PR is still useful without that. I'm happy to add any doc strings other people come up with if needed before merge, of course.

Unresolved questions:

- Return a `LockResult` or not?
- Return `*mut T` like existing APIs (`Cell::as_ptr` / `MaybeUninit::as[_mut]_ptr` / `Vec::as_ptr` / ...) or be more precise and return `NonNull<T>`?
Diffstat (limited to 'library/std/src')
-rw-r--r--library/std/src/sync/poison/mutex.rs11
-rw-r--r--library/std/src/sync/poison/rwlock.rs11
-rw-r--r--library/std/src/sync/reentrant_lock.rs11
3 files changed, 33 insertions, 0 deletions
diff --git a/library/std/src/sync/poison/mutex.rs b/library/std/src/sync/poison/mutex.rs
index 1c29c619edc..30325be685c 100644
--- a/library/std/src/sync/poison/mutex.rs
+++ b/library/std/src/sync/poison/mutex.rs
@@ -608,6 +608,17 @@ impl<T: ?Sized> Mutex<T> {
         let data = self.data.get_mut();
         poison::map_result(self.poison.borrow(), |()| data)
     }
+
+    /// Returns a raw pointer to the underlying data.
+    ///
+    /// The returned pointer is always non-null and properly aligned, but it is
+    /// the user's responsibility to ensure that any reads and writes through it
+    /// are properly synchronized to avoid data races, and that it is not read
+    /// or written through after the mutex is dropped.
+    #[unstable(feature = "mutex_data_ptr", issue = "140368")]
+    pub fn data_ptr(&self) -> *mut T {
+        self.data.get()
+    }
 }
 
 #[stable(feature = "mutex_from", since = "1.24.0")]
diff --git a/library/std/src/sync/poison/rwlock.rs b/library/std/src/sync/poison/rwlock.rs
index 6976c0a64e2..a060e2ea57a 100644
--- a/library/std/src/sync/poison/rwlock.rs
+++ b/library/std/src/sync/poison/rwlock.rs
@@ -634,6 +634,17 @@ impl<T: ?Sized> RwLock<T> {
         let data = self.data.get_mut();
         poison::map_result(self.poison.borrow(), |()| data)
     }
+
+    /// Returns a raw pointer to the underlying data.
+    ///
+    /// The returned pointer is always non-null and properly aligned, but it is
+    /// the user's responsibility to ensure that any reads and writes through it
+    /// are properly synchronized to avoid data races, and that it is not read
+    /// or written through after the lock is dropped.
+    #[unstable(feature = "rwlock_data_ptr", issue = "140368")]
+    pub fn data_ptr(&self) -> *mut T {
+        self.data.get()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/std/src/sync/reentrant_lock.rs b/library/std/src/sync/reentrant_lock.rs
index 96a4cf12659..727252f03a2 100644
--- a/library/std/src/sync/reentrant_lock.rs
+++ b/library/std/src/sync/reentrant_lock.rs
@@ -349,6 +349,17 @@ impl<T: ?Sized> ReentrantLock<T> {
         }
     }
 
+    /// Returns a raw pointer to the underlying data.
+    ///
+    /// The returned pointer is always non-null and properly aligned, but it is
+    /// the user's responsibility to ensure that any reads through it are
+    /// properly synchronized to avoid data races, and that it is not read
+    /// through after the lock is dropped.
+    #[unstable(feature = "reentrant_lock_data_ptr", issue = "140368")]
+    pub fn data_ptr(&self) -> *const T {
+        &raw const self.data
+    }
+
     unsafe fn increment_lock_count(&self) -> Option<()> {
         unsafe {
             *self.lock_count.get() = (*self.lock_count.get()).checked_add(1)?;