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
+
1
14
use std:: {
15
+ // FIX #4 (import `HashSet``)
16
+ collections:: HashSet ,
2
17
io:: { self , Read , Result , Write } ,
3
18
net:: TcpStream ,
4
19
} ;
@@ -20,7 +35,11 @@ fn get_req(path: &str) -> String {
20
35
)
21
36
}
22
37
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 > {
24
43
let mut handled_events = 0 ;
25
44
for event in events {
26
45
let index = event. token ( ) ;
@@ -29,6 +48,13 @@ fn handle_events(events: &[Event], streams: &mut [TcpStream]) -> Result<usize> {
29
48
loop {
30
49
match streams[ index] . read ( & mut data) {
31
50
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
+ }
32
58
handled_events += 1 ;
33
59
break ;
34
60
}
@@ -73,6 +99,9 @@ fn main() -> Result<()> {
73
99
streams. push ( stream) ;
74
100
}
75
101
102
+ // FIX #4: store the handled IDs
103
+ let mut handled_ids = HashSet :: new ( ) ;
104
+
76
105
let mut handled_events = 0 ;
77
106
while handled_events < n_events {
78
107
let mut events = Vec :: with_capacity ( 10 ) ;
@@ -83,7 +112,8 @@ fn main() -> Result<()> {
83
112
continue ;
84
113
}
85
114
86
- handled_events += handle_events ( & events, & mut streams) ?;
115
+ // ------------------------------------------------------⌄ FIX #4 (new signature)
116
+ handled_events += handle_events ( & events, & mut streams, & mut handled_ids) ?;
87
117
}
88
118
89
119
println ! ( "FINISHED" ) ;
0 commit comments