0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-10-01 05:08:59 +02:00

ircd::net: Improve some exception specs related to socket.

This commit is contained in:
Jason Volk 2017-10-19 01:01:07 -07:00
parent c157967559
commit df8faae81d
3 changed files with 62 additions and 27 deletions

View file

@ -41,9 +41,9 @@ namespace ircd::net
string_view string(const hostport &, const mutable_buffer &buf);
bool connected(const socket &) noexcept;
size_t available(const socket &) noexcept;
hostport local_hostport(const socket &);
hostport remote_hostport(const socket &);
size_t available(const socket &);
size_t write(socket &, const ilist<const_buffer> &); // write_all
size_t write(socket &, const iov<const_buffer> &); // write_all

View file

@ -93,7 +93,7 @@ struct ircd::net::socket
void call_user(const handler &, const error_code &) noexcept;
bool handle_error(const error_code &ec);
void handle_timeout(std::weak_ptr<socket> wp, const error_code &ec);
void handle_timeout(std::weak_ptr<socket> wp, const error_code &ec) noexcept;
void handle(std::weak_ptr<socket>, handler, const error_code &, const size_t &) noexcept;
public:
@ -103,6 +103,9 @@ struct ircd::net::socket
ip::tcp::endpoint remote() const { return sd.remote_endpoint(); }
ip::tcp::endpoint local() const { return sd.local_endpoint(); }
bool connected() const noexcept;
size_t available() const;
template<class iov> auto read_some(const iov &, error_code &);
template<class iov> auto read_some(const iov &);
template<class iov> auto read(const iov &, error_code &);
@ -119,9 +122,8 @@ struct ircd::net::socket
// Asynchronous 'ready' closure
void operator()(const milliseconds &timeout, handler);
void operator()(handler);
void cancel();
bool cancel() noexcept;
bool connected() const noexcept;
void disconnect(const dc &type = dc::SSL_NOTIFY);
void connect(const ip::tcp::endpoint &ep, const milliseconds &timeout = -1ms);

View file

@ -346,14 +346,13 @@ noexcept try
string(sock->remote()));
add_client(sock);
next();
}
catch(const std::exception &e)
{
log.error("%s: in handshake(): socket(%p)[%s]: %s",
std::string(*this),
sock.get(),
string(sock->remote()),
sock->connected()? string(sock->remote()) : "<gone>",
e.what());
}
@ -487,8 +486,10 @@ ircd::net::sslv23_client
size_t
ircd::net::available(const socket &s)
noexcept
{
return s.sd.available();
boost::system::error_code ec;
return s.sd.available(ec);
}
ircd::net::hostport
@ -751,11 +752,19 @@ ircd::net::socket::disconnect(const dc &type)
}
}
void
bool
ircd::net::socket::cancel()
noexcept
{
timer.cancel();
sd.cancel();
boost::system::error_code ec[2];
timer.cancel(ec[0]);
sd.cancel(ec[1]);
return std::all_of(begin(ec), end(ec), [](const auto &ec)
{
return ec == boost::system::errc::success;
});
}
/// Asynchronous callback when the socket is ready
@ -812,17 +821,9 @@ ircd::net::socket::handle(const std::weak_ptr<socket> wp,
const handler callback,
const error_code &ec,
const size_t &bytes)
noexcept
noexcept try
{
// This handler may still be registered with asio after the socket destructs, so
// the weak_ptr will indicate that fact. However, this is never intended and is
// a debug assertion which should be corrected.
if(unlikely(wp.expired()))
{
log::warning("socket(%p): belated callback to handler...", this);
assert(0);
return;
}
const life_guard<socket> s{wp};
// This handler and the timeout handler are responsible for canceling each other
// when one or the other is entered. If the timeout handler has already fired for
@ -843,6 +844,23 @@ noexcept
call_user(callback, ec);
}
catch(const std::bad_weak_ptr &e)
{
// This handler may still be registered with asio after the socket destructs, so
// the weak_ptr will indicate that fact. However, this is never intended and is
// a debug assertion which should be corrected.
log::warning("socket(%p): belated callback to handler... (%s)",
this,
e.what());
assert(0);
}
catch(const std::exception &e)
{
log::error("socket(%p): handle: %s",
this,
e.what());
assert(0);
}
void
ircd::net::socket::call_user(const handler &callback,
@ -856,9 +874,6 @@ catch(const std::exception &e)
log::error("socket(%p): async handler: unhandled exception: %s",
this,
e.what());
if(ircd::debugmode)
std::terminate();
}
bool
@ -896,6 +911,7 @@ ircd::net::socket::handle_error(const error_code &ec)
void
ircd::net::socket::handle_timeout(const std::weak_ptr<socket> wp,
const error_code &ec)
noexcept try
{
using namespace boost::system::errc;
@ -904,7 +920,7 @@ ircd::net::socket::handle_timeout(const std::weak_ptr<socket> wp,
// A 'success' for this handler means there was a timeout on the socket
case success:
timedout = true;
cancel();
sd.cancel();
break;
// A cancelation means there was no timeout.
@ -914,11 +930,28 @@ ircd::net::socket::handle_timeout(const std::weak_ptr<socket> wp,
// All other errors are unexpected, logged and ignored here.
default:
log::error("socket::handle_timeout(): unexpected: %s\n",
ec.message());
break;
throw boost::system::system_error(ec);
}
}
catch(const boost::system::system_error &e)
{
log::error("socket(%p): handle_timeout: unexpected: %s\n",
(const void *)this,
e.what());
}
catch(const std::exception &e)
{
log::error("socket(%p): handle timeout: %s",
(const void *)this,
e.what());
}
size_t
ircd::net::socket::available()
const
{
return sd.available();
}
bool
ircd::net::socket::connected()