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
344344
345345 impl<T: 'static> ForeignOwnable for Arc<T> {
346346 type Borrowed<'a> = ArcBorrow<'a, T>;
347+ type BorrowedMut<'a> = Self::Borrowed<'a>;
347348
348349 fn into_foreign(self) -> *mut crate::ffi::c_void {
349350 ManuallyDrop::new(self).ptr.as_ptr().cast()
@@ -369,6 +370,12 @@ impl<T: 'static> ForeignOwnable for Arc<T> { · 19 unmodified lines
369370 // for the lifetime of the returned value.
370371 unsafe { ArcBorrow::new(inner) }
371372 }
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+ }
372379 }
373380
374381 impl<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