Struct lignin::callback_registry::CallbackRegistration[][src]

pub struct CallbackRegistration<R, C> where
    C: CallbackSignature
{ /* fields omitted */ }
Expand description

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.


  1. impl<T: ?Sized> Unpin for Cell<T> where T: Unpin
  2. impl<T> Unpin for Option<T> where T: Unpin

Safety Notes

When storing CallbackRegistrations 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]

Separate impls 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]

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]

Separate impls 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]

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
    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, see ToRefThreadBoundFallback 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]

fn fmt(&self, f: &mut Formatter<'_>) -> Result[src]

Formats the value using the given formatter. Read more

impl<R, C> Drop for CallbackRegistration<R, C> where
    C: CallbackSignature
[src]

fn drop(&mut self)[src]

Executes the destructor for this type. Read more

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]

Performs the conversion.

impl<R, C> From<&'_ CallbackRegistration<R, C>> for CallbackRef<ThreadBound, C> where
    C: CallbackSignature
[src]

fn from(registration: &CallbackRegistration<R, C>) -> Self[src]

Performs the conversion.

impl<R, C> ToRefThreadBoundFallback<C> for CallbackRegistration<R, C> where
    C: CallbackSignature
[src]

fn to_ref(&self) -> CallbackRef<ThreadBound, C>[src]

See CallbackRegistration::to_ref, except that this method is unconstrained and that the resulting CallbackRef is ThreadBound.

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]

Auto Trait Implementations

impl<R, C> RefUnwindSafe for CallbackRegistration<R, C> where
    C: RefUnwindSafe,
    R: RefUnwindSafe

impl<R, C> !Unpin for CallbackRegistration<R, C>

impl<R, C> UnwindSafe for CallbackRegistration<R, C> where
    C: UnwindSafe,
    R: RefUnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

pub fn type_id(&self) -> TypeId[src]

Gets the TypeId of self. Read more

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

pub fn borrow(&self) -> &T[src]

Immutably borrows from an owned value. Read more

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

pub fn borrow_mut(&mut self) -> &mut T[src]

Mutably borrows from an owned value. Read more

impl<T> From<T> for T[src]

pub fn from(t: T) -> T[src]

Performs the conversion.

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

pub fn into(self) -> U[src]

Performs the conversion.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>[src]

Performs the conversion.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

pub fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>[src]

Performs the conversion.