File tree 2 files changed +29
-0
lines changed
2 files changed +29
-0
lines changed Original file line number Diff line number Diff line change 177
177
//! }
178
178
//! ```
179
179
//!
180
+ //! For the special case where initializing a field is a single FFI-function call that cannot fail,
181
+ //! there exist the helper function [`Opaque::ffi_init`]. This function initialize a single
182
+ //! [`Opaque`] field by just delegating to the supplied closure. You can use these in combination
183
+ //! with [`pin_init!`].
184
+ //!
185
+ //! For more information on how to use [`pin_init_from_closure()`], take a look at the uses inside
186
+ //! the `kernel` crate. The [`sync`] module is a good starting point.
187
+ //!
180
188
//! [`sync`]: kernel::sync
181
189
//! [pinning]: https://doc.rust-lang.org/std/pin/index.html
182
190
//! [structurally pinned fields]:
187
195
//! [`impl PinInit<T, E>`]: PinInit
188
196
//! [`impl Init<T, E>`]: Init
189
197
//! [`Opaque`]: kernel::types::Opaque
198
+ //! [`Opaque::ffi_init`]: kernel::types::Opaque::ffi_init
190
199
//! [`pin_data`]: ::macros::pin_data
191
200
192
201
use crate :: {
Original file line number Diff line number Diff line change 2
2
3
3
//! Kernel types.
4
4
5
+ use crate :: init:: { self , PinInit } ;
5
6
use alloc:: boxed:: Box ;
6
7
use core:: {
7
8
cell:: UnsafeCell ,
@@ -234,6 +235,25 @@ impl<T> Opaque<T> {
234
235
Self ( MaybeUninit :: uninit ( ) )
235
236
}
236
237
238
+ /// Creates a pin-initializer from the given initializer closure.
239
+ ///
240
+ /// The returned initializer calls the given closure with the pointer to the inner `T` of this
241
+ /// `Opaque`. Since this memory is uninitialized, the closure is not allowed to read from it.
242
+ ///
243
+ /// This function is safe, because the `T` inside of an `Opaque` is allowed to be
244
+ /// uninitialized. Additionally, access to the inner `T` requires `unsafe`, so the caller needs
245
+ /// to verify at that point that the inner value is valid.
246
+ pub fn ffi_init ( init_func : impl FnOnce ( * mut T ) ) -> impl PinInit < Self > {
247
+ // SAFETY: We contain a `MaybeUninit`, so it is OK for the `init_func` to not fully
248
+ // initialize the `T`.
249
+ unsafe {
250
+ init:: pin_init_from_closure :: < _ , :: core:: convert:: Infallible > ( move |slot| {
251
+ init_func ( Self :: raw_get ( slot) ) ;
252
+ Ok ( ( ) )
253
+ } )
254
+ }
255
+ }
256
+
237
257
/// Returns a raw pointer to the opaque data.
238
258
pub fn get ( & self ) -> * mut T {
239
259
UnsafeCell :: raw_get ( self . 0 . as_ptr ( ) )
You can’t perform that action at this time.
0 commit comments