1+ //! # FIXES:
2+ //!
3+ //! ## FIX ISSUE #4:
4+ //! See:https://github.com/PacktPublishing/Asynchronous-Programming-in-Rust/issues/4
5+ //! Some users reported false event notification causing the counter to increase
6+ //! due to the OS reporting a READ event after we already read the TcpStream to EOF.
7+ //! This caused the counter to increment on the same TcpStream twice and thereby
8+ //! exiting the program before all events were handled.
9+ //!
10+ //! The fix for this is to account for false wakeups which is an easy fix but requires
11+ //! a few changes to the example. I've added an explicit comment: "FIX #4", the places
12+ //! I made a change so it's easy to spot the differences to the example code in the book.
13+
114use std:: {
15+ // FIX #4 (import `HashSet``)
16+ collections:: HashSet ,
217 io:: { self , Read , Result , Write } ,
318 net:: TcpStream ,
419} ;
@@ -20,7 +35,11 @@ fn get_req(path: &str) -> String {
2035 )
2136}
2237
23- fn handle_events ( events : & [ Event ] , streams : & mut [ TcpStream ] ) -> Result < usize > {
38+ fn handle_events (
39+ events : & [ Event ] ,
40+ streams : & mut [ TcpStream ] ,
41+ handled : & mut HashSet < usize > ,
42+ ) -> Result < usize > {
2443 let mut handled_events = 0 ;
2544 for event in events {
2645 let index = event. token ( ) ;
@@ -29,6 +48,13 @@ fn handle_events(events: &[Event], streams: &mut [TcpStream]) -> Result<usize> {
2948 loop {
3049 match streams[ index] . read ( & mut data) {
3150 Ok ( n) if n == 0 => {
51+ // FIX #4
52+ // `insert` returns false if the value already existed in the set. We
53+ // handle it here since we must be sure that the TcpStream is fully
54+ // drained due to using edge triggered epoll.
55+ if !handled. insert ( index) {
56+ break ;
57+ }
3258 handled_events += 1 ;
3359 break ;
3460 }
@@ -73,6 +99,9 @@ fn main() -> Result<()> {
7399 streams. push ( stream) ;
74100 }
75101
102+ // FIX #4: store the handled IDs
103+ let mut handled_ids = HashSet :: new ( ) ;
104+
76105 let mut handled_events = 0 ;
77106 while handled_events < n_events {
78107 let mut events = Vec :: with_capacity ( 10 ) ;
@@ -83,7 +112,8 @@ fn main() -> Result<()> {
83112 continue ;
84113 }
85114
86- handled_events += handle_events ( & events, & mut streams) ?;
115+ // ------------------------------------------------------⌄ FIX #4 (new signature)
116+ handled_events += handle_events ( & events, & mut streams, & mut handled_ids) ?;
87117 }
88118
89119 println ! ( "FINISHED" ) ;
0 commit comments