Move Timeout instances from heap to stack

This commit is contained in:
Alexander A. Klimov 2024-12-02 16:18:13 +01:00 committed by Yonas Habteab
parent 1703f99d14
commit d956920bd7
6 changed files with 21 additions and 23 deletions

View File

@ -9,7 +9,6 @@
#include "base/lazy-init.hpp" #include "base/lazy-init.hpp"
#include "base/logger.hpp" #include "base/logger.hpp"
#include "base/shared.hpp" #include "base/shared.hpp"
#include "base/shared-object.hpp"
#include <atomic> #include <atomic>
#include <exception> #include <exception>
#include <memory> #include <memory>
@ -168,10 +167,9 @@ private:
* *
* @ingroup base * @ingroup base
*/ */
class Timeout : public SharedObject class Timeout
{ {
public: public:
DECLARE_PTR_TYPEDEFS(Timeout);
using Timer = boost::asio::deadline_timer; using Timer = boost::asio::deadline_timer;
template<class OnTimeout> template<class OnTimeout>
@ -189,7 +187,7 @@ public:
)); ));
} }
~Timeout() override ~Timeout()
{ {
Cancel(); Cancel();
} }

View File

@ -140,12 +140,12 @@ void AsioTlsStream::GracefulDisconnect(boost::asio::io_context::strand& strand,
} }
{ {
Timeout::Ptr shutdownTimeout(new Timeout(strand, boost::posix_time::seconds(10), Timeout shutdownTimeout (strand, boost::posix_time::seconds(10),
[this] { [this] {
// Forcefully terminate the connection if async_shutdown() blocked more than 10 seconds. // Forcefully terminate the connection if async_shutdown() blocked more than 10 seconds.
ForceDisconnect(); ForceDisconnect();
} }
)); );
// Close the TLS connection, effectively uses SSL_shutdown() to send a close_notify shutdown alert to the peer. // Close the TLS connection, effectively uses SSL_shutdown() to send a close_notify shutdown alert to the peer.
boost::system::error_code ec; boost::system::error_code ec;

View File

@ -222,7 +222,7 @@ namespace icinga
void Handshake(StreamPtr& stream, boost::asio::yield_context& yc); void Handshake(StreamPtr& stream, boost::asio::yield_context& yc);
template<class StreamPtr> template<class StreamPtr>
Timeout::Ptr MakeTimeout(StreamPtr& stream); Timeout MakeTimeout(StreamPtr& stream);
String m_Path; String m_Path;
String m_Host; String m_Host;
@ -509,9 +509,9 @@ void RedisConnection::Handshake(StreamPtr& strm, boost::asio::yield_context& yc)
* @param stream Redis server connection * @param stream Redis server connection
*/ */
template<class StreamPtr> template<class StreamPtr>
Timeout::Ptr RedisConnection::MakeTimeout(StreamPtr& stream) Timeout RedisConnection::MakeTimeout(StreamPtr& stream)
{ {
return new Timeout( return Timeout(
m_Strand, m_Strand,
boost::posix_time::microseconds(intmax_t(m_ConnectTimeout * 1000000)), boost::posix_time::microseconds(intmax_t(m_ConnectTimeout * 1000000)),
[stream] { [stream] {

View File

@ -456,7 +456,7 @@ void IfwApiCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRes
IoEngine::SpawnCoroutine( IoEngine::SpawnCoroutine(
*strand, *strand,
[strand, checkable, cr, psCommand, psHost, expectedSan, psPort, conn, req, checkTimeout, reportResult = std::move(reportResult)](asio::yield_context yc) { [strand, checkable, cr, psCommand, psHost, expectedSan, psPort, conn, req, checkTimeout, reportResult = std::move(reportResult)](asio::yield_context yc) {
Timeout::Ptr timeout = new Timeout(*strand, boost::posix_time::microseconds(int64_t(checkTimeout * 1e6)), Timeout timeout (*strand, boost::posix_time::microseconds(int64_t(checkTimeout * 1e6)),
[&conn, &checkable] { [&conn, &checkable] {
Log(LogNotice, "IfwApiCheckTask") Log(LogNotice, "IfwApiCheckTask")
<< "Timeout while checking " << checkable->GetReflectionType()->GetName() << "Timeout while checking " << checkable->GetReflectionType()->GetName()

View File

@ -534,7 +534,7 @@ void ApiListener::ListenerCoroutineProc(boost::asio::yield_context yc, const Sha
auto strand (Shared<asio::io_context::strand>::Make(io)); auto strand (Shared<asio::io_context::strand>::Make(io));
IoEngine::SpawnCoroutine(*strand, [this, strand, sslConn, remoteEndpoint](asio::yield_context yc) { IoEngine::SpawnCoroutine(*strand, [this, strand, sslConn, remoteEndpoint](asio::yield_context yc) {
Timeout::Ptr timeout (new Timeout(*strand, boost::posix_time::microseconds(int64_t(GetConnectTimeout() * 1e6)), Timeout timeout (*strand, boost::posix_time::microseconds(int64_t(GetConnectTimeout() * 1e6)),
[sslConn, remoteEndpoint] { [sslConn, remoteEndpoint] {
Log(LogWarning, "ApiListener") Log(LogWarning, "ApiListener")
<< "Timeout while processing incoming connection from " << remoteEndpoint; << "Timeout while processing incoming connection from " << remoteEndpoint;
@ -542,7 +542,7 @@ void ApiListener::ListenerCoroutineProc(boost::asio::yield_context yc, const Sha
boost::system::error_code ec; boost::system::error_code ec;
sslConn->lowest_layer().cancel(ec); sslConn->lowest_layer().cancel(ec);
} }
)); );
NewClientHandler(yc, strand, sslConn, String(), RoleServer); NewClientHandler(yc, strand, sslConn, String(), RoleServer);
}); });
@ -584,7 +584,7 @@ void ApiListener::AddConnection(const Endpoint::Ptr& endpoint)
lock.unlock(); lock.unlock();
Timeout::Ptr timeout (new Timeout(*strand, boost::posix_time::microseconds(int64_t(GetConnectTimeout() * 1e6)), Timeout timeout (*strand, boost::posix_time::microseconds(int64_t(GetConnectTimeout() * 1e6)),
[sslConn, endpoint, host, port] { [sslConn, endpoint, host, port] {
Log(LogCritical, "ApiListener") Log(LogCritical, "ApiListener")
<< "Timeout while reconnecting to endpoint '" << endpoint->GetName() << "' via host '" << host << "Timeout while reconnecting to endpoint '" << endpoint->GetName() << "' via host '" << host
@ -593,7 +593,7 @@ void ApiListener::AddConnection(const Endpoint::Ptr& endpoint)
boost::system::error_code ec; boost::system::error_code ec;
sslConn->lowest_layer().cancel(ec); sslConn->lowest_layer().cancel(ec);
} }
)); );
Connect(sslConn->lowest_layer(), host, port, yc); Connect(sslConn->lowest_layer(), host, port, yc);
@ -681,14 +681,14 @@ void ApiListener::NewClientHandlerInternal(
boost::system::error_code ec; boost::system::error_code ec;
{ {
Timeout::Ptr handshakeTimeout (new Timeout( Timeout handshakeTimeout (
*strand, *strand,
boost::posix_time::microseconds(intmax_t(Configuration::TlsHandshakeTimeout * 1000000)), boost::posix_time::microseconds(intmax_t(Configuration::TlsHandshakeTimeout * 1000000)),
[client] { [client] {
boost::system::error_code ec; boost::system::error_code ec;
client->lowest_layer().cancel(ec); client->lowest_layer().cancel(ec);
} }
)); );
sslConn.async_handshake(role == RoleClient ? sslConn.client : sslConn.server, yc[ec]); sslConn.async_handshake(role == RoleClient ? sslConn.client : sslConn.server, yc[ec]);
} }

View File

@ -20,7 +20,7 @@ BOOST_AUTO_TEST_CASE(timeout_run)
boost::asio::spawn(strand, [&](boost::asio::yield_context yc) { boost::asio::spawn(strand, [&](boost::asio::yield_context yc) {
boost::asio::deadline_timer timer (io); boost::asio::deadline_timer timer (io);
Timeout::Ptr timeout = new Timeout(strand, boost::posix_time::millisec(300), [&called] { ++called; }); Timeout timeout (strand, boost::posix_time::millisec(300), [&called] { ++called; });
BOOST_CHECK_EQUAL(called, 0); BOOST_CHECK_EQUAL(called, 0);
timer.expires_from_now(boost::posix_time::millisec(200)); timer.expires_from_now(boost::posix_time::millisec(200));
@ -46,12 +46,12 @@ BOOST_AUTO_TEST_CASE(timeout_cancelled)
boost::asio::spawn(strand, [&](boost::asio::yield_context yc) { boost::asio::spawn(strand, [&](boost::asio::yield_context yc) {
boost::asio::deadline_timer timer (io); boost::asio::deadline_timer timer (io);
Timeout::Ptr timeout = new Timeout(strand, boost::posix_time::millisec(300), [&called] { ++called; }); Timeout timeout (strand, boost::posix_time::millisec(300), [&called] { ++called; });
timer.expires_from_now(boost::posix_time::millisec(200)); timer.expires_from_now(boost::posix_time::millisec(200));
timer.async_wait(yc); timer.async_wait(yc);
timeout->Cancel(); timeout.Cancel();
BOOST_CHECK_EQUAL(called, 0); BOOST_CHECK_EQUAL(called, 0);
timer.expires_from_now(boost::posix_time::millisec(200)); timer.expires_from_now(boost::posix_time::millisec(200));
@ -75,7 +75,7 @@ BOOST_AUTO_TEST_CASE(timeout_scope)
boost::asio::deadline_timer timer (io); boost::asio::deadline_timer timer (io);
{ {
Timeout::Ptr timeout = new Timeout(strand, boost::posix_time::millisec(300), [&called] { ++called; }); Timeout timeout (strand, boost::posix_time::millisec(300), [&called] { ++called; });
timer.expires_from_now(boost::posix_time::millisec(200)); timer.expires_from_now(boost::posix_time::millisec(200));
timer.async_wait(yc); timer.async_wait(yc);
@ -102,7 +102,7 @@ BOOST_AUTO_TEST_CASE(timeout_due_cancelled)
boost::asio::spawn(strand, [&](boost::asio::yield_context yc) { boost::asio::spawn(strand, [&](boost::asio::yield_context yc) {
boost::asio::deadline_timer timer (io); boost::asio::deadline_timer timer (io);
Timeout::Ptr timeout = new Timeout(strand, boost::posix_time::millisec(300), [&called] { ++called; }); Timeout timeout (strand, boost::posix_time::millisec(300), [&called] { ++called; });
// Give the timeout enough time to become due while blocking its strand to prevent it from actually running... // Give the timeout enough time to become due while blocking its strand to prevent it from actually running...
Utility::Sleep(0.4); Utility::Sleep(0.4);
@ -110,7 +110,7 @@ BOOST_AUTO_TEST_CASE(timeout_due_cancelled)
BOOST_CHECK_EQUAL(called, 0); BOOST_CHECK_EQUAL(called, 0);
// ... so that this shall still work: // ... so that this shall still work:
timeout->Cancel(); timeout.Cancel();
BOOST_CHECK_EQUAL(called, 0); BOOST_CHECK_EQUAL(called, 0);
@ -135,7 +135,7 @@ BOOST_AUTO_TEST_CASE(timeout_due_scope)
boost::asio::deadline_timer timer (io); boost::asio::deadline_timer timer (io);
{ {
Timeout::Ptr timeout = new Timeout(strand, boost::posix_time::millisec(300), [&called] { ++called; }); Timeout timeout (strand, boost::posix_time::millisec(300), [&called] { ++called; });
// Give the timeout enough time to become due while blocking its strand to prevent it from actually running... // Give the timeout enough time to become due while blocking its strand to prevent it from actually running...
Utility::Sleep(0.4); Utility::Sleep(0.4);