Skip to main content

pin_data

Attribute Macro pin_data 

Source
#[pin_data]
Expand description

Used to specify the pinning information of the fields of a struct.

This is somewhat similar in purpose as pin-project-lite. Place this macro on a struct definition and then #[pin] in front of the attributes of each field you want to structurally pin.

This macro enables the use of the pin_init! macro. When pin-initializing a struct, then #[pin] directs the type of initializer that is required.

Tuple structs are supported as well. Their fields have no names, so the generated projection is a tuple struct too and its fields are accessed by index.

If your struct implements Drop, then you need to add PinnedDrop as arguments to this macro, and change your Drop implementation to PinnedDrop annotated with #[pinned_drop], since dropping pinned values requires extra care.

ยงExamples

use pin_init::pin_data;

enum Command {
    /* ... */
}

#[pin_data]
struct DriverData {
    #[pin]
    queue: CMutex<Vec<Command>>,
    buf: Box<[u8; 1024 * 1024]>,
}

The same as a tuple struct, projected by index:

use core::pin::Pin;
use pin_init::pin_data;

enum Command {
    /* ... */
}

#[pin_data]
struct DriverData(#[pin] CMutex<Vec<Command>>, Box<[u8; 1024 * 1024]>);

fn queue(data: Pin<&mut DriverData>) -> Pin<&mut CMutex<Vec<Command>>> {
    data.project().0
}
use core::pin::Pin;
use pin_init::{pin_data, pinned_drop, PinnedDrop};

enum Command {
    /* ... */
}

#[pin_data(PinnedDrop)]
struct DriverData {
    #[pin]
    queue: CMutex<Vec<Command>>,
    buf: Box<[u8; 1024 * 1024]>,
    raw_info: *mut bindings::info,
}

#[pinned_drop]
impl PinnedDrop for DriverData {
    fn drop(self: Pin<&mut Self>) {
        unsafe { bindings::destroy_info(self.raw_info) };
    }
}