diff --git a/include/ircd/net/socket.h b/include/ircd/net/socket.h index 46037342c..ec7627b63 100644 --- a/include/ircd/net/socket.h +++ b/include/ircd/net/socket.h @@ -208,7 +208,6 @@ catch(const boost::system::system_error &e) template size_t ircd::net::socket::read_any(iov&& bufs) -try { assert(!blocking(*this)); static const auto completion @@ -216,39 +215,49 @@ try asio::transfer_all() }; + boost::system::error_code ec; const size_t ret { - asio::read(ssl, std::forward(bufs), completion) + asio::read(ssl, std::forward(bufs), completion, ec) }; in.bytes += ret; ++in.calls; - return ret; -} -catch(const boost::system::system_error &e) -{ - throw_system_error(e); + + if(likely(!ec)) + return ret; + + if(ec == boost::system::errc::resource_unavailable_try_again) + return ret; + + throw_system_error(ec); + __builtin_unreachable(); } /// Non-blocking; One system call only; never throws eof; template size_t ircd::net::socket::read_one(iov&& bufs) -try { assert(!blocking(*this)); + + boost::system::error_code ec; const size_t ret { - ssl.read_some(std::forward(bufs)) + ssl.read_some(std::forward(bufs), ec) }; in.bytes += ret; ++in.calls; - return ret; -} -catch(const boost::system::system_error &e) -{ - throw_system_error(e); + + if(likely(!ec)) + return ret; + + if(ec == boost::system::errc::resource_unavailable_try_again) + return ret; + + throw_system_error(ec); + __builtin_unreachable(); } /// Yields ircd::ctx until all buffers are sent. diff --git a/ircd/net.cc b/ircd/net.cc index eceb78d17..d80b4aadf 100644 --- a/ircd/net.cc +++ b/ircd/net.cc @@ -355,7 +355,6 @@ ircd::net::discard_all(socket &socket, buffer, std::min(remain, sizeof(buffer)) }; - __builtin_prefetch(data(mb), 1, 0); // 1 = write, 0 = no cache remain -= read_all(socket, mb); } @@ -373,23 +372,18 @@ ircd::net::discard_any(socket &socket, { static char buffer[512] alignas(16); - size_t remain{len}; while(remain) try + size_t remain{len}; while(remain) { const mutable_buffer mb { buffer, std::min(remain, sizeof(buffer)) }; - __builtin_prefetch(data(mb), 1, 0); // 1 = write, 0 = no cache - remain -= read_one(socket, mb); - } - catch(const std::system_error &e) - { - if(e.code() == std::errc::resource_unavailable_try_again) - if(remain <= len) - break; + size_t read; + if(!(read = read_one(socket, mb))) + break; - throw; + remain -= read; } return len - remain; diff --git a/ircd/server.cc b/ircd/server.cc index d86d2539e..f9d21cf68 100644 --- a/ircd/server.cc +++ b/ircd/server.cc @@ -1922,7 +1922,14 @@ try { overrun = process_read_next(overrun, tag, done); } - while(!done); + while(!done && !empty(overrun)); + + if(!done) + { + // This branch represents a read of -EAGAIN. + assert(empty(overrun)); + return false; + } assert(peer); peer->handle_tag_done(*this, tag); @@ -1935,25 +1942,6 @@ catch(const buffer_overrun &e) queue.pop_front(); throw; } -catch(const std::system_error &e) -{ - using std::errc; - - if(system_category(e.code())) switch(e.code().value()) - { - case 0: - assert(0); - return true; - - case int(errc::resource_unavailable_try_again): - return false; - - default: - break; - } - - throw; -} /// Process one read operation for one tag ircd::const_buffer @@ -2009,7 +1997,6 @@ ircd::server::link::read(const mutable_buffer &buf) assert(peer); peer->read_bytes += received; - assert(received); return const_buffer { data(buf), received @@ -2566,6 +2553,9 @@ ircd::server::tag::read_buffer(const const_buffer &buffer, { assert(request); + if(empty(buffer)) + return buffer; + if(state.status == (http::code)0) return read_head(buffer, done, link);