Skip to content

Commit 4345b74

Browse files
committed
fixes issue PacktPublishing#4
1 parent bcf9c0d commit 4345b74

File tree

1 file changed

+32
-2
lines changed

1 file changed

+32
-2
lines changed

ch04/a-epoll/src/main.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,19 @@
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+
114
use 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

Comments
 (0)