From 88e4445f0e3de975ed70fc61d65f3eb48c0d0768 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Fri, 12 Jan 2018 14:09:12 -0800 Subject: [PATCH] ircd::net: Move error checking fix back to initiator out of handler. --- ircd/net.cc | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/ircd/net.cc b/ircd/net.cc index 45c33cf3c..b2d6f51de 100644 --- a/ircd/net.cc +++ b/ircd/net.cc @@ -1403,22 +1403,35 @@ ircd::net::socket::wait(const wait_opts &opts, std::bind(&socket::handle_ready, this, weak_from(*this), opts.type, std::move(callback), ph::_1) }; + set_timeout(opts.timeout); + const unwind::exceptional unset{[this] + { + cancel_timeout(); + }}; + switch(opts.type) { case ready::ERROR: - set_timeout(opts.timeout); sd.async_wait(wait_type::wait_error, std::move(handle)); break; case ready::WRITE: - set_timeout(opts.timeout); sd.async_wait(wait_type::wait_write, std::move(handle)); break; case ready::READ: - set_timeout(opts.timeout); - sd.async_wait(wait_type::wait_read, std::move(handle)); + { + // The problem here is that the wait operation gives ec=success on both a + // socket error and when data is actually available. We then have to check + // using a non-blocking peek in the handler. By doing it this way here we + // just get the error in the handler's ec. + static char buf[16] alignas(16); + static const ilist bufs{buf}; + __builtin_prefetch(buf, 1, 0); // 1 = write, 0 = no cache + sd.async_receive(bufs, sd.message_peek, std::move(handle)); + //sd.async_wait(wait_type::wait_read, std::move(handle)); break; + } default: throw ircd::not_implemented{}; @@ -1468,16 +1481,6 @@ noexcept try // After life_guard is constructed it is safe to use *this in this frame. const life_guard s{wp}; - // The problem here is that the wait operation gives ec=success on both a - // socket error and when data is actually available. This could be giving - // the error in ec. - if(ec == success && type == ready::READ) - { - static char buf[16] alignas(16); - __builtin_prefetch(buf, 1, 0); // 1 = write, 0 = no cache - sd.receive(ilist{buf}, sd.message_peek, ec); - } - log.debug("socket(%p) local[%s] remote[%s] ready %s %s available:%zu", this, string(local_ipport(*this)),