0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-26 07:23:53 +01:00

ircd::net: Translate operation_canceled into timed_out where appropos.

This commit is contained in:
Jason Volk 2018-01-20 03:14:14 -08:00
parent 617b0d0777
commit 103ff45553
3 changed files with 62 additions and 30 deletions

View file

@ -67,9 +67,9 @@ struct ircd::net::socket
void call_user(const ec_handler &, const error_code &) noexcept;
bool handle_verify(bool, asio::ssl::verify_context &, const open_opts &) noexcept;
void handle_disconnect(std::shared_ptr<socket>, eptr_handler, error_code) noexcept;
void handle_handshake(std::weak_ptr<socket>, eptr_handler, const error_code &) noexcept;
void handle_connect(std::weak_ptr<socket>, open_opts, eptr_handler, const error_code &) noexcept;
void handle_timeout(std::weak_ptr<socket>, ec_handler, const error_code &) noexcept;
void handle_handshake(std::weak_ptr<socket>, eptr_handler, error_code) noexcept;
void handle_connect(std::weak_ptr<socket>, open_opts, eptr_handler, error_code) noexcept;
void handle_timeout(std::weak_ptr<socket>, ec_handler, error_code) noexcept;
void handle_ready(std::weak_ptr<socket>, ready, ec_handler, error_code) noexcept;
public:

View file

@ -321,7 +321,7 @@ ircd::handle_ec(client &client,
if(ec.category() == system_category()) switch(ec.value())
{
case success: return true;
case operation_canceled: return handle_ec_timeout(client);
case timed_out: return handle_ec_timeout(client);
default: return handle_ec_default(client, ec);
}
else if(ec.category() == get_misc_category()) switch(ec.value())
@ -526,6 +526,7 @@ catch(const boost::system::system_error &e)
return false;
case operation_canceled:
case timed_out:
return false;
case bad_file_descriptor:

View file

@ -1394,6 +1394,7 @@ ircd::net::socket::wait(const wait_opts &opts,
///
void
ircd::net::socket::wait(const wait_opts &opts)
try
{
const scope_timeout timeout
{
@ -1418,6 +1419,19 @@ ircd::net::socket::wait(const wait_opts &opts)
throw ircd::not_implemented{};
}
}
catch(const boost::system::system_error &e)
{
using namespace boost::system::errc;
using boost::system::system_category;
if(e.code() == operation_canceled && timedout)
throw boost::system::system_error
{
timed_out, system_category()
};
throw;
}
/// Asynchronous callback when the socket is ready
///
@ -1494,6 +1508,13 @@ noexcept try
// After life_guard is constructed it is safe to use *this in this frame.
const life_guard<socket> s{wp};
if(timedout)
{
assert(ec == operation_canceled);
ec = { timed_out, system_category() };
}
else cancel_timeout();
log.debug("socket(%p) local[%s] remote[%s] ready %s %s available:%zu",
this,
string(local_ipport(*this)),
@ -1502,17 +1523,9 @@ noexcept try
string(ec),
available(*this));
if(!timedout)
cancel_timeout();
if(ec.category() == system_category()) switch(ec.value())
{
// We expose a timeout condition to the user, but hide
// other cancellations from invoking the callback.
case operation_canceled:
if(timedout)
break;
return;
// This is a condition which we hide from the user.
@ -1560,10 +1573,11 @@ catch(const std::exception &e)
void
ircd::net::socket::handle_timeout(const std::weak_ptr<socket> wp,
ec_handler callback,
const error_code &ec)
error_code ec)
noexcept try
{
using namespace boost::system::errc;
using boost::system::system_category;
switch(ec.value())
{
@ -1572,6 +1586,7 @@ noexcept try
{
assert(timedout == false);
timedout = true;
ec = { timed_out, system_category() };
sd.cancel();
break;
}
@ -1580,9 +1595,8 @@ noexcept try
// A cancelation means there was no timeout.
case operation_canceled: if(likely(!wp.expired()))
{
assert(ec.category() == boost::system::system_category());
assert(ec.category() == system_category());
assert(timedout == false);
timedout = false;
break;
}
else break;
@ -1615,11 +1629,13 @@ void
ircd::net::socket::handle_connect(std::weak_ptr<socket> wp,
const open_opts opts,
eptr_handler callback,
const error_code &ec)
error_code ec)
noexcept try
{
using namespace boost::system::errc;
using boost::system::system_category;
const life_guard<socket> s{wp};
assert(!timedout || ec == boost::system::errc::operation_canceled);
log.debug("socket(%p) local[%s] remote[%s] connect %s",
this,
string(local_ipport(*this)),
@ -1627,8 +1643,12 @@ noexcept try
string(ec));
// The timer was set by socket::connect() and may need to be canceled.
if(!timedout)
cancel_timeout();
if(timedout)
{
assert(ec == operation_canceled);
ec = { timed_out, system_category() };
}
else cancel_timeout();
// A connect error; abort here by calling the user back with error.
if(ec)
@ -1682,17 +1702,22 @@ ircd::net::socket::handle_disconnect(std::shared_ptr<socket> s,
error_code ec)
noexcept try
{
assert(!timedout || ec == boost::system::errc::operation_canceled);
using namespace boost::system::errc;
using boost::system::system_category;
if(timedout)
{
assert(ec == operation_canceled);
ec = { timed_out, system_category() };
}
else cancel_timeout();
log.debug("socket(%p) local[%s] remote[%s] disconnect %s",
this,
string(local_ipport(*this)),
string(remote_ipport(*this)),
string(ec));
// The timer was set by socket::disconnect() and may need to be canceled.
if(!timedout)
cancel_timeout();
// This ignores EOF and turns it into a success to alleviate user concern.
if(ec.category() == asio::error::get_misc_category())
if(ec.value() == asio::error::eof)
@ -1723,21 +1748,27 @@ catch(const std::exception &e)
void
ircd::net::socket::handle_handshake(std::weak_ptr<socket> wp,
eptr_handler callback,
const error_code &ec)
error_code ec)
noexcept try
{
using namespace boost::system::errc;
using boost::system::system_category;
const life_guard<socket> s{wp};
assert(!timedout || ec == boost::system::errc::operation_canceled);
if(timedout)
{
assert(ec == operation_canceled);
ec = { timed_out, system_category() };
}
else cancel_timeout();
log.debug("socket(%p) local[%s] remote[%s] handshake %s",
this,
string(local_ipport(*this)),
string(remote_ipport(*this)),
string(ec));
// The timer was set by socket::handshake() and may need to be canceled.
if(!timedout)
cancel_timeout();
// This is the end of the asynchronous call chain; the user is called
// back with or without error here.
call_user(callback, ec);