Skip to content

Commit 2c9990b

Browse files
committed
Auto merge of #140369 - jplatte:mutex-rwlock-data-ptr, r=Amanieu
Add data_ptr method to Mutex and RwLock Implementation of #140368 / rust-lang/libs-team#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>`?
2 parents d76fe15 + 20589bd commit 2c9990b

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

library/std/src/sync/poison/mutex.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,17 @@ impl<T: ?Sized> Mutex<T> {
608608
let data = self.data.get_mut();
609609
poison::map_result(self.poison.borrow(), |()| data)
610610
}
611+
612+
/// Returns a raw pointer to the underlying data.
613+
///
614+
/// The returned pointer is always non-null and properly aligned, but it is
615+
/// the user's responsibility to ensure that any reads and writes through it
616+
/// are properly synchronized to avoid data races, and that it is not read
617+
/// or written through after the mutex is dropped.
618+
#[unstable(feature = "mutex_data_ptr", issue = "140368")]
619+
pub fn data_ptr(&self) -> *mut T {
620+
self.data.get()
621+
}
611622
}
612623

613624
#[stable(feature = "mutex_from", since = "1.24.0")]

library/std/src/sync/poison/rwlock.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,17 @@ impl<T: ?Sized> RwLock<T> {
634634
let data = self.data.get_mut();
635635
poison::map_result(self.poison.borrow(), |()| data)
636636
}
637+
638+
/// Returns a raw pointer to the underlying data.
639+
///
640+
/// The returned pointer is always non-null and properly aligned, but it is
641+
/// the user's responsibility to ensure that any reads and writes through it
642+
/// are properly synchronized to avoid data races, and that it is not read
643+
/// or written through after the lock is dropped.
644+
#[unstable(feature = "rwlock_data_ptr", issue = "140368")]
645+
pub fn data_ptr(&self) -> *mut T {
646+
self.data.get()
647+
}
637648
}
638649

639650
#[stable(feature = "rust1", since = "1.0.0")]

library/std/src/sync/reentrant_lock.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,17 @@ impl<T: ?Sized> ReentrantLock<T> {
349349
}
350350
}
351351

352+
/// Returns a raw pointer to the underlying data.
353+
///
354+
/// The returned pointer is always non-null and properly aligned, but it is
355+
/// the user's responsibility to ensure that any reads through it are
356+
/// properly synchronized to avoid data races, and that it is not read
357+
/// through after the lock is dropped.
358+
#[unstable(feature = "reentrant_lock_data_ptr", issue = "140368")]
359+
pub fn data_ptr(&self) -> *const T {
360+
&raw const self.data
361+
}
362+
352363
unsafe fn increment_lock_count(&self) -> Option<()> {
353364
unsafe {
354365
*self.lock_count.get() = (*self.lock_count.get()).checked_add(1)?;

0 commit comments

Comments
 (0)