Conversation
darkwisebear
commented
Sep 26, 2025
- Add Producer trait
- Add as_mut_ptr to SampleMaybeUninit
* Add Producer trait * Add as_mut_ptr to SampleMaybeUninit
| /// | ||
| /// The caller has to make sure to initialize the data in the buffer. | ||
| /// Reading from the received pointer before initialization is undefined behavior. | ||
| fn as_mut_ptr(&mut self) -> *mut T; |
There was a problem hiding this comment.
Which exact problem we are solving with this ? This is quite risky API since beside description, we hope user will know T may not be read really (and since as_mut_ptr is common in Rust codebases, it may be easy to miss-spot in review ).
There was a problem hiding this comment.
This enables initializing the sample pointer member-by-member. It becomes important in cases where you want your produce to put the result directly into the shared memory area without first having to initialize a local instance of the type T.
This becomes important when we're talking about really big data structures. In this case, you might either not have (or want to spend) the memory to build the type internally, and copying itself also may take a non-negligible amount of time. In order to safe this, one might want to create an uninitialized sample, use this method to obtain a pointer, and then initialize the type piece by piece by write-only accesses. Since we hand back a pointer, this method can even be safe since working with a pointer is unsafe anyway.
There was a problem hiding this comment.
Yes this is placement new missing in API. So I would say we have two use case
- default placement init for large types
- non default placement init for large types (ie data comming from some other entity ie, hw or cpp code)
For the first I would try standarize approach ie:
pub trait PlacementDef {
unsafe fn placement_def(ptr: *mut Self);
}
and then in SampleMutUninit
fn write_in_place<T: PlacementDef>(&mut self) {
unsafe {
T::placement_def(ptr);
}
}
For the second, since it mimics MaybeUnint api with as_mut_ptr, it shall be fine. But maybe, the SampleMutUninit<T> shall really hold(mandate) MaybeUninit<T> instead and our api shall return ref to it ie, fn data(&mut self) -> &MaybeUninit<T>. From this point, user will get other abilities.