mirror of https://github.com/Icinga/icinga2.git
Dynamically create and destroy the timer thread
This commit is contained in:
parent
6d09efc907
commit
6739023678
|
@ -158,8 +158,6 @@ void Application::InitializeBase(void)
|
|||
|
||||
/* make sure the thread pool gets initialized */
|
||||
GetTP().Start();
|
||||
|
||||
Timer::Initialize();
|
||||
}
|
||||
|
||||
void Application::UninitializeBase(void)
|
||||
|
@ -317,8 +315,6 @@ void Application::SetArgV(char **argv)
|
|||
*/
|
||||
void Application::RunEventLoop(void)
|
||||
{
|
||||
Timer::Initialize();
|
||||
|
||||
double lastLoop = Utility::GetTime();
|
||||
|
||||
mainloop:
|
||||
|
|
|
@ -71,6 +71,7 @@ static boost::condition_variable l_TimerCV;
|
|||
static std::thread l_TimerThread;
|
||||
static bool l_StopTimerThread;
|
||||
static TimerSet l_Timers;
|
||||
static int l_AliveTimers;
|
||||
|
||||
/**
|
||||
* Constructor for the Timer class.
|
||||
|
@ -87,29 +88,16 @@ Timer::~Timer(void)
|
|||
Stop(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the timer sub-system.
|
||||
*/
|
||||
void Timer::Initialize(void)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(l_TimerMutex);
|
||||
l_StopTimerThread = false;
|
||||
l_TimerThread = std::thread(&Timer::TimerThreadProc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the timer sub-system.
|
||||
*/
|
||||
void Timer::Uninitialize(void)
|
||||
{
|
||||
{
|
||||
boost::mutex::scoped_lock lock(l_TimerMutex);
|
||||
l_StopTimerThread = true;
|
||||
l_TimerCV.notify_all();
|
||||
}
|
||||
{
|
||||
boost::mutex::scoped_lock lock(l_TimerMutex);
|
||||
l_StopTimerThread = true;
|
||||
l_TimerCV.notify_all();
|
||||
}
|
||||
|
||||
if (l_TimerThread.joinable())
|
||||
l_TimerThread.join();
|
||||
if (l_TimerThread.joinable())
|
||||
l_TimerThread.join();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -158,6 +146,11 @@ void Timer::Start(void)
|
|||
{
|
||||
boost::mutex::scoped_lock lock(l_TimerMutex);
|
||||
m_Started = true;
|
||||
|
||||
if (l_AliveTimers++ == 0) {
|
||||
l_StopTimerThread = false;
|
||||
l_TimerThread = std::thread(&Timer::TimerThreadProc);
|
||||
}
|
||||
}
|
||||
|
||||
InternalReschedule(false);
|
||||
|
@ -173,6 +166,18 @@ void Timer::Stop(bool wait)
|
|||
|
||||
boost::mutex::scoped_lock lock(l_TimerMutex);
|
||||
|
||||
if (m_Started && --l_AliveTimers == 0) {
|
||||
l_StopTimerThread = true;
|
||||
l_TimerCV.notify_all();
|
||||
|
||||
lock.unlock();
|
||||
|
||||
if (l_TimerThread.joinable() && l_TimerThread.get_id() != std::this_thread::get_id())
|
||||
l_TimerThread.join();
|
||||
|
||||
lock.lock();
|
||||
}
|
||||
|
||||
m_Started = false;
|
||||
l_Timers.erase(this);
|
||||
|
||||
|
|
|
@ -41,6 +41,8 @@ public:
|
|||
Timer(void);
|
||||
~Timer(void);
|
||||
|
||||
static void Uninitialize(void);
|
||||
|
||||
void SetInterval(double interval);
|
||||
double GetInterval(void) const;
|
||||
|
||||
|
@ -65,10 +67,6 @@ private:
|
|||
|
||||
static void TimerThreadProc(void);
|
||||
|
||||
static void Initialize(void);
|
||||
static void Uninitialize(void);
|
||||
|
||||
friend class Application;
|
||||
friend class TimerHolder;
|
||||
};
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "base/timer.hpp"
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
#include <boost/thread/once.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
|
@ -37,18 +38,8 @@ static Timer::Ptr l_CommentsExpireTimer;
|
|||
boost::signals2::signal<void (const Comment::Ptr&)> Comment::OnCommentAdded;
|
||||
boost::signals2::signal<void (const Comment::Ptr&)> Comment::OnCommentRemoved;
|
||||
|
||||
INITIALIZE_ONCE(&Comment::StaticInitialize);
|
||||
|
||||
REGISTER_TYPE(Comment);
|
||||
|
||||
void Comment::StaticInitialize(void)
|
||||
{
|
||||
l_CommentsExpireTimer = new Timer();
|
||||
l_CommentsExpireTimer->SetInterval(60);
|
||||
l_CommentsExpireTimer->OnTimerExpired.connect(std::bind(&Comment::CommentsExpireTimerHandler));
|
||||
l_CommentsExpireTimer->Start();
|
||||
}
|
||||
|
||||
String CommentNameComposer::MakeName(const String& shortName, const Object::Ptr& context) const
|
||||
{
|
||||
Comment::Ptr comment = dynamic_pointer_cast<Comment>(context);
|
||||
|
@ -106,6 +97,15 @@ void Comment::Start(bool runtimeCreated)
|
|||
{
|
||||
ObjectImpl<Comment>::Start(runtimeCreated);
|
||||
|
||||
static boost::once_flag once = BOOST_ONCE_INIT;
|
||||
|
||||
boost::call_once(once, []() {
|
||||
l_CommentsExpireTimer = new Timer();
|
||||
l_CommentsExpireTimer->SetInterval(60);
|
||||
l_CommentsExpireTimer->OnTimerExpired.connect(std::bind(&Comment::CommentsExpireTimerHandler));
|
||||
l_CommentsExpireTimer->Start();
|
||||
});
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock lock(l_CommentMutex);
|
||||
|
||||
|
|
|
@ -56,8 +56,6 @@ public:
|
|||
|
||||
static String GetCommentIDFromLegacyID(int id);
|
||||
|
||||
static void StaticInitialize(void);
|
||||
|
||||
protected:
|
||||
virtual void OnAllConfigLoaded(void) override;
|
||||
virtual void Start(bool runtimeCreated) override;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "base/timer.hpp"
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
#include <boost/thread/once.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
|
@ -41,23 +42,8 @@ boost::signals2::signal<void (const Downtime::Ptr&)> Downtime::OnDowntimeRemoved
|
|||
boost::signals2::signal<void (const Downtime::Ptr&)> Downtime::OnDowntimeStarted;
|
||||
boost::signals2::signal<void (const Downtime::Ptr&)> Downtime::OnDowntimeTriggered;
|
||||
|
||||
INITIALIZE_ONCE(&Downtime::StaticInitialize);
|
||||
|
||||
REGISTER_TYPE(Downtime);
|
||||
|
||||
void Downtime::StaticInitialize(void)
|
||||
{
|
||||
l_DowntimesStartTimer = new Timer();
|
||||
l_DowntimesStartTimer->SetInterval(5);
|
||||
l_DowntimesStartTimer->OnTimerExpired.connect(std::bind(&Downtime::DowntimesStartTimerHandler));
|
||||
l_DowntimesStartTimer->Start();
|
||||
|
||||
l_DowntimesExpireTimer = new Timer();
|
||||
l_DowntimesExpireTimer->SetInterval(60);
|
||||
l_DowntimesExpireTimer->OnTimerExpired.connect(std::bind(&Downtime::DowntimesExpireTimerHandler));
|
||||
l_DowntimesExpireTimer->Start();
|
||||
}
|
||||
|
||||
String DowntimeNameComposer::MakeName(const String& shortName, const Object::Ptr& context) const
|
||||
{
|
||||
Downtime::Ptr downtime = dynamic_pointer_cast<Downtime>(context);
|
||||
|
@ -115,6 +101,20 @@ void Downtime::Start(bool runtimeCreated)
|
|||
{
|
||||
ObjectImpl<Downtime>::Start(runtimeCreated);
|
||||
|
||||
static boost::once_flag once = BOOST_ONCE_INIT;
|
||||
|
||||
boost::call_once(once, []() {
|
||||
l_DowntimesStartTimer = new Timer();
|
||||
l_DowntimesStartTimer->SetInterval(5);
|
||||
l_DowntimesStartTimer->OnTimerExpired.connect(std::bind(&Downtime::DowntimesStartTimerHandler));
|
||||
l_DowntimesStartTimer->Start();
|
||||
|
||||
l_DowntimesExpireTimer = new Timer();
|
||||
l_DowntimesExpireTimer->SetInterval(60);
|
||||
l_DowntimesExpireTimer->OnTimerExpired.connect(std::bind(&Downtime::DowntimesExpireTimerHandler));
|
||||
l_DowntimesExpireTimer->Start();
|
||||
});
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock lock(l_DowntimeMutex);
|
||||
|
||||
|
|
|
@ -65,8 +65,6 @@ public:
|
|||
|
||||
static String GetDowntimeIDFromLegacyID(int id);
|
||||
|
||||
static void StaticInitialize(void);
|
||||
|
||||
protected:
|
||||
virtual void OnAllConfigLoaded(void) override;
|
||||
virtual void Start(bool runtimeCreated) override;
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <fstream>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/thread/once.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
|
@ -111,6 +112,12 @@ void ExternalCommandProcessor::Execute(double time, const String& command, const
|
|||
{
|
||||
ExternalCommandInfo eci;
|
||||
|
||||
static boost::once_flag once = BOOST_ONCE_INIT;
|
||||
|
||||
boost::call_once(once, []() {
|
||||
RegisterCommands();
|
||||
});
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock lock(GetMutex());
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "icinga/service.hpp"
|
||||
#include "base/timer.hpp"
|
||||
#include "base/configtype.hpp"
|
||||
#include "base/initialize.hpp"
|
||||
#include "base/utility.hpp"
|
||||
#include "base/objectlock.hpp"
|
||||
#include "base/convert.hpp"
|
||||
|
@ -32,13 +31,12 @@
|
|||
#include "base/exception.hpp"
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
#include <boost/thread/once.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
REGISTER_TYPE(ScheduledDowntime);
|
||||
|
||||
INITIALIZE_ONCE(&ScheduledDowntime::StaticInitialize);
|
||||
|
||||
static Timer::Ptr l_Timer;
|
||||
|
||||
String ScheduledDowntimeNameComposer::MakeName(const String& shortName, const Object::Ptr& context) const
|
||||
|
@ -79,14 +77,6 @@ Dictionary::Ptr ScheduledDowntimeNameComposer::ParseName(const String& name) con
|
|||
return result;
|
||||
}
|
||||
|
||||
void ScheduledDowntime::StaticInitialize(void)
|
||||
{
|
||||
l_Timer = new Timer();
|
||||
l_Timer->SetInterval(60);
|
||||
l_Timer->OnTimerExpired.connect(std::bind(&ScheduledDowntime::TimerProc));
|
||||
l_Timer->Start();
|
||||
}
|
||||
|
||||
void ScheduledDowntime::OnAllConfigLoaded(void)
|
||||
{
|
||||
ObjectImpl<ScheduledDowntime>::OnAllConfigLoaded();
|
||||
|
@ -99,6 +89,15 @@ void ScheduledDowntime::Start(bool runtimeCreated)
|
|||
{
|
||||
ObjectImpl<ScheduledDowntime>::Start(runtimeCreated);
|
||||
|
||||
static boost::once_flag once = BOOST_ONCE_INIT;
|
||||
|
||||
boost::call_once(once, []() {
|
||||
l_Timer = new Timer();
|
||||
l_Timer->SetInterval(60);
|
||||
l_Timer->OnTimerExpired.connect(std::bind(&ScheduledDowntime::TimerProc));
|
||||
l_Timer->Start();
|
||||
});
|
||||
|
||||
Utility::QueueAsyncCallback(std::bind(&ScheduledDowntime::CreateNextDowntime, this));
|
||||
}
|
||||
|
||||
|
|
|
@ -44,8 +44,6 @@ public:
|
|||
DECLARE_OBJECT(ScheduledDowntime);
|
||||
DECLARE_OBJECTNAME(ScheduledDowntime);
|
||||
|
||||
static void StaticInitialize(void);
|
||||
|
||||
Checkable::Ptr GetCheckable(void) const;
|
||||
|
||||
static void EvaluateApplyRules(const intrusive_ptr<Host>& host);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "base/logger.hpp"
|
||||
#include "base/timer.hpp"
|
||||
#include "base/utility.hpp"
|
||||
#include <boost/thread/once.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
|
@ -33,20 +34,19 @@ REGISTER_TYPE(TimePeriod);
|
|||
|
||||
static Timer::Ptr l_UpdateTimer;
|
||||
|
||||
INITIALIZE_ONCE(&TimePeriod::StaticInitialize);
|
||||
|
||||
void TimePeriod::StaticInitialize(void)
|
||||
{
|
||||
l_UpdateTimer = new Timer();
|
||||
l_UpdateTimer->SetInterval(300);
|
||||
l_UpdateTimer->OnTimerExpired.connect(std::bind(&TimePeriod::UpdateTimerHandler));
|
||||
l_UpdateTimer->Start();
|
||||
}
|
||||
|
||||
void TimePeriod::Start(bool runtimeCreated)
|
||||
{
|
||||
ObjectImpl<TimePeriod>::Start(runtimeCreated);
|
||||
|
||||
static boost::once_flag once = BOOST_ONCE_INIT;
|
||||
|
||||
boost::call_once(once, []() {
|
||||
l_UpdateTimer = new Timer();
|
||||
l_UpdateTimer->SetInterval(300);
|
||||
l_UpdateTimer->OnTimerExpired.connect(std::bind(&TimePeriod::UpdateTimerHandler));
|
||||
l_UpdateTimer->Start();
|
||||
});
|
||||
|
||||
/* Pre-fill the time period for the next 24 hours. */
|
||||
double now = Utility::GetTime();
|
||||
UpdateRegion(now, now + 24 * 3600, true);
|
||||
|
|
|
@ -37,8 +37,6 @@ public:
|
|||
DECLARE_OBJECT(TimePeriod);
|
||||
DECLARE_OBJECTNAME(TimePeriod);
|
||||
|
||||
static void StaticInitialize(void);
|
||||
|
||||
virtual void Start(bool runtimeCreated) override;
|
||||
|
||||
void UpdateRegion(double begin, double end, bool clearExisting);
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "base/timer.hpp"
|
||||
#include "base/initialize.hpp"
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/thread/once.hpp>
|
||||
#include <set>
|
||||
|
||||
using namespace icinga;
|
||||
|
@ -57,12 +58,17 @@ static void ScriptFrameCleanupHandler(void)
|
|||
l_ApiScriptFrames.erase(key);
|
||||
}
|
||||
|
||||
INITIALIZE_ONCE([]() {
|
||||
l_FrameCleanupTimer = new Timer();
|
||||
l_FrameCleanupTimer->OnTimerExpired.connect(std::bind(ScriptFrameCleanupHandler));
|
||||
l_FrameCleanupTimer->SetInterval(30);
|
||||
l_FrameCleanupTimer->Start();
|
||||
});
|
||||
static void EnsureFrameCleanupTimer(void)
|
||||
{
|
||||
static boost::once_flag once = BOOST_ONCE_INIT;
|
||||
|
||||
boost::call_once(once, []() {
|
||||
l_FrameCleanupTimer = new Timer();
|
||||
l_FrameCleanupTimer->OnTimerExpired.connect(std::bind(ScriptFrameCleanupHandler));
|
||||
l_FrameCleanupTimer->SetInterval(30);
|
||||
l_FrameCleanupTimer->Start();
|
||||
});
|
||||
}
|
||||
|
||||
bool ConsoleHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
|
||||
{
|
||||
|
@ -102,6 +108,8 @@ bool ConsoleHandler::ExecuteScriptHelper(HttpRequest& request, HttpResponse& res
|
|||
Log(LogNotice, "Console")
|
||||
<< "Executing expression: " << command;
|
||||
|
||||
EnsureFrameCleanupTimer();
|
||||
|
||||
ApiScriptFrame& lsf = l_ApiScriptFrames[session];
|
||||
lsf.Seen = Utility::GetTime();
|
||||
|
||||
|
@ -175,6 +183,8 @@ bool ConsoleHandler::AutocompleteScriptHelper(HttpRequest& request, HttpResponse
|
|||
Log(LogInformation, "Console")
|
||||
<< "Auto-completing expression: " << command;
|
||||
|
||||
EnsureFrameCleanupTimer();
|
||||
|
||||
ApiScriptFrame& lsf = l_ApiScriptFrames[session];
|
||||
lsf.Seen = Utility::GetTime();
|
||||
|
||||
|
|
|
@ -29,15 +29,6 @@ using namespace icinga;
|
|||
|
||||
REGISTER_APIFUNCTION(Heartbeat, event, &JsonRpcConnection::HeartbeatAPIHandler);
|
||||
|
||||
static Timer::Ptr l_HeartbeatTimer;
|
||||
|
||||
INITIALIZE_ONCE([]() {
|
||||
l_HeartbeatTimer = new Timer();
|
||||
l_HeartbeatTimer->OnTimerExpired.connect(std::bind(&JsonRpcConnection::HeartbeatTimerHandler));
|
||||
l_HeartbeatTimer->SetInterval(10);
|
||||
l_HeartbeatTimer->Start();
|
||||
});
|
||||
|
||||
void JsonRpcConnection::HeartbeatTimerHandler(void)
|
||||
{
|
||||
for (const Endpoint::Ptr& endpoint : ConfigType::GetObjectsByType<Endpoint>()) {
|
||||
|
|
|
@ -39,6 +39,7 @@ static Timer::Ptr l_JsonRpcConnectionTimeoutTimer;
|
|||
static WorkQueue *l_JsonRpcConnectionWorkQueues;
|
||||
static size_t l_JsonRpcConnectionWorkQueueCount;
|
||||
static int l_JsonRpcConnectionNextID;
|
||||
static Timer::Ptr l_HeartbeatTimer;
|
||||
|
||||
JsonRpcConnection::JsonRpcConnection(const String& identity, bool authenticated,
|
||||
const TlsStream::Ptr& stream, ConnectionRole role)
|
||||
|
@ -65,6 +66,11 @@ void JsonRpcConnection::StaticInitialize(void)
|
|||
for (size_t i = 0; i < l_JsonRpcConnectionWorkQueueCount; i++) {
|
||||
l_JsonRpcConnectionWorkQueues[i].SetName("JsonRpcConnection, #" + Convert::ToString(i));
|
||||
}
|
||||
|
||||
l_HeartbeatTimer = new Timer();
|
||||
l_HeartbeatTimer->OnTimerExpired.connect(std::bind(&JsonRpcConnection::HeartbeatTimerHandler));
|
||||
l_HeartbeatTimer->SetInterval(10);
|
||||
l_HeartbeatTimer->Start();
|
||||
}
|
||||
|
||||
void JsonRpcConnection::Start(void)
|
||||
|
|
Loading…
Reference in New Issue