pub struct WellDefinedCopyable<T: Copy + FromBytes + IntoBytes + Immutable> { /* private fields */ }Expand description
Wrapper for transferring trivially copyable data into and out of shared memory using well-defined atomic operations.
Users wrap a type T in WellDefinedCopyable<T> and use Self::update
and Self::read to copy data into and out of the contained T instance,
respectively. These methods deliberately restrict access to the underlying
storage so transfers occur through the lowest-level well-defined copy
functions.
T must implement [Copy], FromBytes, IntoBytes, and Immutable
to guarantee that it has no uninitialized padding bytes and that any byte
pattern observed during a concurrent transfer is a valid representation of
T. In addition, align_of::<T>() must be at least
MAX_TRANSFER_GRANULARITY (8 bytes) so that source and destination
buffers always share identical alignment modulo 8.
Implementations§
Source§impl<T: Copy + FromBytes + IntoBytes + Immutable> WellDefinedCopyable<T>
impl<T: Copy + FromBytes + IntoBytes + Immutable> WellDefinedCopyable<T>
Sourcepub fn read<const SYNC_OPT: u8>(&self, dst: &mut T)
pub fn read<const SYNC_OPT: u8>(&self, dst: &mut T)
Read from the wrapped object into the destination buffer provided by the caller.
Sourcepub fn update<const SYNC_OPT: u8>(&self, src: &T)
pub fn update<const SYNC_OPT: u8>(&self, src: &T)
Update the wrapped object from the source buffer provided by the caller.
Sourcepub const fn unsynchronized_get(&self) -> *const T
pub const fn unsynchronized_get(&self) -> *const T
WARNING: There be dragons here!
unsynchronized_get returns a raw pointer providing direct read-only
access to the underlying instance of T. Dereferencing the pointer is
only safe if the user can guarantee that no write operations may be
concurrently performed against the storage while reading the instance.
One example of a legitimate use of this method might be when a user is
operating in the write exclusive portion of a sequence lock. They are
guaranteed to be the only potential writer of the wrapped object, so while
it is still important that they continue to use update when they wish to
mutate their instance of T, it is OK for them to read T directly without
using read as this will not cause any undefined behavior when done
concurrently with other readers in the system.
Returning a raw pointer *const T rather than a reference &T avoids
Rust’s aliasing requirement that the pointee remain immutable for the
entire lifetime of a reference, matching C++ where holding a reference
across concurrent writes is permitted as long as it is not read during a
write.