Lines Matching +full:foo +full:- +full:supply

1 // SPDX-License-Identifier: Apache-2.0 OR MIT
3 //! API to safely and fallibly initialize pinned `struct`s using in-place constructors.
5 //! It also allows in-place initialization of big `struct`s that would otherwise produce a stack
8 //! Most `struct`s from the [`sync`] module need to be pinned, because they contain self-referential
13 //! To initialize a `struct` with an in-place constructor you will need two things:
14 //! - an in-place constructor,
15 //! - a memory location that can hold your `struct` (this can be the [stack], an [`Arc<T>`],
18 //! To get an in-place constructor there are generally three options:
19 //! - directly creating an in-place constructor using the [`pin_init!`] macro,
20 //! - a custom function/macro returning an in-place constructor provided by someone else,
21 //! - using the unsafe function [`pin_init_from_closure()`] to manually create an initializer.
23 //! Aside from pinned initialization, this API also supports in-place construction without pinning,
33 //! [structurally pinned fields]. After doing this, you can then create an in-place constructor via
35 //! that you need to write `<-` instead of `:` for fields that you want to initialize in-place.
42 //! struct Foo {
48 //! let foo = pin_init!(Foo {
49 //! a <- new_mutex!(42, "Foo::a"),
54 //! `foo` now is of the type [`impl PinInit<Foo>`]. We can now use any smart pointer that we like
55 //! (or just the stack) to actually initialize a `Foo`:
62 //! # struct Foo {
67 //! # let foo = pin_init!(Foo {
68 //! # a <- new_mutex!(42, "Foo::a"),
71 //! let foo: Result<Pin<Box<Foo>>> = Box::pin_init(foo, GFP_KERNEL);
78 //! Many types from the kernel supply a function/macro that returns an initializer, because the
100 //! fn new() -> impl PinInit<Self, Error> {
102 //! status <- new_mutex!(0, "DriverData::status"),
116 //! - when the closure returns `Ok(())`, then it has completed the initialization successfully, so
118 //! - when the closure returns `Err(e)`, then the caller may deallocate the memory at `slot`, so
119 //! you need to take care to clean up anything if your initialization fails mid-way,
120 //! - you may assume that `slot` will stay pinned even after the closure returns until `drop` of
129 //! # pub struct foo;
130 //! # pub unsafe fn init_foo(_ptr: *mut foo) {}
131 //! # pub unsafe fn destroy_foo(_ptr: *mut foo) {}
132 //! # pub unsafe fn enable_foo(_ptr: *mut foo, _flags: u32) -> i32 { 0 }
136 //! # fn from_errno(errno: core::ffi::c_int) -> Error {
144 //! /// `foo` is always initialized
148 //! foo: Opaque<bindings::foo>,
154 //! pub fn new(flags: u32) -> impl PinInit<Self, Error> {
156 //! // - when the closure returns `Ok(())`, then it has successfully initialized and
157 //! // enabled `foo`,
158 //! // - when it returns `Err(e)`, then it has cleaned up before
162 //! let foo = addr_of_mut!((*slot).foo);
164 //! // Initialize the `foo`
165 //! bindings::init_foo(Opaque::raw_get(foo));
168 //! let err = bindings::enable_foo(Opaque::raw_get(foo), flags);
170 //! // Enabling has failed, first clean up the foo and then return the error.
171 //! bindings::destroy_foo(Opaque::raw_get(foo));
185 //! // SAFETY: Since `foo` is initialized, destroying is safe.
186 //! unsafe { bindings::destroy_foo(self.foo.get()) };
191 //! For the special case where initializing a field is a single FFI-function call that cannot fail,
200 //! [pinning]: https://doc.rust-lang.org/std/pin/index.html
202 //! https://doc.rust-lang.org/std/pin/index.html#pinning-is-structural-for-field
205 //! [`impl PinInit<Foo>`]: PinInit
245 /// struct Foo {
256 /// stack_pin_init!(let foo = pin_init!(Foo {
257 /// a <- new_mutex!(42),
262 /// let foo: Pin<&mut Foo> = foo;
263 /// pr_info!("a: {}", &*foo.a.lock());
298 /// struct Foo {
308 /// stack_try_pin_init!(let foo: Result<Pin<&mut Foo>, AllocError> = pin_init!(Foo {
309 /// a <- new_mutex!(42),
314 /// let foo = foo.unwrap();
315 /// pr_info!("a: {}", &*foo.a.lock());
324 /// struct Foo {
334 /// stack_try_pin_init!(let foo: Pin<&mut Foo> =? pin_init!(Foo {
335 /// a <- new_mutex!(42),
340 /// pr_info!("a: {}", &*foo.a.lock());
363 /// Construct an in-place, pinned initializer for `struct`s.
375 /// struct Foo {
385 /// # fn demo() -> impl PinInit<Foo> {
388 /// let initializer = pin_init!(Foo {
406 /// # Init-functions
420 /// # struct Foo {
428 /// impl Foo {
429 /// fn new() -> impl PinInit<Self> {
440 /// Users of `Foo` can now create it like this:
447 /// # struct Foo {
455 /// # impl Foo {
456 /// # fn new() -> impl PinInit<Self> {
465 /// let foo = Box::pin_init(Foo::new(), GFP_KERNEL);
475 /// # struct Foo {
483 /// # impl Foo {
484 /// # fn new() -> impl PinInit<Self> {
496 /// foo1: Foo,
498 /// foo2: Foo,
503 /// fn new(other: u32) -> impl PinInit<Self> {
505 /// foo1 <- Foo::new(),
506 /// foo2 <- Foo::new(),
513 /// Here we see that when using `pin_init!` with `PinInit`, one needs to write `<-` instead of `:`.
514 /// This signifies that the given field is initialized in-place. As with `struct` initializers, just
515 /// writing the field (in this case `other`) without `:` or `<-` means `other: other,`.
521 /// - Fields that you want to initialize in-place have to use `<-` instead of `:`.
522 /// - In front of the initializer you can write `&this in` to have access to a [`NonNull<Self>`]
524 /// - Using struct update syntax one can place `..Zeroable::zeroed()` at the very end of the
575 /// Construct an in-place, fallible pinned initializer for `struct`s.
603 /// fn new() -> impl PinInit<Self, Error> {
646 /// Construct an in-place initializer for `struct`s.
652 /// - `unsafe` code must guarantee either full initialization or return an error and allow
654 /// - the fields are initialized in the order given in the initializer.
655 /// - no references to fields are allowed to be created inside of the initializer.
657 /// This initializer is for initializing data in-place that might later be moved. If you want to
658 /// pin-initialize, use [`pin_init!`].
681 /// Construct an in-place fallible initializer for `struct`s.
689 /// - `unsafe` code must guarantee either full initialization or return an error and allow
691 /// - the fields are initialized in the order given in the initializer.
692 /// - no references to fields are allowed to be created inside of the initializer.
704 /// fn new() -> impl Init<Self, Error> {
781 /// struct Foo<T> {
786 /// impl<T> Foo<T> {
787 /// fn project(self: Pin<&mut Self>) -> Pin<&mut T> {
788 /// assert_pinned!(Foo<T>, elem, T, inline);
814 /// A pin-initializer for the type `T`.
828 /// - returns `Ok(())` if it initialized every field of `slot`,
829 /// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means:
830 /// - `slot` can be deallocated without UB occurring,
831 /// - `slot` does not need to be dropped,
832 /// - `slot` is not partially initialized.
833 /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`.
843 /// - `slot` is a valid pointer to uninitialized memory.
844 /// - the caller does not touch `slot` when `Err` is returned, they are only permitted to
846 /// - `slot` will not move until it is dropped, i.e. it will be pinned.
847 unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E>; in __pinned_init()
866 /// struct Foo {
871 /// impl Foo {
873 /// pr_info!("Setting up foo");
877 /// let foo = pin_init!(Foo {
878 /// raw <- unsafe {
883 /// }).pin_chain(|foo| {
884 /// foo.setup();
888 fn pin_chain<F>(self, f: F) -> ChainPinInit<Self, F, T, E> in pin_chain()
890 F: FnOnce(Pin<&mut T>) -> Result<(), E>, in pin_chain()
900 // - returns `Ok(())` on successful initialization,
901 // - returns `Err(err)` on error and in this case `slot` will be dropped.
902 // - considers `slot` pinned.
906 F: FnOnce(Pin<&mut T>) -> Result<(), E>,
908 unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> { in __pinned_init()
935 /// - returns `Ok(())` if it initialized every field of `slot`,
936 /// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means:
937 /// - `slot` can be deallocated without UB occurring,
938 /// - `slot` does not need to be dropped,
939 /// - `slot` is not partially initialized.
940 /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`.
955 /// - `slot` is a valid pointer to uninitialized memory.
956 /// - the caller does not touch `slot` when `Err` is returned, they are only permitted to
958 unsafe fn __init(self, slot: *mut T) -> Result<(), E>; in __init()
970 /// struct Foo {
974 /// impl Foo {
976 /// pr_info!("Setting up foo");
980 /// let foo = init!(Foo {
981 /// buf <- init::zeroed()
982 /// }).chain(|foo| {
983 /// foo.setup();
987 fn chain<F>(self, f: F) -> ChainInit<Self, F, T, E> in chain()
989 F: FnOnce(&mut T) -> Result<(), E>, in chain()
999 // - returns `Ok(())` on successful initialization,
1000 // - returns `Err(err)` on error and in this case `slot` will be dropped.
1004 F: FnOnce(&mut T) -> Result<(), E>,
1006 unsafe fn __init(self, slot: *mut T) -> Result<(), E> { in __init()
1020 F: FnOnce(&mut T) -> Result<(), E>,
1022 unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> { in __pinned_init()
1033 /// - returns `Ok(())` if it initialized every field of `slot`,
1034 /// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means:
1035 /// - `slot` can be deallocated without UB occurring,
1036 /// - `slot` does not need to be dropped,
1037 /// - `slot` is not partially initialized.
1038 /// - may assume that the `slot` does not move if `T: !Unpin`,
1039 /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`.
1042 f: impl FnOnce(*mut T) -> Result<(), E>, in pin_init_from_closure()
1043 ) -> impl PinInit<T, E> { in pin_init_from_closure()
1052 /// - returns `Ok(())` if it initialized every field of `slot`,
1053 /// - returns `Err(err)` if it encountered an error and then cleaned `slot`, this means:
1054 /// - `slot` can be deallocated without UB occurring,
1055 /// - `slot` does not need to be dropped,
1056 /// - `slot` is not partially initialized.
1057 /// - the `slot` may move after initialization.
1058 /// - while constructing the `T` at `slot` it upholds the pinning invariants of `T`.
1061 f: impl FnOnce(*mut T) -> Result<(), E>, in init_from_closure()
1062 ) -> impl Init<T, E> { in init_from_closure()
1068 /// The initializer is a no-op. The `slot` memory is not changed.
1070 pub fn uninit<T, E>() -> impl Init<MaybeUninit<T>, E> { in uninit()
1085 mut make_init: impl FnMut(usize) -> I, in init_array_from_fn()
1086 ) -> impl Init<[T; N], E> in init_array_from_fn()
1129 mut make_init: impl FnMut(usize) -> I, in pin_init_array_from_fn()
1130 ) -> impl PinInit<[T; N], E> in pin_init_array_from_fn()
1162 // SAFETY: Every type can be initialized by-value.
1164 unsafe fn __init(self, slot: *mut T) -> Result<(), E> { in __init()
1170 // SAFETY: Every type can be initialized by-value. `__pinned_init` calls `__init`.
1172 unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> { in __pinned_init()
1177 /// Smart pointer that can initialize memory in-place.
1185 /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this
1189 fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Self::PinnedSelf, E> in try_pin_init()
1193 /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this
1197 fn pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> error::Result<Self::PinnedSelf> in pin_init()
1208 /// Use the given initializer to in-place initialize a `T`.
1209 fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E> in try_init()
1213 /// Use the given initializer to in-place initialize a `T`.
1214 fn init<E>(init: impl Init<T, E>, flags: Flags) -> error::Result<Self> in init()
1230 fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Self::PinnedSelf, E> in try_pin_init()
1238 fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E> in try_init()
1250 fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Self::PinnedSelf, E> in try_pin_init()
1258 fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E> in try_init()
1270 fn try_pin_init<E>(init: impl PinInit<T, E>, flags: Flags) -> Result<Self::PinnedSelf, E> in try_pin_init()
1278 fn try_init<E>(init: impl Init<T, E>, flags: Flags) -> Result<Self, E> in try_init()
1294 fn write_init<E>(self, init: impl Init<T, E>) -> Result<Self::Initialized, E>; in write_init()
1296 /// Use the given pin-initializer to write a value into `self`.
1299 fn write_pin_init<E>(self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, E>; in write_pin_init()
1305 fn write_init<E>(mut self, init: impl Init<T, E>) -> Result<Self::Initialized, E> { in write_init()
1314 fn write_pin_init<E>(mut self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, E> { in write_pin_init()
1327 fn write_init<E>(mut self, init: impl Init<T, E>) -> Result<Self::Initialized, E> { in write_init()
1336 fn write_pin_init<E>(mut self, init: impl PinInit<T, E>) -> Result<Pin<Self::Initialized>, E> { in write_pin_init()
1355 /// struct Foo {
1361 /// impl PinnedDrop for Foo {
1363 /// pr_info!("Foo is being dropped!");
1370 /// This trait must be implemented via the [`pinned_drop`] proc-macro attribute on the impl.
1380 /// This extra parameter will be generated by the `#[pinned_drop]` proc-macro attribute
1401 pub fn zeroed<T: Zeroable>() -> impl Init<T> { in zeroed()
1429 // <https://doc.rust-lang.org/stable/nomicon/exotic-sizes.html#empty-types>. The Rust Reference
1431 // <https://doc.rust-lang.org/stable/reference/behavior-considered-undefined.html>.