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
sourceimpl<T> UniqueArc<T>
impl<T> UniqueArc<T>
sourcepub fn try_new_uninit() -> Result<UniqueArc<MaybeUninit<T>>>
pub fn try_new_uninit() -> Result<UniqueArc<MaybeUninit<T>>>
Tries to allocate a new UniqueArc
instance whose contents are not initialised yet.