event_listener/
lib.rs

1//! Notify async tasks or threads.
2//!
3//! This is a synchronization primitive similar to [eventcounts] invented by Dmitry Vyukov.
4//!
5//! You can use this crate to turn non-blocking data structures into async or blocking data
6//! structures. See a [simple mutex] implementation that exposes an async and a blocking interface
7//! for acquiring locks.
8//!
9//! [eventcounts]: https://www.1024cores.net/home/lock-free-algorithms/eventcounts
10//! [simple mutex]: https://github.com/smol-rs/event-listener/blob/master/examples/mutex.rs
11//!
12//! # Examples
13//!
14//! Wait until another thread sets a boolean flag:
15//!
16//! ```
17//! use std::sync::atomic::{AtomicBool, Ordering};
18//! use std::sync::Arc;
19//! use std::thread;
20//! use std::time::Duration;
21//! use std::usize;
22//! use event_listener::{Event, Listener};
23//!
24//! let flag = Arc::new(AtomicBool::new(false));
25//! let event = Arc::new(Event::new());
26//!
27//! // Spawn a thread that will set the flag after 1 second.
28//! thread::spawn({
29//!     let flag = flag.clone();
30//!     let event = event.clone();
31//!     move || {
32//!         // Wait for a second.
33//!         thread::sleep(Duration::from_secs(1));
34//!
35//!         // Set the flag.
36//!         flag.store(true, Ordering::SeqCst);
37//!
38//!         // Notify all listeners that the flag has been set.
39//!         event.notify(usize::MAX);
40//!     }
41//! });
42//!
43//! // Wait until the flag is set.
44//! loop {
45//!     // Check the flag.
46//!     if flag.load(Ordering::SeqCst) {
47//!         break;
48//!     }
49//!
50//!     // Start listening for events.
51//!     let mut listener = event.listen();
52//!
53//!     // Check the flag again after creating the listener.
54//!     if flag.load(Ordering::SeqCst) {
55//!         break;
56//!     }
57//!
58//!     // Wait for a notification and continue the loop.
59//!     listener.wait();
60//! }
61//! ```
62//!
63//! # Features
64//!
65//! - The `std` feature (enabled by default) enables the use of the Rust standard library. Disable it for `no_std`
66//!   support.
67//!
68//! - The `critical-section` feature enables usage of the [`critical-section`] crate to enable a
69//!   more efficient implementation of `event-listener` for `no_std` platforms.
70//!
71//! - The `portable-atomic` feature enables the use of the [`portable-atomic`] crate to provide
72//!   atomic operations on platforms that don't support them.
73//!
74//! [`critical-section`]: https://crates.io/crates/critical-section
75//! [`portable-atomic`]: https://crates.io/crates/portable-atomic
76
77#![cfg_attr(not(feature = "std"), no_std)]
78#![allow(clippy::multiple_bound_locations)] // This is a WONTFIX issue with pin-project-lite
79#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)]
80#![doc(
81    html_favicon_url = "https://raw.githubusercontent.com/smol-rs/smol/master/assets/images/logo_fullsize_transparent.png"
82)]
83#![doc(
84    html_logo_url = "https://raw.githubusercontent.com/smol-rs/smol/master/assets/images/logo_fullsize_transparent.png"
85)]
86
87#[cfg(not(feature = "std"))]
88extern crate alloc;
89#[cfg(feature = "std")]
90extern crate std as alloc;
91
92#[cfg_attr(
93    any(feature = "std", feature = "critical-section"),
94    path = "intrusive.rs"
95)]
96#[cfg_attr(
97    not(any(feature = "std", feature = "critical-section")),
98    path = "slab.rs"
99)]
100mod sys;
101
102mod notify;
103
104#[cfg(not(feature = "std"))]
105use alloc::boxed::Box;
106
107use core::borrow::Borrow;
108use core::fmt;
109use core::future::Future;
110use core::mem::ManuallyDrop;
111use core::pin::Pin;
112use core::ptr;
113use core::task::{Context, Poll, Waker};
114
115#[cfg(all(feature = "std", not(target_family = "wasm")))]
116use {
117    parking::{Parker, Unparker},
118    std::time::{Duration, Instant},
119};
120
121use sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
122use sync::Arc;
123
124#[cfg(not(loom))]
125use sync::WithMut;
126
127use notify::NotificationPrivate;
128pub use notify::{IntoNotification, Notification};
129
130/// Inner state of [`Event`].
131struct Inner<T> {
132    /// The number of notified entries, or `usize::MAX` if all of them have been notified.
133    ///
134    /// If there are no entries, this value is set to `usize::MAX`.
135    notified: AtomicUsize,
136
137    /// Inner queue of event listeners.
138    ///
139    /// On `std` platforms, this is an intrusive linked list. On `no_std` platforms, this is a
140    /// more traditional `Vec` of listeners, with an atomic queue used as a backup for high
141    /// contention.
142    list: sys::List<T>,
143}
144
145impl<T> Inner<T> {
146    fn new() -> Self {
147        Self {
148            notified: AtomicUsize::new(usize::MAX),
149            list: sys::List::new(),
150        }
151    }
152}
153
154/// A synchronization primitive for notifying async tasks and threads.
155///
156/// Listeners can be registered using [`Event::listen()`]. There are two ways to notify listeners:
157///
158/// 1. [`Event::notify()`] notifies a number of listeners.
159/// 2. [`Event::notify_additional()`] notifies a number of previously unnotified listeners.
160///
161/// If there are no active listeners at the time a notification is sent, it simply gets lost.
162///
163/// There are two ways for a listener to wait for a notification:
164///
165/// 1. In an asynchronous manner using `.await`.
166/// 2. In a blocking manner by calling [`EventListener::wait()`] on it.
167///
168/// If a notified listener is dropped without receiving a notification, dropping will notify
169/// another active listener. Whether one *additional* listener will be notified depends on what
170/// kind of notification was delivered.
171///
172/// Listeners are registered and notified in the first-in first-out fashion, ensuring fairness.
173pub struct Event<T = ()> {
174    /// A pointer to heap-allocated inner state.
175    ///
176    /// This pointer is initially null and gets lazily initialized on first use. Semantically, it
177    /// is an `Arc<Inner>` so it's important to keep in mind that it contributes to the [`Arc`]'s
178    /// reference count.
179    inner: AtomicPtr<Inner<T>>,
180}
181
182unsafe impl<T: Send> Send for Event<T> {}
183unsafe impl<T: Send> Sync for Event<T> {}
184
185impl<T> core::panic::UnwindSafe for Event<T> {}
186impl<T> core::panic::RefUnwindSafe for Event<T> {}
187
188impl<T> fmt::Debug for Event<T> {
189    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
190        match self.try_inner() {
191            Some(inner) => {
192                let notified_count = inner.notified.load(Ordering::Relaxed);
193                let total_count = match inner.list.try_total_listeners() {
194                    Some(total_count) => total_count,
195                    None => {
196                        return f
197                            .debug_tuple("Event")
198                            .field(&format_args!("<locked>"))
199                            .finish()
200                    }
201                };
202
203                f.debug_struct("Event")
204                    .field("listeners_notified", &notified_count)
205                    .field("listeners_total", &total_count)
206                    .finish()
207            }
208            None => f
209                .debug_tuple("Event")
210                .field(&format_args!("<uninitialized>"))
211                .finish(),
212        }
213    }
214}
215
216impl Default for Event {
217    #[inline]
218    fn default() -> Self {
219        Self::new()
220    }
221}
222
223impl<T> Event<T> {
224    /// Creates a new `Event` with a tag type.
225    ///
226    /// Tagging cannot be implemented efficiently on `no_std`, so this is only available when the
227    /// `std` feature is enabled.
228    ///
229    /// # Examples
230    ///
231    /// ```
232    /// use event_listener::Event;
233    ///
234    /// let event = Event::<usize>::with_tag();
235    /// ```
236    #[cfg(all(feature = "std", not(loom)))]
237    #[inline]
238    pub const fn with_tag() -> Self {
239        Self {
240            inner: AtomicPtr::new(ptr::null_mut()),
241        }
242    }
243    #[cfg(all(feature = "std", loom))]
244    #[inline]
245    pub fn with_tag() -> Self {
246        Self {
247            inner: AtomicPtr::new(ptr::null_mut()),
248        }
249    }
250
251    /// Tell whether any listeners are currently notified.
252    ///
253    /// # Examples
254    ///
255    /// ```
256    /// use event_listener::{Event, Listener};
257    ///
258    /// let event = Event::new();
259    /// let listener = event.listen();
260    /// assert!(!event.is_notified());
261    ///
262    /// event.notify(1);
263    /// assert!(event.is_notified());
264    /// ```
265    #[inline]
266    pub fn is_notified(&self) -> bool {
267        self.try_inner()
268            .map_or(false, |inner| inner.notified.load(Ordering::Acquire) > 0)
269    }
270
271    /// Returns a guard listening for a notification.
272    ///
273    /// This method emits a `SeqCst` fence after registering a listener. For now, this method
274    /// is an alias for calling [`EventListener::new()`], pinning it to the heap, and then
275    /// inserting it into a list.
276    ///
277    /// # Examples
278    ///
279    /// ```
280    /// use event_listener::Event;
281    ///
282    /// let event = Event::new();
283    /// let listener = event.listen();
284    /// ```
285    ///
286    /// # Caveats
287    ///
288    /// The above example is equivalent to this code:
289    ///
290    /// ```no_compile
291    /// use event_listener::{Event, EventListener};
292    ///
293    /// let event = Event::new();
294    /// let mut listener = Box::pin(EventListener::new());
295    /// listener.listen(&event);
296    /// ```
297    ///
298    /// It creates a new listener, pins it to the heap, and inserts it into the linked list
299    /// of listeners. While this type of usage is simple, it may be desired to eliminate this
300    /// heap allocation. In this case, consider using the [`EventListener::new`] constructor
301    /// directly, which allows for greater control over where the [`EventListener`] is
302    /// allocated. However, users of this `new` method must be careful to ensure that the
303    /// [`EventListener`] is `listen`ing before waiting on it; panics may occur otherwise.
304    #[cold]
305    pub fn listen(&self) -> EventListener<T> {
306        let inner = ManuallyDrop::new(unsafe { Arc::from_raw(self.inner()) });
307
308        // Allocate the listener on the heap and insert it.
309        let mut listener = Box::pin(InnerListener {
310            event: Arc::clone(&inner),
311            listener: None,
312        });
313        listener.as_mut().listen();
314
315        // Return the listener.
316        EventListener { listener }
317    }
318
319    /// Notifies a number of active listeners.
320    ///
321    /// The number is allowed to be zero or exceed the current number of listeners.
322    ///
323    /// The [`Notification`] trait is used to define what kind of notification is delivered.
324    /// The default implementation (implemented on `usize`) is a notification that only notifies
325    /// *at least* the specified number of listeners.
326    ///
327    /// In certain cases, this function emits a `SeqCst` fence before notifying listeners.
328    ///
329    /// This function returns the number of [`EventListener`]s that were notified by this call.
330    ///
331    /// # Caveats
332    ///
333    /// If the `std` feature is disabled, the notification will be delayed under high contention,
334    /// such as when another thread is taking a while to `notify` the event. In this circumstance,
335    /// this function will return `0` instead of the number of listeners actually notified. Therefore
336    /// if the `std` feature is disabled the return value of this function should not be relied upon
337    /// for soundness and should be used only as a hint.
338    ///
339    /// If the `std` feature is enabled, no spurious returns are possible, since the `std`
340    /// implementation uses system locking primitives to ensure there is no unavoidable
341    /// contention.
342    ///
343    /// # Examples
344    ///
345    /// Use the default notification strategy:
346    ///
347    /// ```
348    /// use event_listener::Event;
349    ///
350    /// let event = Event::new();
351    ///
352    /// // This notification gets lost because there are no listeners.
353    /// event.notify(1);
354    ///
355    /// let listener1 = event.listen();
356    /// let listener2 = event.listen();
357    /// let listener3 = event.listen();
358    ///
359    /// // Notifies two listeners.
360    /// //
361    /// // Listener queueing is fair, which means `listener1` and `listener2`
362    /// // get notified here since they start listening before `listener3`.
363    /// event.notify(2);
364    /// ```
365    ///
366    /// Notify without emitting a `SeqCst` fence. This uses the [`relaxed`] notification strategy.
367    /// This is equivalent to calling [`Event::notify_relaxed()`].
368    ///
369    /// [`relaxed`]: IntoNotification::relaxed
370    ///
371    /// ```
372    /// use event_listener::{IntoNotification, Event};
373    /// use std::sync::atomic::{self, Ordering};
374    ///
375    /// let event = Event::new();
376    ///
377    /// // This notification gets lost because there are no listeners.
378    /// event.notify(1.relaxed());
379    ///
380    /// let listener1 = event.listen();
381    /// let listener2 = event.listen();
382    /// let listener3 = event.listen();
383    ///
384    /// // We should emit a fence manually when using relaxed notifications.
385    /// atomic::fence(Ordering::SeqCst);
386    ///
387    /// // Notifies two listeners.
388    /// //
389    /// // Listener queueing is fair, which means `listener1` and `listener2`
390    /// // get notified here since they start listening before `listener3`.
391    /// event.notify(2.relaxed());
392    /// ```
393    ///
394    /// Notify additional listeners. In contrast to [`Event::notify()`], this method will notify `n`
395    /// *additional* listeners that were previously unnotified. This uses the [`additional`]
396    /// notification strategy. This is equivalent to calling [`Event::notify_additional()`].
397    ///
398    /// [`additional`]: IntoNotification::additional
399    ///
400    /// ```
401    /// use event_listener::{IntoNotification, Event};
402    ///
403    /// let event = Event::new();
404    ///
405    /// // This notification gets lost because there are no listeners.
406    /// event.notify(1.additional());
407    ///
408    /// let listener1 = event.listen();
409    /// let listener2 = event.listen();
410    /// let listener3 = event.listen();
411    ///
412    /// // Notifies two listeners.
413    /// //
414    /// // Listener queueing is fair, which means `listener1` and `listener2`
415    /// // get notified here since they start listening before `listener3`.
416    /// event.notify(1.additional());
417    /// event.notify(1.additional());
418    /// ```
419    ///
420    /// Notifies with the [`additional`] and [`relaxed`] strategies at the same time. This is
421    /// equivalent to calling [`Event::notify_additional_relaxed()`].
422    ///
423    /// ```
424    /// use event_listener::{IntoNotification, Event};
425    /// use std::sync::atomic::{self, Ordering};
426    ///
427    /// let event = Event::new();
428    ///
429    /// // This notification gets lost because there are no listeners.
430    /// event.notify(1.additional().relaxed());
431    ///
432    /// let listener1 = event.listen();
433    /// let listener2 = event.listen();
434    /// let listener3 = event.listen();
435    ///
436    /// // We should emit a fence manually when using relaxed notifications.
437    /// atomic::fence(Ordering::SeqCst);
438    ///
439    /// // Notifies two listeners.
440    /// //
441    /// // Listener queueing is fair, which means `listener1` and `listener2`
442    /// // get notified here since they start listening before `listener3`.
443    /// event.notify(1.additional().relaxed());
444    /// event.notify(1.additional().relaxed());
445    /// ```
446    #[inline]
447    pub fn notify(&self, notify: impl IntoNotification<Tag = T>) -> usize {
448        let notify = notify.into_notification();
449
450        // Make sure the notification comes after whatever triggered it.
451        notify.fence(notify::Internal::new());
452
453        let inner = unsafe { &*self.inner() };
454        inner.notify(notify)
455    }
456
457    /// Return a reference to the inner state if it has been initialized.
458    #[inline]
459    fn try_inner(&self) -> Option<&Inner<T>> {
460        let inner = self.inner.load(Ordering::Acquire);
461        unsafe { inner.as_ref() }
462    }
463
464    /// Returns a raw, initialized pointer to the inner state.
465    ///
466    /// This returns a raw pointer instead of reference because `from_raw`
467    /// requires raw/mut provenance: <https://github.com/rust-lang/rust/pull/67339>.
468    fn inner(&self) -> *const Inner<T> {
469        let mut inner = self.inner.load(Ordering::Acquire);
470
471        // If this is the first use, initialize the state.
472        if inner.is_null() {
473            // Allocate the state on the heap.
474            let new = Arc::new(Inner::<T>::new());
475
476            // Convert the state to a raw pointer.
477            let new = Arc::into_raw(new) as *mut Inner<T>;
478
479            // Replace the null pointer with the new state pointer.
480            inner = self
481                .inner
482                .compare_exchange(inner, new, Ordering::AcqRel, Ordering::Acquire)
483                .unwrap_or_else(|x| x);
484
485            // Check if the old pointer value was indeed null.
486            if inner.is_null() {
487                // If yes, then use the new state pointer.
488                inner = new;
489            } else {
490                // If not, that means a concurrent operation has initialized the state.
491                // In that case, use the old pointer and deallocate the new one.
492                unsafe {
493                    drop(Arc::from_raw(new));
494                }
495            }
496        }
497
498        inner
499    }
500
501    /// Get the number of listeners currently listening to this [`Event`].
502    ///
503    /// This call returns the number of [`EventListener`]s that are currently listening to
504    /// this event. It does this by acquiring the internal event lock and reading the listener
505    /// count. Therefore it is only available for `std`-enabled platforms.
506    ///
507    /// # Caveats
508    ///
509    /// This function returns just a snapshot of the number of listeners at this point in time.
510    /// Due to the nature of multi-threaded CPUs, it is possible that this number will be
511    /// inaccurate by the time that this function returns.
512    ///
513    /// It is possible for the actual number to change at any point. Therefore, the number should
514    /// only ever be used as a hint.
515    ///
516    /// # Examples
517    ///
518    /// ```
519    /// use event_listener::Event;
520    ///
521    /// let event = Event::new();
522    ///
523    /// assert_eq!(event.total_listeners(), 0);
524    ///
525    /// let listener1 = event.listen();
526    /// assert_eq!(event.total_listeners(), 1);
527    ///
528    /// let listener2 = event.listen();
529    /// assert_eq!(event.total_listeners(), 2);
530    ///
531    /// drop(listener1);
532    /// drop(listener2);
533    /// assert_eq!(event.total_listeners(), 0);
534    /// ```
535    #[cfg(feature = "std")]
536    #[inline]
537    pub fn total_listeners(&self) -> usize {
538        if let Some(inner) = self.try_inner() {
539            inner.list.total_listeners()
540        } else {
541            0
542        }
543    }
544}
545
546impl Event<()> {
547    /// Creates a new [`Event`].
548    ///
549    /// # Examples
550    ///
551    /// ```
552    /// use event_listener::Event;
553    ///
554    /// let event = Event::new();
555    /// ```
556    #[inline]
557    #[cfg(not(loom))]
558    pub const fn new() -> Self {
559        Self {
560            inner: AtomicPtr::new(ptr::null_mut()),
561        }
562    }
563
564    #[inline]
565    #[cfg(loom)]
566    pub fn new() -> Self {
567        Self {
568            inner: AtomicPtr::new(ptr::null_mut()),
569        }
570    }
571
572    /// Notifies a number of active listeners without emitting a `SeqCst` fence.
573    ///
574    /// The number is allowed to be zero or exceed the current number of listeners.
575    ///
576    /// In contrast to [`Event::notify_additional()`], this method only makes sure *at least* `n`
577    /// listeners among the active ones are notified.
578    ///
579    /// Unlike [`Event::notify()`], this method does not emit a `SeqCst` fence.
580    ///
581    /// This method only works for untagged events. In other cases, it is recommended to instead
582    /// use [`Event::notify()`] like so:
583    ///
584    /// ```
585    /// use event_listener::{IntoNotification, Event};
586    /// let event = Event::new();
587    ///
588    /// // Old way:
589    /// event.notify_relaxed(1);
590    ///
591    /// // New way:
592    /// event.notify(1.relaxed());
593    /// ```
594    ///
595    /// # Examples
596    ///
597    /// ```
598    /// use event_listener::{Event, IntoNotification};
599    /// use std::sync::atomic::{self, Ordering};
600    ///
601    /// let event = Event::new();
602    ///
603    /// // This notification gets lost because there are no listeners.
604    /// event.notify_relaxed(1);
605    ///
606    /// let listener1 = event.listen();
607    /// let listener2 = event.listen();
608    /// let listener3 = event.listen();
609    ///
610    /// // We should emit a fence manually when using relaxed notifications.
611    /// atomic::fence(Ordering::SeqCst);
612    ///
613    /// // Notifies two listeners.
614    /// //
615    /// // Listener queueing is fair, which means `listener1` and `listener2`
616    /// // get notified here since they start listening before `listener3`.
617    /// event.notify_relaxed(2);
618    /// ```
619    #[inline]
620    pub fn notify_relaxed(&self, n: usize) -> usize {
621        self.notify(n.relaxed())
622    }
623
624    /// Notifies a number of active and still unnotified listeners.
625    ///
626    /// The number is allowed to be zero or exceed the current number of listeners.
627    ///
628    /// In contrast to [`Event::notify()`], this method will notify `n` *additional* listeners that
629    /// were previously unnotified.
630    ///
631    /// This method emits a `SeqCst` fence before notifying listeners.
632    ///
633    /// This method only works for untagged events. In other cases, it is recommended to instead
634    /// use [`Event::notify()`] like so:
635    ///
636    /// ```
637    /// use event_listener::{IntoNotification, Event};
638    /// let event = Event::new();
639    ///
640    /// // Old way:
641    /// event.notify_additional(1);
642    ///
643    /// // New way:
644    /// event.notify(1.additional());
645    /// ```
646    ///
647    /// # Examples
648    ///
649    /// ```
650    /// use event_listener::Event;
651    ///
652    /// let event = Event::new();
653    ///
654    /// // This notification gets lost because there are no listeners.
655    /// event.notify_additional(1);
656    ///
657    /// let listener1 = event.listen();
658    /// let listener2 = event.listen();
659    /// let listener3 = event.listen();
660    ///
661    /// // Notifies two listeners.
662    /// //
663    /// // Listener queueing is fair, which means `listener1` and `listener2`
664    /// // get notified here since they start listening before `listener3`.
665    /// event.notify_additional(1);
666    /// event.notify_additional(1);
667    /// ```
668    #[inline]
669    pub fn notify_additional(&self, n: usize) -> usize {
670        self.notify(n.additional())
671    }
672
673    /// Notifies a number of active and still unnotified listeners without emitting a `SeqCst`
674    /// fence.
675    ///
676    /// The number is allowed to be zero or exceed the current number of listeners.
677    ///
678    /// In contrast to [`Event::notify()`], this method will notify `n` *additional* listeners that
679    /// were previously unnotified.
680    ///
681    /// Unlike [`Event::notify_additional()`], this method does not emit a `SeqCst` fence.
682    ///
683    /// This method only works for untagged events. In other cases, it is recommended to instead
684    /// use [`Event::notify()`] like so:
685    ///
686    /// ```
687    /// use event_listener::{IntoNotification, Event};
688    /// let event = Event::new();
689    ///
690    /// // Old way:
691    /// event.notify_additional_relaxed(1);
692    ///
693    /// // New way:
694    /// event.notify(1.additional().relaxed());
695    /// ```
696    ///
697    /// # Examples
698    ///
699    /// ```
700    /// use event_listener::Event;
701    /// use std::sync::atomic::{self, Ordering};
702    ///
703    /// let event = Event::new();
704    ///
705    /// // This notification gets lost because there are no listeners.
706    /// event.notify(1);
707    ///
708    /// let listener1 = event.listen();
709    /// let listener2 = event.listen();
710    /// let listener3 = event.listen();
711    ///
712    /// // We should emit a fence manually when using relaxed notifications.
713    /// atomic::fence(Ordering::SeqCst);
714    ///
715    /// // Notifies two listeners.
716    /// //
717    /// // Listener queueing is fair, which means `listener1` and `listener2`
718    /// // get notified here since they start listening before `listener3`.
719    /// event.notify_additional_relaxed(1);
720    /// event.notify_additional_relaxed(1);
721    /// ```
722    #[inline]
723    pub fn notify_additional_relaxed(&self, n: usize) -> usize {
724        self.notify(n.additional().relaxed())
725    }
726}
727
728impl<T> Drop for Event<T> {
729    #[inline]
730    fn drop(&mut self) {
731        self.inner.with_mut(|&mut inner| {
732            // If the state pointer has been initialized, drop it.
733            if !inner.is_null() {
734                unsafe {
735                    drop(Arc::from_raw(inner));
736                }
737            }
738        })
739    }
740}
741
742/// A handle that is listening to an [`Event`].
743///
744/// This trait represents a type waiting for a notification from an [`Event`]. See the
745/// [`EventListener`] type for more documentation on this trait's usage.
746pub trait Listener<T = ()>: Future<Output = T> + __sealed::Sealed {
747    /// Blocks until a notification is received.
748    ///
749    /// # Examples
750    ///
751    /// ```
752    /// use event_listener::{Event, Listener};
753    ///
754    /// let event = Event::new();
755    /// let mut listener = event.listen();
756    ///
757    /// // Notify `listener`.
758    /// event.notify(1);
759    ///
760    /// // Receive the notification.
761    /// listener.wait();
762    /// ```
763    #[cfg(all(feature = "std", not(target_family = "wasm")))]
764    fn wait(self) -> T;
765
766    /// Blocks until a notification is received or a timeout is reached.
767    ///
768    /// Returns `true` if a notification was received.
769    ///
770    /// # Examples
771    ///
772    /// ```
773    /// use std::time::Duration;
774    /// use event_listener::{Event, Listener};
775    ///
776    /// let event = Event::new();
777    /// let mut listener = event.listen();
778    ///
779    /// // There are no notification so this times out.
780    /// assert!(listener.wait_timeout(Duration::from_secs(1)).is_none());
781    /// ```
782    #[cfg(all(feature = "std", not(target_family = "wasm")))]
783    fn wait_timeout(self, timeout: Duration) -> Option<T>;
784
785    /// Blocks until a notification is received or a deadline is reached.
786    ///
787    /// Returns `true` if a notification was received.
788    ///
789    /// # Examples
790    ///
791    /// ```
792    /// use std::time::{Duration, Instant};
793    /// use event_listener::{Event, Listener};
794    ///
795    /// let event = Event::new();
796    /// let mut listener = event.listen();
797    ///
798    /// // There are no notification so this times out.
799    /// assert!(listener.wait_deadline(Instant::now() + Duration::from_secs(1)).is_none());
800    /// ```
801    #[cfg(all(feature = "std", not(target_family = "wasm")))]
802    fn wait_deadline(self, deadline: Instant) -> Option<T>;
803
804    /// Drops this listener and discards its notification (if any) without notifying another
805    /// active listener.
806    ///
807    /// Returns `true` if a notification was discarded.
808    ///
809    /// # Examples
810    ///
811    /// ```
812    /// use event_listener::{Event, Listener};
813    ///
814    /// let event = Event::new();
815    /// let mut listener1 = event.listen();
816    /// let mut listener2 = event.listen();
817    ///
818    /// event.notify(1);
819    ///
820    /// assert!(listener1.discard());
821    /// assert!(!listener2.discard());
822    /// ```
823    fn discard(self) -> bool;
824
825    /// Returns `true` if this listener listens to the given `Event`.
826    ///
827    /// # Examples
828    ///
829    /// ```
830    /// use event_listener::{Event, Listener};
831    ///
832    /// let event = Event::new();
833    /// let listener = event.listen();
834    ///
835    /// assert!(listener.listens_to(&event));
836    /// ```
837    fn listens_to(&self, event: &Event<T>) -> bool;
838
839    /// Returns `true` if both listeners listen to the same `Event`.
840    ///
841    /// # Examples
842    ///
843    /// ```
844    /// use event_listener::{Event, Listener};
845    ///
846    /// let event = Event::new();
847    /// let listener1 = event.listen();
848    /// let listener2 = event.listen();
849    ///
850    /// assert!(listener1.same_event(&listener2));
851    /// ```
852    fn same_event(&self, other: &Self) -> bool;
853}
854
855/// Implement the `Listener` trait using the underlying `InnerListener`.
856macro_rules! forward_impl_to_listener {
857    ($gen:ident => $ty:ty) => {
858        impl<$gen> crate::Listener<$gen> for $ty {
859            #[cfg(all(feature = "std", not(target_family = "wasm")))]
860            fn wait(mut self) -> $gen {
861                self.listener_mut().wait_internal(None).unwrap()
862            }
863
864            #[cfg(all(feature = "std", not(target_family = "wasm")))]
865            fn wait_timeout(mut self, timeout: std::time::Duration) -> Option<$gen> {
866                self.listener_mut()
867                    .wait_internal(std::time::Instant::now().checked_add(timeout))
868            }
869
870            #[cfg(all(feature = "std", not(target_family = "wasm")))]
871            fn wait_deadline(mut self, deadline: std::time::Instant) -> Option<$gen> {
872                self.listener_mut().wait_internal(Some(deadline))
873            }
874
875            fn discard(mut self) -> bool {
876                self.listener_mut().discard()
877            }
878
879            #[inline]
880            fn listens_to(&self, event: &Event<$gen>) -> bool {
881                core::ptr::eq::<Inner<$gen>>(
882                    &*self.listener().event,
883                    event.inner.load(core::sync::atomic::Ordering::Acquire),
884                )
885            }
886
887            #[inline]
888            fn same_event(&self, other: &$ty) -> bool {
889                core::ptr::eq::<Inner<$gen>>(&*self.listener().event, &*other.listener().event)
890            }
891        }
892
893        impl<$gen> Future for $ty {
894            type Output = $gen;
895
896            #[inline]
897            fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<$gen> {
898                self.listener_mut().poll_internal(cx)
899            }
900        }
901    };
902}
903
904/// A guard waiting for a notification from an [`Event`].
905///
906/// There are two ways for a listener to wait for a notification:
907///
908/// 1. In an asynchronous manner using `.await`.
909/// 2. In a blocking manner by calling [`EventListener::wait()`] on it.
910///
911/// If a notified listener is dropped without receiving a notification, dropping will notify
912/// another active listener. Whether one *additional* listener will be notified depends on what
913/// kind of notification was delivered.
914///
915/// See the [`Listener`] trait for the functionality exposed by this type.
916///
917/// This structure allocates the listener on the heap.
918pub struct EventListener<T = ()> {
919    listener: Pin<Box<InnerListener<T, Arc<Inner<T>>>>>,
920}
921
922unsafe impl<T: Send> Send for EventListener<T> {}
923unsafe impl<T: Send> Sync for EventListener<T> {}
924
925impl<T> core::panic::UnwindSafe for EventListener<T> {}
926impl<T> core::panic::RefUnwindSafe for EventListener<T> {}
927impl<T> Unpin for EventListener<T> {}
928
929impl<T> fmt::Debug for EventListener<T> {
930    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
931        f.debug_struct("EventListener").finish_non_exhaustive()
932    }
933}
934
935impl<T> EventListener<T> {
936    #[inline]
937    fn listener(&self) -> &InnerListener<T, Arc<Inner<T>>> {
938        &self.listener
939    }
940
941    #[inline]
942    fn listener_mut(&mut self) -> Pin<&mut InnerListener<T, Arc<Inner<T>>>> {
943        self.listener.as_mut()
944    }
945}
946
947forward_impl_to_listener! { T => EventListener<T> }
948
949/// Create a stack-based event listener for an [`Event`].
950///
951/// [`EventListener`] allocates the listener on the heap. While this works for most use cases, in
952/// practice this heap allocation can be expensive for repeated uses. This method allows for
953/// allocating the listener on the stack instead.
954///
955/// There are limitations to using this macro instead of the [`EventListener`] type, however.
956/// Firstly, it is significantly less flexible. The listener is locked to the current stack
957/// frame, meaning that it can't be returned or put into a place where it would go out of
958/// scope. For instance, this will not work:
959///
960/// ```compile_fail
961/// use event_listener::{Event, Listener, listener};
962///
963/// fn get_listener(event: &Event) -> impl Listener {
964///     listener!(event => cant_return_this);
965///     cant_return_this
966/// }
967/// ```
968///
969/// In addition, the types involved in creating this listener are not able to be named. Therefore
970/// it cannot be used in hand-rolled futures or similar structures.
971///
972/// The type created by this macro implements [`Listener`], allowing it to be used in cases where
973/// [`EventListener`] would normally be used.
974///
975/// ## Example
976///
977/// To use this macro, replace cases where you would normally use this...
978///
979/// ```no_compile
980/// let listener = event.listen();
981/// ```
982///
983/// ...with this:
984///
985/// ```no_compile
986/// listener!(event => listener);
987/// ```
988///
989/// Here is the top level example from this crate's documentation, but using [`listener`] instead
990/// of [`EventListener`].
991///
992/// ```
993/// use std::sync::atomic::{AtomicBool, Ordering};
994/// use std::sync::Arc;
995/// use std::thread;
996/// use std::time::Duration;
997/// use std::usize;
998/// use event_listener::{Event, listener, IntoNotification, Listener};
999///
1000/// let flag = Arc::new(AtomicBool::new(false));
1001/// let event = Arc::new(Event::new());
1002///
1003/// // Spawn a thread that will set the flag after 1 second.
1004/// thread::spawn({
1005///     let flag = flag.clone();
1006///     let event = event.clone();
1007///     move || {
1008///         // Wait for a second.
1009///         thread::sleep(Duration::from_secs(1));
1010///
1011///         // Set the flag.
1012///         flag.store(true, Ordering::SeqCst);
1013///
1014///         // Notify all listeners that the flag has been set.
1015///         event.notify(usize::MAX);
1016///     }
1017/// });
1018///
1019/// // Wait until the flag is set.
1020/// loop {
1021///     // Check the flag.
1022///     if flag.load(Ordering::SeqCst) {
1023///         break;
1024///     }
1025///
1026///     // Start listening for events.
1027///     // NEW: Changed to a stack-based listener.
1028///     listener!(event => listener);
1029///
1030///     // Check the flag again after creating the listener.
1031///     if flag.load(Ordering::SeqCst) {
1032///         break;
1033///     }
1034///
1035///     // Wait for a notification and continue the loop.
1036///     listener.wait();
1037/// }
1038/// ```
1039#[macro_export]
1040macro_rules! listener {
1041    ($event:expr => $listener:ident) => {
1042        let mut $listener = $crate::__private::StackSlot::new(&$event);
1043        // SAFETY: We shadow $listener so it can't be moved after.
1044        let mut $listener = unsafe { $crate::__private::Pin::new_unchecked(&mut $listener) };
1045        #[allow(unused_mut)]
1046        let mut $listener = $listener.listen();
1047    };
1048}
1049
1050pin_project_lite::pin_project! {
1051    #[project(!Unpin)]
1052    #[project = ListenerProject]
1053    struct InnerListener<T, B: Borrow<Inner<T>>>
1054    where
1055        B: Unpin,
1056    {
1057        // The reference to the original event.
1058        event: B,
1059
1060        // The inner state of the listener.
1061        //
1062        // This is only ever `None` during initialization. After `listen()` has completed, this
1063        // should be `Some`.
1064        #[pin]
1065        listener: Option<sys::Listener<T>>,
1066    }
1067
1068    impl<T, B: Borrow<Inner<T>>> PinnedDrop for InnerListener<T, B>
1069    where
1070        B: Unpin,
1071    {
1072        fn drop(mut this: Pin<&mut Self>) {
1073            // If we're being dropped, we need to remove ourself from the list.
1074            let this = this.project();
1075            (*this.event).borrow().remove(this.listener, true);
1076        }
1077    }
1078}
1079
1080unsafe impl<T: Send, B: Borrow<Inner<T>> + Unpin + Send> Send for InnerListener<T, B> {}
1081unsafe impl<T: Send, B: Borrow<Inner<T>> + Unpin + Sync> Sync for InnerListener<T, B> {}
1082
1083impl<T, B: Borrow<Inner<T>> + Unpin> InnerListener<T, B> {
1084    /// Insert this listener into the linked list.
1085    #[inline]
1086    fn listen(self: Pin<&mut Self>) {
1087        let this = self.project();
1088        (*this.event).borrow().insert(this.listener);
1089    }
1090
1091    /// Wait until the provided deadline.
1092    #[cfg(all(feature = "std", not(target_family = "wasm")))]
1093    fn wait_internal(mut self: Pin<&mut Self>, deadline: Option<Instant>) -> Option<T> {
1094        fn parker_and_task() -> (Parker, Task) {
1095            let parker = Parker::new();
1096            let unparker = parker.unparker();
1097            (parker, Task::Unparker(unparker))
1098        }
1099
1100        crate::sync::thread_local! {
1101            /// Cached thread-local parker/unparker pair.
1102            static PARKER: (Parker, Task) = parker_and_task();
1103        }
1104
1105        // Try to borrow the thread-local parker/unparker pair.
1106        PARKER
1107            .try_with({
1108                let this = self.as_mut();
1109                |(parker, unparker)| this.wait_with_parker(deadline, parker, unparker.as_task_ref())
1110            })
1111            .unwrap_or_else(|_| {
1112                // If the pair isn't accessible, we may be being called in a destructor.
1113                // Just create a new pair.
1114                let (parker, unparker) = parking::pair();
1115                self.as_mut()
1116                    .wait_with_parker(deadline, &parker, TaskRef::Unparker(&unparker))
1117            })
1118    }
1119
1120    /// Wait until the provided deadline using the specified parker/unparker pair.
1121    #[cfg(all(feature = "std", not(target_family = "wasm")))]
1122    fn wait_with_parker(
1123        self: Pin<&mut Self>,
1124        deadline: Option<Instant>,
1125        parker: &Parker,
1126        unparker: TaskRef<'_>,
1127    ) -> Option<T> {
1128        let mut this = self.project();
1129        let inner = (*this.event).borrow();
1130
1131        // Set the listener's state to `Task`.
1132        if let Some(tag) = inner.register(this.listener.as_mut(), unparker).notified() {
1133            // We were already notified, so we don't need to park.
1134            return Some(tag);
1135        }
1136
1137        // Wait until a notification is received or the timeout is reached.
1138        loop {
1139            match deadline {
1140                None => parker.park(),
1141
1142                #[cfg(loom)]
1143                Some(_deadline) => {
1144                    panic!("parking does not support timeouts under loom");
1145                }
1146
1147                #[cfg(not(loom))]
1148                Some(deadline) => {
1149                    // Make sure we're not timed out already.
1150                    let now = Instant::now();
1151                    if now >= deadline {
1152                        // Remove our entry and check if we were notified.
1153                        return inner
1154                            .remove(this.listener.as_mut(), false)
1155                            .expect("We never removed ourself from the list")
1156                            .notified();
1157                    }
1158                    parker.park_deadline(deadline);
1159                }
1160            }
1161
1162            // See if we were notified.
1163            if let Some(tag) = inner.register(this.listener.as_mut(), unparker).notified() {
1164                return Some(tag);
1165            }
1166        }
1167    }
1168
1169    /// Drops this listener and discards its notification (if any) without notifying another
1170    /// active listener.
1171    fn discard(self: Pin<&mut Self>) -> bool {
1172        let this = self.project();
1173        (*this.event)
1174            .borrow()
1175            .remove(this.listener, false)
1176            .map_or(false, |state| state.is_notified())
1177    }
1178
1179    /// Poll this listener for a notification.
1180    fn poll_internal(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
1181        let this = self.project();
1182        let inner = (*this.event).borrow();
1183
1184        // Try to register the listener.
1185        match inner
1186            .register(this.listener, TaskRef::Waker(cx.waker()))
1187            .notified()
1188        {
1189            Some(tag) => {
1190                // We were already notified, so we don't need to park.
1191                Poll::Ready(tag)
1192            }
1193
1194            None => {
1195                // We're now waiting for a notification.
1196                Poll::Pending
1197            }
1198        }
1199    }
1200}
1201
1202/// The state of a listener.
1203#[derive(PartialEq)]
1204enum State<T> {
1205    /// The listener was just created.
1206    Created,
1207
1208    /// The listener has received a notification.
1209    ///
1210    /// The `bool` is `true` if this was an "additional" notification.
1211    Notified {
1212        /// Whether or not this is an "additional" notification.
1213        additional: bool,
1214
1215        /// The tag associated with the notification.
1216        tag: T,
1217    },
1218
1219    /// A task is waiting for a notification.
1220    Task(Task),
1221
1222    /// Empty hole used to replace a notified listener.
1223    NotifiedTaken,
1224}
1225
1226impl<T> fmt::Debug for State<T> {
1227    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1228        match self {
1229            Self::Created => f.write_str("Created"),
1230            Self::Notified { additional, .. } => f
1231                .debug_struct("Notified")
1232                .field("additional", additional)
1233                .finish(),
1234            Self::Task(_) => f.write_str("Task(_)"),
1235            Self::NotifiedTaken => f.write_str("NotifiedTaken"),
1236        }
1237    }
1238}
1239
1240impl<T> State<T> {
1241    fn is_notified(&self) -> bool {
1242        matches!(self, Self::Notified { .. } | Self::NotifiedTaken)
1243    }
1244
1245    /// If this state was notified, return the tag associated with the notification.
1246    #[allow(unused)]
1247    fn notified(self) -> Option<T> {
1248        match self {
1249            Self::Notified { tag, .. } => Some(tag),
1250            Self::NotifiedTaken => panic!("listener was already notified but taken"),
1251            _ => None,
1252        }
1253    }
1254}
1255
1256/// The result of registering a listener.
1257#[derive(Debug, PartialEq)]
1258enum RegisterResult<T> {
1259    /// The listener was already notified.
1260    Notified(T),
1261
1262    /// The listener has been registered.
1263    Registered,
1264
1265    /// The listener was never inserted into the list.
1266    NeverInserted,
1267}
1268
1269impl<T> RegisterResult<T> {
1270    /// Whether or not the listener was notified.
1271    ///
1272    /// Panics if the listener was never inserted into the list.
1273    fn notified(self) -> Option<T> {
1274        match self {
1275            Self::Notified(tag) => Some(tag),
1276            Self::Registered => None,
1277            Self::NeverInserted => panic!("{}", NEVER_INSERTED_PANIC),
1278        }
1279    }
1280}
1281
1282/// A task that can be woken up.
1283#[derive(Debug, Clone)]
1284enum Task {
1285    /// A waker that wakes up a future.
1286    Waker(Waker),
1287
1288    /// An unparker that wakes up a thread.
1289    #[cfg(all(feature = "std", not(target_family = "wasm")))]
1290    Unparker(Unparker),
1291}
1292
1293impl Task {
1294    fn as_task_ref(&self) -> TaskRef<'_> {
1295        match self {
1296            Self::Waker(waker) => TaskRef::Waker(waker),
1297            #[cfg(all(feature = "std", not(target_family = "wasm")))]
1298            Self::Unparker(unparker) => TaskRef::Unparker(unparker),
1299        }
1300    }
1301
1302    fn wake(self) {
1303        match self {
1304            Self::Waker(waker) => waker.wake(),
1305            #[cfg(all(feature = "std", not(target_family = "wasm")))]
1306            Self::Unparker(unparker) => {
1307                unparker.unpark();
1308            }
1309        }
1310    }
1311}
1312
1313impl PartialEq for Task {
1314    fn eq(&self, other: &Self) -> bool {
1315        self.as_task_ref().will_wake(other.as_task_ref())
1316    }
1317}
1318
1319/// A reference to a task.
1320#[derive(Clone, Copy)]
1321enum TaskRef<'a> {
1322    /// A waker that wakes up a future.
1323    Waker(&'a Waker),
1324
1325    /// An unparker that wakes up a thread.
1326    #[cfg(all(feature = "std", not(target_family = "wasm")))]
1327    Unparker(&'a Unparker),
1328}
1329
1330impl TaskRef<'_> {
1331    /// Tells if this task will wake up the other task.
1332    #[allow(unreachable_patterns)]
1333    fn will_wake(self, other: Self) -> bool {
1334        match (self, other) {
1335            (Self::Waker(a), Self::Waker(b)) => a.will_wake(b),
1336            #[cfg(all(feature = "std", not(target_family = "wasm")))]
1337            (Self::Unparker(_), Self::Unparker(_)) => {
1338                // TODO: Use unreleased will_unpark API.
1339                false
1340            }
1341            _ => false,
1342        }
1343    }
1344
1345    /// Converts this task reference to a task by cloning.
1346    fn into_task(self) -> Task {
1347        match self {
1348            Self::Waker(waker) => Task::Waker(waker.clone()),
1349            #[cfg(all(feature = "std", not(target_family = "wasm")))]
1350            Self::Unparker(unparker) => Task::Unparker(unparker.clone()),
1351        }
1352    }
1353}
1354
1355const NEVER_INSERTED_PANIC: &str = "\
1356EventListener was not inserted into the linked list, make sure you're not polling \
1357EventListener/listener! after it has finished";
1358
1359#[cfg(not(loom))]
1360/// Synchronization primitive implementation.
1361mod sync {
1362    #[cfg(not(feature = "portable-atomic"))]
1363    pub(super) use alloc::sync::Arc;
1364    #[cfg(not(feature = "portable-atomic"))]
1365    pub(super) use core::sync::atomic;
1366
1367    #[cfg(feature = "portable-atomic")]
1368    pub(super) use portable_atomic_crate as atomic;
1369    #[cfg(feature = "portable-atomic")]
1370    pub(super) use portable_atomic_util::Arc;
1371
1372    #[allow(unused)]
1373    #[cfg(all(feature = "std", not(feature = "critical-section"), not(loom)))]
1374    pub(super) use std::sync::{Mutex, MutexGuard};
1375    #[cfg(all(feature = "std", not(target_family = "wasm"), not(loom)))]
1376    pub(super) use std::thread_local;
1377
1378    pub(super) trait WithMut {
1379        type Output;
1380
1381        fn with_mut<F, R>(&mut self, f: F) -> R
1382        where
1383            F: FnOnce(&mut Self::Output) -> R;
1384    }
1385
1386    impl<T> WithMut for atomic::AtomicPtr<T> {
1387        type Output = *mut T;
1388
1389        #[inline]
1390        fn with_mut<F, R>(&mut self, f: F) -> R
1391        where
1392            F: FnOnce(&mut Self::Output) -> R,
1393        {
1394            f(self.get_mut())
1395        }
1396    }
1397
1398    pub(crate) mod cell {
1399        pub(crate) use core::cell::Cell;
1400
1401        /// This newtype around *mut T exists for interoperability with loom::cell::ConstPtr,
1402        /// which works as a guard and performs additional logic to track access scope.
1403        pub(crate) struct ConstPtr<T>(*mut T);
1404        impl<T> ConstPtr<T> {
1405            pub(crate) unsafe fn deref(&self) -> &T {
1406                &*self.0
1407            }
1408
1409            #[allow(unused)] // std code does not need this
1410            pub(crate) unsafe fn deref_mut(&mut self) -> &mut T {
1411                &mut *self.0
1412            }
1413        }
1414
1415        /// This UnsafeCell wrapper exists for interoperability with loom::cell::UnsafeCell, and
1416        /// only contains the interface that is needed for this crate.
1417        #[derive(Debug, Default)]
1418        pub(crate) struct UnsafeCell<T>(core::cell::UnsafeCell<T>);
1419
1420        impl<T> UnsafeCell<T> {
1421            pub(crate) fn new(data: T) -> UnsafeCell<T> {
1422                UnsafeCell(core::cell::UnsafeCell::new(data))
1423            }
1424
1425            pub(crate) fn get(&self) -> ConstPtr<T> {
1426                ConstPtr(self.0.get())
1427            }
1428
1429            #[allow(dead_code)] // no_std does not need this
1430            pub(crate) fn into_inner(self) -> T {
1431                self.0.into_inner()
1432            }
1433        }
1434    }
1435}
1436
1437#[cfg(loom)]
1438/// Synchronization primitive implementation.
1439mod sync {
1440    pub(super) use loom::sync::{atomic, Arc, Mutex, MutexGuard};
1441    pub(super) use loom::{cell, thread_local};
1442}
1443
1444fn __test_send_and_sync() {
1445    fn _assert_send<T: Send>() {}
1446    fn _assert_sync<T: Sync>() {}
1447
1448    _assert_send::<crate::__private::StackSlot<'_, ()>>();
1449    _assert_sync::<crate::__private::StackSlot<'_, ()>>();
1450    _assert_send::<crate::__private::StackListener<'_, '_, ()>>();
1451    _assert_sync::<crate::__private::StackListener<'_, '_, ()>>();
1452    _assert_send::<Event<()>>();
1453    _assert_sync::<Event<()>>();
1454    _assert_send::<EventListener<()>>();
1455    _assert_sync::<EventListener<()>>();
1456}
1457
1458#[doc(hidden)]
1459mod __sealed {
1460    use super::{EventListener, __private::StackListener};
1461
1462    pub trait Sealed {}
1463    impl<T> Sealed for EventListener<T> {}
1464    impl<T> Sealed for StackListener<'_, '_, T> {}
1465}
1466
1467/// Semver exempt module.
1468#[doc(hidden)]
1469pub mod __private {
1470    pub use core::pin::Pin;
1471
1472    use super::{Event, Inner, InnerListener};
1473    use core::fmt;
1474    use core::future::Future;
1475    use core::task::{Context, Poll};
1476
1477    pin_project_lite::pin_project! {
1478        /// Space on the stack where a stack-based listener can be allocated.
1479        #[doc(hidden)]
1480        #[project(!Unpin)]
1481        pub struct StackSlot<'ev, T> {
1482            #[pin]
1483            listener: InnerListener<T, &'ev Inner<T>>
1484        }
1485    }
1486
1487    impl<T> fmt::Debug for StackSlot<'_, T> {
1488        #[inline]
1489        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1490            f.debug_struct("StackSlot").finish_non_exhaustive()
1491        }
1492    }
1493
1494    impl<T> core::panic::UnwindSafe for StackSlot<'_, T> {}
1495    impl<T> core::panic::RefUnwindSafe for StackSlot<'_, T> {}
1496    unsafe impl<T> Send for StackSlot<'_, T> {}
1497    unsafe impl<T> Sync for StackSlot<'_, T> {}
1498
1499    impl<'ev, T> StackSlot<'ev, T> {
1500        /// Create a new `StackSlot` on the stack.
1501        #[inline]
1502        #[doc(hidden)]
1503        pub fn new(event: &'ev Event<T>) -> Self {
1504            let inner = unsafe { &*event.inner() };
1505            Self {
1506                listener: InnerListener {
1507                    event: inner,
1508                    listener: None,
1509                },
1510            }
1511        }
1512
1513        /// Start listening on this `StackSlot`.
1514        #[inline]
1515        #[doc(hidden)]
1516        pub fn listen(mut self: Pin<&mut Self>) -> StackListener<'ev, '_, T> {
1517            // Insert ourselves into the list.
1518            self.as_mut().project().listener.listen();
1519
1520            // We are now listening.
1521            StackListener { slot: self }
1522        }
1523    }
1524
1525    /// A stack-based `EventListener`.
1526    #[doc(hidden)]
1527    pub struct StackListener<'ev, 'stack, T> {
1528        slot: Pin<&'stack mut StackSlot<'ev, T>>,
1529    }
1530
1531    impl<T> core::panic::UnwindSafe for StackListener<'_, '_, T> {}
1532    impl<T> core::panic::RefUnwindSafe for StackListener<'_, '_, T> {}
1533    impl<T> Unpin for StackListener<'_, '_, T> {}
1534
1535    impl<T> fmt::Debug for StackListener<'_, '_, T> {
1536        #[inline]
1537        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1538            f.debug_struct("StackListener").finish_non_exhaustive()
1539        }
1540    }
1541
1542    impl<'ev, T> StackListener<'ev, '_, T> {
1543        #[inline]
1544        fn listener(&self) -> &InnerListener<T, &'ev Inner<T>> {
1545            &self.slot.listener
1546        }
1547
1548        #[inline]
1549        fn listener_mut(&mut self) -> Pin<&mut InnerListener<T, &'ev Inner<T>>> {
1550            self.slot.as_mut().project().listener
1551        }
1552    }
1553
1554    forward_impl_to_listener! { T => StackListener<'_, '_, T> }
1555}