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

1 [![Crates.io](https://img.shields.io/crates/v/pin-init.svg)](https://crates.io/crates/pin-init)
2 [![Documentation](https://docs.rs/pin-init/badge.svg)](https://docs.rs/pin-init/)
3 [![Dependency status](https://deps.rs/repo/github/Rust-for-Linux/pin-init/status.svg)](https://deps.rs/repo/github/Rust-for-Linux/pin-init)
4 ![License](https://img.shields.io/crates/l/pin-init)
5 [![Toolchain](https://img.shields.io/badge/toolchain-nightly-red)](#nightly-only)
6 ![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/Rust-for-Linux/pin-init/test.yml)
7 # `pin-init`
11 > This crate was originally named [`pinned-init`], but the migration to
12 > `pin-init` is not yet complete. The `legcay` branch contains the current
13 > version of the `pinned-init` crate & the `main` branch already incorporates
14 > the rename to `pin-init`.
19 [`pinned-init`]: https://crates.io/crates/pinned-init
21 <!-- cargo-rdme start -->
23 Library to safely and fallibly initialize pinned `struct`s using in-place constructors.
27 It also allows in-place initialization of big `struct`s that would otherwise produce a stack
30 This library's main use-case is in [Rust-for-Linux]. Although this version can be used
33 There are cases when you want to in-place initialize a struct. For example when it is very big
38 <https://rust-for-linux.com/the-safe-pinned-initialization-problem>.
40 This library allows you to do in-place initialization safely.
48 [`allocator_api` unstable feature]: https://doc.rust-lang.org/nightly/unstable-book/library-features/allocator-api.html
50 The feature is enabled by default, thus by default `pin-init` will require a nightly compiler.
52 will require the `std` feature, because stable compilers have neither `Box` nor `Arc` in no-std
55 ### Nightly needed for `unsafe-pinned` feature
58 This requires the [`unsafe_pinned` unstable feature](https://github.com/rust-lang/rust/issues/125735)
63 To initialize a `struct` with an in-place constructor you will need two things:
64 - an in-place constructor,
65 - a memory location that can hold your `struct` (this can be the [stack], an [`Arc<T>`],
68 To get an in-place constructor there are generally three options:
69 - directly creating an in-place constructor using the [`pin_init!`] macro,
70 - a custom function/macro returning an in-place constructor provided by someone else,
71 - using the unsafe function [`pin_init_from_closure()`] to manually create an initializer.
73 Aside from pinned initialization, this library also supports in-place construction without
88 [structurally pinned fields]. After doing this, you can then create an in-place constructor via
90 that you need to write `<-` instead of `:` for fields that you want to initialize in-place.
96 struct Foo {
102 let foo = pin_init!(Foo {
103 a <- CMutex::new(42),
108 `foo` now is of the type [`impl PinInit<Foo>`]. We can now use any smart pointer that we like
109 (or just the stack) to actually initialize a `Foo`:
112 let foo: Result<Pin<Box<Foo>>, AllocError> = Box::pin_init(foo);
119 Many types that use this library supply a function/macro that returns an initializer, because
137 fn new() -> impl PinInit<Self, Error> {
139 status <- CMutex::new(0),
153 - when the closure returns `Ok(())`, then it has completed the initialization successfully, so
155 - when the closure returns `Err(e)`, then the caller may deallocate the memory at `slot`, so
156 you need to take care to clean up anything if your initialization fails mid-way,
157 - you may assume that `slot` will stay pinned even after the closure returns until `drop` of
171 pub struct foo {
175 pub fn init_foo(ptr: *mut foo);
176 pub fn destroy_foo(ptr: *mut foo);
178 pub fn enable_foo(ptr: *mut foo, flags: u32) -> i32;
184 /// `foo` is always initialized
190 foo: UnsafeCell<MaybeUninit<bindings::foo>>,
194 pub fn new(flags: u32) -> impl PinInit<Self, i32> {
196 // - when the closure returns `Ok(())`, then it has successfully initialized and
197 // enabled `foo`,
198 // - when it returns `Err(e)`, then it has cleaned up before
202 let foo = addr_of_mut!((*slot).foo);
203 let foo = UnsafeCell::raw_get(foo).cast::<bindings::foo>();
205 // Initialize the `foo`
206 bindings::init_foo(foo);
209 let err = bindings::enable_foo(foo, flags);
211 // Enabling has failed, first clean up the foo and then return the error.
212 bindings::destroy_foo(foo);
226 // SAFETY: Since `foo` is initialized, destroying is safe.
227 unsafe { bindings::destroy_foo(self.foo.get().cast::<bindings::foo>()) };
236 [pinning]: https://doc.rust-lang.org/std/pin/index.html
237 [structurally pinned fields]: https://doc.rust-lang.org/std/pin/index.html#projections-and-structural-pinning
238 [stack]: https://docs.rs/pin-init/latest/pin_init/macro.stack_pin_init.html
239 [`impl PinInit<Foo>`]: https://docs.rs/pin-init/latest/pin_init/trait.PinInit.html
240 [`impl PinInit<T, E>`]: https://docs.rs/pin-init/latest/pin_init/trait.PinInit.html
241 [`impl Init<T, E>`]: https://docs.rs/pin-init/latest/pin_init/trait.Init.html
242 [Rust-for-Linux]: https://rust-for-linux.com/
244 <!-- cargo-rdme end -->
246 <!-- These links are not picked up by cargo-rdme, since they are behind cfgs... -->
247 [`Arc<T>`]: https://doc.rust-lang.org/stable/alloc/sync/struct.Arc.html
248 [`Box<T>`]: https://doc.rust-lang.org/stable/alloc/boxed/struct.Box.html