Avoid the Defer-Disconnect destructor pattern with Boost.Coroutines

Exceptions in Disconnect() might be thrown (this has been reworked
into error_code locally) which are swallowed inside the Destructor
for being dangerous. On the other hand, swallowing them may
corrupt the stack unwinding operation from the coroutine layer.

The best is to avoid Defer inside lib/remote and call Disconnect()
directly after breaking from other operations.

refs #7351
refs #7431
This commit is contained in:
Michael Friedrich 2019-09-09 10:53:37 +02:00
parent 5aa5ab956d
commit 17d4d17307
3 changed files with 10 additions and 7 deletions

View File

@ -553,7 +553,10 @@ void ApiListener::NewClientHandlerInternal(boost::asio::yield_context yc, const
Defer shutDownIfNeeded ([&sslConn, &willBeShutDown, &yc]() {
if (!willBeShutDown) {
sslConn.async_shutdown(yc);
// Ignore the error, but do not throw an exception being swallowed at all cost.
// https://github.com/Icinga/icinga2/issues/7351
boost::system::error_code ec;
sslConn.async_shutdown(yc[ec]);
}
});

View File

@ -478,8 +478,6 @@ void HttpServerConnection::ProcessMessages(boost::asio::yield_context yc)
namespace beast = boost::beast;
namespace http = beast::http;
Defer disconnect ([this]() { Disconnect(); });
try {
beast::flat_buffer buf;
@ -563,6 +561,8 @@ void HttpServerConnection::ProcessMessages(boost::asio::yield_context yc)
<< "Unhandled exception while processing HTTP request: " << ex.what();
}
}
Disconnect();
}
void HttpServerConnection::CheckLiveness(boost::asio::yield_context yc)

View File

@ -60,8 +60,6 @@ void JsonRpcConnection::Start()
void JsonRpcConnection::HandleIncomingMessages(boost::asio::yield_context yc)
{
Defer disconnect ([this]() { Disconnect(); });
for (;;) {
String message;
@ -97,12 +95,12 @@ void JsonRpcConnection::HandleIncomingMessages(boost::asio::yield_context yc)
l_TaskStats.InsertValue(Utility::GetTime(), 1);
}
Disconnect();
}
void JsonRpcConnection::WriteOutgoingMessages(boost::asio::yield_context yc)
{
Defer disconnect ([this]() { Disconnect(); });
Defer signalWriterDone ([this]() { m_WriterDone.Set(); });
do {
@ -136,6 +134,8 @@ void JsonRpcConnection::WriteOutgoingMessages(boost::asio::yield_context yc)
}
}
} while (!m_ShuttingDown);
Disconnect();
}
double JsonRpcConnection::GetTimestamp() const