pub struct NonPersistent<T: ?Sized>(/* private fields */);Expand description
Smart pointer around a nonpersistent allocation of T.
Rustmex marks all heap allocations as persistent — for most allocations, we want to be the only owner of the data. We know how to free the memory of our types, and will do so when we’re done with it; we don’t need Matlab’s help.
But there are some circumstances where we can’t, and thus where a nonpersistent allocation is required: for instance with divergent MEX API functions. If you need to pass some data to such a function which is dynamic and must be behind a pointer, you can use this type.
It is specifically meant to work with those API functions; it is not a general usage
smart pointer. To make it slightly less of a footcannon, it implements some guardrails
(such as Drop in case the function is conditionally divergent, or if you forgot to
pass it into one you wont leak memory) — but it remains a footgun nonentheless.
A footgun it is, as alluded to, because it fundamentally does not comply with the
basic principles of safe Rust code, i.e. there can be only one owner of the data. With
NonPersistent, you now share ownership with Matlab’s garbage collector — which,
since it does not know about you, may pull the rug out from underneath you at any
point (especially if you persist the object after MexFunction returns). Maybe not
such a footgun, but more of a ticking time bomb. All constructor methods are therefore
marked as unsafe; you must understand that memory safety is now up to you to uphold.
To make it somewhat ergonomic to work with, it implements a basic set of traits (PartialEq, Display, AsRef, etc) by forwarding those to the inner types. It’s basically a meager Box.
It is also Send and Sync if the inner types are. While this has can be used to hold on
to the NonPersistent longer than the lifetime of the MexFunction, it is not per
se memory unsafe.
In short: only use for good, and only when absolutely required.
Implementations§
Source§impl<T> NonPersistent<T>
impl<T> NonPersistent<T>
Source§impl<T: Copy> NonPersistent<T>
impl<T: Copy> NonPersistent<T>
Sourcepub fn inner(np: NonPersistent<T>) -> T
pub fn inner(np: NonPersistent<T>) -> T
Return the inner value, and free the allocation
Source§impl NonPersistent<[u8]>
impl NonPersistent<[u8]>
Sourcepub unsafe fn from_stringish<B: AsRef<[u8]>>(b: B, append_null: bool) -> Self
pub unsafe fn from_stringish<B: AsRef<[u8]>>(b: B, append_null: bool) -> Self
Construct a NonPersistent byte buffer from stringish types, optionally
with a nul byte terminator.
Some MEX API functions expect a C string, while most of rust works with string
slices. Instead of copying to a CString first (to add the nul terminator),
directly copy into a nonpersistent buffer, eliding one copy.
Note that this function provides fewer guarantees than CString does.
Source§impl<T: ?Sized> NonPersistent<T>
impl<T: ?Sized> NonPersistent<T>
Sourcepub unsafe fn ptr(np: &NonPersistent<T>) -> *const T
pub unsafe fn ptr(np: &NonPersistent<T>) -> *const T
Get the inner pointer for communication with the MEX api. Marked as unsafe since the pointer may be used to create an alias to the data, so the invariants assumed by Send and Sync no longer hold.
Sourcepub unsafe fn mut_ptr(np: &mut NonPersistent<T>) -> *mut T
pub unsafe fn mut_ptr(np: &mut NonPersistent<T>) -> *mut T
Get the inner pointer as mutable for communcation with the MEX api. Marked as unsafe since the pointer may be used to create an alias to the data, so the invariants assumed by Send and Sync no longer hold.
Sourcepub fn persist(np: NonPersistent<T>) -> Box<T>
pub fn persist(np: NonPersistent<T>) -> Box<T>
Persist the current allocation by turning it into a “normal” box.
This does not copy the allocation, since there is a function to mark an allocation as persistent (but not the other way around).