Struct lignin::callback_registry::CallbackRegistration [−][src]
pub struct CallbackRegistration<R, C> where
C: CallbackSignature, { /* fields omitted */ }
A callback registration handle that should be held onto by the matching receiver R
or a container with pin-projection towards that value.
CallbackRegistration
is !Unpin
for convenience: A receiver correctly becomes !Unpin
if it contains for example a Cell<Option<CallbackRegistration<R, T>>
¹⁻², which can be conveniently initialized in a rendering function called with Pin<&…>
argument.
To hold onto a CallbackRegistration
without boxing or pinning, use a newtype wrapper with explicit Unpin
implementation.
Safety Notes
When storing CallbackRegistration
s inside a receiver, care must be taken that these fields are dropped first, before any other component state is invalidated.
This should in most cases be done by placing them in the first fields of the receiver data structure.
Code generators that must run more complex code but also want to avoid any overhead from clearing an Option
can make use of ManuallyDrop
.
However, this is somewhat more tricky to get right and much less easy to read, so I wouldn’t recommend it for one-off code.
Double-dropping a CallbackRegistration
will lead to, at best, a panic, but retrieving a CallbackRef
from a dropped CallbackRegistration
is guaranteed be sound.
Such a CallbackRef
will never lead to a handler invocation unless the callback registry is reset.
receiver
pointer
It is impossible to soundly derive a &mut R
from the *const R
, as this pointer was originally derived from a shared reference.
Similarly, no &mut R
for the given instance may be created or mutably re-borrowed elsewhere in the program, by whatever means,
between the call to any CallbackRegistration::new
and dereferencing receiver
in handler
,
as doing so would invalidate all sibling references and pointers.
(Avoiding this situation dynamically is sound.)
To still update values, use atomics, cells or, if necessary, critical sections.
Implementations
impl<R> CallbackRegistration<R, fn(event: Event)>
[src]
impl<R> CallbackRegistration<R, fn(event: Event)>
[src]Separate impl
s due to Rust language limitation. See CallbackSignature
and expect future broadening.
#[must_use]pub fn new(
receiver: Pin<&R>,
handler: fn(receiver: *const R, event: Event)
) -> Self
[src]
receiver: Pin<&R>,
handler: fn(receiver: *const R, event: Event)
) -> Self
Creates a new CallbackRegistration<R, T>
with the given receiver
and handler
.
Deadlocks / Panics
Creating or dropping any CallbackRegistration
from within handler
may deadlock or panic.
This happens due to read-to-write re-entrance of the single internal callback registry
RwLock
, but this constraint may be relaxed somewhat in the future.File an issue or open a discussion with your use case if you would benefit from that, so that I can better prioritize.
Use callback_registry::when_unlocked_locally
to defer any such operations where necessary.
Safety
The receiver
pointer given to handler
may dangle unless receiver
remains pinned until the created CallbackRegistration
is dropped.
You can ensure this most easily by storing the latter in for example a Cell<Option<CallbackRegistration>>
embedded in the receiver
.
Dropping the CallbackRegistration
instance prevents any further calls to handler
derived from it from running, blocking until this can be guaranteed.
impl<R, T> CallbackRegistration<R, fn(dom_ref: DomRef<&T>)>
[src]
impl<R, T> CallbackRegistration<R, fn(dom_ref: DomRef<&T>)>
[src]Separate impl
s due to Rust language limitation. See CallbackSignature
and expect future broadening.
#[must_use]pub fn new(
receiver: Pin<&R>,
handler: fn(receiver: *const R, dom_ref: DomRef<&T>)
) -> Self
[src]
receiver: Pin<&R>,
handler: fn(receiver: *const R, dom_ref: DomRef<&T>)
) -> Self
Creates a new CallbackRegistration<R, T>
with the given receiver
and handler
.
Deadlocks / Panics
Creating or dropping any CallbackRegistration
from within handler
may deadlock or panic.
This happens due to read-to-write re-entrance of the single internal callback registry
RwLock
, but this constraint may be relaxed somewhat in the future.File an issue or open a discussion with your use case if you would benefit from that, so that I can better prioritize.
Use callback_registry::when_unlocked_locally
to defer any such operations where necessary.
Safety
The receiver
pointer given to handler
may dangle unless receiver
remains pinned until the created CallbackRegistration
is dropped.
You can ensure this most easily by storing the latter in for example a Cell<Option<CallbackRegistration>>
embedded in the receiver
.
Dropping the CallbackRegistration
instance prevents any further calls to handler
derived from it from running, blocking until this can be guaranteed.
impl<R, C> CallbackRegistration<R, C> where
C: CallbackSignature,
[src]
impl<R, C> CallbackRegistration<R, C> where
C: CallbackSignature,
[src]#[must_use]pub fn to_ref_thread_bound(&self) -> CallbackRef<ThreadBound, C>
[src]
Creates a ThreadBound
CallbackRef
from this CallbackRegistration
.
impl<R, C> CallbackRegistration<R, C> where
R: Sync,
C: CallbackSignature,
[src]
impl<R, C> CallbackRegistration<R, C> where
R: Sync,
C: CallbackSignature,
[src]#[must_use]pub fn to_ref(&self) -> CallbackRef<ThreadSafe, C>
[src]
Creates a ThreadSafe
CallbackRef
from this CallbackRegistration
.
If you are developing a macro framework with
ThreadSafety
inference, seeToRefThreadBoundFallback
for a way to overload this method appropriately.
(See also the warning there.)For handwritten code or generated code with stricter thread-safety, please use
.to_ref_thread_bound()
instead whenever possible.
pub unsafe fn leak(self)
[src]
Destroys a CallbackRegistration
instance without running its destructor.
Safety
Calling this method is technically always sound due to the soundness requirements on CallbackRegistration::new
.
It is still marked as unsafe
since it has far-reaching implications regarding the validity guarantees of the receiver
pointers given to CallbackRegistration::new
’s handler
parameter.
Trait Implementations
impl<R: Debug, C: Debug> Debug for CallbackRegistration<R, C> where
C: CallbackSignature,
[src]
impl<R: Debug, C: Debug> Debug for CallbackRegistration<R, C> where
C: CallbackSignature,
[src]impl<R, C> Drop for CallbackRegistration<R, C> where
C: CallbackSignature,
[src]
impl<R, C> Drop for CallbackRegistration<R, C> where
C: CallbackSignature,
[src]impl<R, C> From<&'_ CallbackRegistration<R, C>> for CallbackRef<ThreadSafe, C> where
R: Sync,
C: CallbackSignature,
[src]
impl<R, C> From<&'_ CallbackRegistration<R, C>> for CallbackRef<ThreadSafe, C> where
R: Sync,
C: CallbackSignature,
[src]fn from(registration: &CallbackRegistration<R, C>) -> Self
[src]
impl<R, C> From<&'_ CallbackRegistration<R, C>> for CallbackRef<ThreadBound, C> where
C: CallbackSignature,
[src]
impl<R, C> From<&'_ CallbackRegistration<R, C>> for CallbackRef<ThreadBound, C> where
C: CallbackSignature,
[src]fn from(registration: &CallbackRegistration<R, C>) -> Self
[src]
impl<R, C> Send for CallbackRegistration<R, C> where
R: Sync,
C: CallbackSignature,
[src]
impl<R, C> Send for CallbackRegistration<R, C> where
R: Sync,
C: CallbackSignature,
[src]impl<R, C> Sync for CallbackRegistration<R, C> where
R: Sync,
C: CallbackSignature,
[src]
impl<R, C> Sync for CallbackRegistration<R, C> where
R: Sync,
C: CallbackSignature,
[src]impl<R, C> ToRefThreadBoundFallback<C> for CallbackRegistration<R, C> where
C: CallbackSignature,
[src]
impl<R, C> ToRefThreadBoundFallback<C> for CallbackRegistration<R, C> where
C: CallbackSignature,
[src]fn to_ref(&self) -> CallbackRef<ThreadBound, C>
[src]
Auto Trait Implementations
impl<R, C> RefUnwindSafe for CallbackRegistration<R, C> where
C: RefUnwindSafe,
R: RefUnwindSafe,
impl<R, C> RefUnwindSafe for CallbackRegistration<R, C> where
C: RefUnwindSafe,
R: RefUnwindSafe,
impl<R, C> !Unpin for CallbackRegistration<R, C>
impl<R, C> !Unpin for CallbackRegistration<R, C>
impl<R, C> UnwindSafe for CallbackRegistration<R, C> where
C: UnwindSafe,
R: RefUnwindSafe,
impl<R, C> UnwindSafe for CallbackRegistration<R, C> where
C: UnwindSafe,
R: RefUnwindSafe,