Trait kernel::init::Init

source ·
pub unsafe trait Init<T: ?Sized, E = Infallible>: PinInit<T, E> {
    // Required method
    unsafe fn __init(self, slot: *mut T) -> Result<(), E>;

    // Provided method
    fn chain<F>(self, f: F) -> ChainInit<Self, F, T, E>
       where F: FnOnce(&mut T) -> Result<(), E> { ... }
}
Expand description

An initializer for 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::init function of a smart pointer like Arc<T> on this. Because PinInit<T, E> is a super trait, you can use every function that takes it as well.

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 init_from_closure where possible.

The Init::__init function

  • returns Ok(()) if it initialized every field of slot,
  • returns Err(err) if it encountered an error and then cleaned slot, 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 at slot it upholds the pinning invariants of T.

The __pinned_init function from the supertrait PinInit needs to execute the exact same code as __init.

Contrary to its supertype PinInit<T, E> the caller is allowed to move the pointee after initialization.

Required Methods§

source

unsafe fn __init(self, slot: *mut T) -> Result<(), E>

Initializes slot.

Safety
  • slot is a valid pointer to uninitialized memory.
  • the caller does not touch slot when Err is returned, they are only permitted to deallocate.

Provided Methods§

source

fn chain<F>(self, f: F) -> ChainInit<Self, F, T, E>where F: FnOnce(&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::{self, init_from_closure}};
struct Foo {
    buf: [u8; 1_000_000],
}

impl Foo {
    fn setup(&mut self) {
        pr_info!("Setting up foo");
    }
}

let foo = init!(Foo {
    buf <- init::zeroed()
}).chain(|foo| {
    foo.setup();
    Ok(())
});

Implementors§

source§

impl<T, E> Init<T, E> for T

source§

impl<T: ?Sized, E, I, F> Init<T, E> for ChainInit<I, F, T, E>where I: Init<T, E>, F: FnOnce(&mut T) -> Result<(), E>,

This documentation is an old archive. Please see https://rust.docs.kernel.org instead.