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