@@ -117,6 +117,9 @@ pub trait SerialEvents {
117117 fn out_byte ( & self ) ;
118118 /// An error occurred while writing a byte to serial output resulting in a lost byte.
119119 fn tx_lost_byte ( & self ) ;
120+ /// This event can be used by the consumer to re-enable events coming from
121+ /// the serial input.
122+ fn in_buffer_empty ( & self ) ;
120123}
121124
122125/// Provides a no-op implementation of `SerialEvents` which can be used in situations that
@@ -128,6 +131,7 @@ impl SerialEvents for NoEvents {
128131 fn buffer_read ( & self ) { }
129132 fn out_byte ( & self ) { }
130133 fn tx_lost_byte ( & self ) { }
134+ fn in_buffer_empty ( & self ) { }
131135}
132136
133137impl < EV : SerialEvents > SerialEvents for Arc < EV > {
@@ -142,6 +146,10 @@ impl<EV: SerialEvents> SerialEvents for Arc<EV> {
142146 fn tx_lost_byte ( & self ) {
143147 self . as_ref ( ) . tx_lost_byte ( ) ;
144148 }
149+
150+ fn in_buffer_empty ( & self ) {
151+ self . as_ref ( ) . in_buffer_empty ( ) ;
152+ }
145153}
146154
147155/// The serial console emulation is done by emulating a serial COM port.
@@ -450,12 +458,13 @@ impl<T: Trigger, EV: SerialEvents, W: Write> Serial<T, EV, W> {
450458 // interrupt identification register and RDA bit when no
451459 // more data is available).
452460 self . del_interrupt ( IIR_RDA_BIT ) ;
453- if self . in_buffer . len ( ) <= 1 {
461+ let byte = self . in_buffer . pop_front ( ) . unwrap_or_default ( ) ;
462+ if self . in_buffer . is_empty ( ) {
454463 self . clear_lsr_rda_bit ( ) ;
464+ self . events . in_buffer_empty ( ) ;
455465 }
456-
457466 self . events . buffer_read ( ) ;
458- self . in_buffer . pop_front ( ) . unwrap_or_default ( )
467+ byte
459468 }
460469 IER_OFFSET => self . interrupt_enable ,
461470 IIR_OFFSET => {
@@ -566,14 +575,25 @@ mod tests {
566575 }
567576 }
568577
569- #[ derive( Default ) ]
570- struct ExampleSerialMetrics {
578+ struct ExampleSerialEvents {
571579 read_count : AtomicU64 ,
572580 out_byte_count : AtomicU64 ,
573581 tx_lost_byte_count : AtomicU64 ,
582+ buffer_ready_event : EventFd ,
583+ }
584+
585+ impl ExampleSerialEvents {
586+ fn new ( ) -> Self {
587+ ExampleSerialEvents {
588+ read_count : AtomicU64 :: new ( 0 ) ,
589+ out_byte_count : AtomicU64 :: new ( 0 ) ,
590+ tx_lost_byte_count : AtomicU64 :: new ( 0 ) ,
591+ buffer_ready_event : EventFd :: new ( libc:: EFD_NONBLOCK ) . unwrap ( ) ,
592+ }
593+ }
574594 }
575595
576- impl SerialEvents for ExampleSerialMetrics {
596+ impl SerialEvents for ExampleSerialEvents {
577597 fn buffer_read ( & self ) {
578598 self . read_count . inc ( ) ;
579599 // We can also log a message here, or as part of any of the other methods.
@@ -586,6 +606,10 @@ mod tests {
586606 fn tx_lost_byte ( & self ) {
587607 self . tx_lost_byte_count . inc ( ) ;
588608 }
609+
610+ fn in_buffer_empty ( & self ) {
611+ self . buffer_ready_event . write ( 1 ) . unwrap ( ) ;
612+ }
589613 }
590614
591615 #[ test]
@@ -812,18 +836,29 @@ mod tests {
812836 #[ test]
813837 fn test_serial_events ( ) {
814838 let intr_evt = EventFd :: new ( libc:: EFD_NONBLOCK ) . unwrap ( ) ;
815- let metrics = Arc :: new ( ExampleSerialMetrics :: default ( ) ) ;
839+
840+ let events_ = Arc :: new ( ExampleSerialEvents :: new ( ) ) ;
816841 let mut oneslot_buf = [ 0u8 ; 1 ] ;
817- let mut serial = Serial :: with_events ( intr_evt, metrics, oneslot_buf. as_mut ( ) ) ;
842+ let mut serial = Serial :: with_events ( intr_evt, events_, oneslot_buf. as_mut ( ) ) ;
843+
844+ // This should be an error because buffer_ready_event has not been
845+ // triggered yet so no one should have written to that fd yet.
846+ assert_eq ! (
847+ serial. events. buffer_ready_event. read( ) . unwrap_err( ) . kind( ) ,
848+ io:: ErrorKind :: WouldBlock
849+ ) ;
818850
819851 // Check everything is equal to 0 at the beginning.
820852 assert_eq ! ( serial. events. read_count. count( ) , 0 ) ;
821853 assert_eq ! ( serial. events. out_byte_count. count( ) , 0 ) ;
822854 assert_eq ! ( serial. events. tx_lost_byte_count. count( ) , 0 ) ;
823855
824856 // This DATA read should cause the `SerialEvents::buffer_read` method to be invoked.
857+ // And since the in_buffer is empty the buffer_ready_event should have
858+ // been triggered, hence we can read from that fd.
825859 serial. read ( DATA_OFFSET ) ;
826860 assert_eq ! ( serial. events. read_count. count( ) , 1 ) ;
861+ assert_eq ! ( serial. events. buffer_ready_event. read( ) . unwrap( ) , 1 ) ;
827862
828863 // This DATA write should cause `SerialEvents::out_byte` to be called.
829864 serial. write ( DATA_OFFSET , 1 ) . unwrap ( ) ;
@@ -840,6 +875,22 @@ mod tests {
840875 assert_eq ! ( serial. events. read_count. count( ) , 1 ) ;
841876 assert_eq ! ( serial. events. out_byte_count. count( ) , 1 ) ;
842877 assert_eq ! ( serial. events. tx_lost_byte_count. count( ) , 1 ) ;
878+
879+ // This DATA read should cause the `SerialEvents::buffer_read` method to be invoked.
880+ // And since it was the last byte from in buffer the `SerialEvents::in_buffer_empty`
881+ // was also invoked.
882+ serial. read ( DATA_OFFSET ) ;
883+ assert_eq ! ( serial. events. read_count. count( ) , 2 ) ;
884+ assert_eq ! ( serial. events. buffer_ready_event. read( ) . unwrap( ) , 1 ) ;
885+ let _res = serial. enqueue_raw_bytes ( & [ 1 , 2 ] ) ;
886+ serial. read ( DATA_OFFSET ) ;
887+ // Since there is still one byte in the in_buffer, buffer_ready_events
888+ // should have not been triggered so we shouldn't have anything to read
889+ // from that fd.
890+ assert_eq ! (
891+ serial. events. buffer_ready_event. read( ) . unwrap_err( ) . kind( ) ,
892+ io:: ErrorKind :: WouldBlock
893+ ) ;
843894 }
844895
845896 #[ test]
0 commit comments