Lines Matching +full:foo +full:- +full:queue

1 // SPDX-License-Identifier: Apache-2.0 OR MIT
3 //! Library to safely and fallibly initialize pinned `struct`s using in-place constructors.
7 //! It also allows in-place initialization of big `struct`s that would otherwise produce a stack
10 //! This library's main use-case is in [Rust-for-Linux]. Although this version can be used
13 //! There are cases when you want to in-place initialize a struct. For example when it is very big
18 //! <https://rust-for-linux.com/the-safe-pinned-initialization-problem>.
20 //! This library allows you to do in-place initialization safely.
28 …ocator_api` unstable feature]: https://doc.rust-lang.org/nightly/unstable-book/library-features/al…
30 //! The feature is enabled by default, thus by default `pin-init` will require a nightly compiler.
32 //! will require the `std` feature, because stable compilers have neither `Box` nor `Arc` in no-std
37 //! To initialize a `struct` with an in-place constructor you will need two things:
38 //! - an in-place constructor,
39 //! - a memory location that can hold your `struct` (this can be the [stack], an [`Arc<T>`],
42 //! To get an in-place constructor there are generally three options:
43 //! - directly creating an in-place constructor using the [`pin_init!`] macro,
44 //! - a custom function/macro returning an in-place constructor provided by someone else,
45 //! - using the unsafe function [`pin_init_from_closure()`] to manually create an initializer.
47 //! Aside from pinned initialization, this library also supports in-place construction without
62 //! [structurally pinned fields]. After doing this, you can then create an in-place constructor via
64 //! that you need to write `<-` instead of `:` for fields that you want to initialize in-place.
74 //! struct Foo {
80 //! let foo = pin_init!(Foo {
81 //! a <- CMutex::new(42),
84 //! # let _ = Box::pin_init(foo);
87 //! `foo` now is of the type [`impl PinInit<Foo>`]. We can now use any smart pointer that we like
88 //! (or just the stack) to actually initialize a `Foo`:
98 //! # struct Foo {
104 //! # let foo = pin_init!(Foo {
105 //! # a <- CMutex::new(42),
108 //! let foo: Result<Pin<Box<Foo>>, AllocError> = Box::pin_init(foo);
142 //! fn new() -> impl PinInit<Self, Error> {
144 //! status <- CMutex::new(0),
158 //! - when the closure returns `Ok(())`, then it has completed the initialization successfully, so
160 //! - when the closure returns `Err(e)`, then the caller may deallocate the memory at `slot`, so
161 //! you need to take care to clean up anything if your initialization fails mid-way,
162 //! - you may assume that `slot` will stay pinned even after the closure returns until `drop` of
177 //! pub struct foo {
181 //! pub fn init_foo(ptr: *mut foo);
182 //! pub fn destroy_foo(ptr: *mut foo);
184 //! pub fn enable_foo(ptr: *mut foo, flags: u32) -> i32;
190 //! /// `foo` is always initialized
196 //! foo: UnsafeCell<MaybeUninit<bindings::foo>>,
200 //! pub fn new(flags: u32) -> impl PinInit<Self, i32> {
202 //! // - when the closure returns `Ok(())`, then it has successfully initialized and
203 //! // enabled `foo`,
204 //! // - when it returns `Err(e)`, then it has cleaned up before
208 //! let foo = addr_of_mut!((*slot).foo);
209 //! let foo = UnsafeCell::raw_get(foo).cast::<bindings::foo>();
211 //! // Initialize the `foo`
212 //! bindings::init_foo(foo);
215 //! let err = bindings::enable_foo(foo, flags);
217 //! // Enabling has failed, first clean up the foo and then return the error.
218 //! bindings::destroy_foo(foo);
232 //! // SAFETY: Since `foo` is initialized, destroying is safe.
233 //! unsafe { bindings::destroy_foo(self.foo.get().cast::<bindings::foo>()) };
242 //! [pinning]: https://doc.rust-lang.org/std/pin/index.html
244 //! https://doc.rust-lang.org/std/pin/index.html#pinning-is-structural-for-field
256 //! [`impl PinInit<Foo>`]: crate::PinInit
259 //! [Rust-for-Linux]: https://rust-for-linux.com/
296 /// [pin-project-lite](https://crates.io/crates/pin-project-lite).
300 /// This macro enables the use of the [`pin_init!`] macro. When pin-initializing a `struct`,
321 /// queue: CMutex<Vec<Command>>,
340 /// queue: CMutex<Vec<Command>>,
374 /// queue: CMutex<Vec<Command>>,
417 /// struct Foo {
428 /// stack_pin_init!(let foo = pin_init!(Foo {
429 /// a <- CMutex::new(42),
434 /// let foo: Pin<&mut Foo> = foo;
435 /// println!("a: {}", &*foo.a.lock());
469 /// struct Foo {
479 /// stack_try_pin_init!(let foo: Foo = try_pin_init!(Foo {
480 /// a <- CMutex::new(42),
485 /// let foo = foo.unwrap();
486 /// println!("a: {}", &*foo.a.lock());
496 /// struct Foo {
506 /// stack_try_pin_init!(let foo: Foo =? try_pin_init!(Foo {
507 /// a <- CMutex::new(42),
512 /// println!("a: {}", &*foo.a.lock());
535 /// Construct an in-place, pinned initializer for `struct`s.
546 /// struct Foo {
556 /// # fn demo() -> impl PinInit<Foo> {
559 /// let initializer = pin_init!(Foo {
577 /// # Init-functions
590 /// # struct Foo {
598 /// impl Foo {
599 /// fn new() -> impl PinInit<Self> {
610 /// Users of `Foo` can now create it like this:
617 /// # struct Foo {
625 /// # impl Foo {
626 /// # fn new() -> impl PinInit<Self> {
635 /// let foo = Box::pin_init(Foo::new());
644 /// # struct Foo {
652 /// # impl Foo {
653 /// # fn new() -> impl PinInit<Self> {
665 /// foo1: Foo,
667 /// foo2: Foo,
672 /// fn new(other: u32) -> impl PinInit<Self> {
674 /// foo1 <- Foo::new(),
675 /// foo2 <- Foo::new(),
682 /// Here we see that when using `pin_init!` with `PinInit`, one needs to write `<-` instead of `:`.
683 /// This signifies that the given field is initialized in-place. As with `struct` initializers, just
684 /// writing the field (in this case `other`) without `:` or `<-` means `other: other,`.
690 /// - Fields that you want to initialize in-place have to use `<-` instead of `:`.
691 /// - In front of the initializer you can write `&this in` to have access to a [`NonNull<Self>`]
693 /// - Using struct update syntax one can place `..Zeroable::zeroed()` at the very end of the
738 /// Construct an in-place, fallible pinned initializer for `struct`s.
766 /// fn new() -> impl PinInit<Self, Error> {
796 /// Construct an in-place initializer for `struct`s.
802 /// - `unsafe` code must guarantee either full initialization or return an error and allow
804 /// - the fields are initialized in the order given in the initializer.
805 /// - no references to fields are allowed to be created inside of the initializer.
807 /// This initializer is for initializing data in-place that might later be moved. If you want to
808 /// pin-initialize, use [`pin_init!`].
824 /// fn new() -> impl Init<Self> {
826 /// small <- zeroed(),
845 /// Construct an in-place fallible initializer for `struct`s.
853 /// - `unsafe` code must guarantee either full initialization or return an error and allow
855 /// - the fields are initialized in the order given in the initializer.
856 /// - no references to fields are allowed to be created inside of the initializer.
872 /// fn new() -> impl Init<Self, AllocError> {
939 /// struct Foo<T> {
944 /// impl<T> Foo<T> {
945 /// fn project(self: Pin<&mut Self>) -> Pin<&mut T> {
946 /// assert_pinned!(Foo<T>, elem, T, inline);
972 /// A pin-initializer for the type `T`.
985 /// - returns `Ok(())` if it initialized every field of `slot`,
986 /// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means:
987 /// - `slot` can be deallocated without UB occurring,
988 /// - `slot` does not need to be dropped,
989 /// - `slot` is not partially initialized.
990 /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`.
1008 /// - `slot` is a valid pointer to uninitialized memory.
1009 /// - the caller does not touch `slot` when `Err` is returned, they are only permitted to
1011 /// - `slot` will not move until it is dropped, i.e. it will be pinned.
1012 unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E>; in __pinned_init()
1032 fn pin_chain<F>(self, f: F) -> ChainPinInit<Self, F, T, E> in pin_chain()
1034 F: FnOnce(Pin<&mut T>) -> Result<(), E>, in pin_chain()
1044 // - returns `Ok(())` on successful initialization,
1045 // - returns `Err(err)` on error and in this case `slot` will be dropped.
1046 // - considers `slot` pinned.
1050 F: FnOnce(Pin<&mut T>) -> Result<(), E>,
1052 unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> { in __pinned_init()
1078 /// - returns `Ok(())` if it initialized every field of `slot`,
1079 /// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means:
1080 /// - `slot` can be deallocated without UB occurring,
1081 /// - `slot` does not need to be dropped,
1082 /// - `slot` is not partially initialized.
1083 /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`.
1107 /// - `slot` is a valid pointer to uninitialized memory.
1108 /// - the caller does not touch `slot` when `Err` is returned, they are only permitted to
1110 unsafe fn __init(self, slot: *mut T) -> Result<(), E>; in __init()
1123 /// struct Foo {
1127 /// impl Foo {
1129 /// println!("Setting up foo");
1133 /// let foo = init!(Foo {
1134 /// buf <- zeroed()
1135 /// }).chain(|foo| {
1136 /// foo.setup();
1140 fn chain<F>(self, f: F) -> ChainInit<Self, F, T, E> in chain()
1142 F: FnOnce(&mut T) -> Result<(), E>, in chain()
1152 // - returns `Ok(())` on successful initialization,
1153 // - returns `Err(err)` on error and in this case `slot` will be dropped.
1157 F: FnOnce(&mut T) -> Result<(), E>,
1159 unsafe fn __init(self, slot: *mut T) -> Result<(), E> { in __init()
1173 F: FnOnce(&mut T) -> Result<(), E>,
1175 unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> { in __pinned_init()
1186 /// - returns `Ok(())` if it initialized every field of `slot`,
1187 /// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means:
1188 /// - `slot` can be deallocated without UB occurring,
1189 /// - `slot` does not need to be dropped,
1190 /// - `slot` is not partially initialized.
1191 /// - may assume that the `slot` does not move if `T: !Unpin`,
1192 /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`.
1195 f: impl FnOnce(*mut T) -> Result<(), E>, in pin_init_from_closure()
1196 ) -> impl PinInit<T, E> { in pin_init_from_closure()
1205 /// - returns `Ok(())` if it initialized every field of `slot`,
1206 /// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means:
1207 /// - `slot` can be deallocated without UB occurring,
1208 /// - `slot` does not need to be dropped,
1209 /// - `slot` is not partially initialized.
1210 /// - the `slot` may move after initialization.
1211 /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`.
1214 f: impl FnOnce(*mut T) -> Result<(), E>, in init_from_closure()
1215 ) -> impl Init<T, E> { in init_from_closure()
1221 /// The initializer is a no-op. The `slot` memory is not changed.
1223 pub fn uninit<T, E>() -> impl Init<MaybeUninit<T>, E> { in uninit()
1239 mut make_init: impl FnMut(usize) -> I, in init_array_from_fn()
1240 ) -> impl Init<[T; N], E> in init_array_from_fn()
1282 mut make_init: impl FnMut(usize) -> I, in pin_init_array_from_fn()
1283 ) -> impl PinInit<[T; N], E> in pin_init_array_from_fn()
1309 // SAFETY: Every type can be initialized by-value.
1311 unsafe fn __init(self, slot: *mut T) -> Result<(), E> { in __init()
1318 // SAFETY: Every type can be initialized by-value. `__pinned_init` calls `__init`.
1320 unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> { in __pinned_init()
1334 fn write_init<E>(self, init: impl Init<T, E>) -> Result<Self::Initialized, E>; in write_init()
1336 /// Use the given pin-initializer to write a value into `self`.
1339 fn write_pin_init<E>(self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, E>; in write_pin_init()
1352 /// struct Foo {
1358 /// impl PinnedDrop for Foo {
1360 /// println!("Foo is being dropped!");
1367 /// This trait must be implemented via the [`pinned_drop`] proc-macro attribute on the impl.
1375 /// This extra parameter will be generated by the `#[pinned_drop]` proc-macro attribute
1407 pub fn zeroed<T: Zeroable>() -> impl Init<T> { in zeroed()
1436 // <https://doc.rust-lang.org/stable/nomicon/exotic-sizes.html#empty-types>. The Rust Reference
1438 // <https://doc.rust-lang.org/stable/reference/behavior-considered-undefined.html>.
1450 // <https://doc.rust-lang.org/stable/std/option/index.html#representation>).