From fa845775a2719be628f787a9e8bdbd6bded1a90c Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Thu, 17 Oct 2013 10:56:42 +0200 Subject: [PATCH] Fix crashes when restarting Icinga. --- components/cluster/clusterlistener.cpp | 4 ---- components/cluster/endpoint.cpp | 15 +++++++++++-- components/cluster/endpoint.h | 3 +++ icinga-app/icinga.cpp | 8 ++++++- lib/base/application.cpp | 30 +++++++++++--------------- lib/base/application.h | 1 - 6 files changed, 35 insertions(+), 26 deletions(-) diff --git a/components/cluster/clusterlistener.cpp b/components/cluster/clusterlistener.cpp index 5baea767a..c2f773fcf 100644 --- a/components/cluster/clusterlistener.cpp +++ b/components/cluster/clusterlistener.cpp @@ -565,10 +565,6 @@ void ClusterListener::NewClientHandler(const Socket::Ptr& client, TlsRole role) { ObjectLock olock(endpoint); - Stream::Ptr oldClient = endpoint->GetClient(); - if (oldClient) - oldClient->Close(); - endpoint->SetSyncing(true); endpoint->SetSeen(Utility::GetTime()); endpoint->SetClient(tlsStream); diff --git a/components/cluster/endpoint.cpp b/components/cluster/endpoint.cpp index 003288577..a7eb813f1 100644 --- a/components/cluster/endpoint.cpp +++ b/components/cluster/endpoint.cpp @@ -38,6 +38,11 @@ Endpoint::Endpoint(void) : m_Syncing(false) { } +Endpoint::~Endpoint(void) +{ + SetClient(Stream::Ptr()); +} + /** * Checks whether this endpoint is connected. * @@ -55,11 +60,17 @@ Stream::Ptr Endpoint::GetClient(void) const void Endpoint::SetClient(const Stream::Ptr& client) { + if (m_Client) + m_Client->Close(); + + Log(LogInformation, "cluster", "Joining endpoint message thread."); + + m_Thread.join(); + m_Client = client; if (client) { - boost::thread thread(boost::bind(&Endpoint::MessageThreadProc, this, client)); - thread.detach(); + m_Thread = boost::thread(boost::bind(&Endpoint::MessageThreadProc, this, client)); OnConnected(GetSelf()); } diff --git a/components/cluster/endpoint.h b/components/cluster/endpoint.h index a0d2e7f39..158df7dfb 100644 --- a/components/cluster/endpoint.h +++ b/components/cluster/endpoint.h @@ -42,6 +42,7 @@ public: DECLARE_TYPENAME(Endpoint); Endpoint(void); + ~Endpoint(void); static boost::signals2::signal OnConnected; static boost::signals2::signal OnMessageReceived; @@ -93,6 +94,8 @@ private: Dictionary::Ptr m_Features; bool m_Syncing; + boost::thread m_Thread; + void MessageThreadProc(const Stream::Ptr& stream); }; diff --git a/icinga-app/icinga.cpp b/icinga-app/icinga.cpp index 1cd6e03bb..2ff859138 100644 --- a/icinga-app/icinga.cpp +++ b/icinga-app/icinga.cpp @@ -376,5 +376,11 @@ int main(int argc, char **argv) sigaction(SIGHUP, &sa, NULL); #endif /* _WIN32 */ - return Application::GetInstance()->Run(); + int rc = Application::GetInstance()->Run(); + +#ifdef _DEBUG + exit(rc); +#else /* _DEBUG */ + _exit(rc); // Yay, our static destructors are pretty much beyond repair at this point. +#endif /* _DEBUG */ } diff --git a/lib/base/application.cpp b/lib/base/application.cpp index 16ac7ba04..6e3cb944e 100644 --- a/lib/base/application.cpp +++ b/lib/base/application.cpp @@ -132,18 +132,6 @@ void Application::SetArgV(char **argv) m_ArgV = argv; } -void Application::ShutdownTimerHandler(void) -{ - if (m_ShuttingDown || m_Restarting) { - Log(LogInformation, "base", "Shutting down Icinga..."); - Application::GetInstance()->OnShutdown(); - - DynamicObject::StopObjects(); - GetTP().Stop(); - m_ShuttingDown = false; - } -} - /** * Processes events for registered sockets and timers and calls whatever * handlers have been set up for these events. @@ -154,17 +142,23 @@ void Application::RunEventLoop(void) const boost::thread t(&Application::TimeWatchThreadProc); t.detach(); - /* Set up a timer that watches the m_Shutdown flag. */ - Timer::Ptr shutdownTimer = boost::make_shared(); - shutdownTimer->OnTimerExpired.connect(boost::bind(&Application::ShutdownTimerHandler)); - shutdownTimer->SetInterval(0.5); - shutdownTimer->Start(); - Timer::Initialize(); + while (!m_ShuttingDown && !m_Restarting) + Utility::Sleep(0.5); + + Log(LogInformation, "base", "Shutting down Icinga..."); + Application::GetInstance()->OnShutdown(); + +#ifdef _DEBUG + DynamicObject::StopObjects(); + GetTP().Stop(); + m_ShuttingDown = false; + GetTP().Join(); Timer::Uninitialize(); +#endif /* _DEBUG */ } /** diff --git a/lib/base/application.h b/lib/base/application.h index 9a5c302e1..c98b7dc7b 100644 --- a/lib/base/application.h +++ b/lib/base/application.h @@ -127,7 +127,6 @@ private: static void TimeWatchThreadProc(void); static void NewTxTimerHandler(void); - static void ShutdownTimerHandler(void); }; }