summaryrefslogtreecommitdiff
path: root/rust/kernel/sync/arc.rs
diff options
context:
space:
mode:
authorBenno Lossin <benno.lossin@proton.me>2023-04-08 15:25:56 +0300
committerMiguel Ojeda <ojeda@kernel.org>2023-04-12 19:41:05 +0300
commit92c4a1e7e81cc775b2ad6bedb348098230f7ed87 (patch)
treed83e5991bdea03d060c2de7f598f0c279f4eb7f2 /rust/kernel/sync/arc.rs
parentfc6c6baa1f40ded13e539d0c1a17bcefc00abad9 (diff)
downloadlinux-92c4a1e7e81cc775b2ad6bedb348098230f7ed87.tar.xz
rust: init/sync: add `InPlaceInit` trait to pin-initialize smart pointers
The `InPlaceInit` trait that provides two functions, for initializing using `PinInit<T, E>` and `Init<T>`. It is implemented by `Arc<T>`, `UniqueArc<T>` and `Box<T>`. Signed-off-by: Benno Lossin <benno.lossin@proton.me> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Gary Guo <gary@garyguo.net> Reviewed-by: Andreas Hindborg <a.hindborg@samsung.com> Link: https://lore.kernel.org/r/20230408122429.1103522-9-y86-dev@protonmail.com Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'rust/kernel/sync/arc.rs')
-rw-r--r--rust/kernel/sync/arc.rs24
1 files changed, 24 insertions, 0 deletions
diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs
index 34d0e7cbe62e..b45769a29541 100644
--- a/rust/kernel/sync/arc.rs
+++ b/rust/kernel/sync/arc.rs
@@ -17,6 +17,8 @@
use crate::{
bindings,
+ error::{self, Error},
+ init::{InPlaceInit, Init, PinInit},
types::{ForeignOwnable, Opaque},
};
use alloc::boxed::Box;
@@ -166,6 +168,28 @@ impl<T> Arc<T> {
// `Arc` object.
Ok(unsafe { Self::from_inner(Box::leak(inner).into()) })
}
+
+ /// Use the given initializer to in-place initialize a `T`.
+ ///
+ /// If `T: !Unpin` it will not be able to move afterwards.
+ #[inline]
+ pub fn pin_init<E>(init: impl PinInit<T, E>) -> error::Result<Self>
+ where
+ Error: From<E>,
+ {
+ UniqueArc::pin_init(init).map(|u| u.into())
+ }
+
+ /// Use the given initializer to in-place initialize a `T`.
+ ///
+ /// This is equivalent to [`pin_init`], since an [`Arc`] is always pinned.
+ #[inline]
+ pub fn init<E>(init: impl Init<T, E>) -> error::Result<Self>
+ where
+ Error: From<E>,
+ {
+ UniqueArc::init(init).map(|u| u.into())
+ }
}
impl<T: ?Sized> Arc<T> {