History

rust: kernel: add improved version of `ForeignOwnable::borrow_mut`

Previously, the `ForeignOwnable` trait had a method called `borrow_mut` that was intended to provide mutable access to the inner value. However, the method accidentally made it possible to change the address of the object being modified, which usually isn't what we want. (And when we want that, it can be done by calling `from_foreign` and `into_foreign`, like how the old `borrow_mut` was implemented.) In this patch, we introduce an alternate definition of `borrow_mut` that solves the previous problem. Conceptually, given a pointer type `P` that implements `ForeignOwnable`, the `borrow_mut` method gives you the same kind of access as an `&mut P` would, except that it does not let you change the pointer `P` itself. This is analogous to how the existing `borrow` method provides the same kind of access to the inner value as an `&P`. Note that for types like `Arc`, having an `&mut Arc<T>` only gives you immutable access to the inner `T`. This is because mutable references assume exclusive access, but there might be other handles to the same reference counted value, so the access isn't exclusive. The `Arc` type implements this by making `borrow_mut` return the same type as `borrow`.

Alice Ryhl committed 1 year ago

Commit c27e7051 parent c6b97533 files · +86 −13Browse files

Showing the changes to rust/kernel/sync (1 of 3 files). Show all

Unified · Split

rust/kernel/sync/arc.rs+7−0
@@ -344,6 +344,7 @@ impl<T: ?Sized> Arc<T> { · 343 unmodified lines
344 344
345impl<T: 'static> ForeignOwnable for Arc<T> {345impl<T: 'static> ForeignOwnable for Arc<T> {
346 type Borrowed<'a> = ArcBorrow<'a, T>;346 type Borrowed<'a> = ArcBorrow<'a, T>;
347 type BorrowedMut<'a> = Self::Borrowed<'a>;
347 348
348 fn into_foreign(self) -> *mut crate::ffi::c_void {349 fn into_foreign(self) -> *mut crate::ffi::c_void {
349 ManuallyDrop::new(self).ptr.as_ptr().cast()350 ManuallyDrop::new(self).ptr.as_ptr().cast()
@@ -369,6 +370,12 @@ impl<T: 'static> ForeignOwnable for Arc<T> { · 19 unmodified lines
369 // for the lifetime of the returned value.370 // for the lifetime of the returned value.
370 unsafe { ArcBorrow::new(inner) }371 unsafe { ArcBorrow::new(inner) }
371 }372 }
373
374 unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> ArcBorrow<'a, T> {
375 // SAFETY: The safety requirements for `borrow_mut` are a superset of the safety
376 // requirements for `borrow`.
377 unsafe { Self::borrow(ptr) }
378 }
372}379}
373 380
374impl<T: ?Sized> Deref for Arc<T> {381impl<T: ?Sized> Deref for Arc<T> {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t