pub struct UniqueArc<T: ?Sized> { /* private fields */ }
Expand description
A refcounted object that is known to have a refcount of 1.
It is mutable and can be converted to an Arc
so that it can be shared.
Invariants
inner
always has a reference count of 1.
Examples
In the following example, we make changes to the inner object before turning it into an
Arc<Test>
object (after which point, it cannot be mutated directly). Note that x.into()
cannot fail.
use kernel::sync::{Arc, UniqueArc};
struct Example {
a: u32,
b: u32,
}
fn test() -> Result<Arc<Example>> {
let mut x = UniqueArc::try_new(Example { a: 10, b: 20 })?;
x.a += 1;
x.b += 1;
Ok(x.into())
}
In the following example we first allocate memory for a ref-counted Example
but we don’t
initialise it on allocation. We do initialise it later with a call to UniqueArc::write
,
followed by a conversion to Arc<Example>
. This is particularly useful when allocation happens
in one context (e.g., sleepable) and initialisation in another (e.g., atomic):
use kernel::sync::{Arc, UniqueArc};
struct Example {
a: u32,
b: u32,
}
fn test() -> Result<Arc<Example>> {
let x = UniqueArc::try_new_uninit()?;
Ok(x.write(Example { a: 10, b: 20 }).into())
}
In the last example below, the caller gets a pinned instance of Example
while converting to
Arc<Example>
; this is useful in scenarios where one needs a pinned reference during
initialisation, for example, when initialising fields that are wrapped in locks.
use kernel::sync::{Arc, UniqueArc};
struct Example {
a: u32,
b: u32,
}
fn test() -> Result<Arc<Example>> {
let mut pinned = Pin::from(UniqueArc::try_new(Example { a: 10, b: 20 })?);
// We can modify `pinned` because it is `Unpin`.
pinned.as_mut().a += 1;
Ok(pinned.into())
}
Implementations§
source§impl<T> UniqueArc<T>
impl<T> UniqueArc<T>
sourcepub fn try_new(value: T) -> Result<Self, AllocError>
pub fn try_new(value: T) -> Result<Self, AllocError>
Tries to allocate a new UniqueArc
instance.
sourcepub fn try_new_uninit() -> Result<UniqueArc<MaybeUninit<T>>, AllocError>
pub fn try_new_uninit() -> Result<UniqueArc<MaybeUninit<T>>, AllocError>
Tries to allocate a new UniqueArc
instance whose contents are not initialised yet.
source§impl<T> UniqueArc<MaybeUninit<T>>
impl<T> UniqueArc<MaybeUninit<T>>
sourcepub fn write(self, value: T) -> UniqueArc<T>
pub fn write(self, value: T) -> UniqueArc<T>
Converts a UniqueArc<MaybeUninit<T>>
into a UniqueArc<T>
by writing a value into it.
sourcepub unsafe fn assume_init(self) -> UniqueArc<T>
pub unsafe fn assume_init(self) -> UniqueArc<T>
Unsafely assume that self
is initialized.
Safety
The caller guarantees that the value behind this pointer has been initialized. It is immediate UB to call this when the value is not initialized.
Trait Implementations§
source§impl<T> InPlaceInit<T> for UniqueArc<T>
impl<T> InPlaceInit<T> for UniqueArc<T>
source§fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E>where
E: From<AllocError>,
fn try_pin_init<E>(init: impl PinInit<T, E>) -> Result<Pin<Self>, E>where E: From<AllocError>,
T
inside of a new smart pointer of this
type. Read moresource§fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E>where
E: From<AllocError>,
fn try_init<E>(init: impl Init<T, E>) -> Result<Self, E>where E: From<AllocError>,
T
.