event_listener

Trait IntoNotification

Source
pub trait IntoNotification: Sealed {
    type Tag;
    type Notify: Notification<Tag = Self::Tag>;

    // Required method
    fn into_notification(self) -> Self::Notify;

    // Provided methods
    fn additional(self) -> Additional<Self::Notify>
       where Self: Sized { ... }
    fn relaxed(self) -> Relaxed<Self::Notify>
       where Self: Sized { ... }
    fn tag<T: Clone>(self, tag: T) -> Tag<Self::Notify, T>
       where Self: Sized + IntoNotification<Tag = ()> { ... }
    fn tag_with<T, F>(self, tag: F) -> TagWith<Self::Notify, F>
       where Self: Sized + IntoNotification<Tag = ()>,
             F: FnMut() -> T { ... }
}
Expand description

A value that can be converted into a Notification.

This trait adds onto the Notification trait by providing combinators that can be applied to all notification types as well as numeric literals. This transforms what would normally be:

use event_listener::Event;

let event = Event::new();

// Note that each use case needs its own function, leading to bloat.
event.notify(1);
event.notify_additional(3);
event.notify_relaxed(5);
event.notify_additional_relaxed(2);

into this:

use event_listener::{Event, IntoNotification, Listener};

let event = Event::new();

event.notify(1);
event.notify(3.additional());
event.notify(5.relaxed());
event.notify(2.additional().relaxed());

This trait is implemented for all types that implement Notification, as well as for non-floating-point numeric literals (usize, i32, etc).

This function can be thought of as being analogous to std::iter::IntoIterator, but for Notification.

Required Associated Types§

Source

type Tag

The tag data associated with a notification.

By default, most [Event]s will use the unit type, (). However, this can be used to pass data along to the listener.

Source

type Notify: Notification<Tag = Self::Tag>

The notification type.

Tells what kind of underlying type that the Notification is. You probably don’t need to worry about this.

Required Methods§

Source

fn into_notification(self) -> Self::Notify

Convert this value into a notification.

This allows the user to convert an IntoNotification into a Notification.

§Panics

This function panics if the value represents a negative number of notifications.

§Examples
use event_listener::IntoNotification;

let _ = 3.into_notification();

Provided Methods§

Source

fn additional(self) -> Additional<Self::Notify>
where Self: Sized,

Convert this value into an additional notification.

By default, notifications ignore listeners that are already notified. Generally, this happens when there is an [EventListener] that has been woken up, but hasn’t been polled to completion or waited on yet. For instance, if you have three notified listeners and you call event.notify(5), only two listeners will be woken up.

This default behavior is generally desired. For instance, if you are writing a Mutex implementation powered by an [Event], you usually only want one consumer to be notified at a time. If you notified a listener when another listener is already notified, you would have unnecessary contention for your lock, as both listeners fight over the lock. Therefore, you would call event.notify(1) to make sure at least one listener is awake.

Sometimes, this behavior is not desired. For instance, if you are writing an MPMC channel, it is desirable for multiple listeners to be reading from the underlying queue at once. In this case, you would instead call event.notify(1.additional()).

§Examples
use event_listener::{Event, IntoNotification, Listener};

let event = Event::new();

let mut l1 = event.listen();
let mut l2 = event.listen();

// This will only wake up the first listener, as the second call observes that there is already a
// notified listener.
event.notify(1);
event.notify(1);

// This call wakes up the other listener.
event.notify(1.additional());
Source

fn relaxed(self) -> Relaxed<Self::Notify>
where Self: Sized,

Don’t emit a fence for this notification.

Usually, notifications emit a SeqCst atomic fence before any listeners are woken up. This ensures that notification state isn’t inconsistent before any wakers are woken up. However, it may be desirable to omit this fence in certain cases.

  • You are running the [Event] on a single thread, where no synchronization needs to occur.
  • You are emitting the SeqCst fence yourself.

In these cases, relaxed() can be used to avoid emitting the SeqCst fence.

§Examples
use event_listener::{Event, IntoNotification, Listener};
use std::sync::atomic::{self, Ordering};

let event = Event::new();

let listener1 = event.listen();
let listener2 = event.listen();
let listener3 = event.listen();

// We should emit a fence manually when using relaxed notifications.
atomic::fence(Ordering::SeqCst);

// Notifies two listeners.
//
// Listener queueing is fair, which means `listener1` and `listener2`
// get notified here since they start listening before `listener3`.
event.notify(1.relaxed());
event.notify(1.relaxed());
Source

fn tag<T: Clone>(self, tag: T) -> Tag<Self::Notify, T>
where Self: Sized + IntoNotification<Tag = ()>,

Use a tag with this notification.

In many cases, it is desired to send additional information to the listener of the [Event]. For instance, it is possible to optimize a Mutex implementation by locking directly on the next listener, without needing to ever unlock the mutex at all.

The tag provided is cloned to provide the tag for all listeners. In cases where this is not flexible enough, use [IntoNotification::with_tag()] instead.

Tagging functions cannot be implemented efficiently for no_std, so this is only available when the std feature is enabled.

§Examples
use event_listener::{IntoNotification, Listener, Event};

let event = Event::<bool>::with_tag();

let mut listener1 = event.listen();
let mut listener2 = event.listen();

// Notify with `true` then `false`.
event.notify(1.additional().tag(true));
event.notify(1.additional().tag(false));

assert_eq!(listener1.wait(), true);
assert_eq!(listener2.wait(), false);
Source

fn tag_with<T, F>(self, tag: F) -> TagWith<Self::Notify, F>
where Self: Sized + IntoNotification<Tag = ()>, F: FnMut() -> T,

Use a function to generate a tag with this notification.

In many cases, it is desired to send additional information to the listener of the [Event]. For instance, it is possible to optimize a Mutex implementation by locking directly on the next listener, without needing to ever unlock the mutex at all.

Tagging functions cannot be implemented efficiently for no_std, so this is only available when the std feature is enabled.

§Examples
use event_listener::{IntoNotification, Listener, Event};

let event = Event::<bool>::with_tag();

let mut listener1 = event.listen();
let mut listener2 = event.listen();

// Notify with `true` then `false`.
event.notify(1.additional().tag_with(|| true));
event.notify(1.additional().tag_with(|| false));

assert_eq!(listener1.wait(), true);
assert_eq!(listener2.wait(), false);

Implementations on Foreign Types§

Source§

impl IntoNotification for i8

Source§

type Tag = ()

Source§

type Notify = Notify

Source§

fn into_notification(self) -> Self::Notify

Source§

impl IntoNotification for i16

Source§

type Tag = ()

Source§

type Notify = Notify

Source§

fn into_notification(self) -> Self::Notify

Source§

impl IntoNotification for i32

Source§

type Tag = ()

Source§

type Notify = Notify

Source§

fn into_notification(self) -> Self::Notify

Source§

impl IntoNotification for i64

Source§

type Tag = ()

Source§

type Notify = Notify

Source§

fn into_notification(self) -> Self::Notify

Source§

impl IntoNotification for i128

Source§

type Tag = ()

Source§

type Notify = Notify

Source§

fn into_notification(self) -> Self::Notify

Source§

impl IntoNotification for isize

Source§

type Tag = ()

Source§

type Notify = Notify

Source§

fn into_notification(self) -> Self::Notify

Source§

impl IntoNotification for u8

Source§

type Tag = ()

Source§

type Notify = Notify

Source§

fn into_notification(self) -> Self::Notify

Source§

impl IntoNotification for u16

Source§

type Tag = ()

Source§

type Notify = Notify

Source§

fn into_notification(self) -> Self::Notify

Source§

impl IntoNotification for u32

Source§

type Tag = ()

Source§

type Notify = Notify

Source§

fn into_notification(self) -> Self::Notify

Source§

impl IntoNotification for u64

Source§

type Tag = ()

Source§

type Notify = Notify

Source§

fn into_notification(self) -> Self::Notify

Source§

impl IntoNotification for u128

Source§

type Tag = ()

Source§

type Notify = Notify

Source§

fn into_notification(self) -> Self::Notify

Source§

impl IntoNotification for usize

Source§

type Tag = ()

Source§

type Notify = Notify

Source§

fn into_notification(self) -> Self::Notify

Implementors§

Source§

impl<N: Notification> IntoNotification for N

Source§

type Tag = <N as NotificationPrivate>::Tag

Source§

type Notify = N