@@ -73,6 +73,7 @@ mod sys;
73
73
74
74
use alloc:: sync:: Arc ;
75
75
76
+ use core:: borrow:: Borrow ;
76
77
use core:: fmt;
77
78
use core:: future:: Future ;
78
79
use core:: mem:: ManuallyDrop ;
@@ -176,12 +177,12 @@ impl Event {
176
177
let inner = self . inner ( ) ;
177
178
178
179
// Register the listener.
179
- let mut listener = EventListener {
180
- inner : unsafe { Arc :: clone ( & ManuallyDrop :: new ( Arc :: from_raw ( inner) ) ) } ,
181
- state : sys:: Listener :: Discarded ,
182
- } ;
180
+ let mut listener = EventListener ( Listener {
181
+ event : unsafe { Arc :: clone ( & ManuallyDrop :: new ( Arc :: from_raw ( inner) ) ) } ,
182
+ listener : sys:: Listener :: Discarded ,
183
+ } ) ;
183
184
184
- listener. inner . insert ( & mut listener. state ) ;
185
+ listener. 0 . event . insert ( & mut listener. 0 . listener ) ;
185
186
186
187
// Make sure the listener is registered before whatever happens next.
187
188
full_fence ( ) ;
@@ -443,12 +444,12 @@ impl Default for Event {
443
444
/// If a notified listener is dropped without receiving a notification, dropping will notify
444
445
/// another active listener. Whether one *additional* listener will be notified depends on what
445
446
/// kind of notification was delivered.
446
- pub struct EventListener {
447
- /// A reference to [`Event`]'s inner state.
448
- inner : Arc < Inner > ,
447
+ pub struct EventListener ( Listener < Arc < Inner > > ) ;
449
448
450
- /// The current state of the listener.
451
- state : sys:: Listener ,
449
+ impl fmt:: Debug for EventListener {
450
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
451
+ f. write_str ( "EventListener { .. }" )
452
+ }
452
453
}
453
454
454
455
#[ cfg( feature = "std" ) ]
@@ -475,7 +476,7 @@ impl EventListener {
475
476
/// listener.wait();
476
477
/// ```
477
478
pub fn wait ( self ) {
478
- self . wait_internal ( None ) ;
479
+ self . 0 . wait_internal ( None ) ;
479
480
}
480
481
481
482
/// Blocks until a notification is received or a timeout is reached.
@@ -495,7 +496,7 @@ impl EventListener {
495
496
/// assert!(!listener.wait_timeout(Duration::from_secs(1)));
496
497
/// ```
497
498
pub fn wait_timeout ( self , timeout : Duration ) -> bool {
498
- self . wait_internal ( Some ( Instant :: now ( ) + timeout) )
499
+ self . 0 . wait_internal ( Instant :: now ( ) . checked_add ( timeout) )
499
500
}
500
501
501
502
/// Blocks until a notification is received or a deadline is reached.
@@ -509,69 +510,14 @@ impl EventListener {
509
510
/// use event_listener::Event;
510
511
///
511
512
/// let event = Event::new();
512
- /// let listener = event.listen();
513
+ /// let mut listener = event.listen();
513
514
///
514
515
/// // There are no notification so this times out.
515
- /// assert!(!listener.wait_deadline(Instant::now() + Duration::from_secs(1)));
516
+ /// assert!(!listener.as_mut(). wait_deadline(Instant::now() + Duration::from_secs(1)));
516
517
/// ```
518
+ #[ cfg( feature = "std" ) ]
517
519
pub fn wait_deadline ( self , deadline : Instant ) -> bool {
518
- self . wait_internal ( Some ( deadline) )
519
- }
520
-
521
- fn wait_internal ( mut self , deadline : Option < Instant > ) -> bool {
522
- let ( parker, unparker) = parking:: pair ( ) ;
523
-
524
- // Set the listener's state to `Task`.
525
- match self
526
- . inner
527
- . register ( & mut self . state , TaskRef :: Unparker ( & unparker) )
528
- {
529
- Some ( true ) => {
530
- // We were already notified, so we don't need to park.
531
- return true ;
532
- }
533
-
534
- Some ( false ) => {
535
- // We're now waiting for a notification.
536
- }
537
-
538
- None => {
539
- // We were never inserted into the list.
540
- panic ! ( "listener was never inserted into the list" ) ;
541
- }
542
- }
543
-
544
- // Wait until a notification is received or the timeout is reached.
545
- loop {
546
- match deadline {
547
- None => parker. park ( ) ,
548
-
549
- Some ( deadline) => {
550
- // Check for timeout.
551
- let now = Instant :: now ( ) ;
552
- if now >= deadline {
553
- // Remove our entry and check if we were notified.
554
- return self
555
- . inner
556
- . remove ( & mut self . state , false )
557
- . expect ( "We never removed ourself from the list" )
558
- . is_notified ( ) ;
559
- }
560
-
561
- // Park until the deadline.
562
- parker. park_timeout ( deadline - now) ;
563
- }
564
- }
565
-
566
- // See if we were notified.
567
- if self
568
- . inner
569
- . register ( & mut self . state , TaskRef :: Unparker ( & unparker) )
570
- . expect ( "We never removed ourself from the list" )
571
- {
572
- return true ;
573
- }
574
- }
520
+ self . 0 . wait_internal ( Some ( deadline) )
575
521
}
576
522
}
577
523
@@ -595,10 +541,8 @@ impl EventListener {
595
541
/// assert!(listener1.discard());
596
542
/// assert!(!listener2.discard());
597
543
/// ```
598
- pub fn discard ( mut self ) -> bool {
599
- self . inner
600
- . remove ( & mut self . state , false )
601
- . map_or ( false , |state| state. is_notified ( ) )
544
+ pub fn discard ( self ) -> bool {
545
+ self . 0 . discard ( )
602
546
}
603
547
604
548
/// Returns `true` if this listener listens to the given `Event`.
@@ -615,7 +559,7 @@ impl EventListener {
615
559
/// ```
616
560
#[ inline]
617
561
pub fn listens_to ( & self , event : & Event ) -> bool {
618
- ptr:: eq :: < Inner > ( & * self . inner , event. inner . load ( Ordering :: Acquire ) )
562
+ ptr:: eq :: < Inner > ( & * * self . inner ( ) , event. inner . load ( Ordering :: Acquire ) )
619
563
}
620
564
621
565
/// Returns `true` if both listeners listen to the same `Event`.
@@ -632,27 +576,112 @@ impl EventListener {
632
576
/// assert!(listener1.same_event(&listener2));
633
577
/// ```
634
578
pub fn same_event ( & self , other : & EventListener ) -> bool {
635
- ptr:: eq :: < Inner > ( & * self . inner , & * other. inner )
579
+ ptr:: eq :: < Inner > ( & * * self . inner ( ) , & * * other. inner ( ) )
636
580
}
637
- }
638
581
639
- impl fmt:: Debug for EventListener {
640
- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
641
- f. pad ( "EventListener { .. }" )
582
+ fn listener ( & mut self ) -> & mut Listener < Arc < Inner > > {
583
+ & mut self . 0
584
+ }
585
+
586
+ fn inner ( & self ) -> & Arc < Inner > {
587
+ & self . 0 . event
642
588
}
643
589
}
644
590
645
591
impl Future for EventListener {
646
592
type Output = ( ) ;
647
593
648
- #[ allow( unreachable_patterns) ]
649
- fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
650
- let this = self . get_mut ( ) ;
594
+ fn poll ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
595
+ self . listener ( ) . poll_internal ( cx)
596
+ }
597
+ }
598
+
599
+ struct Listener < B : Borrow < Inner > + Unpin > {
600
+ /// The reference to the original event.
601
+ event : B ,
602
+
603
+ /// The inner state of the listener.
604
+ listener : sys:: Listener ,
605
+ }
606
+
607
+ unsafe impl < B : Borrow < Inner > + Unpin + Send > Send for Listener < B > { }
608
+ unsafe impl < B : Borrow < Inner > + Unpin + Sync > Sync for Listener < B > { }
609
+
610
+ impl < B : Borrow < Inner > + Unpin > Listener < B > {
611
+ /// Wait until the provided deadline.
612
+ #[ cfg( feature = "std" ) ]
613
+ fn wait_internal ( mut self , deadline : Option < Instant > ) -> bool {
614
+ let ( parker, unparker) = parking:: pair ( ) ;
615
+
616
+ // Set the listener's state to `Task`.
617
+ match self
618
+ . event
619
+ . borrow ( )
620
+ . register ( & mut self . listener , TaskRef :: Unparker ( & unparker) )
621
+ {
622
+ Some ( true ) => {
623
+ // We were already notified, so we don't need to park.
624
+ return true ;
625
+ }
626
+
627
+ Some ( false ) => {
628
+ // We're now waiting for a notification.
629
+ }
651
630
631
+ None => {
632
+ // We were never inserted into the list.
633
+ panic ! ( "listener was never inserted into the list" ) ;
634
+ }
635
+ }
636
+
637
+ // Wait until a notification is received or the timeout is reached.
638
+ loop {
639
+ match deadline {
640
+ None => parker. park ( ) ,
641
+
642
+ Some ( deadline) => {
643
+ // Make sure we're not timed out already.
644
+ let now = Instant :: now ( ) ;
645
+ if now >= deadline {
646
+ // Remove our entry and check if we were notified.
647
+ return self
648
+ . event
649
+ . borrow ( )
650
+ . remove ( & mut self . listener , false )
651
+ . expect ( "We never removed ourself from the list" )
652
+ . is_notified ( ) ;
653
+ }
654
+ }
655
+ }
656
+
657
+ // See if we were notified.
658
+ if self
659
+ . event
660
+ . borrow ( )
661
+ . register ( & mut self . listener , TaskRef :: Unparker ( & unparker) )
662
+ . expect ( "We never removed ourself from the list" )
663
+ {
664
+ return true ;
665
+ }
666
+ }
667
+ }
668
+
669
+ /// Drops this listener and discards its notification (if any) without notifying another
670
+ /// active listener.
671
+ fn discard ( mut self ) -> bool {
672
+ self . event
673
+ . borrow ( )
674
+ . remove ( & mut self . listener , false )
675
+ . map_or ( false , |state| state. is_notified ( ) )
676
+ }
677
+
678
+ /// Poll this listener for a notification.
679
+ fn poll_internal ( & mut self , cx : & mut Context < ' _ > ) -> Poll < ( ) > {
652
680
// Try to register the listener.
653
- match this
654
- . inner
655
- . register ( & mut this. state , TaskRef :: Waker ( cx. waker ( ) ) )
681
+ match self
682
+ . event
683
+ . borrow ( )
684
+ . register ( & mut self . listener , TaskRef :: Waker ( cx. waker ( ) ) )
656
685
{
657
686
Some ( true ) => {
658
687
// We were already notified, so we don't need to park.
@@ -672,9 +701,10 @@ impl Future for EventListener {
672
701
}
673
702
}
674
703
675
- impl Drop for EventListener {
704
+ impl < B : Borrow < Inner > + Unpin > Drop for Listener < B > {
676
705
fn drop ( & mut self ) {
677
- self . inner . remove ( & mut self . state , true ) ;
706
+ // If we're being dropped, we need to remove ourself from the list.
707
+ self . event . borrow ( ) . remove ( & mut self . listener , true ) ;
678
708
}
679
709
}
680
710
0 commit comments