pub struct COpaque<T> {
inner: UnsafePinned<MaybeUninit<T>>,
}Expand description
A wrapper for an opaque C object.
Some libraries like UNIX’s pthread have data types that must be treated
as entirely opaque. Soundly wrapping these types is very hard since
Rust’s operational semantics are much stricter when it comes to e.g. the
initialization state of data types and pointer aliasing. For instance, a
function like pthread_mutexattr_init might not fully initialize the
libc::pthread_mutexattr_t passed to it, so doing e.g.
let mut attr = MaybeUninit::uninit();
pthread_mutexattr_init(attr.as_mut_ptr());
let attr = attr.assume_init();is unsound. Another example: on platforms like macOS a pthread_mutex_t
cannot be moved because the implementation will dynamically align some inner
fields to a higher alignment than required by the definition. And furthermore,
some implementations (e.g. AIX) of pthread_cond_t use intrinsically linked
lists, and hence doing
pub struct Condvar(UnsafeCell<libc::pthread_cont_t>);
/* initialization and usage omitted for brevity */
impl Drop for Condvar {
fn drop(&mut self) {
unsafe { libc::pthread_cond_destroy(self.0.get()) };
}
}results in undefined behaviour (even when utilizing Pin to ensure
immovability) because the creation of the &mut Condvar passed to drop
invalidates other pointers in the linked list.
COpaque helps with avoiding all these caveats:
- it wraps the inner value in
MaybeUninitand thus is entirely oblivious of its initialization state. COpaque::gettakes aPinand thus prevents accidental moves.- it utilizes
UnsafePinnedto relax the aliasing guarantees of mutable references to theCOpaque.
The only way to access the inner value is via COpaque::get. It returns
a pointer which should be directly passed to the platform functions.
In effect, a pinned instance of this wrapper acts very much like a C variable.
Fields§
§inner: UnsafePinned<MaybeUninit<T>>Implementations§
Source§impl<T> COpaque<T>
impl<T> COpaque<T>
Sourcepub fn uninit() -> COpaque<T>
pub fn uninit() -> COpaque<T>
Creates an uninitialized C-like storage for T.
If you’d write
T var;in C, the equivalent Rust code is
Sourcepub fn zeroed() -> COpaque<T>
pub fn zeroed() -> COpaque<T>
Creates a zero-initialized C-like storage for T.
If you’d write
T var = {};in C, the equivalent Rust code is
Auto Trait Implementations§
impl<T> !Freeze for COpaque<T>
impl<T> !RefUnwindSafe for COpaque<T>
impl<T> !Unpin for COpaque<T>
impl<T> !UnsafeUnpin for COpaque<T>
impl<T> Send for COpaque<T>
impl<T> Sync for COpaque<T>
impl<T> UnwindSafe for COpaque<T>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> SizeHint for Twhere
T: ?Sized,
impl<T> SizeHint for Twhere
T: ?Sized,
Source§default fn lower_bound(&self) -> usize
default fn lower_bound(&self) -> usize
core_io_internals)[u8; 12] could return any value between 0 and
12 inclusively as a correct implementation. Read moreSource§impl<T> SizedTypeProperties for T
impl<T> SizedTypeProperties for T
Source§#[doc(hidden)]const SIZE: usize = _
#[doc(hidden)]const SIZE: usize = _
sized_type_properties)Source§#[doc(hidden)]const ALIGN: usize = _
#[doc(hidden)]const ALIGN: usize = _
sized_type_properties)Source§#[doc(hidden)]const ALIGNMENT: Alignment = _
#[doc(hidden)]const ALIGNMENT: Alignment = _
ptr_alignment_type #102070)Source§#[doc(hidden)]const IS_ZST: bool = _
#[doc(hidden)]const IS_ZST: bool = _
sized_type_properties)Source§#[doc(hidden)]const LAYOUT: Layout = _
#[doc(hidden)]const LAYOUT: Layout = _
sized_type_properties)Source§#[doc(hidden)]const MAX_SLICE_LEN: usize = _
#[doc(hidden)]const MAX_SLICE_LEN: usize = _
sized_type_properties)[Self]. Read more