Handle hup events as indicating read readiness

Using Linux's `epoll(7)` interface, a `EPOLLHUP` condition is
signalled for the reading end of a pipe or socket when the other end
is closed for writing. This may happen in combination with `EPOLLIN`
being signalled (if further data is available for reading), or with
`EPOLLIN`.

If `EPOLLHUP` is signalled without `EPOLLIN` it indicates an immediate
EOF condition, which will result in the next `read()` suceeding with 0
bytes read. It is thus not required to handle `EPOLLHUP` specially in
the reader, but we need to indicate readiness upon encountering it.

Looking at the `kqueue` and `windows` mio backends, they seem to be
turn a detected EOF and connection reset into `mio::Ready::hup()`
events, so it may be reasonable to speculate that this change is an
improvement for these platforms as well.

Fixes #117.
This commit is contained in:
Andreas Rottmann
2016-12-08 17:52:40 +01:00
parent dc27c0a524
commit 5bab8e85b9
+2 -2
View File
@@ -306,7 +306,7 @@ impl Core {
let mut writer = None;
let mut inner = self.inner.borrow_mut();
if let Some(io) = inner.io_dispatch.get_mut(token) {
if ready.is_readable() {
if ready.is_readable() || ready.is_hup() {
reader = io.reader.take();
io.readiness.fetch_or(1, Ordering::Relaxed);
}
@@ -430,7 +430,7 @@ impl Inner {
let entry = self.io_dispatch.vacant_entry().unwrap();
try!(self.io.register(source,
mio::Token(TOKEN_START + entry.index() * 2),
mio::Ready::readable() | mio::Ready::writable(),
mio::Ready::readable() | mio::Ready::writable() | mio::Ready::hup(),
mio::PollOpt::edge()));
Ok((sched.readiness.clone(), entry.insert(sched).index()))
}