fix(conn): Handle remote hangup

Not handling this was an issue for keep-alive connections because
requests would get assigned to a closed connection and then immediately
error. Handling the HUP event makes this situation much less likely. It
is still possible however; consider the situation where a HUP arrives
while the event loop is busy processing new requests to add. The
connection is disconnected, but the HUP hasn't been processed, and a
request could be assigned to it. This case is, however, unlikely.
This commit is contained in:
Joe Wilm
2016-10-10 15:44:51 -07:00
parent c2734c6330
commit 9652a42d45

View File

@@ -553,6 +553,13 @@ impl<K: Key, T: Transport, H: MessageHandler<T>> Conn<K, T, H> {
} }
} }
if events.is_hup() {
trace!("Conn::ready got hangup");
let _ = scope.deregister(&self.0.transport);
self.on_remove();
return ReadyResult::Done(None);
}
// if the user had an io interest, but the transport was blocked differently, // if the user had an io interest, but the transport was blocked differently,
// the event needs to be translated to what the user was actually expecting. // the event needs to be translated to what the user was actually expecting.
// //
@@ -593,7 +600,7 @@ impl<K: Key, T: Transport, H: MessageHandler<T>> Conn<K, T, H> {
self.0.on_writable(scope); self.0.on_writable(scope);
} }
let events = match self.0.register() { let mut events = match self.0.register() {
Reg::Read => EventSet::readable(), Reg::Read => EventSet::readable(),
Reg::Write => EventSet::writable(), Reg::Write => EventSet::writable(),
Reg::ReadWrite => EventSet::readable() | EventSet::writable(), Reg::ReadWrite => EventSet::readable() | EventSet::writable(),
@@ -610,6 +617,8 @@ impl<K: Key, T: Transport, H: MessageHandler<T>> Conn<K, T, H> {
return ReadyResult::Continue(self); return ReadyResult::Continue(self);
} }
events = events | EventSet::hup();
trace!("scope.reregister({:?})", events); trace!("scope.reregister({:?})", events);
match scope.reregister(&self.0.transport, events, PollOpt::level()) { match scope.reregister(&self.0.transport, events, PollOpt::level()) {
Ok(..) => { Ok(..) => {