From 53528772fb5a174c8606cdf0047ac4899ce05be7 Mon Sep 17 00:00:00 2001 From: Wedson Almeida Filho Date: Wed, 28 Dec 2022 06:03:41 +0000 Subject: rust: sync: allow type of `self` to be `Arc` or variants This allows associated functions whose `self` argument has `Arc` or variants as their type. This, in turn, allows callers to use the dot syntax to make calls. Signed-off-by: Wedson Almeida Filho Reviewed-by: Alice Ryhl Reviewed-by: Gary Guo Reviewed-by: Vincenzo Palazzo Acked-by: Boqun Feng Signed-off-by: Miguel Ojeda --- rust/kernel/lib.rs | 1 + rust/kernel/sync/arc.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) 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` as the type of `self`: +/// +/// ``` +/// use kernel::sync::Arc; +/// +/// struct Example { +/// a: u32, +/// b: u32, +/// } +/// +/// impl Example { +/// fn take_over(self: Arc) { +/// // ... +/// } +/// +/// fn use_reference(self: &Arc) { +/// // ... +/// } +/// } +/// +/// let obj = Arc::try_new(Example { a: 10, b: 20 })?; +/// obj.use_reference(); +/// obj.take_over(); +/// ``` pub struct Arc { ptr: NonNull>, _p: PhantomData>, @@ -68,6 +93,9 @@ struct ArcInner { data: T, } +// This is to allow [`Arc`] (and variants) to be used as the type of `self`. +impl core::ops::Receiver for Arc {} + // SAFETY: It is safe to send `Arc` 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` may ultimately access `T` directly, for -- cgit v1.2.3