mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-26 07:04:37 +02:00
parent
63f22b055b
commit
951c61ed16
@ -188,7 +188,7 @@ void CheckerComponent::CheckThreadProc(void)
|
|||||||
Log(LogDebug, "checker", "Executing check for '" + checkable->GetName() + "'");
|
Log(LogDebug, "checker", "Executing check for '" + checkable->GetName() + "'");
|
||||||
|
|
||||||
CheckerComponent::Ptr self = GetSelf();
|
CheckerComponent::Ptr self = GetSelf();
|
||||||
m_Pool.Post(boost::bind(&CheckerComponent::ExecuteCheckHelper, self, checkable));
|
Utility::QueueAsyncCallback(boost::bind(&CheckerComponent::ExecuteCheckHelper, self, checkable));
|
||||||
|
|
||||||
lock.lock();
|
lock.lock();
|
||||||
}
|
}
|
||||||
|
@ -98,8 +98,6 @@ private:
|
|||||||
void NextCheckChangedHandler(const Checkable::Ptr& checkable);
|
void NextCheckChangedHandler(const Checkable::Ptr& checkable);
|
||||||
|
|
||||||
void RescheduleCheckTimer(void);
|
void RescheduleCheckTimer(void);
|
||||||
|
|
||||||
ThreadPool m_Pool;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -257,6 +257,9 @@ int Main(void)
|
|||||||
("daemonize,d", "detach from the controlling terminal")
|
("daemonize,d", "detach from the controlling terminal")
|
||||||
("user,u", po::value<std::string>(), "user to run Icinga as")
|
("user,u", po::value<std::string>(), "user to run Icinga as")
|
||||||
("group,g", po::value<std::string>(), "group to run Icinga as")
|
("group,g", po::value<std::string>(), "group to run Icinga as")
|
||||||
|
# ifdef RLIMIT_STACK
|
||||||
|
("no-stack-rlimit", "don't attempt to set RLIMIT_STACK")
|
||||||
|
# endif /* RLIMIT_STACK */
|
||||||
#else /* _WIN32 */
|
#else /* _WIN32 */
|
||||||
("scm", "run as a Windows service (must be the first argument if specified)")
|
("scm", "run as a Windows service (must be the first argument if specified)")
|
||||||
("scm-install", "installs Icinga 2 as a Windows service (must be the first argument if specified")
|
("scm-install", "installs Icinga 2 as a Windows service (must be the first argument if specified")
|
||||||
|
@ -117,8 +117,9 @@ Application::Ptr Application::GetInstance(void)
|
|||||||
void Application::SetResourceLimits(void)
|
void Application::SetResourceLimits(void)
|
||||||
{
|
{
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
# ifdef RLIMIT_NOFILE
|
|
||||||
rlimit rl;
|
rlimit rl;
|
||||||
|
|
||||||
|
# ifdef RLIMIT_NOFILE
|
||||||
rl.rlim_cur = 16 * 1024;
|
rl.rlim_cur = 16 * 1024;
|
||||||
rl.rlim_max = rl.rlim_cur;
|
rl.rlim_max = rl.rlim_cur;
|
||||||
|
|
||||||
@ -137,6 +138,54 @@ void Application::SetResourceLimits(void)
|
|||||||
# else /* RLIMIT_NPROC */
|
# else /* RLIMIT_NPROC */
|
||||||
Log(LogDebug, "base", "System does not support adjusting the resource limit for number of processes (RLIMIT_NPROC)");
|
Log(LogDebug, "base", "System does not support adjusting the resource limit for number of processes (RLIMIT_NPROC)");
|
||||||
# endif /* RLIMIT_NPROC */
|
# endif /* RLIMIT_NPROC */
|
||||||
|
|
||||||
|
# ifdef RLIMIT_STACK
|
||||||
|
int argc = Application::GetArgC();
|
||||||
|
char **argv = Application::GetArgV();
|
||||||
|
bool set_stack_rlimit = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < argc; i++) {
|
||||||
|
if (strcmp(argv[i], "--no-stack-rlimit") == 0) {
|
||||||
|
set_stack_rlimit = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (set_stack_rlimit) {
|
||||||
|
rl.rlim_cur = 256 * 1024;
|
||||||
|
rl.rlim_max = rl.rlim_cur;
|
||||||
|
|
||||||
|
if (setrlimit(RLIMIT_STACK, &rl) < 0)
|
||||||
|
Log(LogDebug, "base", "Could not adjust resource limit for stack size (RLIMIT_STACK)");
|
||||||
|
else {
|
||||||
|
char **new_argv = static_cast<char **>(malloc(sizeof(char *) * (argc + 2)));
|
||||||
|
|
||||||
|
if (!new_argv) {
|
||||||
|
perror("malloc");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < argc; i++)
|
||||||
|
new_argv[i] = argv[i];
|
||||||
|
|
||||||
|
new_argv[argc] = strdup("--no-stack-rlimit");
|
||||||
|
|
||||||
|
if (!new_argv[argc]) {
|
||||||
|
perror("strdup");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
new_argv[argc + 1] = NULL;
|
||||||
|
|
||||||
|
if (execvp(new_argv[0], new_argv) < 0)
|
||||||
|
perror("execvp");
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# else /* RLIMIT_STACK */
|
||||||
|
Log(LogDebug, "base", "System does not support adjusting the resource limit for stack size (RLIMIT_STACK)");
|
||||||
|
# endif /* RLIMIT_STACK */
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,14 +215,30 @@ void Application::SetArgV(char **argv)
|
|||||||
*/
|
*/
|
||||||
void Application::RunEventLoop(void) const
|
void Application::RunEventLoop(void) const
|
||||||
{
|
{
|
||||||
/* Start the system time watch thread. */
|
|
||||||
boost::thread t(&Application::TimeWatchThreadProc);
|
|
||||||
t.detach();
|
|
||||||
|
|
||||||
Timer::Initialize();
|
Timer::Initialize();
|
||||||
|
|
||||||
while (!m_ShuttingDown && !m_Restarting)
|
double lastLoop = Utility::GetTime();
|
||||||
Utility::Sleep(0.5);
|
|
||||||
|
while (!m_ShuttingDown && !m_Restarting) {
|
||||||
|
/* Watches for changes to the system time. Adjusts timers if necessary. */
|
||||||
|
Utility::Sleep(2.5);
|
||||||
|
|
||||||
|
double now = Utility::GetTime();
|
||||||
|
double timeDiff = lastLoop - now;
|
||||||
|
|
||||||
|
if (abs(timeDiff) > 15) {
|
||||||
|
/* We made a significant jump in time. */
|
||||||
|
std::ostringstream msgbuf;
|
||||||
|
msgbuf << "We jumped "
|
||||||
|
<< (timeDiff < 0 ? "forward" : "backward")
|
||||||
|
<< " in time: " << abs(timeDiff) << " seconds";
|
||||||
|
Log(LogInformation, "base", msgbuf.str());
|
||||||
|
|
||||||
|
Timer::AdjustTimers(-timeDiff);
|
||||||
|
}
|
||||||
|
|
||||||
|
lastLoop = now;
|
||||||
|
}
|
||||||
|
|
||||||
Log(LogInformation, "base", "Shutting down Icinga...");
|
Log(LogInformation, "base", "Shutting down Icinga...");
|
||||||
DynamicObject::StopObjects();
|
DynamicObject::StopObjects();
|
||||||
@ -194,36 +259,6 @@ void Application::OnShutdown(void)
|
|||||||
/* Nothing to do here. */
|
/* Nothing to do here. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Watches for changes to the system time. Adjusts timers if necessary.
|
|
||||||
*/
|
|
||||||
void Application::TimeWatchThreadProc(void)
|
|
||||||
{
|
|
||||||
Utility::SetThreadName("Time Watch");
|
|
||||||
|
|
||||||
double lastLoop = Utility::GetTime();
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
Utility::Sleep(5);
|
|
||||||
|
|
||||||
double now = Utility::GetTime();
|
|
||||||
double timeDiff = lastLoop - now;
|
|
||||||
|
|
||||||
if (abs(timeDiff) > 15) {
|
|
||||||
/* We made a significant jump in time. */
|
|
||||||
std::ostringstream msgbuf;
|
|
||||||
msgbuf << "We jumped "
|
|
||||||
<< (timeDiff < 0 ? "forward" : "backward")
|
|
||||||
<< " in time: " << abs(timeDiff) << " seconds";
|
|
||||||
Log(LogInformation, "base", msgbuf.str());
|
|
||||||
|
|
||||||
Timer::AdjustTimers(-timeDiff);
|
|
||||||
}
|
|
||||||
|
|
||||||
lastLoop = now;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signals the application to shut down during the next
|
* Signals the application to shut down during the next
|
||||||
* execution of the event loop.
|
* execution of the event loop.
|
||||||
|
@ -134,9 +134,6 @@ private:
|
|||||||
|
|
||||||
static void SigAbrtHandler(int signum);
|
static void SigAbrtHandler(int signum);
|
||||||
static void ExceptionHandler(void);
|
static void ExceptionHandler(void);
|
||||||
|
|
||||||
static void TimeWatchThreadProc(void);
|
|
||||||
static void NewTxTimerHandler(void);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ extern char **environ;
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
#define IOTHREADS 8
|
#define IOTHREADS 2
|
||||||
|
|
||||||
static boost::mutex l_ProcessMutex[IOTHREADS];
|
static boost::mutex l_ProcessMutex[IOTHREADS];
|
||||||
static std::map<Process::ProcessHandle, Process::Ptr> l_Processes[IOTHREADS];
|
static std::map<Process::ProcessHandle, Process::Ptr> l_Processes[IOTHREADS];
|
||||||
|
@ -54,7 +54,6 @@ void ThreadPool::Start(void)
|
|||||||
m_Queues[i].SpawnWorker(m_ThreadGroup);
|
m_Queues[i].SpawnWorker(m_ThreadGroup);
|
||||||
|
|
||||||
m_ThreadGroup.create_thread(boost::bind(&ThreadPool::ManagerThreadProc, this));
|
m_ThreadGroup.create_thread(boost::bind(&ThreadPool::ManagerThreadProc, this));
|
||||||
m_ThreadGroup.create_thread(boost::bind(&ThreadPool::StatsThreadProc, this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadPool::Stop(void)
|
void ThreadPool::Stop(void)
|
||||||
@ -226,6 +225,8 @@ void ThreadPool::ManagerThreadProc(void)
|
|||||||
idbuf << "TP #" << m_ID << " Manager";
|
idbuf << "TP #" << m_ID << " Manager";
|
||||||
Utility::SetThreadName(idbuf.str());
|
Utility::SetThreadName(idbuf.str());
|
||||||
|
|
||||||
|
double lastStats = 0;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
size_t total_pending = 0, total_alive = 0;
|
size_t total_pending = 0, total_alive = 0;
|
||||||
double total_avg_latency = 0;
|
double total_avg_latency = 0;
|
||||||
@ -250,6 +251,9 @@ void ThreadPool::ManagerThreadProc(void)
|
|||||||
|
|
||||||
boost::mutex::scoped_lock lock(queue.Mutex);
|
boost::mutex::scoped_lock lock(queue.Mutex);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sizeof(queue.Threads) / sizeof(queue.Threads[0]); i++)
|
||||||
|
queue.Threads[i].UpdateUtilization();
|
||||||
|
|
||||||
pending = queue.Items.size();
|
pending = queue.Items.size();
|
||||||
|
|
||||||
for (size_t i = 0; i < sizeof(queue.Threads) / sizeof(queue.Threads[0]); i++) {
|
for (size_t i = 0; i < sizeof(queue.Threads) / sizeof(queue.Threads[0]); i++) {
|
||||||
@ -271,9 +275,9 @@ void ThreadPool::ManagerThreadProc(void)
|
|||||||
|
|
||||||
int tthreads = wthreads - alive;
|
int tthreads = wthreads - alive;
|
||||||
|
|
||||||
/* Don't ever kill the last threads. */
|
/* Don't ever kill the last thread. */
|
||||||
if (alive + tthreads < 2)
|
if (alive + tthreads < 1)
|
||||||
tthreads = 2 - alive;
|
tthreads = 1 - alive;
|
||||||
|
|
||||||
/* Don't kill more than 8 threads at once. */
|
/* Don't kill more than 8 threads at once. */
|
||||||
if (tthreads < -8)
|
if (tthreads < -8)
|
||||||
@ -309,12 +313,18 @@ void ThreadPool::ManagerThreadProc(void)
|
|||||||
total_utilization += utilization;
|
total_utilization += utilization;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostringstream msgbuf;
|
double now = Utility::GetTime();
|
||||||
msgbuf << "Pool #" << m_ID << ": Pending tasks: " << total_pending << "; Average latency: "
|
|
||||||
<< (long)(total_avg_latency * 1000 / (sizeof(m_Queues) / sizeof(m_Queues[0]))) << "ms"
|
if (lastStats < now - 15) {
|
||||||
<< "; Threads: " << total_alive
|
lastStats = now;
|
||||||
<< "; Pool utilization: " << (total_utilization / (sizeof(m_Queues) / sizeof(m_Queues[0]))) << "%";
|
|
||||||
Log(LogInformation, "base", msgbuf.str());
|
std::ostringstream msgbuf;
|
||||||
|
msgbuf << "Pool #" << m_ID << ": Pending tasks: " << total_pending << "; Average latency: "
|
||||||
|
<< (long)(total_avg_latency * 1000 / (sizeof(m_Queues) / sizeof(m_Queues[0]))) << "ms"
|
||||||
|
<< "; Threads: " << total_alive
|
||||||
|
<< "; Pool utilization: " << (total_utilization / (sizeof(m_Queues) / sizeof(m_Queues[0]))) << "%";
|
||||||
|
Log(LogInformation, "base", msgbuf.str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,34 +366,6 @@ void ThreadPool::Queue::KillWorker(boost::thread_group& group)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadPool::StatsThreadProc(void)
|
|
||||||
{
|
|
||||||
std::ostringstream idbuf;
|
|
||||||
idbuf << "TP #" << m_ID << " Stats";
|
|
||||||
Utility::SetThreadName(idbuf.str());
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
{
|
|
||||||
boost::mutex::scoped_lock lock(m_MgmtMutex);
|
|
||||||
|
|
||||||
if (!m_Stopped)
|
|
||||||
m_MgmtCV.timed_wait(lock, boost::posix_time::milliseconds(250));
|
|
||||||
|
|
||||||
if (m_Stopped)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < sizeof(m_Queues) / sizeof(m_Queues[0]); i++) {
|
|
||||||
Queue& queue = m_Queues[i];
|
|
||||||
|
|
||||||
boost::mutex::scoped_lock lock(queue.Mutex);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < sizeof(queue.Threads) / sizeof(queue.Threads[0]); i++)
|
|
||||||
queue.Threads[i].UpdateUtilization();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note: Caller must hold queue Mutex.
|
* Note: Caller must hold queue Mutex.
|
||||||
*/
|
*/
|
||||||
|
@ -121,7 +121,6 @@ private:
|
|||||||
Queue m_Queues[4];
|
Queue m_Queues[4];
|
||||||
|
|
||||||
void ManagerThreadProc(void);
|
void ManagerThreadProc(void);
|
||||||
void StatsThreadProc(void);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user