@@ -287,7 +287,7 @@ impl<T> Event<T> {
287287 event : Arc :: clone ( & inner) ,
288288 listener : None ,
289289 } ) ;
290- inner . insert ( listener. as_mut ( ) . project ( ) . listener ) ;
290+ listener. as_mut ( ) . listen ( ) ;
291291
292292 // Return the listener.
293293 EventListener { listener }
@@ -724,7 +724,7 @@ impl<T> Drop for Event<T> {
724724///
725725/// This trait represents a type waiting for a notification from an [`Event`]. See the
726726/// [`EventListener`] type for more documentation on this trait's usage.
727- pub trait Listener < T > : Future < Output = T > + __private :: Sealed {
727+ pub trait Listener < T > : Future < Output = T > + __sealed :: Sealed {
728728 /// Blocks until a notification is received.
729729 ///
730730 /// # Examples
@@ -833,6 +833,45 @@ pub trait Listener<T>: Future<Output = T> + __private::Sealed {
833833 fn same_event ( & self , other : & Self ) -> bool ;
834834}
835835
836+ macro_rules! forward_impl_to_listener {
837+ ( $gen: ident => $ty: ty) => {
838+ impl <$gen> crate :: Listener <$gen> for $ty {
839+ #[ cfg( all( feature = "std" , not( target_family = "wasm" ) ) ) ]
840+ fn wait( mut self ) -> $gen {
841+ self . listener_mut( ) . wait_internal( None ) . unwrap( )
842+ }
843+
844+ #[ cfg( all( feature = "std" , not( target_family = "wasm" ) ) ) ]
845+ fn wait_timeout( mut self , timeout: std:: time:: Duration ) -> Option <$gen> {
846+ self . listener_mut( )
847+ . wait_internal( std:: time:: Instant :: now( ) . checked_add( timeout) )
848+ }
849+
850+ #[ cfg( all( feature = "std" , not( target_family = "wasm" ) ) ) ]
851+ fn wait_deadline( mut self , deadline: std:: time:: Instant ) -> Option <$gen> {
852+ self . listener_mut( ) . wait_internal( Some ( deadline) )
853+ }
854+
855+ fn discard( mut self ) -> bool {
856+ self . listener_mut( ) . discard( )
857+ }
858+
859+ #[ inline]
860+ fn listens_to( & self , event: & Event <$gen>) -> bool {
861+ core:: ptr:: eq:: <Inner <$gen>>(
862+ & * self . listener( ) . event,
863+ event. inner. load( core:: sync:: atomic:: Ordering :: Acquire ) ,
864+ )
865+ }
866+
867+ #[ inline]
868+ fn same_event( & self , other: & $ty) -> bool {
869+ core:: ptr:: eq:: <Inner <$gen>>( & * self . listener( ) . event, & * other. listener( ) . event)
870+ }
871+ }
872+ } ;
873+ }
874+
836875/// A guard waiting for a notification from an [`Event`].
837876///
838877/// There are two ways for a listener to wait for a notification:
@@ -869,39 +908,20 @@ impl<T> fmt::Debug for EventListener<T> {
869908 }
870909}
871910
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-
911+ impl < T > EventListener < T > {
894912 #[ inline]
895- fn listens_to ( & self , event : & Event < T > ) -> bool {
896- ptr :: eq :: < Inner < T > > ( & * self . listener . event , event . inner . load ( Ordering :: Acquire ) )
913+ fn listener ( & self ) -> & InnerListener < T , Arc < Inner < T > > > {
914+ & self . listener
897915 }
898916
899917 #[ inline]
900- fn same_event ( & self , other : & EventListener < T > ) -> bool {
901- ptr :: eq :: < Inner < T > > ( & * self . listener . event , & * other . listener . event )
918+ fn listener_mut ( & mut self ) -> Pin < & mut InnerListener < T , Arc < Inner < T > > > > {
919+ self . listener . as_mut ( )
902920 }
903921}
904922
923+ forward_impl_to_listener ! { T => EventListener <T > }
924+
905925impl < T > Future for EventListener < T > {
906926 type Output = T ;
907927
@@ -910,6 +930,18 @@ impl<T> Future for EventListener<T> {
910930 }
911931}
912932
933+ /// Create a stack-based event listener for an [`Event`].
934+ #[ macro_export]
935+ macro_rules! listener {
936+ ( $event: expr => $listener: ident) => {
937+ let mut $listener = $crate:: __private:: StackSlot :: new( & $event) ;
938+ // SAFETY: We shadow $listener so it can't be moved after.
939+ let mut $listener = unsafe { $crate:: __private:: Pin :: new_unchecked( & mut $listener) } ;
940+ #[ allow( unused_mut) ]
941+ let mut $listener = $listener. listen( ) ;
942+ } ;
943+ }
944+
913945pin_project_lite:: pin_project! {
914946 #[ project( !Unpin ) ]
915947 #[ project = ListenerProject ]
@@ -944,6 +976,13 @@ unsafe impl<T: Send, B: Borrow<Inner<T>> + Unpin + Send> Send for InnerListener<
944976unsafe impl < T : Send , B : Borrow < Inner < T > > + Unpin + Sync > Sync for InnerListener < T , B > { }
945977
946978impl < T , B : Borrow < Inner < T > > + Unpin > InnerListener < T , B > {
979+ /// Insert this listener into the linked list.
980+ #[ inline]
981+ fn listen ( self : Pin < & mut Self > ) {
982+ let this = self . project ( ) ;
983+ ( * this. event ) . borrow ( ) . insert ( this. listener ) ;
984+ }
985+
947986 /// Wait until the provided deadline.
948987 #[ cfg( all( feature = "std" , not( target_family = "wasm" ) ) ) ]
949988 fn wait_internal ( mut self : Pin < & mut Self > , deadline : Option < Instant > ) -> Option < T > {
@@ -1251,9 +1290,99 @@ fn __test_send_and_sync() {
12511290}
12521291
12531292#[ doc( hidden) ]
1254- mod __private {
1255- use super :: EventListener ;
1293+ mod __sealed {
1294+ use super :: { EventListener , __private :: StackListener } ;
12561295
12571296 pub trait Sealed { }
12581297 impl < T > Sealed for EventListener < T > { }
1298+ impl < T > Sealed for StackListener < ' _ , ' _ , T > { }
1299+ }
1300+
1301+ /// Semver exempt module.
1302+ #[ doc( hidden) ]
1303+ pub mod __private {
1304+ pub use core:: pin:: Pin ;
1305+
1306+ use super :: { Event , Inner , InnerListener } ;
1307+ use core:: fmt;
1308+ use core:: future:: Future ;
1309+ use core:: task:: { Context , Poll } ;
1310+
1311+ pin_project_lite:: pin_project! {
1312+ /// Space on the stack where a stack-based listener can be allocated.
1313+ #[ doc( hidden) ]
1314+ pub struct StackSlot <' ev, T > {
1315+ #[ pin]
1316+ listener: InnerListener <T , & ' ev Inner <T >>
1317+ }
1318+ }
1319+
1320+ impl < T > fmt:: Debug for StackSlot < ' _ , T > {
1321+ #[ inline]
1322+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1323+ f. debug_struct ( "StackSlot" ) . finish_non_exhaustive ( )
1324+ }
1325+ }
1326+
1327+ impl < ' ev , T > StackSlot < ' ev , T > {
1328+ /// Create a new `StackSlot` on the stack.
1329+ #[ inline]
1330+ #[ doc( hidden) ]
1331+ pub fn new ( event : & ' ev Event < T > ) -> Self {
1332+ let inner = unsafe { & * event. inner ( ) } ;
1333+ Self {
1334+ listener : InnerListener {
1335+ event : inner,
1336+ listener : None ,
1337+ } ,
1338+ }
1339+ }
1340+
1341+ /// Start listening on this `StackSlot`.
1342+ #[ inline]
1343+ #[ doc( hidden) ]
1344+ pub fn listen ( mut self : Pin < & mut Self > ) -> StackListener < ' ev , ' _ , T > {
1345+ // Insert ourselves into the list.
1346+ self . as_mut ( ) . project ( ) . listener . listen ( ) ;
1347+
1348+ // We are now listening.
1349+ StackListener { slot : self }
1350+ }
1351+ }
1352+
1353+ /// A stack-based `EventListener`.
1354+ #[ doc( hidden) ]
1355+ pub struct StackListener < ' ev , ' stack , T > {
1356+ slot : Pin < & ' stack mut StackSlot < ' ev , T > > ,
1357+ }
1358+
1359+ impl < T > fmt:: Debug for StackListener < ' _ , ' _ , T > {
1360+ #[ inline]
1361+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1362+ f. debug_struct ( "StackListener" ) . finish_non_exhaustive ( )
1363+ }
1364+ }
1365+
1366+ impl < ' ev , T > StackListener < ' ev , ' _ , T > {
1367+ #[ inline]
1368+ fn listener ( & self ) -> & InnerListener < T , & ' ev Inner < T > > {
1369+ & self . slot . listener
1370+ }
1371+
1372+ #[ inline]
1373+ fn listener_mut ( & mut self ) -> Pin < & mut InnerListener < T , & ' ev Inner < T > > > {
1374+ self . slot . as_mut ( ) . project ( ) . listener
1375+ }
1376+ }
1377+
1378+ forward_impl_to_listener ! { T => StackListener <' _, ' _, T > }
1379+
1380+ impl < T > Future for StackListener < ' _ , ' _ , T > {
1381+ type Output = T ;
1382+
1383+ #[ inline]
1384+ fn poll ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
1385+ self . listener_mut ( ) . poll_internal ( cx)
1386+ }
1387+ }
12591388}
0 commit comments