Skip to content

Commit 66f1ea8

Browse files
danielalmeida-collaboraPeter Zijlstra
authored andcommitted
rust: lock: Add a Pin<&mut T> accessor
In order for callers to be able to access the inner T safely if T: !Unpin, there needs to be a way to get a Pin<&mut T>. Add this accessor and a corresponding example to tell users how it works. This requires the pin projection functionality [1] for better ergonomic. [boqun: Apply Daniel's fix to the code example, add the reference to pin projection patch and remove out-of-date part in the commit log] Suggested-by: Benno Lossin <lossin@kernel.org> Suggested-by: Boqun Feng <boqun.feng@gmail.com> Signed-off-by: Daniel Almeida <daniel.almeida@collabora.com> Signed-off-by: Boqun Feng <boqun.feng@gmail.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Benno Lossin <lossin@kernel.org> Link: #1181 Link: https://lore.kernel.org/rust-for-linux/20250912174148.373530-1-lossin@kernel.org/ [1]
1 parent 2497a71 commit 66f1ea8

1 file changed

Lines changed: 25 additions & 0 deletions

File tree

rust/kernel/sync/lock.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,31 @@ impl<'a, T: ?Sized, B: Backend> Guard<'a, T, B> {
245245

246246
cb()
247247
}
248+
249+
/// Returns a pinned mutable reference to the protected data.
250+
///
251+
/// The guard implements [`DerefMut`] when `T: Unpin`, so for [`Unpin`]
252+
/// types [`DerefMut`] should be used instead of this function.
253+
///
254+
/// [`DerefMut`]: core::ops::DerefMut
255+
/// [`Unpin`]: core::marker::Unpin
256+
///
257+
/// # Examples
258+
///
259+
/// ```
260+
/// # use kernel::sync::{Mutex, MutexGuard};
261+
/// # use core::{pin::Pin, marker::PhantomPinned};
262+
/// struct Data(PhantomPinned);
263+
///
264+
/// fn example(mutex: &Mutex<Data>) {
265+
/// let mut data: MutexGuard<'_, Data> = mutex.lock();
266+
/// let mut data: Pin<&mut Data> = data.as_mut();
267+
/// }
268+
/// ```
269+
pub fn as_mut(&mut self) -> Pin<&mut T> {
270+
// SAFETY: `self.lock.data` is structurally pinned.
271+
unsafe { Pin::new_unchecked(&mut *self.lock.data.get()) }
272+
}
248273
}
249274

250275
impl<T: ?Sized, B: Backend> core::ops::Deref for Guard<'_, T, B> {

0 commit comments

Comments
 (0)