pub unsafe trait PinInit<T: ?Sized, E = Infallible>: Sized {
// Required method
unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E>;
// Provided method
fn pin_chain<F>(self, f: F) -> ChainPinInit<Self, F, T, E>
where F: FnOnce(Pin<&mut T>) -> Result<(), E> { ... }
}
Expand description
A pin-initializer for the type T
.
To use this initializer, you will need a suitable memory location that can hold a T
. This can
be Box<T>
, Arc<T>
, UniqueArc<T>
or even the stack (see stack_pin_init!
). Use the
InPlaceInit::pin_init
function of a smart pointer like Arc<T>
on this.
Also see the module description.
Safety
When implementing this type you will need to take great care. Also there are probably very few
cases where a manual implementation is necessary. Use pin_init_from_closure
where possible.
The PinInit::__pinned_init
function
- returns
Ok(())
if it initialized every field ofslot
, - returns
Err(err)
if it encountered an error and then cleanedslot
, this means:slot
can be deallocated without UB occurring,slot
does not need to be dropped,slot
is not partially initialized.
- while constructing the
T
atslot
it upholds the pinning invariants ofT
.
Required Methods§
Provided Methods§
sourcefn pin_chain<F>(self, f: F) -> ChainPinInit<Self, F, T, E>where
F: FnOnce(Pin<&mut T>) -> Result<(), E>,
fn pin_chain<F>(self, f: F) -> ChainPinInit<Self, F, T, E>where F: FnOnce(Pin<&mut T>) -> Result<(), E>,
First initializes the value using self
then calls the function f
with the initialized
value.
If f
returns an error the value is dropped and the initializer will forward the error.
Examples
use kernel::{types::Opaque, init::pin_init_from_closure};
#[repr(C)]
struct RawFoo([u8; 16]);
extern {
fn init_foo(_: *mut RawFoo);
}
#[pin_data]
struct Foo {
#[pin]
raw: Opaque<RawFoo>,
}
impl Foo {
fn setup(self: Pin<&mut Self>) {
pr_info!("Setting up foo");
}
}
let foo = pin_init!(Foo {
raw <- unsafe {
Opaque::ffi_init(|s| {
init_foo(s);
})
},
}).pin_chain(|foo| {
foo.setup();
Ok(())
});