Skip to content

Commit d9144a8

Browse files
committed
feat: Create Listener trait
This commit creates the Listener trait and moves most of EventListener's functionality to that trait. Signed-off-by: John Nunley <[email protected]>
1 parent 86b7780 commit d9144a8

File tree

3 files changed

+110
-78
lines changed

3 files changed

+110
-78
lines changed

benches/bench.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::iter;
22

33
use criterion::{criterion_group, criterion_main, Criterion};
4-
use event_listener::Event;
4+
use event_listener::{prelude::*, Event};
55

66
const COUNT: usize = 8000;
77

examples/mutex.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ mod example {
1313
use std::thread;
1414
use std::time::{Duration, Instant};
1515

16-
use event_listener::Event;
16+
use event_listener::{Event, Listener};
1717

1818
/// A simple mutex.
1919
struct Mutex<T> {

src/lib.rs

Lines changed: 108 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
//! use std::thread;
2020
//! use std::time::Duration;
2121
//! use std::usize;
22-
//! use event_listener::Event;
22+
//! use event_listener::{Event, prelude::*};
2323
//!
2424
//! let flag = Arc::new(AtomicBool::new(false));
2525
//! let event = Arc::new(Event::new());
@@ -108,7 +108,7 @@ pub use notify::{IntoNotification, Notification};
108108

109109
/// Useful traits for notifications.
110110
pub mod prelude {
111-
pub use crate::{IntoNotification, Notification};
111+
pub use crate::{IntoNotification, Listener, Notification};
112112
}
113113

114114
/// Inner state of [`Event`].
@@ -213,7 +213,7 @@ impl<T> Event<T> {
213213
/// # Examples
214214
///
215215
/// ```
216-
/// use event_listener::Event;
216+
/// use event_listener::{Event, prelude::*};
217217
///
218218
/// let event = Event::<usize>::with_tag();
219219
/// ```
@@ -230,7 +230,7 @@ impl<T> Event<T> {
230230
/// # Examples
231231
///
232232
/// ```
233-
/// use event_listener::Event;
233+
/// use event_listener::{Event, prelude::*};
234234
///
235235
/// let event = Event::new();
236236
/// let listener = event.listen();
@@ -254,7 +254,7 @@ impl<T> Event<T> {
254254
/// # Examples
255255
///
256256
/// ```
257-
/// use event_listener::Event;
257+
/// use event_listener::{Event, prelude::*};
258258
///
259259
/// let event = Event::new();
260260
/// let listener = event.listen();
@@ -283,7 +283,7 @@ impl<T> Event<T> {
283283
let inner = ManuallyDrop::new(unsafe { Arc::from_raw(self.inner()) });
284284

285285
// Allocate the listener on the heap and insert it.
286-
let mut listener = Box::pin(Listener {
286+
let mut listener = Box::pin(InnerListener {
287287
event: Arc::clone(&inner),
288288
listener: None,
289289
});
@@ -322,7 +322,7 @@ impl<T> Event<T> {
322322
/// Use the default notification strategy:
323323
///
324324
/// ```
325-
/// use event_listener::Event;
325+
/// use event_listener::{Event, prelude::*};
326326
///
327327
/// let event = Event::new();
328328
///
@@ -539,7 +539,7 @@ impl Event<()> {
539539
/// # Examples
540540
///
541541
/// ```
542-
/// use event_listener::Event;
542+
/// use event_listener::{Event, prelude::*};
543543
///
544544
/// let event = Event::new();
545545
/// ```
@@ -576,7 +576,7 @@ impl Event<()> {
576576
/// # Examples
577577
///
578578
/// ```
579-
/// use event_listener::Event;
579+
/// use event_listener::{Event, prelude::*};
580580
/// use std::sync::atomic::{self, Ordering};
581581
///
582582
/// let event = Event::new();
@@ -628,7 +628,7 @@ impl Event<()> {
628628
/// # Examples
629629
///
630630
/// ```
631-
/// use event_listener::Event;
631+
/// use event_listener::{Event, prelude::*};
632632
///
633633
/// let event = Event::new();
634634
///
@@ -678,7 +678,7 @@ impl Event<()> {
678678
/// # Examples
679679
///
680680
/// ```
681-
/// use event_listener::Event;
681+
/// use event_listener::{Event, prelude::*};
682682
/// use std::sync::atomic::{self, Ordering};
683683
///
684684
/// let event = Event::new();
@@ -720,47 +720,17 @@ impl<T> Drop for Event<T> {
720720
}
721721
}
722722

723-
/// A guard waiting for a notification from an [`Event`].
724-
///
725-
/// There are two ways for a listener to wait for a notification:
726-
///
727-
/// 1. In an asynchronous manner using `.await`.
728-
/// 2. In a blocking manner by calling [`EventListener::wait()`] on it.
723+
/// A handle that is listening to an [`Event`].
729724
///
730-
/// If a notified listener is dropped without receiving a notification, dropping will notify
731-
/// another active listener. Whether one *additional* listener will be notified depends on what
732-
/// kind of notification was delivered.
733-
///
734-
/// The listener is not registered into the linked list inside of the [`Event`] by default if
735-
/// it is created via the `new()` method. It needs to be pinned first before being inserted
736-
/// using the `listen()` method. After the listener has begun `listen`ing, the user can
737-
/// `await` it like a future or call `wait()` to block the current thread until it is notified.
738-
///
739-
/// This structure allocates the listener on the heap.
740-
pub struct EventListener<T = ()> {
741-
listener: Pin<Box<Listener<T, Arc<Inner<T>>>>>,
742-
}
743-
744-
unsafe impl<T: Send> Send for EventListener<T> {}
745-
unsafe impl<T: Send> Sync for EventListener<T> {}
746-
747-
impl<T> core::panic::UnwindSafe for EventListener<T> {}
748-
impl<T> core::panic::RefUnwindSafe for EventListener<T> {}
749-
impl<T> Unpin for EventListener<T> {}
750-
751-
impl<T> fmt::Debug for EventListener<T> {
752-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
753-
f.debug_struct("EventListener").finish_non_exhaustive()
754-
}
755-
}
756-
757-
impl<T> EventListener<T> {
725+
/// This trait represents a type waiting for a notification from an [`Event`]. See the
726+
/// [`EventListener`] type for more documentation on this trait's usage.
727+
pub trait Listener<T>: Future<Output = T> + __private::Sealed {
758728
/// Blocks until a notification is received.
759729
///
760730
/// # Examples
761731
///
762732
/// ```
763-
/// use event_listener::Event;
733+
/// use event_listener::{Event, prelude::*};
764734
///
765735
/// let event = Event::new();
766736
/// let mut listener = event.listen();
@@ -772,9 +742,7 @@ impl<T> EventListener<T> {
772742
/// listener.wait();
773743
/// ```
774744
#[cfg(all(feature = "std", not(target_family = "wasm")))]
775-
pub fn wait(mut self) -> T {
776-
self.listener.as_mut().wait_internal(None).unwrap()
777-
}
745+
fn wait(self) -> T;
778746

779747
/// Blocks until a notification is received or a timeout is reached.
780748
///
@@ -784,7 +752,7 @@ impl<T> EventListener<T> {
784752
///
785753
/// ```
786754
/// use std::time::Duration;
787-
/// use event_listener::Event;
755+
/// use event_listener::{Event, prelude::*};
788756
///
789757
/// let event = Event::new();
790758
/// let mut listener = event.listen();
@@ -793,11 +761,7 @@ impl<T> EventListener<T> {
793761
/// assert!(listener.wait_timeout(Duration::from_secs(1)).is_none());
794762
/// ```
795763
#[cfg(all(feature = "std", not(target_family = "wasm")))]
796-
pub fn wait_timeout(mut self, timeout: Duration) -> Option<T> {
797-
self.listener
798-
.as_mut()
799-
.wait_internal(Instant::now().checked_add(timeout))
800-
}
764+
fn wait_timeout(self, timeout: Duration) -> Option<T>;
801765

802766
/// Blocks until a notification is received or a deadline is reached.
803767
///
@@ -807,7 +771,7 @@ impl<T> EventListener<T> {
807771
///
808772
/// ```
809773
/// use std::time::{Duration, Instant};
810-
/// use event_listener::Event;
774+
/// use event_listener::{Event, prelude::*};
811775
///
812776
/// let event = Event::new();
813777
/// let mut listener = event.listen();
@@ -816,19 +780,17 @@ impl<T> EventListener<T> {
816780
/// assert!(listener.wait_deadline(Instant::now() + Duration::from_secs(1)).is_none());
817781
/// ```
818782
#[cfg(all(feature = "std", not(target_family = "wasm")))]
819-
pub fn wait_deadline(mut self, deadline: Instant) -> Option<T> {
820-
self.listener.as_mut().wait_internal(Some(deadline))
821-
}
783+
fn wait_deadline(self, deadline: Instant) -> Option<T>;
822784

823785
/// Drops this listener and discards its notification (if any) without notifying another
824786
/// active listener.
825787
///
826788
/// Returns `true` if a notification was discarded.
827789
///
828790
/// # Examples
829-
///
791+
///
830792
/// ```
831-
/// use event_listener::Event;
793+
/// use event_listener::{Event, prelude::*};
832794
///
833795
/// let event = Event::new();
834796
/// let mut listener1 = event.listen();
@@ -839,41 +801,103 @@ impl<T> EventListener<T> {
839801
/// assert!(listener1.discard());
840802
/// assert!(!listener2.discard());
841803
/// ```
842-
pub fn discard(mut self) -> bool {
843-
self.listener.as_mut().discard()
844-
}
804+
fn discard(self) -> bool;
845805

846806
/// Returns `true` if this listener listens to the given `Event`.
847807
///
848808
/// # Examples
849809
///
850810
/// ```
851-
/// use event_listener::Event;
811+
/// use event_listener::{Event, prelude::*};
852812
///
853813
/// let event = Event::new();
854814
/// let listener = event.listen();
855815
///
856816
/// assert!(listener.listens_to(&event));
857817
/// ```
858-
#[inline]
859-
pub fn listens_to(&self, event: &Event<T>) -> bool {
860-
ptr::eq::<Inner<T>>(&*self.listener.event, event.inner.load(Ordering::Acquire))
861-
}
818+
fn listens_to(&self, event: &Event<T>) -> bool;
862819

863820
/// Returns `true` if both listeners listen to the same `Event`.
864821
///
865822
/// # Examples
866823
///
867824
/// ```
868-
/// use event_listener::Event;
825+
/// use event_listener::{Event, prelude::*};
869826
///
870827
/// let event = Event::new();
871828
/// let listener1 = event.listen();
872829
/// let listener2 = event.listen();
873830
///
874831
/// assert!(listener1.same_event(&listener2));
875832
/// ```
876-
pub fn same_event(&self, other: &EventListener<T>) -> bool {
833+
fn same_event(&self, other: &Self) -> bool;
834+
}
835+
836+
/// A guard waiting for a notification from an [`Event`].
837+
///
838+
/// There are two ways for a listener to wait for a notification:
839+
///
840+
/// 1. In an asynchronous manner using `.await`.
841+
/// 2. In a blocking manner by calling [`EventListener::wait()`] on it.
842+
///
843+
/// If a notified listener is dropped without receiving a notification, dropping will notify
844+
/// another active listener. Whether one *additional* listener will be notified depends on what
845+
/// kind of notification was delivered.
846+
///
847+
/// See the [`Listener`] trait for the functionality exposed by this type.
848+
///
849+
/// The listener is not registered into the linked list inside of the [`Event`] by default if
850+
/// it is created via the `new()` method. It needs to be pinned first before being inserted
851+
/// using the `listen()` method. After the listener has begun `listen`ing, the user can
852+
/// `await` it like a future or call `wait()` to block the current thread until it is notified.
853+
///
854+
/// This structure allocates the listener on the heap.
855+
pub struct EventListener<T = ()> {
856+
listener: Pin<Box<InnerListener<T, Arc<Inner<T>>>>>,
857+
}
858+
859+
unsafe impl<T: Send> Send for EventListener<T> {}
860+
unsafe impl<T: Send> Sync for EventListener<T> {}
861+
862+
impl<T> core::panic::UnwindSafe for EventListener<T> {}
863+
impl<T> core::panic::RefUnwindSafe for EventListener<T> {}
864+
impl<T> Unpin for EventListener<T> {}
865+
866+
impl<T> fmt::Debug for EventListener<T> {
867+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
868+
f.debug_struct("EventListener").finish_non_exhaustive()
869+
}
870+
}
871+
872+
impl<T> Listener<T> for EventListener<T> {
873+
#[cfg(all(feature = "std", not(target_family = "wasm")))]
874+
fn wait(mut self) -> T {
875+
self.listener.as_mut().wait_internal(None).unwrap()
876+
}
877+
878+
#[cfg(all(feature = "std", not(target_family = "wasm")))]
879+
fn wait_timeout(mut self, timeout: Duration) -> Option<T> {
880+
self.listener
881+
.as_mut()
882+
.wait_internal(Instant::now().checked_add(timeout))
883+
}
884+
885+
#[cfg(all(feature = "std", not(target_family = "wasm")))]
886+
fn wait_deadline(mut self, deadline: Instant) -> Option<T> {
887+
self.listener.as_mut().wait_internal(Some(deadline))
888+
}
889+
890+
fn discard(mut self) -> bool {
891+
self.listener.as_mut().discard()
892+
}
893+
894+
#[inline]
895+
fn listens_to(&self, event: &Event<T>) -> bool {
896+
ptr::eq::<Inner<T>>(&*self.listener.event, event.inner.load(Ordering::Acquire))
897+
}
898+
899+
#[inline]
900+
fn same_event(&self, other: &EventListener<T>) -> bool {
877901
ptr::eq::<Inner<T>>(&*self.listener.event, &*other.listener.event)
878902
}
879903
}
@@ -889,7 +913,7 @@ impl<T> Future for EventListener<T> {
889913
pin_project_lite::pin_project! {
890914
#[project(!Unpin)]
891915
#[project = ListenerProject]
892-
struct Listener<T, B: Borrow<Inner<T>>>
916+
struct InnerListener<T, B: Borrow<Inner<T>>>
893917
where
894918
B: Unpin,
895919
{
@@ -904,7 +928,7 @@ pin_project_lite::pin_project! {
904928
listener: Option<sys::Listener<T>>,
905929
}
906930

907-
impl<T, B: Borrow<Inner<T>>> PinnedDrop for Listener<T, B>
931+
impl<T, B: Borrow<Inner<T>>> PinnedDrop for InnerListener<T, B>
908932
where
909933
B: Unpin,
910934
{
@@ -916,10 +940,10 @@ pin_project_lite::pin_project! {
916940
}
917941
}
918942

919-
unsafe impl<T: Send, B: Borrow<Inner<T>> + Unpin + Send> Send for Listener<T, B> {}
920-
unsafe impl<T: Send, B: Borrow<Inner<T>> + Unpin + Sync> Sync for Listener<T, B> {}
943+
unsafe impl<T: Send, B: Borrow<Inner<T>> + Unpin + Send> Send for InnerListener<T, B> {}
944+
unsafe impl<T: Send, B: Borrow<Inner<T>> + Unpin + Sync> Sync for InnerListener<T, B> {}
921945

922-
impl<T, B: Borrow<Inner<T>> + Unpin> Listener<T, B> {
946+
impl<T, B: Borrow<Inner<T>> + Unpin> InnerListener<T, B> {
923947
/// Wait until the provided deadline.
924948
#[cfg(all(feature = "std", not(target_family = "wasm")))]
925949
fn wait_internal(mut self: Pin<&mut Self>, deadline: Option<Instant>) -> Option<T> {
@@ -1225,3 +1249,11 @@ fn __test_send_and_sync() {
12251249
_assert_send::<EventListener<()>>();
12261250
_assert_sync::<EventListener<()>>();
12271251
}
1252+
1253+
#[doc(hidden)]
1254+
mod __private {
1255+
use super::EventListener;
1256+
1257+
pub trait Sealed {}
1258+
impl<T> Sealed for EventListener<T> {}
1259+
}

0 commit comments

Comments
 (0)