diff options
author | Wedson Almeida Filho <wedsonaf@gmail.com> | 2022-12-28 06:03:41 +0000 |
---|---|---|
committer | Miguel Ojeda <ojeda@kernel.org> | 2023-01-16 22:20:18 +0100 |
commit | 53528772fb5a174c8606cdf0047ac4899ce05be7 (patch) | |
tree | 0d307da0adaab9a81d0579f88c379db967cdf6c9 /rust | |
parent | 9dc04365500340e6d60a996333d562af747337b1 (diff) |
rust: sync: allow type of `self` to be `Arc<T>` or variants
This allows associated functions whose `self` argument has `Arc<T>` or
variants as their type. This, in turn, allows callers to use the dot
syntax to make calls.
Signed-off-by: Wedson Almeida Filho <wedsonaf@gmail.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
Acked-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'rust')
-rw-r--r-- | rust/kernel/lib.rs | 1 | ||||
-rw-r--r-- | rust/kernel/sync/arc.rs | 28 |
2 files changed, 29 insertions, 0 deletions
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index ace064a3702a..1a10f7c0ddd9 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -14,6 +14,7 @@ #![no_std] #![feature(allocator_api)] #![feature(core_ffi_c)] +#![feature(receiver_trait)] // Ensure conditional compilation based on the kernel configuration works; // otherwise we may silently break things like initcall handling. diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs index 22290eb5ab9b..e2eb0e67d483 100644 --- a/rust/kernel/sync/arc.rs +++ b/rust/kernel/sync/arc.rs @@ -57,6 +57,31 @@ use core::{marker::PhantomData, ops::Deref, ptr::NonNull}; /// /// // The refcount drops to zero when `cloned` goes out of scope, and the memory is freed. /// ``` +/// +/// Using `Arc<T>` as the type of `self`: +/// +/// ``` +/// use kernel::sync::Arc; +/// +/// struct Example { +/// a: u32, +/// b: u32, +/// } +/// +/// impl Example { +/// fn take_over(self: Arc<Self>) { +/// // ... +/// } +/// +/// fn use_reference(self: &Arc<Self>) { +/// // ... +/// } +/// } +/// +/// let obj = Arc::try_new(Example { a: 10, b: 20 })?; +/// obj.use_reference(); +/// obj.take_over(); +/// ``` pub struct Arc<T: ?Sized> { ptr: NonNull<ArcInner<T>>, _p: PhantomData<ArcInner<T>>, @@ -68,6 +93,9 @@ struct ArcInner<T: ?Sized> { data: T, } +// This is to allow [`Arc`] (and variants) to be used as the type of `self`. +impl<T: ?Sized> core::ops::Receiver for Arc<T> {} + // SAFETY: It is safe to send `Arc<T>` to another thread when the underlying `T` is `Sync` because // it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs // `T` to be `Send` because any thread that has an `Arc<T>` may ultimately access `T` directly, for |