]> granicus.if.org Git - icinga2/commitdiff
Avoid the Defer-Disconnect destructor pattern with Boost.Coroutines 7485/head
authorMichael Friedrich <michael.friedrich@icinga.com>
Mon, 9 Sep 2019 08:53:37 +0000 (10:53 +0200)
committerMichael Friedrich <michael.friedrich@icinga.com>
Mon, 9 Sep 2019 08:57:13 +0000 (10:57 +0200)
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

lib/remote/apilistener.cpp
lib/remote/httpserverconnection.cpp
lib/remote/jsonrpcconnection.cpp

index 661a4eaaf6f2aac8add181b57e1c6698eb59165d..5a2ca048cb5f8176a91f5ad0e5e0d369ec138e19 100644 (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]);
                }
        });
 
index 01b32f403b36370d5e402313d1138144915c37fc..6052f923a1b6f41eed39781af915e8f94ba76932 100644 (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)
index e63f1183ab696cad12c38a043589fcfb2bdbab0e..e8279eac26ea59a67dc6ddcee6ddeb89b21f0c7e 100644 (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