mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-22 05:04:30 +02:00
Fine-grained locks (WIP, Part 2).
This commit is contained in:
parent
c63c28dd9c
commit
a4c7052a6e
@ -35,10 +35,8 @@ void CheckerComponent::Start(void)
|
|||||||
Service::OnNextCheckChanged.connect(bind(&CheckerComponent::NextCheckChangedHandler, this, _1));
|
Service::OnNextCheckChanged.connect(bind(&CheckerComponent::NextCheckChangedHandler, this, _1));
|
||||||
DynamicObject::OnUnregistered.connect(bind(&CheckerComponent::ObjectRemovedHandler, this, _1));
|
DynamicObject::OnUnregistered.connect(bind(&CheckerComponent::ObjectRemovedHandler, this, _1));
|
||||||
|
|
||||||
m_CheckTimer = boost::make_shared<Timer>();
|
boost::thread thread(boost::bind(&CheckerComponent::CheckThreadProc, this));
|
||||||
m_CheckTimer->SetInterval(0.1);
|
thread.detach();
|
||||||
m_CheckTimer->OnTimerExpired.connect(boost::bind(&CheckerComponent::CheckTimerHandler, this));
|
|
||||||
m_CheckTimer->Start();
|
|
||||||
|
|
||||||
m_ResultTimer = boost::make_shared<Timer>();
|
m_ResultTimer = boost::make_shared<Timer>();
|
||||||
m_ResultTimer->SetInterval(5);
|
m_ResultTimer->SetInterval(5);
|
||||||
@ -51,15 +49,8 @@ void CheckerComponent::Stop(void)
|
|||||||
m_Endpoint->Unregister();
|
m_Endpoint->Unregister();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckerComponent::CheckTimerHandler(void)
|
void CheckerComponent::CheckThreadProc(void)
|
||||||
{
|
{
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
|
|
||||||
double now = Utility::GetTime();
|
|
||||||
long tasks = 0;
|
|
||||||
|
|
||||||
int missedServices = 0, missedChecks = 0;
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
Service::Ptr service;
|
Service::Ptr service;
|
||||||
|
|
||||||
@ -69,8 +60,8 @@ void CheckerComponent::CheckTimerHandler(void)
|
|||||||
typedef nth_index<ServiceSet, 1>::type CheckTimeView;
|
typedef nth_index<ServiceSet, 1>::type CheckTimeView;
|
||||||
CheckTimeView& idx = boost::get<1>(m_IdleServices);
|
CheckTimeView& idx = boost::get<1>(m_IdleServices);
|
||||||
|
|
||||||
if (idx.begin() == idx.end())
|
while (idx.begin() == idx.end())
|
||||||
break;
|
m_CV.wait(lock);
|
||||||
|
|
||||||
CheckTimeView::iterator it = idx.begin();
|
CheckTimeView::iterator it = idx.begin();
|
||||||
service = it->lock();
|
service = it->lock();
|
||||||
@ -79,18 +70,32 @@ void CheckerComponent::CheckTimerHandler(void)
|
|||||||
idx.erase(it);
|
idx.erase(it);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
ObjectLock olock(service);
|
|
||||||
|
|
||||||
if (service->GetNextCheck() > now)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
idx.erase(it);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectLock olock(service);
|
double wait;
|
||||||
|
|
||||||
|
{
|
||||||
|
ObjectLock olock(service);
|
||||||
|
wait = service->GetNextCheck() - Utility::GetTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wait > 0) {
|
||||||
|
/* Make sure the service we just examined can be destroyed while we're waiting. */
|
||||||
|
service.reset();
|
||||||
|
|
||||||
|
/* Wait for the next check. */
|
||||||
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
|
m_CV.timed_wait(lock, boost::posix_time::milliseconds(wait * 1000));
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
|
m_IdleServices.erase(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectLock olock(service); /* also required for the key extractor */
|
||||||
|
|
||||||
/* reschedule the service if checks are currently disabled
|
/* reschedule the service if checks are currently disabled
|
||||||
* for it and this is not a forced check */
|
* for it and this is not a forced check */
|
||||||
@ -115,51 +120,28 @@ void CheckerComponent::CheckTimerHandler(void)
|
|||||||
|
|
||||||
service->SetForceNextCheck(false);
|
service->SetForceNextCheck(false);
|
||||||
|
|
||||||
Dictionary::Ptr cr = service->GetLastCheckResult();
|
|
||||||
|
|
||||||
if (cr) {
|
|
||||||
double lastCheck = cr->Get("execution_end");
|
|
||||||
int missed = (Utility::GetTime() - lastCheck) / service->GetCheckInterval() - 1;
|
|
||||||
|
|
||||||
if (missed > 0 && !service->GetFirstCheck()) {
|
|
||||||
missedChecks += missed;
|
|
||||||
missedServices++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
service->SetFirstCheck(false);
|
service->SetFirstCheck(false);
|
||||||
|
|
||||||
Logger::Write(LogDebug, "checker", "Executing service check for '" + service->GetName() + "'");
|
Logger::Write(LogDebug, "checker", "Executing service check for '" + service->GetName() + "'");
|
||||||
|
|
||||||
m_IdleServices.erase(service);
|
{
|
||||||
m_PendingServices.insert(service);
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
|
m_IdleServices.erase(service);
|
||||||
|
m_PendingServices.insert(service);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
service->BeginExecuteCheck(boost::bind(&CheckerComponent::CheckCompletedHandler, this, service));
|
service->BeginExecuteCheck(boost::bind(&CheckerComponent::CheckCompletedHandler, this, service));
|
||||||
} catch (const exception& ex) {
|
} catch (const exception& ex) {
|
||||||
Logger::Write(LogCritical, "checker", "Exception occured while checking service '" + service->GetName() + "': " + diagnostic_information(ex));
|
Logger::Write(LogCritical, "checker", "Exception occured while checking service '" + service->GetName() + "': " + diagnostic_information(ex));
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (missedServices > 0) {
|
|
||||||
stringstream msgbuf;
|
|
||||||
msgbuf << "Missed " << missedChecks << " checks for " << missedServices << " services";;
|
|
||||||
Logger::Write(LogWarning, "checker", msgbuf.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tasks > 0) {
|
|
||||||
stringstream msgbuf;
|
|
||||||
msgbuf << "CheckTimerHandler: created " << tasks << " task(s)";
|
|
||||||
Logger::Write(LogDebug, "checker", msgbuf.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
RescheduleCheckTimer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckerComponent::CheckCompletedHandler(const Service::Ptr& service)
|
void CheckerComponent::CheckCompletedHandler(const Service::Ptr& service)
|
||||||
{
|
{
|
||||||
|
ObjectLock olock(service); /* required for the key extractor */
|
||||||
|
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
|
|
||||||
@ -171,15 +153,11 @@ void CheckerComponent::CheckCompletedHandler(const Service::Ptr& service)
|
|||||||
if (it != m_PendingServices.end()) {
|
if (it != m_PendingServices.end()) {
|
||||||
m_PendingServices.erase(it);
|
m_PendingServices.erase(it);
|
||||||
m_IdleServices.insert(service);
|
m_IdleServices.insert(service);
|
||||||
|
m_CV.notify_all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RescheduleCheckTimer();
|
Logger::Write(LogDebug, "checker", "Check finished for service '" + service->GetName() + "'");
|
||||||
|
|
||||||
{
|
|
||||||
ObjectLock olock(service);
|
|
||||||
Logger::Write(LogDebug, "checker", "Check finished for service '" + service->GetName() + "'");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckerComponent::ResultTimerHandler(void)
|
void CheckerComponent::ResultTimerHandler(void)
|
||||||
@ -199,12 +177,8 @@ void CheckerComponent::ResultTimerHandler(void)
|
|||||||
|
|
||||||
void CheckerComponent::CheckerChangedHandler(const Service::Ptr& service)
|
void CheckerComponent::CheckerChangedHandler(const Service::Ptr& service)
|
||||||
{
|
{
|
||||||
String checker;
|
ObjectLock olock(service); /* also required for the key extractor */
|
||||||
|
String checker = service->GetChecker();
|
||||||
{
|
|
||||||
ObjectLock olock(service);
|
|
||||||
checker = service->GetChecker();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (checker == EndpointManager::GetInstance()->GetIdentity() || checker == m_Endpoint->GetName()) {
|
if (checker == EndpointManager::GetInstance()->GetIdentity() || checker == m_Endpoint->GetName()) {
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
@ -213,17 +187,20 @@ void CheckerComponent::CheckerChangedHandler(const Service::Ptr& service)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
m_IdleServices.insert(service);
|
m_IdleServices.insert(service);
|
||||||
|
m_CV.notify_all();
|
||||||
} else {
|
} else {
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
|
|
||||||
m_IdleServices.erase(service);
|
m_IdleServices.erase(service);
|
||||||
m_PendingServices.erase(service);
|
m_PendingServices.erase(service);
|
||||||
|
m_CV.notify_all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckerComponent::NextCheckChangedHandler(const Service::Ptr& service)
|
void CheckerComponent::NextCheckChangedHandler(const Service::Ptr& service)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
ObjectLock olock(service); /* required for the key extractor */
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
|
|
||||||
/* remove and re-insert the service from the set in order to force an index update */
|
/* remove and re-insert the service from the set in order to force an index update */
|
||||||
@ -234,11 +211,9 @@ void CheckerComponent::NextCheckChangedHandler(const Service::Ptr& service)
|
|||||||
if (it == idx.end())
|
if (it == idx.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
idx.erase(it);
|
idx.replace(it, service);
|
||||||
idx.insert(service);
|
m_CV.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
RescheduleCheckTimer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckerComponent::ObjectRemovedHandler(const DynamicObject::Ptr& object)
|
void CheckerComponent::ObjectRemovedHandler(const DynamicObject::Ptr& object)
|
||||||
@ -254,35 +229,6 @@ void CheckerComponent::ObjectRemovedHandler(const DynamicObject::Ptr& object)
|
|||||||
|
|
||||||
m_IdleServices.erase(service);
|
m_IdleServices.erase(service);
|
||||||
m_PendingServices.erase(service);
|
m_PendingServices.erase(service);
|
||||||
|
m_CV.notify_all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckerComponent::RescheduleCheckTimer(void)
|
|
||||||
{
|
|
||||||
Service::Ptr service;
|
|
||||||
|
|
||||||
{
|
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
|
||||||
|
|
||||||
if (m_IdleServices.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
typedef nth_index<ServiceSet, 1>::type CheckTimeView;
|
|
||||||
CheckTimeView& idx = boost::get<1>(m_IdleServices);
|
|
||||||
|
|
||||||
do {
|
|
||||||
CheckTimeView::iterator it = idx.begin();
|
|
||||||
|
|
||||||
if (it == idx.end())
|
|
||||||
return;
|
|
||||||
|
|
||||||
service = it->lock();
|
|
||||||
|
|
||||||
if (!service)
|
|
||||||
idx.erase(it);
|
|
||||||
} while (!service);
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectLock olock(service);
|
|
||||||
m_CheckTimer->Reschedule(service->GetNextCheck());
|
|
||||||
}
|
|
||||||
|
@ -30,6 +30,9 @@ struct ServiceNextCheckExtractor
|
|||||||
{
|
{
|
||||||
typedef double result_type;
|
typedef double result_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @threadsafety Caller must hold the mutex for the service.
|
||||||
|
*/
|
||||||
double operator()(const Service::WeakPtr& wservice)
|
double operator()(const Service::WeakPtr& wservice)
|
||||||
{
|
{
|
||||||
Service::Ptr service = wservice.lock();
|
Service::Ptr service = wservice.lock();
|
||||||
@ -37,10 +40,7 @@ struct ServiceNextCheckExtractor
|
|||||||
if (!service)
|
if (!service)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
{
|
return service->GetNextCheck();
|
||||||
ObjectLock olock(service);
|
|
||||||
return service->GetNextCheck();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -68,15 +68,14 @@ private:
|
|||||||
Endpoint::Ptr m_Endpoint;
|
Endpoint::Ptr m_Endpoint;
|
||||||
|
|
||||||
boost::mutex m_Mutex;
|
boost::mutex m_Mutex;
|
||||||
|
boost::condition_variable m_CV;
|
||||||
|
|
||||||
ServiceSet m_IdleServices;
|
ServiceSet m_IdleServices;
|
||||||
ServiceSet m_PendingServices;
|
ServiceSet m_PendingServices;
|
||||||
|
|
||||||
Timer::Ptr m_CheckTimer;
|
|
||||||
|
|
||||||
Timer::Ptr m_ResultTimer;
|
Timer::Ptr m_ResultTimer;
|
||||||
|
|
||||||
void CheckTimerHandler(void);
|
void CheckThreadProc(void);
|
||||||
void ResultTimerHandler(void);
|
void ResultTimerHandler(void);
|
||||||
|
|
||||||
void CheckCompletedHandler(const Service::Ptr& service);
|
void CheckCompletedHandler(const Service::Ptr& service);
|
||||||
|
@ -154,11 +154,7 @@ void CompatComponent::CommandPipeThread(const String& commandPath)
|
|||||||
|
|
||||||
String command = line;
|
String command = line;
|
||||||
|
|
||||||
{
|
ProcessCommand(command);
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
|
|
||||||
ProcessCommand(command);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
@ -181,6 +177,8 @@ void CompatComponent::ProcessCommand(const String& command)
|
|||||||
|
|
||||||
void CompatComponent::DumpComments(ofstream& fp, const Service::Ptr& owner, CompatObjectType type)
|
void CompatComponent::DumpComments(ofstream& fp, const Service::Ptr& owner, CompatObjectType type)
|
||||||
{
|
{
|
||||||
|
ObjectLock olock(owner);
|
||||||
|
|
||||||
Service::Ptr service;
|
Service::Ptr service;
|
||||||
Host::Ptr host;
|
Host::Ptr host;
|
||||||
Dictionary::Ptr comments = owner->GetComments();
|
Dictionary::Ptr comments = owner->GetComments();
|
||||||
@ -216,6 +214,8 @@ void CompatComponent::DumpComments(ofstream& fp, const Service::Ptr& owner, Comp
|
|||||||
|
|
||||||
void CompatComponent::DumpDowntimes(ofstream& fp, const Service::Ptr& owner, CompatObjectType type)
|
void CompatComponent::DumpDowntimes(ofstream& fp, const Service::Ptr& owner, CompatObjectType type)
|
||||||
{
|
{
|
||||||
|
ObjectLock olock(owner);
|
||||||
|
|
||||||
Dictionary::Ptr downtimes = owner->GetDowntimes();
|
Dictionary::Ptr downtimes = owner->GetDowntimes();
|
||||||
|
|
||||||
if (!downtimes)
|
if (!downtimes)
|
||||||
@ -257,6 +257,8 @@ void CompatComponent::DumpDowntimes(ofstream& fp, const Service::Ptr& owner, Com
|
|||||||
|
|
||||||
void CompatComponent::DumpHostStatus(ofstream& fp, const Host::Ptr& host)
|
void CompatComponent::DumpHostStatus(ofstream& fp, const Host::Ptr& host)
|
||||||
{
|
{
|
||||||
|
ObjectLock olock(host);
|
||||||
|
|
||||||
int state;
|
int state;
|
||||||
if (!host->IsReachable())
|
if (!host->IsReachable())
|
||||||
state = 2; /* unreachable */
|
state = 2; /* unreachable */
|
||||||
@ -285,6 +287,8 @@ void CompatComponent::DumpHostStatus(ofstream& fp, const Host::Ptr& host)
|
|||||||
|
|
||||||
void CompatComponent::DumpHostObject(ofstream& fp, const Host::Ptr& host)
|
void CompatComponent::DumpHostObject(ofstream& fp, const Host::Ptr& host)
|
||||||
{
|
{
|
||||||
|
ObjectLock olock(host);
|
||||||
|
|
||||||
fp << "define host {" << "\n"
|
fp << "define host {" << "\n"
|
||||||
<< "\t" << "host_name" << "\t" << host->GetName() << "\n"
|
<< "\t" << "host_name" << "\t" << host->GetName() << "\n"
|
||||||
<< "\t" << "display_name" << "\t" << host->GetDisplayName() << "\n"
|
<< "\t" << "display_name" << "\t" << host->GetDisplayName() << "\n"
|
||||||
@ -308,6 +312,8 @@ void CompatComponent::DumpHostObject(ofstream& fp, const Host::Ptr& host)
|
|||||||
|
|
||||||
void CompatComponent::DumpServiceStatusAttrs(ofstream& fp, const Service::Ptr& service, CompatObjectType type)
|
void CompatComponent::DumpServiceStatusAttrs(ofstream& fp, const Service::Ptr& service, CompatObjectType type)
|
||||||
{
|
{
|
||||||
|
ObjectLock olock(service);
|
||||||
|
|
||||||
String output;
|
String output;
|
||||||
String perfdata;
|
String perfdata;
|
||||||
double schedule_start = -1, schedule_end = -1;
|
double schedule_start = -1, schedule_end = -1;
|
||||||
@ -370,6 +376,8 @@ void CompatComponent::DumpServiceStatusAttrs(ofstream& fp, const Service::Ptr& s
|
|||||||
|
|
||||||
void CompatComponent::DumpServiceStatus(ofstream& fp, const Service::Ptr& service)
|
void CompatComponent::DumpServiceStatus(ofstream& fp, const Service::Ptr& service)
|
||||||
{
|
{
|
||||||
|
ObjectLock olock(service);
|
||||||
|
|
||||||
fp << "servicestatus {" << "\n"
|
fp << "servicestatus {" << "\n"
|
||||||
<< "\t" << "host_name=" << service->GetHost()->GetName() << "\n"
|
<< "\t" << "host_name=" << service->GetHost()->GetName() << "\n"
|
||||||
<< "\t" << "service_description=" << service->GetShortName() << "\n";
|
<< "\t" << "service_description=" << service->GetShortName() << "\n";
|
||||||
@ -385,6 +393,8 @@ void CompatComponent::DumpServiceStatus(ofstream& fp, const Service::Ptr& servic
|
|||||||
|
|
||||||
void CompatComponent::DumpServiceObject(ofstream& fp, const Service::Ptr& service)
|
void CompatComponent::DumpServiceObject(ofstream& fp, const Service::Ptr& service)
|
||||||
{
|
{
|
||||||
|
ObjectLock olock(service);
|
||||||
|
|
||||||
fp << "define service {" << "\n"
|
fp << "define service {" << "\n"
|
||||||
<< "\t" << "host_name" << "\t" << service->GetHost()->GetName() << "\n"
|
<< "\t" << "host_name" << "\t" << service->GetHost()->GetName() << "\n"
|
||||||
<< "\t" << "service_description" << "\t" << service->GetShortName() << "\n"
|
<< "\t" << "service_description" << "\t" << service->GetShortName() << "\n"
|
||||||
@ -399,6 +409,8 @@ void CompatComponent::DumpServiceObject(ofstream& fp, const Service::Ptr& servic
|
|||||||
<< "\n";
|
<< "\n";
|
||||||
|
|
||||||
BOOST_FOREACH(const Service::Ptr& parent, service->GetParentServices()) {
|
BOOST_FOREACH(const Service::Ptr& parent, service->GetParentServices()) {
|
||||||
|
ObjectLock plock(parent);
|
||||||
|
|
||||||
fp << "define servicedependency {" << "\n"
|
fp << "define servicedependency {" << "\n"
|
||||||
<< "\t" << "dependent_host_name" << "\t" << service->GetHost()->GetName() << "\n"
|
<< "\t" << "dependent_host_name" << "\t" << service->GetHost()->GetName() << "\n"
|
||||||
<< "\t" << "dependent_service_description" << "\t" << service->GetShortName() << "\n"
|
<< "\t" << "dependent_service_description" << "\t" << service->GetShortName() << "\n"
|
||||||
@ -416,8 +428,6 @@ void CompatComponent::DumpServiceObject(ofstream& fp, const Service::Ptr& servic
|
|||||||
*/
|
*/
|
||||||
void CompatComponent::StatusTimerHandler(void)
|
void CompatComponent::StatusTimerHandler(void)
|
||||||
{
|
{
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
|
|
||||||
Logger::Write(LogInformation, "compat", "Writing compat status information");
|
Logger::Write(LogInformation, "compat", "Writing compat status information");
|
||||||
|
|
||||||
String statuspath = GetStatusPath();
|
String statuspath = GetStatusPath();
|
||||||
@ -468,55 +478,85 @@ void CompatComponent::StatusTimerHandler(void)
|
|||||||
<< "# This file is auto-generated. Do not modify this file." << "\n"
|
<< "# This file is auto-generated. Do not modify this file." << "\n"
|
||||||
<< "\n";
|
<< "\n";
|
||||||
|
|
||||||
DynamicObject::Ptr object;
|
{
|
||||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Host")->GetObjects()) {
|
DynamicType::Ptr dt = DynamicType::GetByName("Host");
|
||||||
const Host::Ptr& host = static_pointer_cast<Host>(object);
|
ObjectLock dlock(dt);
|
||||||
|
|
||||||
DumpHostStatus(statusfp, host);
|
DynamicObject::Ptr object;
|
||||||
DumpHostObject(objectfp, host);
|
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
|
||||||
}
|
Host::Ptr host = static_pointer_cast<Host>(object);
|
||||||
|
|
||||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("HostGroup")->GetObjects()) {
|
DumpHostStatus(statusfp, host);
|
||||||
const HostGroup::Ptr& hg = static_pointer_cast<HostGroup>(object);
|
DumpHostObject(objectfp, host);
|
||||||
|
|
||||||
objectfp << "define hostgroup {" << "\n"
|
|
||||||
<< "\t" << "hostgroup_name" << "\t" << hg->GetName() << "\n"
|
|
||||||
<< "\t" << "notes_url" << "\t" << hg->GetNotesUrl() << "\n"
|
|
||||||
<< "\t" << "action_url" << "\t" << hg->GetActionUrl() << "\n";
|
|
||||||
|
|
||||||
objectfp << "\t" << "members" << "\t";
|
|
||||||
DumpNameList(objectfp, hg->GetMembers());
|
|
||||||
objectfp << "\n"
|
|
||||||
<< "}" << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
|
|
||||||
const Service::Ptr& service = static_pointer_cast<Service>(object);
|
|
||||||
|
|
||||||
DumpServiceStatus(statusfp, service);
|
|
||||||
DumpServiceObject(objectfp, service);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("ServiceGroup")->GetObjects()) {
|
|
||||||
const ServiceGroup::Ptr& sg = static_pointer_cast<ServiceGroup>(object);
|
|
||||||
|
|
||||||
objectfp << "define servicegroup {" << "\n"
|
|
||||||
<< "\t" << "servicegroup_name" << "\t" << sg->GetName() << "\n"
|
|
||||||
<< "\t" << "notes_url" << "\t" << sg->GetNotesUrl() << "\n"
|
|
||||||
<< "\t" << "action_url" << "\t" << sg->GetActionUrl() << "\n";
|
|
||||||
|
|
||||||
objectfp << "\t" << "members" << "\t";
|
|
||||||
|
|
||||||
vector<String> sglist;
|
|
||||||
BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
|
|
||||||
sglist.push_back(service->GetHost()->GetName());
|
|
||||||
sglist.push_back(service->GetShortName());
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DumpStringList(objectfp, sglist);
|
{
|
||||||
|
DynamicType::Ptr dt = DynamicType::GetByName("Host");
|
||||||
|
ObjectLock dlock(dt);
|
||||||
|
|
||||||
objectfp << "\n"
|
DynamicObject::Ptr object;
|
||||||
<< "}" << "\n";
|
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
|
||||||
|
HostGroup::Ptr hg = static_pointer_cast<HostGroup>(object);
|
||||||
|
ObjectLock olock(hg);
|
||||||
|
|
||||||
|
objectfp << "define hostgroup {" << "\n"
|
||||||
|
<< "\t" << "hostgroup_name" << "\t" << hg->GetName() << "\n"
|
||||||
|
<< "\t" << "notes_url" << "\t" << hg->GetNotesUrl() << "\n"
|
||||||
|
<< "\t" << "action_url" << "\t" << hg->GetActionUrl() << "\n";
|
||||||
|
|
||||||
|
objectfp << "\t" << "members" << "\t";
|
||||||
|
DumpNameList(objectfp, hg->GetMembers());
|
||||||
|
objectfp << "\n"
|
||||||
|
<< "}" << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
DynamicType::Ptr dt = DynamicType::GetByName("Service");
|
||||||
|
ObjectLock dlock(dt);
|
||||||
|
|
||||||
|
DynamicObject::Ptr object;
|
||||||
|
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
|
||||||
|
Service::Ptr service = static_pointer_cast<Service>(object);
|
||||||
|
|
||||||
|
DumpServiceStatus(statusfp, service);
|
||||||
|
DumpServiceObject(objectfp, service);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
DynamicType::Ptr dt = DynamicType::GetByName("ServiceGroup");
|
||||||
|
ObjectLock dlock(dt);
|
||||||
|
|
||||||
|
DynamicObject::Ptr object;
|
||||||
|
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
|
||||||
|
ServiceGroup::Ptr sg = static_pointer_cast<ServiceGroup>(object);
|
||||||
|
ObjectLock olock(sg);
|
||||||
|
|
||||||
|
objectfp << "define servicegroup {" << "\n"
|
||||||
|
<< "\t" << "servicegroup_name" << "\t" << sg->GetName() << "\n"
|
||||||
|
<< "\t" << "notes_url" << "\t" << sg->GetNotesUrl() << "\n"
|
||||||
|
<< "\t" << "action_url" << "\t" << sg->GetActionUrl() << "\n";
|
||||||
|
|
||||||
|
objectfp << "\t" << "members" << "\t";
|
||||||
|
|
||||||
|
vector<String> sglist;
|
||||||
|
BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
|
||||||
|
ObjectLock slock(service);
|
||||||
|
Host::Ptr host = service->GetHost();
|
||||||
|
|
||||||
|
ObjectLock hlock(host);
|
||||||
|
sglist.push_back(host->GetName());
|
||||||
|
|
||||||
|
sglist.push_back(service->GetShortName());
|
||||||
|
}
|
||||||
|
|
||||||
|
DumpStringList(objectfp, sglist);
|
||||||
|
|
||||||
|
objectfp << "\n"
|
||||||
|
<< "}" << "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
statusfp.close();
|
statusfp.close();
|
||||||
|
@ -71,6 +71,7 @@ private:
|
|||||||
else
|
else
|
||||||
first = false;
|
first = false;
|
||||||
|
|
||||||
|
ObjectLock olock(*it);
|
||||||
fp << (*it)->GetName();
|
fp << (*it)->GetName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,13 +48,17 @@ bool DelegationComponent::IsEndpointChecker(const Endpoint::Ptr& endpoint)
|
|||||||
return (endpoint->HasSubscription("checker"));
|
return (endpoint->HasSubscription("checker"));
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Endpoint::Ptr> DelegationComponent::GetCheckerCandidates(const Service::Ptr& service) const
|
set<Endpoint::Ptr> DelegationComponent::GetCheckerCandidates(const Service::Ptr& service) const
|
||||||
{
|
{
|
||||||
vector<Endpoint::Ptr> candidates;
|
set<Endpoint::Ptr> candidates;
|
||||||
|
|
||||||
|
DynamicType::Ptr dt = DynamicType::GetByName("Endpoint");
|
||||||
|
ObjectLock dlock(dt);
|
||||||
|
|
||||||
DynamicObject::Ptr object;
|
DynamicObject::Ptr object;
|
||||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Endpoint")->GetObjects()) {
|
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
|
||||||
Endpoint::Ptr endpoint = dynamic_pointer_cast<Endpoint>(object);
|
Endpoint::Ptr endpoint = dynamic_pointer_cast<Endpoint>(object);
|
||||||
|
ObjectLock olock(endpoint);
|
||||||
|
|
||||||
String myIdentity = EndpointManager::GetInstance()->GetIdentity();
|
String myIdentity = EndpointManager::GetInstance()->GetIdentity();
|
||||||
|
|
||||||
@ -74,7 +78,7 @@ vector<Endpoint::Ptr> DelegationComponent::GetCheckerCandidates(const Service::P
|
|||||||
if (!service->IsAllowedChecker(endpoint->GetName()))
|
if (!service->IsAllowedChecker(endpoint->GetName()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
candidates.push_back(endpoint);
|
candidates.insert(endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
return candidates;
|
return candidates;
|
||||||
@ -82,59 +86,71 @@ vector<Endpoint::Ptr> DelegationComponent::GetCheckerCandidates(const Service::P
|
|||||||
|
|
||||||
void DelegationComponent::DelegationTimerHandler(void)
|
void DelegationComponent::DelegationTimerHandler(void)
|
||||||
{
|
{
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
|
|
||||||
map<Endpoint::Ptr, int> histogram;
|
map<Endpoint::Ptr, int> histogram;
|
||||||
|
|
||||||
DynamicObject::Ptr object;
|
{
|
||||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Endpoint")->GetObjects()) {
|
DynamicType::Ptr dt = DynamicType::GetByName("Endpoint");
|
||||||
Endpoint::Ptr endpoint = dynamic_pointer_cast<Endpoint>(object);
|
ObjectLock dlock(dt);
|
||||||
|
|
||||||
histogram[endpoint] = 0;
|
DynamicObject::Ptr object;
|
||||||
|
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
|
||||||
|
Endpoint::Ptr endpoint = dynamic_pointer_cast<Endpoint>(object);
|
||||||
|
|
||||||
|
histogram[endpoint] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Service::Ptr> services;
|
vector<Service::Ptr> services;
|
||||||
|
|
||||||
/* build "checker -> service count" histogram */
|
{
|
||||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
|
/* build "checker -> service count" histogram */
|
||||||
Service::Ptr service = dynamic_pointer_cast<Service>(object);
|
DynamicType::Ptr dt = DynamicType::GetByName("Service");
|
||||||
|
ObjectLock dlock(dt);
|
||||||
|
|
||||||
if (!service)
|
DynamicObject::Ptr object;
|
||||||
continue;
|
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
|
||||||
|
Service::Ptr service = dynamic_pointer_cast<Service>(object);
|
||||||
|
|
||||||
services.push_back(service);
|
if (!service)
|
||||||
|
continue;
|
||||||
|
|
||||||
String checker = service->GetChecker();
|
services.push_back(service);
|
||||||
if (checker.IsEmpty())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!Endpoint::Exists(checker))
|
ObjectLock olock(service);
|
||||||
continue;
|
String checker = service->GetChecker();
|
||||||
|
if (checker.IsEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
Endpoint::Ptr endpoint = Endpoint::GetByName(checker);
|
if (!Endpoint::Exists(checker))
|
||||||
|
continue;
|
||||||
|
|
||||||
histogram[endpoint]++;
|
Endpoint::Ptr endpoint = Endpoint::GetByName(checker);
|
||||||
|
|
||||||
|
histogram[endpoint]++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::random_shuffle(services.begin(), services.end());
|
//std::random_shuffle(services.begin(), services.end());
|
||||||
|
|
||||||
int delegated = 0;
|
int delegated = 0;
|
||||||
|
|
||||||
/* re-assign services */
|
/* re-assign services */
|
||||||
BOOST_FOREACH(const Service::Ptr& service, services) {
|
BOOST_FOREACH(const Service::Ptr& service, services) {
|
||||||
|
ObjectLock olock(service);
|
||||||
|
|
||||||
String checker = service->GetChecker();
|
String checker = service->GetChecker();
|
||||||
|
|
||||||
Endpoint::Ptr oldEndpoint;
|
Endpoint::Ptr oldEndpoint;
|
||||||
if (Endpoint::Exists(checker))
|
if (Endpoint::Exists(checker))
|
||||||
oldEndpoint = Endpoint::GetByName(checker);
|
oldEndpoint = Endpoint::GetByName(checker);
|
||||||
|
|
||||||
vector<Endpoint::Ptr> candidates = GetCheckerCandidates(service);
|
set<Endpoint::Ptr> candidates = GetCheckerCandidates(service);
|
||||||
|
|
||||||
int avg_services = 0, overflow_tolerance = 0;
|
int avg_services = 0, overflow_tolerance = 0;
|
||||||
vector<Endpoint::Ptr>::iterator cit;
|
vector<Endpoint::Ptr>::iterator cit;
|
||||||
|
|
||||||
if (candidates.size() > 0) {
|
if (candidates.size() > 0) {
|
||||||
std::random_shuffle(candidates.begin(), candidates.end());
|
//std::random_shuffle(candidates.begin(), candidates.end());
|
||||||
|
|
||||||
stringstream msgbuf;
|
stringstream msgbuf;
|
||||||
msgbuf << "Service: " << service->GetName() << ", candidates: " << candidates.size();
|
msgbuf << "Service: " << service->GetName() << ", candidates: " << candidates.size();
|
||||||
@ -150,8 +166,11 @@ void DelegationComponent::DelegationTimerHandler(void)
|
|||||||
|
|
||||||
/* don't re-assign service if the checker is still valid
|
/* don't re-assign service if the checker is still valid
|
||||||
* and doesn't have too many services */
|
* and doesn't have too many services */
|
||||||
|
|
||||||
|
ObjectLock elock(oldEndpoint);
|
||||||
|
|
||||||
if (oldEndpoint && oldEndpoint->IsConnected() &&
|
if (oldEndpoint && oldEndpoint->IsConnected() &&
|
||||||
find(candidates.begin(), candidates.end(), oldEndpoint) != candidates.end() &&
|
candidates.find(oldEndpoint) != candidates.end() &&
|
||||||
histogram[oldEndpoint] <= avg_services + overflow_tolerance)
|
histogram[oldEndpoint] <= avg_services + overflow_tolerance)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -169,6 +188,7 @@ void DelegationComponent::DelegationTimerHandler(void)
|
|||||||
if (histogram[candidate] > avg_services)
|
if (histogram[candidate] > avg_services)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
ObjectLock clock(candidate);
|
||||||
service->SetChecker(candidate->GetName());
|
service->SetChecker(candidate->GetName());
|
||||||
histogram[candidate]++;
|
histogram[candidate]++;
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ private:
|
|||||||
|
|
||||||
void DelegationTimerHandler(void);
|
void DelegationTimerHandler(void);
|
||||||
|
|
||||||
vector<Endpoint::Ptr> GetCheckerCandidates(const Service::Ptr& service) const;
|
set<Endpoint::Ptr> GetCheckerCandidates(const Service::Ptr& service) const;
|
||||||
|
|
||||||
static bool IsEndpointChecker(const Endpoint::Ptr& endpoint);
|
static bool IsEndpointChecker(const Endpoint::Ptr& endpoint);
|
||||||
|
|
||||||
|
@ -54,16 +54,16 @@ void DemoComponent::Stop(void)
|
|||||||
*/
|
*/
|
||||||
void DemoComponent::DemoTimerHandler(void)
|
void DemoComponent::DemoTimerHandler(void)
|
||||||
{
|
{
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
|
|
||||||
Logger::Write(LogInformation, "demo", "Sending multicast 'hello"
|
Logger::Write(LogInformation, "demo", "Sending multicast 'hello"
|
||||||
" world' message.");
|
" world' message.");
|
||||||
|
|
||||||
RequestMessage request;
|
RequestMessage request;
|
||||||
request.SetMethod("demo::HelloWorld");
|
request.SetMethod("demo::HelloWorld");
|
||||||
|
|
||||||
EndpointManager::GetInstance()->SendMulticastMessage(m_Endpoint,
|
EndpointManager::Ptr em = EndpointManager::GetInstance();
|
||||||
request);
|
|
||||||
|
ObjectLock olock(em);
|
||||||
|
em->SendMulticastMessage(m_Endpoint, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -29,6 +29,8 @@ EXPORT_COMPONENT(notification, NotificationComponent);
|
|||||||
void NotificationComponent::Start(void)
|
void NotificationComponent::Start(void)
|
||||||
{
|
{
|
||||||
m_Endpoint = Endpoint::MakeEndpoint("notification", false);
|
m_Endpoint = Endpoint::MakeEndpoint("notification", false);
|
||||||
|
|
||||||
|
ObjectLock olock(m_Endpoint);
|
||||||
m_Endpoint->RegisterTopicHandler("icinga::SendNotifications",
|
m_Endpoint->RegisterTopicHandler("icinga::SendNotifications",
|
||||||
boost::bind(&NotificationComponent::SendNotificationsRequestHandler, this, _2,
|
boost::bind(&NotificationComponent::SendNotificationsRequestHandler, this, _2,
|
||||||
_3));
|
_3));
|
||||||
@ -53,8 +55,6 @@ void NotificationComponent::Stop(void)
|
|||||||
*/
|
*/
|
||||||
void NotificationComponent::NotificationTimerHandler(void)
|
void NotificationComponent::NotificationTimerHandler(void)
|
||||||
{
|
{
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
|
|
||||||
// TODO: implement
|
// TODO: implement
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,5 +78,7 @@ void NotificationComponent::SendNotificationsRequestHandler(const Endpoint::Ptr&
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Service::Ptr service = Service::GetByName(svc);
|
Service::Ptr service = Service::GetByName(svc);
|
||||||
|
|
||||||
|
ObjectLock olock(service);
|
||||||
service->SendNotifications(static_cast<NotificationType>(type));
|
service->SendNotifications(static_cast<NotificationType>(type));
|
||||||
}
|
}
|
||||||
|
@ -88,12 +88,8 @@ static bool LoadConfigFiles(bool validateOnly)
|
|||||||
static void ReloadConfigTimerHandler(void)
|
static void ReloadConfigTimerHandler(void)
|
||||||
{
|
{
|
||||||
if (g_ReloadConfig) {
|
if (g_ReloadConfig) {
|
||||||
{
|
Logger::Write(LogInformation, "icinga-app", "Received SIGHUP. Reloading config files.");
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
LoadConfigFiles(false);
|
||||||
|
|
||||||
Logger::Write(LogInformation, "icinga-app", "Received SIGHUP. Reloading config files.");
|
|
||||||
LoadConfigFiles(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_ReloadConfig = false;
|
g_ReloadConfig = false;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
recursive_mutex Application::m_Mutex;
|
|
||||||
Application *Application::m_Instance = NULL;
|
Application *Application::m_Instance = NULL;
|
||||||
bool Application::m_ShuttingDown = false;
|
bool Application::m_ShuttingDown = false;
|
||||||
bool Application::m_Debugging = false;
|
bool Application::m_Debugging = false;
|
||||||
@ -110,11 +109,6 @@ void Application::SetArgV(char **argv)
|
|||||||
m_ArgV = argv;
|
m_ArgV = argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::NewTxTimerHandler(void)
|
|
||||||
{
|
|
||||||
DynamicObject::NewTx();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
void Application::ProfileTimerHandler(void)
|
void Application::ProfileTimerHandler(void)
|
||||||
{
|
{
|
||||||
@ -142,12 +136,6 @@ void Application::RunEventLoop(void) const
|
|||||||
thread t(&Application::TimeWatchThreadProc);
|
thread t(&Application::TimeWatchThreadProc);
|
||||||
t.detach();
|
t.detach();
|
||||||
|
|
||||||
/* Set up a timer to periodically flush the tx. */
|
|
||||||
Timer::Ptr newTxTimer = boost::make_shared<Timer>();
|
|
||||||
newTxTimer->OnTimerExpired.connect(boost::bind(&Application::NewTxTimerHandler));
|
|
||||||
newTxTimer->SetInterval(0.5);
|
|
||||||
newTxTimer->Start();
|
|
||||||
|
|
||||||
/* Set up a timer that watches the m_Shutdown flag. */
|
/* Set up a timer that watches the m_Shutdown flag. */
|
||||||
Timer::Ptr shutdownTimer = boost::make_shared<Timer>();
|
Timer::Ptr shutdownTimer = boost::make_shared<Timer>();
|
||||||
shutdownTimer->OnTimerExpired.connect(boost::bind(&Application::ShutdownTimerHandler));
|
shutdownTimer->OnTimerExpired.connect(boost::bind(&Application::ShutdownTimerHandler));
|
||||||
@ -162,7 +150,7 @@ void Application::RunEventLoop(void) const
|
|||||||
flushTxTimer->Start();
|
flushTxTimer->Start();
|
||||||
#endif /* _DEBUG */
|
#endif /* _DEBUG */
|
||||||
|
|
||||||
GetEQ().Run();
|
GetEQ().Join();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -569,16 +557,6 @@ void Application::SetPkgDataDir(const String& path)
|
|||||||
m_PkgDataDir = path;
|
m_PkgDataDir = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the global mutex.
|
|
||||||
*
|
|
||||||
* @returns The mutex.
|
|
||||||
*/
|
|
||||||
recursive_mutex& Application::GetMutex(void)
|
|
||||||
{
|
|
||||||
return m_Mutex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the main thread's event queue.
|
* Returns the main thread's event queue.
|
||||||
*
|
*
|
||||||
|
@ -79,15 +79,12 @@ public:
|
|||||||
static String GetPkgDataDir(void);
|
static String GetPkgDataDir(void);
|
||||||
static void SetPkgDataDir(const String& path);
|
static void SetPkgDataDir(const String& path);
|
||||||
|
|
||||||
static recursive_mutex& GetMutex(void);
|
|
||||||
|
|
||||||
static EventQueue& GetEQ(void);
|
static EventQueue& GetEQ(void);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void RunEventLoop(void) const;
|
void RunEventLoop(void) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static recursive_mutex m_Mutex; /**< The global mutex. */
|
|
||||||
static Application *m_Instance; /**< The application instance. */
|
static Application *m_Instance; /**< The application instance. */
|
||||||
|
|
||||||
static bool m_ShuttingDown; /**< Whether the application is in the process of
|
static bool m_ShuttingDown; /**< Whether the application is in the process of
|
||||||
|
@ -66,12 +66,7 @@ public:
|
|||||||
void Start(const CompletionCallback& completionCallback = CompletionCallback())
|
void Start(const CompletionCallback& completionCallback = CompletionCallback())
|
||||||
{
|
{
|
||||||
m_CompletionCallback = completionCallback;
|
m_CompletionCallback = completionCallback;
|
||||||
|
Utility::QueueAsyncCallback(boost::bind(&AsyncTask<TClass, TResult>::Run, this));
|
||||||
try {
|
|
||||||
Run();
|
|
||||||
} catch (...) {
|
|
||||||
FinishException(boost::current_exception());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,4 +48,4 @@ private:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONNECTION_H */
|
#endif /* CONNECTION_H */
|
||||||
|
@ -59,9 +59,12 @@ struct DictionaryKeyLessComparer
|
|||||||
*
|
*
|
||||||
* @param key The key whose value should be retrieved.
|
* @param key The key whose value should be retrieved.
|
||||||
* @returns The value of an empty value if the key was not found.
|
* @returns The value of an empty value if the key was not found.
|
||||||
|
* @threadsafety Always.
|
||||||
*/
|
*/
|
||||||
Value Dictionary::Get(const char *key) const
|
Value Dictionary::Get(const char *key) const
|
||||||
{
|
{
|
||||||
|
ObjectLock olock(this);
|
||||||
|
|
||||||
map<String, Value>::const_iterator it;
|
map<String, Value>::const_iterator it;
|
||||||
|
|
||||||
it = std::lower_bound(m_Data.begin(), m_Data.end(), key, DictionaryKeyLessComparer());
|
it = std::lower_bound(m_Data.begin(), m_Data.end(), key, DictionaryKeyLessComparer());
|
||||||
@ -77,6 +80,7 @@ Value Dictionary::Get(const char *key) const
|
|||||||
*
|
*
|
||||||
* @param key The key whose value should be retrieved.
|
* @param key The key whose value should be retrieved.
|
||||||
* @returns The value or an empty value if the key was not found.
|
* @returns The value or an empty value if the key was not found.
|
||||||
|
* @threadsafety Always.
|
||||||
*/
|
*/
|
||||||
Value Dictionary::Get(const String& key) const
|
Value Dictionary::Get(const String& key) const
|
||||||
{
|
{
|
||||||
@ -88,9 +92,12 @@ Value Dictionary::Get(const String& key) const
|
|||||||
*
|
*
|
||||||
* @param key The key.
|
* @param key The key.
|
||||||
* @param value The value.
|
* @param value The value.
|
||||||
|
* @threadsafety Always.
|
||||||
*/
|
*/
|
||||||
void Dictionary::Set(const String& key, const Value& value)
|
void Dictionary::Set(const String& key, const Value& value)
|
||||||
{
|
{
|
||||||
|
ObjectLock olock(this);
|
||||||
|
|
||||||
if (value.IsEmpty()) {
|
if (value.IsEmpty()) {
|
||||||
Remove(key);
|
Remove(key);
|
||||||
return;
|
return;
|
||||||
@ -107,9 +114,12 @@ void Dictionary::Set(const String& key, const Value& value)
|
|||||||
*
|
*
|
||||||
* @param value The value.
|
* @param value The value.
|
||||||
* @returns The key that was used to add the new item.
|
* @returns The key that was used to add the new item.
|
||||||
|
* @threadsafety Always.
|
||||||
*/
|
*/
|
||||||
String Dictionary::Add(const Value& value)
|
String Dictionary::Add(const Value& value)
|
||||||
{
|
{
|
||||||
|
ObjectLock olock(this);
|
||||||
|
|
||||||
Dictionary::Iterator it;
|
Dictionary::Iterator it;
|
||||||
String key;
|
String key;
|
||||||
long index = GetLength();
|
long index = GetLength();
|
||||||
@ -150,9 +160,12 @@ Dictionary::Iterator Dictionary::End(void)
|
|||||||
* Returns the number of elements in the dictionary.
|
* Returns the number of elements in the dictionary.
|
||||||
*
|
*
|
||||||
* @returns Number of elements.
|
* @returns Number of elements.
|
||||||
|
* @threadsafety Always.
|
||||||
*/
|
*/
|
||||||
size_t Dictionary::GetLength(void) const
|
size_t Dictionary::GetLength(void) const
|
||||||
{
|
{
|
||||||
|
ObjectLock olock(this);
|
||||||
|
|
||||||
return m_Data.size();
|
return m_Data.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,9 +174,12 @@ size_t Dictionary::GetLength(void) const
|
|||||||
*
|
*
|
||||||
* @param key The key.
|
* @param key The key.
|
||||||
* @returns true if the dictionary contains the key, false otherwise.
|
* @returns true if the dictionary contains the key, false otherwise.
|
||||||
|
* @threadsafety Always.
|
||||||
*/
|
*/
|
||||||
bool Dictionary::Contains(const String& key) const
|
bool Dictionary::Contains(const String& key) const
|
||||||
{
|
{
|
||||||
|
ObjectLock olock(this);
|
||||||
|
|
||||||
return (m_Data.find(key) != m_Data.end());
|
return (m_Data.find(key) != m_Data.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,9 +187,12 @@ bool Dictionary::Contains(const String& key) const
|
|||||||
* Removes the specified key from the dictionary.
|
* Removes the specified key from the dictionary.
|
||||||
*
|
*
|
||||||
* @param key The key.
|
* @param key The key.
|
||||||
|
* @threadsafety Always.
|
||||||
*/
|
*/
|
||||||
void Dictionary::Remove(const String& key)
|
void Dictionary::Remove(const String& key)
|
||||||
{
|
{
|
||||||
|
ObjectLock olock(this);
|
||||||
|
|
||||||
Dictionary::Iterator it;
|
Dictionary::Iterator it;
|
||||||
it = m_Data.find(key);
|
it = m_Data.find(key);
|
||||||
|
|
||||||
@ -198,9 +217,12 @@ void Dictionary::Remove(Dictionary::Iterator it)
|
|||||||
* Makes a shallow copy of a dictionary.
|
* Makes a shallow copy of a dictionary.
|
||||||
*
|
*
|
||||||
* @returns a copy of the dictionary.
|
* @returns a copy of the dictionary.
|
||||||
|
* @threadsafety Always.
|
||||||
*/
|
*/
|
||||||
Dictionary::Ptr Dictionary::ShallowClone(void) const
|
Dictionary::Ptr Dictionary::ShallowClone(void) const
|
||||||
{
|
{
|
||||||
|
ObjectLock olock(this);
|
||||||
|
|
||||||
Dictionary::Ptr clone = boost::make_shared<Dictionary>();
|
Dictionary::Ptr clone = boost::make_shared<Dictionary>();
|
||||||
|
|
||||||
String key;
|
String key;
|
||||||
@ -217,6 +239,7 @@ Dictionary::Ptr Dictionary::ShallowClone(void) const
|
|||||||
*
|
*
|
||||||
* @param json The JSON object.
|
* @param json The JSON object.
|
||||||
* @returns A dictionary that is equivalent to the JSON object.
|
* @returns A dictionary that is equivalent to the JSON object.
|
||||||
|
* @threadsafety Always.
|
||||||
*/
|
*/
|
||||||
Dictionary::Ptr Dictionary::FromJson(cJSON *json)
|
Dictionary::Ptr Dictionary::FromJson(cJSON *json)
|
||||||
{
|
{
|
||||||
@ -237,12 +260,15 @@ Dictionary::Ptr Dictionary::FromJson(cJSON *json)
|
|||||||
*
|
*
|
||||||
* @returns A JSON object that is equivalent to the dictionary. Values that
|
* @returns A JSON object that is equivalent to the dictionary. Values that
|
||||||
* cannot be represented in JSON are omitted.
|
* cannot be represented in JSON are omitted.
|
||||||
|
* @threadsafety Always.
|
||||||
*/
|
*/
|
||||||
cJSON *Dictionary::ToJson(void) const
|
cJSON *Dictionary::ToJson(void) const
|
||||||
{
|
{
|
||||||
cJSON *json = cJSON_CreateObject();
|
cJSON *json = cJSON_CreateObject();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
ObjectLock olock(this);
|
||||||
|
|
||||||
String key;
|
String key;
|
||||||
Value value;
|
Value value;
|
||||||
BOOST_FOREACH(tie(key, value), m_Data) {
|
BOOST_FOREACH(tie(key, value), m_Data) {
|
||||||
|
@ -23,7 +23,9 @@ using namespace icinga;
|
|||||||
|
|
||||||
double DynamicObject::m_CurrentTx = 0;
|
double DynamicObject::m_CurrentTx = 0;
|
||||||
set<DynamicObject *> DynamicObject::m_ModifiedObjects;
|
set<DynamicObject *> DynamicObject::m_ModifiedObjects;
|
||||||
boost::mutex DynamicObject::m_ModifiedObjectsMutex;
|
boost::mutex DynamicObject::m_TransactionMutex;
|
||||||
|
boost::once_flag DynamicObject::m_TransactionOnce;
|
||||||
|
Timer::Ptr DynamicObject::m_TransactionTimer;
|
||||||
|
|
||||||
signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnRegistered;
|
signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnRegistered;
|
||||||
signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnUnregistered;
|
signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnUnregistered;
|
||||||
@ -46,6 +48,8 @@ DynamicObject::DynamicObject(const Dictionary::Ptr& serializedObject)
|
|||||||
* The DynamicObject::Create function takes care of restoring
|
* The DynamicObject::Create function takes care of restoring
|
||||||
* non-config state after the object has been fully constructed */
|
* non-config state after the object has been fully constructed */
|
||||||
ApplyUpdate(serializedObject, Attribute_Config);
|
ApplyUpdate(serializedObject, Attribute_Config);
|
||||||
|
|
||||||
|
boost::call_once(m_TransactionOnce, &DynamicObject::Initialize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -53,10 +57,22 @@ DynamicObject::DynamicObject(const Dictionary::Ptr& serializedObject)
|
|||||||
*/
|
*/
|
||||||
DynamicObject::~DynamicObject(void)
|
DynamicObject::~DynamicObject(void)
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_ModifiedObjectsMutex);
|
boost::mutex::scoped_lock lock(m_TransactionMutex);
|
||||||
m_ModifiedObjects.erase(this);
|
m_ModifiedObjects.erase(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DynamicObject::Initialize(void)
|
||||||
|
{
|
||||||
|
/* Set up a timer to periodically create a new transaction. */
|
||||||
|
m_TransactionTimer = boost::make_shared<Timer>();
|
||||||
|
m_TransactionTimer->SetInterval(0.5);
|
||||||
|
m_TransactionTimer->OnTimerExpired.connect(boost::bind(&DynamicObject::NewTx));
|
||||||
|
m_TransactionTimer->Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @threadsafety Always.
|
||||||
|
*/
|
||||||
void DynamicObject::SendLocalUpdateEvents(void)
|
void DynamicObject::SendLocalUpdateEvents(void)
|
||||||
{
|
{
|
||||||
map<String, Value, string_iless>::iterator it;
|
map<String, Value, string_iless>::iterator it;
|
||||||
@ -199,7 +215,7 @@ void DynamicObject::InternalSetAttribute(const String& name, const Value& data,
|
|||||||
m_ConfigTx = tx;
|
m_ConfigTx = tx;
|
||||||
|
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_ModifiedObjectsMutex);
|
boost::mutex::scoped_lock lock(m_TransactionMutex);
|
||||||
m_ModifiedObjects.insert(this);
|
m_ModifiedObjects.insert(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,8 +296,6 @@ String DynamicObject::GetSource(void) const
|
|||||||
|
|
||||||
void DynamicObject::Register(void)
|
void DynamicObject::Register(void)
|
||||||
{
|
{
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
|
|
||||||
DynamicType::Ptr dtype = GetType();
|
DynamicType::Ptr dtype = GetType();
|
||||||
|
|
||||||
DynamicObject::Ptr dobj = dtype->GetObject(GetName());
|
DynamicObject::Ptr dobj = dtype->GetObject(GetName());
|
||||||
@ -302,9 +316,8 @@ void DynamicObject::Start(void)
|
|||||||
|
|
||||||
void DynamicObject::Unregister(void)
|
void DynamicObject::Unregister(void)
|
||||||
{
|
{
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
|
|
||||||
DynamicType::Ptr dtype = GetType();
|
DynamicType::Ptr dtype = GetType();
|
||||||
|
ObjectLock olock(dtype);
|
||||||
|
|
||||||
if (!dtype || !dtype->GetObject(GetName()))
|
if (!dtype || !dtype->GetObject(GetName()))
|
||||||
return;
|
return;
|
||||||
@ -322,11 +335,16 @@ ScriptTask::Ptr DynamicObject::InvokeMethod(const String& method,
|
|||||||
if (!value.IsObjectType<Dictionary>())
|
if (!value.IsObjectType<Dictionary>())
|
||||||
return ScriptTask::Ptr();
|
return ScriptTask::Ptr();
|
||||||
|
|
||||||
|
String funcName;
|
||||||
Dictionary::Ptr methods = value;
|
Dictionary::Ptr methods = value;
|
||||||
if (!methods->Contains(method))
|
|
||||||
return ScriptTask::Ptr();
|
|
||||||
|
|
||||||
String funcName = methods->Get(method);
|
{
|
||||||
|
ObjectLock olock(methods);
|
||||||
|
if (!methods->Contains(method))
|
||||||
|
return ScriptTask::Ptr();
|
||||||
|
|
||||||
|
funcName = methods->Get(method);
|
||||||
|
}
|
||||||
|
|
||||||
ScriptFunction::Ptr func = ScriptFunction::GetByName(funcName);
|
ScriptFunction::Ptr func = ScriptFunction::GetByName(funcName);
|
||||||
|
|
||||||
@ -344,8 +362,6 @@ ScriptTask::Ptr DynamicObject::InvokeMethod(const String& method,
|
|||||||
*/
|
*/
|
||||||
void DynamicObject::DumpObjects(const String& filename)
|
void DynamicObject::DumpObjects(const String& filename)
|
||||||
{
|
{
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
|
|
||||||
Logger::Write(LogInformation, "base", "Dumping program state to file '" + filename + "'");
|
Logger::Write(LogInformation, "base", "Dumping program state to file '" + filename + "'");
|
||||||
|
|
||||||
String tempFilename = filename + ".tmp";
|
String tempFilename = filename + ".tmp";
|
||||||
@ -409,8 +425,6 @@ void DynamicObject::DumpObjects(const String& filename)
|
|||||||
*/
|
*/
|
||||||
void DynamicObject::RestoreObjects(const String& filename)
|
void DynamicObject::RestoreObjects(const String& filename)
|
||||||
{
|
{
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
|
|
||||||
Logger::Write(LogInformation, "base", "Restoring program state from file '" + filename + "'");
|
Logger::Write(LogInformation, "base", "Restoring program state from file '" + filename + "'");
|
||||||
|
|
||||||
std::fstream fp;
|
std::fstream fp;
|
||||||
@ -432,6 +446,7 @@ void DynamicObject::RestoreObjects(const String& filename)
|
|||||||
bool hasConfig = update->Contains("configTx");
|
bool hasConfig = update->Contains("configTx");
|
||||||
|
|
||||||
DynamicType::Ptr dt = DynamicType::GetByName(type);
|
DynamicType::Ptr dt = DynamicType::GetByName(type);
|
||||||
|
ObjectLock dlock(dt);
|
||||||
|
|
||||||
if (!dt)
|
if (!dt)
|
||||||
BOOST_THROW_EXCEPTION(invalid_argument("Invalid type: " + type));
|
BOOST_THROW_EXCEPTION(invalid_argument("Invalid type: " + type));
|
||||||
@ -455,13 +470,8 @@ void DynamicObject::RestoreObjects(const String& filename)
|
|||||||
Logger::Write(LogDebug, "base", msgbuf.str());
|
Logger::Write(LogDebug, "base", msgbuf.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @threadsafety Always.
|
|
||||||
*/
|
|
||||||
void DynamicObject::DeactivateObjects(void)
|
void DynamicObject::DeactivateObjects(void)
|
||||||
{
|
{
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
|
|
||||||
DynamicType::TypeMap::iterator tt;
|
DynamicType::TypeMap::iterator tt;
|
||||||
for (tt = DynamicType::GetTypes().begin(); tt != DynamicType::GetTypes().end(); tt++) {
|
for (tt = DynamicType::GetTypes().begin(); tt != DynamicType::GetTypes().end(); tt++) {
|
||||||
DynamicType::NameMap::iterator nt;
|
DynamicType::NameMap::iterator nt;
|
||||||
@ -479,7 +489,7 @@ void DynamicObject::DeactivateObjects(void)
|
|||||||
*/
|
*/
|
||||||
double DynamicObject::GetCurrentTx(void)
|
double DynamicObject::GetCurrentTx(void)
|
||||||
{
|
{
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
boost::mutex::scoped_lock lock(m_TransactionMutex);
|
||||||
|
|
||||||
assert(m_CurrentTx != 0);
|
assert(m_CurrentTx != 0);
|
||||||
|
|
||||||
@ -487,29 +497,27 @@ double DynamicObject::GetCurrentTx(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @threadsafety Always.
|
* @threadsafety Always. Caller must not hold any Object locks.
|
||||||
*/
|
*/
|
||||||
void DynamicObject::NewTx(void)
|
void DynamicObject::NewTx(void)
|
||||||
{
|
{
|
||||||
|
double tx;
|
||||||
set<DynamicObject *> objects;
|
set<DynamicObject *> objects;
|
||||||
|
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_ModifiedObjectsMutex);
|
boost::mutex::scoped_lock lock(m_TransactionMutex);
|
||||||
|
|
||||||
/* Some objects may accidentally bleed into the next transaction because
|
tx = m_CurrentTx;
|
||||||
* we're not holding the global mutex while "stealing" the modified objects,
|
|
||||||
* but that's entirely ok. */
|
|
||||||
m_ModifiedObjects.swap(objects);
|
m_ModifiedObjects.swap(objects);
|
||||||
|
m_CurrentTx = Utility::GetTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
|
|
||||||
BOOST_FOREACH(DynamicObject *object, objects) {
|
BOOST_FOREACH(DynamicObject *object, objects) {
|
||||||
|
ObjectLock olock(object);
|
||||||
object->SendLocalUpdateEvents();
|
object->SendLocalUpdateEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
OnTransactionClosing(m_CurrentTx, objects);
|
OnTransactionClosing(tx, objects);
|
||||||
m_CurrentTx = Utility::GetTime();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynamicObject::OnInitCompleted(void)
|
void DynamicObject::OnInitCompleted(void)
|
||||||
@ -523,10 +531,12 @@ void DynamicObject::OnAttributeChanged(const String&, const Value&)
|
|||||||
*/
|
*/
|
||||||
DynamicObject::Ptr DynamicObject::GetObject(const String& type, const String& name)
|
DynamicObject::Ptr DynamicObject::GetObject(const String& type, const String& name)
|
||||||
{
|
{
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
|
|
||||||
DynamicType::Ptr dtype = DynamicType::GetByName(type);
|
DynamicType::Ptr dtype = DynamicType::GetByName(type);
|
||||||
return dtype->GetObject(name);
|
|
||||||
|
{
|
||||||
|
ObjectLock olock(dtype);
|
||||||
|
return dtype->GetObject(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const DynamicObject::AttributeMap& DynamicObject::GetAttributes(void) const
|
const DynamicObject::AttributeMap& DynamicObject::GetAttributes(void) const
|
||||||
|
@ -81,6 +81,8 @@ public:
|
|||||||
DynamicObject(const Dictionary::Ptr& serializedObject);
|
DynamicObject(const Dictionary::Ptr& serializedObject);
|
||||||
~DynamicObject(void);
|
~DynamicObject(void);
|
||||||
|
|
||||||
|
static void Initialize(void);
|
||||||
|
|
||||||
Dictionary::Ptr BuildUpdate(double sinceTx, int attributeTypes) const;
|
Dictionary::Ptr BuildUpdate(double sinceTx, int attributeTypes) const;
|
||||||
void ApplyUpdate(const Dictionary::Ptr& serializedUpdate, int allowedTypes);
|
void ApplyUpdate(const Dictionary::Ptr& serializedUpdate, int allowedTypes);
|
||||||
|
|
||||||
@ -147,7 +149,9 @@ private:
|
|||||||
/* This has to be a set of raw pointers because the DynamicObject
|
/* This has to be a set of raw pointers because the DynamicObject
|
||||||
* constructor has to be able to insert objects into this list. */
|
* constructor has to be able to insert objects into this list. */
|
||||||
static set<DynamicObject *> m_ModifiedObjects;
|
static set<DynamicObject *> m_ModifiedObjects;
|
||||||
static boost::mutex m_ModifiedObjectsMutex;
|
static boost::mutex m_TransactionMutex;
|
||||||
|
static boost::once_flag m_TransactionOnce;
|
||||||
|
static Timer::Ptr m_TransactionTimer;
|
||||||
|
|
||||||
friend class DynamicType; /* for OnInitCompleted. */
|
friend class DynamicType; /* for OnInitCompleted. */
|
||||||
};
|
};
|
||||||
|
@ -21,8 +21,6 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
boost::mutex DynamicType::m_Mutex;
|
|
||||||
|
|
||||||
DynamicType::DynamicType(const String& name, const DynamicType::ObjectFactory& factory)
|
DynamicType::DynamicType(const String& name, const DynamicType::ObjectFactory& factory)
|
||||||
: m_Name(name), m_ObjectFactory(factory)
|
: m_Name(name), m_ObjectFactory(factory)
|
||||||
{ }
|
{ }
|
||||||
@ -32,7 +30,7 @@ DynamicType::DynamicType(const String& name, const DynamicType::ObjectFactory& f
|
|||||||
*/
|
*/
|
||||||
DynamicType::Ptr DynamicType::GetByName(const String& name)
|
DynamicType::Ptr DynamicType::GetByName(const String& name)
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
boost::mutex::scoped_lock lock(GetStaticMutex());
|
||||||
|
|
||||||
DynamicType::TypeMap::const_iterator tt = GetTypes().find(name);
|
DynamicType::TypeMap::const_iterator tt = GetTypes().find(name);
|
||||||
|
|
||||||
@ -43,7 +41,7 @@ DynamicType::Ptr DynamicType::GetByName(const String& name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @threadsafety Caller must hold DynamicType::m_Mutex while using the map.
|
* @threadsafety Caller must hold DynamicType::GetStaticMutex() while using the map.
|
||||||
*/
|
*/
|
||||||
DynamicType::TypeMap& DynamicType::GetTypes(void)
|
DynamicType::TypeMap& DynamicType::GetTypes(void)
|
||||||
{
|
{
|
||||||
@ -52,7 +50,7 @@ DynamicType::TypeMap& DynamicType::GetTypes(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @threadsafety Caller must hold DynamicType::m_Mutex while using the map.
|
* @threadsafety Caller must hold DynamicType::GetStaticMutex() while using the map.
|
||||||
*/
|
*/
|
||||||
DynamicType::NameMap& DynamicType::GetObjects(void)
|
DynamicType::NameMap& DynamicType::GetObjects(void)
|
||||||
{
|
{
|
||||||
@ -89,7 +87,7 @@ DynamicObject::Ptr DynamicType::GetObject(const String& name) const
|
|||||||
*/
|
*/
|
||||||
void DynamicType::RegisterType(const DynamicType::Ptr& type)
|
void DynamicType::RegisterType(const DynamicType::Ptr& type)
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
boost::mutex::scoped_lock lock(GetStaticMutex());
|
||||||
|
|
||||||
DynamicType::TypeMap::const_iterator tt = GetTypes().find(type->GetName());
|
DynamicType::TypeMap::const_iterator tt = GetTypes().find(type->GetName());
|
||||||
|
|
||||||
@ -147,3 +145,9 @@ void DynamicType::AddAttributes(const AttributeDescription *attributes, int attr
|
|||||||
for (int i = 0; i < attributeCount; i++)
|
for (int i = 0; i < attributeCount; i++)
|
||||||
AddAttribute(attributes[i].Name, attributes[i].Type);
|
AddAttribute(attributes[i].Name, attributes[i].Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::mutex& DynamicType::GetStaticMutex(void)
|
||||||
|
{
|
||||||
|
static boost::mutex mutex;
|
||||||
|
return mutex;
|
||||||
|
}
|
||||||
|
@ -64,12 +64,13 @@ public:
|
|||||||
void AddAttributes(const AttributeDescription *attributes, int attributeCount);
|
void AddAttributes(const AttributeDescription *attributes, int attributeCount);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static boost::mutex m_Mutex;
|
|
||||||
String m_Name;
|
String m_Name;
|
||||||
ObjectFactory m_ObjectFactory;
|
ObjectFactory m_ObjectFactory;
|
||||||
map<String, DynamicAttributeType> m_Attributes;
|
map<String, DynamicAttributeType> m_Attributes;
|
||||||
|
|
||||||
NameMap m_Objects;
|
NameMap m_Objects;
|
||||||
|
|
||||||
|
static boost::mutex& GetStaticMutex(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,7 +26,15 @@ using namespace icinga;
|
|||||||
*/
|
*/
|
||||||
EventQueue::EventQueue(void)
|
EventQueue::EventQueue(void)
|
||||||
: m_Stopped(false)
|
: m_Stopped(false)
|
||||||
{ }
|
{
|
||||||
|
int cpus = thread::hardware_concurrency();
|
||||||
|
|
||||||
|
if (cpus < 4)
|
||||||
|
cpus = 4;
|
||||||
|
|
||||||
|
for (int i = 0; i < cpus; i++)
|
||||||
|
m_Threads.create_thread(boost::bind(&EventQueue::QueueThreadProc, this));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @threadsafety Always.
|
* @threadsafety Always.
|
||||||
@ -34,6 +42,7 @@ EventQueue::EventQueue(void)
|
|||||||
EventQueue::~EventQueue(void)
|
EventQueue::~EventQueue(void)
|
||||||
{
|
{
|
||||||
Stop();
|
Stop();
|
||||||
|
Join();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,23 +56,13 @@ void EventQueue::Stop(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spawns worker threads and waits for them to complete.
|
* Waits for all worker threads to finish.
|
||||||
*
|
*
|
||||||
* @threadsafety Always.
|
* @threadsafety Always.
|
||||||
*/
|
*/
|
||||||
void EventQueue::Run(void)
|
void EventQueue::Join(void)
|
||||||
{
|
{
|
||||||
thread_group threads;
|
m_Threads.join_all();
|
||||||
|
|
||||||
int cpus = thread::hardware_concurrency();
|
|
||||||
|
|
||||||
if (cpus == 0)
|
|
||||||
cpus = 4;
|
|
||||||
|
|
||||||
for (int i = 0; i < cpus * 4; i++)
|
|
||||||
threads.create_thread(boost::bind(&EventQueue::QueueThreadProc, this));
|
|
||||||
|
|
||||||
threads.join_all();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,13 +36,13 @@ public:
|
|||||||
EventQueue(void);
|
EventQueue(void);
|
||||||
~EventQueue(void);
|
~EventQueue(void);
|
||||||
|
|
||||||
void Run(void);
|
void Stop(void);
|
||||||
|
void Join(void);
|
||||||
|
|
||||||
void Post(const Callback& callback);
|
void Post(const Callback& callback);
|
||||||
|
|
||||||
void Stop(void);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::thread::id m_Owner;
|
thread_group m_Threads;
|
||||||
|
|
||||||
boost::mutex m_Mutex;
|
boost::mutex m_Mutex;
|
||||||
condition_variable m_CV;
|
condition_variable m_CV;
|
||||||
|
@ -81,10 +81,7 @@ void Logger::Write(LogSeverity severity, const String& facility,
|
|||||||
entry.Facility = facility;
|
entry.Facility = facility;
|
||||||
entry.Message = message;
|
entry.Message = message;
|
||||||
|
|
||||||
{
|
ForwardLogEntry(entry);
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
ForwardLogEntry(entry);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -113,13 +110,21 @@ void Logger::ForwardLogEntry(const LogEntry& entry)
|
|||||||
DynamicType::Ptr dt = DynamicType::GetByName("Logger");
|
DynamicType::Ptr dt = DynamicType::GetByName("Logger");
|
||||||
|
|
||||||
DynamicObject::Ptr object;
|
DynamicObject::Ptr object;
|
||||||
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
|
|
||||||
Logger::Ptr logger = dynamic_pointer_cast<Logger>(object);
|
|
||||||
|
|
||||||
if (entry.Severity >= logger->GetMinSeverity())
|
{
|
||||||
logger->m_Impl->ProcessLogEntry(entry);
|
ObjectLock olock(dt);
|
||||||
|
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
|
||||||
|
Logger::Ptr logger = dynamic_pointer_cast<Logger>(object);
|
||||||
|
|
||||||
processed = true;
|
{
|
||||||
|
ObjectLock llock(logger);
|
||||||
|
|
||||||
|
if (entry.Severity >= logger->GetMinSeverity())
|
||||||
|
logger->m_Impl->ProcessLogEntry(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
processed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogSeverity defaultLogLevel;
|
LogSeverity defaultLogLevel;
|
||||||
|
@ -37,9 +37,11 @@ Object::~Object(void)
|
|||||||
* Returns a reference-counted pointer to this object.
|
* Returns a reference-counted pointer to this object.
|
||||||
*
|
*
|
||||||
* @returns A shared_ptr object that points to this object
|
* @returns A shared_ptr object that points to this object
|
||||||
|
* @threadsafety Always.
|
||||||
*/
|
*/
|
||||||
Object::SharedPtrHolder Object::GetSelf(void)
|
Object::SharedPtrHolder Object::GetSelf(void)
|
||||||
{
|
{
|
||||||
|
ObjectLock olock(this);
|
||||||
return Object::SharedPtrHolder(shared_from_this());
|
return Object::SharedPtrHolder(shared_from_this());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +52,7 @@ Object::SharedPtrHolder Object::GetSelf(void)
|
|||||||
* @returns The object's mutex.
|
* @returns The object's mutex.
|
||||||
* @threadsafety Always.
|
* @threadsafety Always.
|
||||||
*/
|
*/
|
||||||
recursive_mutex& Object::GetMutex(void)
|
recursive_mutex& Object::GetMutex(void) const
|
||||||
{
|
{
|
||||||
return m_Mutex;
|
return m_Mutex;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ public:
|
|||||||
|
|
||||||
SharedPtrHolder GetSelf(void);
|
SharedPtrHolder GetSelf(void);
|
||||||
|
|
||||||
recursive_mutex& GetMutex(void);
|
recursive_mutex& GetMutex(void) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Object(void);
|
Object(void);
|
||||||
@ -103,7 +103,7 @@ private:
|
|||||||
Object(const Object& other);
|
Object(const Object& other);
|
||||||
Object& operator=(const Object& rhs);
|
Object& operator=(const Object& rhs);
|
||||||
|
|
||||||
recursive_mutex m_Mutex;
|
mutable recursive_mutex m_Mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -112,15 +112,35 @@ private:
|
|||||||
struct ObjectLock {
|
struct ObjectLock {
|
||||||
public:
|
public:
|
||||||
ObjectLock(const Object::Ptr& object)
|
ObjectLock(const Object::Ptr& object)
|
||||||
: m_Lock(object->GetMutex())
|
#ifdef _DEBUG
|
||||||
{ }
|
: m_Lock(), m_Object(object)
|
||||||
|
#endif /* _DEBUG */
|
||||||
|
{
|
||||||
|
if (object)
|
||||||
|
m_Lock = recursive_mutex::scoped_lock(object->GetMutex());
|
||||||
|
}
|
||||||
|
|
||||||
ObjectLock(Object *object)
|
ObjectLock(const Object *object)
|
||||||
: m_Lock(object->GetMutex())
|
#ifdef _DEBUG
|
||||||
{ }
|
: m_Lock(), m_Object(object->GetSelf())
|
||||||
|
#endif /* _DEBUG */
|
||||||
|
{
|
||||||
|
if (object)
|
||||||
|
m_Lock = recursive_mutex::scoped_lock(object->GetMutex());
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
~ObjectLock(void)
|
||||||
|
{
|
||||||
|
assert(m_Object.lock());
|
||||||
|
}
|
||||||
|
#endif /* _DEBUG */
|
||||||
|
|
||||||
private:
|
private:
|
||||||
recursive_mutex::scoped_lock m_Lock;
|
recursive_mutex::scoped_lock m_Lock;
|
||||||
|
#ifdef _DEBUG
|
||||||
|
Object::WeakPtr m_Object;
|
||||||
|
#endif /* _DEBUG */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,4 +48,4 @@ private:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* STDIOSTREAM_H */
|
#endif /* STDIOSTREAM_H */
|
||||||
|
@ -82,6 +82,8 @@ void Timer::Call(void)
|
|||||||
Logger::Write(LogWarning, "base", msgbuf.str());
|
Logger::Write(LogWarning, "base", msgbuf.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Re-enable the timer so it can be called again. */
|
||||||
|
m_Started = true;
|
||||||
Reschedule();
|
Reschedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,6 +120,8 @@ void Timer::Start(void)
|
|||||||
{
|
{
|
||||||
boost::call_once(&Timer::Initialize, m_ThreadOnce);
|
boost::call_once(&Timer::Initialize, m_ThreadOnce);
|
||||||
|
|
||||||
|
m_Started = true;
|
||||||
|
|
||||||
Reschedule();
|
Reschedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,6 +133,8 @@ void Timer::Start(void)
|
|||||||
void Timer::Stop(void)
|
void Timer::Stop(void)
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
|
|
||||||
|
m_Started = false;
|
||||||
m_Timers.erase(GetSelf());
|
m_Timers.erase(GetSelf());
|
||||||
|
|
||||||
/* Notify the worker thread that we've disabled a timer. */
|
/* Notify the worker thread that we've disabled a timer. */
|
||||||
@ -158,12 +164,14 @@ void Timer::Reschedule(double next)
|
|||||||
|
|
||||||
m_Next = next;
|
m_Next = next;
|
||||||
|
|
||||||
/* Remove and re-add the timer to update the index. */
|
if (m_Started) {
|
||||||
m_Timers.erase(GetSelf());
|
/* Remove and re-add the timer to update the index. */
|
||||||
m_Timers.insert(GetSelf());
|
m_Timers.erase(GetSelf());
|
||||||
|
m_Timers.insert(GetSelf());
|
||||||
|
|
||||||
/* Notify the worker that we've rescheduled a timer. */
|
/* Notify the worker that we've rescheduled a timer. */
|
||||||
m_CV.notify_all();
|
m_CV.notify_all();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -250,6 +258,7 @@ void Timer::TimerThreadProc(void)
|
|||||||
|
|
||||||
/* Remove the timer from the list so it doesn't get called again
|
/* Remove the timer from the list so it doesn't get called again
|
||||||
* until the current call is completed. */
|
* until the current call is completed. */
|
||||||
|
timer->m_Started = false;
|
||||||
m_Timers.erase(timer);
|
m_Timers.erase(timer);
|
||||||
|
|
||||||
/* Asynchronously call the timer. */
|
/* Asynchronously call the timer. */
|
||||||
|
@ -67,6 +67,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
double m_Interval; /**< The interval of the timer. */
|
double m_Interval; /**< The interval of the timer. */
|
||||||
double m_Next; /**< When the next event should happen. */
|
double m_Next; /**< When the next event should happen. */
|
||||||
|
bool m_Started; /**< Whether the timer is enabled. */
|
||||||
|
|
||||||
typedef multi_index_container<
|
typedef multi_index_container<
|
||||||
Timer::WeakPtr,
|
Timer::WeakPtr,
|
||||||
|
@ -548,3 +548,8 @@ void Utility::SetNonBlockingSocket(SOCKET s)
|
|||||||
ioctlsocket(s, FIONBIO, &lTrue);
|
ioctlsocket(s, FIONBIO, &lTrue);
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Utility::QueueAsyncCallback(const boost::function<void (void)>& callback)
|
||||||
|
{
|
||||||
|
Application::GetEQ().Post(callback);
|
||||||
|
}
|
||||||
|
@ -58,6 +58,8 @@ public:
|
|||||||
|
|
||||||
static bool Glob(const String& pathSpec, const function<void (const String&)>& callback);
|
static bool Glob(const String& pathSpec, const function<void (const String&)>& callback);
|
||||||
|
|
||||||
|
static void QueueAsyncCallback(const boost::function<void (void)>& callback);
|
||||||
|
|
||||||
static
|
static
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
HMODULE
|
HMODULE
|
||||||
|
@ -120,7 +120,17 @@ Dictionary::Ptr ConfigItem::Link(void) const
|
|||||||
void ConfigItem::InternalLink(const Dictionary::Ptr& dictionary) const
|
void ConfigItem::InternalLink(const Dictionary::Ptr& dictionary) const
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(const String& name, m_Parents) {
|
BOOST_FOREACH(const String& name, m_Parents) {
|
||||||
ConfigItem::Ptr parent = ConfigItem::GetObject(GetType(), name);
|
ConfigItem::Ptr parent;
|
||||||
|
|
||||||
|
ConfigCompilerContext *context = ConfigCompilerContext::GetContext();
|
||||||
|
|
||||||
|
if (context)
|
||||||
|
parent = context->GetItem(GetType(), name);
|
||||||
|
|
||||||
|
/* ignore already active objects while we're in the compiler
|
||||||
|
* context and linking to existing items is disabled. */
|
||||||
|
if (!parent && (!context || (context->GetFlags() & CompilerLinkExisting)))
|
||||||
|
parent = ConfigItem::GetObject(GetType(), name);
|
||||||
|
|
||||||
if (!parent) {
|
if (!parent) {
|
||||||
stringstream message;
|
stringstream message;
|
||||||
@ -158,6 +168,7 @@ DynamicObject::Ptr ConfigItem::Commit(void)
|
|||||||
if (it != m_Items.end()) {
|
if (it != m_Items.end()) {
|
||||||
/* Unregister the old item from its parents. */
|
/* Unregister the old item from its parents. */
|
||||||
ConfigItem::Ptr oldItem = it->second;
|
ConfigItem::Ptr oldItem = it->second;
|
||||||
|
ObjectLock olock(oldItem);
|
||||||
oldItem->UnregisterFromParents();
|
oldItem->UnregisterFromParents();
|
||||||
|
|
||||||
/* Steal the old item's children. */
|
/* Steal the old item's children. */
|
||||||
@ -167,6 +178,7 @@ DynamicObject::Ptr ConfigItem::Commit(void)
|
|||||||
/* Register this item with its parents. */
|
/* Register this item with its parents. */
|
||||||
BOOST_FOREACH(const String& parentName, m_Parents) {
|
BOOST_FOREACH(const String& parentName, m_Parents) {
|
||||||
ConfigItem::Ptr parent = GetObject(GetType(), parentName);
|
ConfigItem::Ptr parent = GetObject(GetType(), parentName);
|
||||||
|
ObjectLock olock(parent);
|
||||||
parent->RegisterChild(GetSelf());
|
parent->RegisterChild(GetSelf());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,20 +208,32 @@ DynamicObject::Ptr ConfigItem::Commit(void)
|
|||||||
/* Update or create the object and apply the configuration settings. */
|
/* Update or create the object and apply the configuration settings. */
|
||||||
DynamicObject::Ptr dobj = m_DynamicObject.lock();
|
DynamicObject::Ptr dobj = m_DynamicObject.lock();
|
||||||
|
|
||||||
if (!dobj)
|
if (!dobj) {
|
||||||
|
ObjectLock dlock(dtype);
|
||||||
dobj = dtype->GetObject(GetName());
|
dobj = dtype->GetObject(GetName());
|
||||||
|
}
|
||||||
|
|
||||||
if (!dobj)
|
bool was_null = false;
|
||||||
|
|
||||||
|
if (!dobj) {
|
||||||
|
ObjectLock dlock(dtype);
|
||||||
dobj = dtype->CreateObject(update);
|
dobj = dtype->CreateObject(update);
|
||||||
else
|
was_null = true;
|
||||||
dobj->ApplyUpdate(update, Attribute_Config);
|
}
|
||||||
|
|
||||||
m_DynamicObject = dobj;
|
{
|
||||||
|
ObjectLock olock(dobj);
|
||||||
|
|
||||||
if (dobj->IsAbstract())
|
if (!was_null)
|
||||||
dobj->Unregister();
|
dobj->ApplyUpdate(update, Attribute_Config);
|
||||||
else
|
|
||||||
dobj->Register();
|
m_DynamicObject = dobj;
|
||||||
|
|
||||||
|
if (dobj->IsAbstract())
|
||||||
|
dobj->Unregister();
|
||||||
|
else
|
||||||
|
dobj->Register();
|
||||||
|
}
|
||||||
|
|
||||||
/* We need to make a copy of the child objects because the
|
/* We need to make a copy of the child objects because the
|
||||||
* OnParentCommitted() handler is going to update the list. */
|
* OnParentCommitted() handler is going to update the list. */
|
||||||
@ -222,6 +246,7 @@ DynamicObject::Ptr ConfigItem::Commit(void)
|
|||||||
if (!child)
|
if (!child)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
ObjectLock olock(child);
|
||||||
child->OnParentCommitted();
|
child->OnParentCommitted();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,8 +262,10 @@ void ConfigItem::Unregister(void)
|
|||||||
{
|
{
|
||||||
DynamicObject::Ptr dobj = m_DynamicObject.lock();
|
DynamicObject::Ptr dobj = m_DynamicObject.lock();
|
||||||
|
|
||||||
if (dobj)
|
if (dobj) {
|
||||||
|
ObjectLock olock(dobj);
|
||||||
dobj->Unregister();
|
dobj->Unregister();
|
||||||
|
}
|
||||||
|
|
||||||
ConfigItem::ItemMap::iterator it;
|
ConfigItem::ItemMap::iterator it;
|
||||||
it = m_Items.find(make_pair(GetType(), GetName()));
|
it = m_Items.find(make_pair(GetType(), GetName()));
|
||||||
@ -266,8 +293,10 @@ void ConfigItem::UnregisterFromParents(void)
|
|||||||
BOOST_FOREACH(const String& parentName, m_Parents) {
|
BOOST_FOREACH(const String& parentName, m_Parents) {
|
||||||
ConfigItem::Ptr parent = GetObject(GetType(), parentName);
|
ConfigItem::Ptr parent = GetObject(GetType(), parentName);
|
||||||
|
|
||||||
if (parent)
|
if (parent) {
|
||||||
|
ObjectLock olock(parent);
|
||||||
parent->UnregisterChild(GetSelf());
|
parent->UnregisterChild(GetSelf());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,24 +329,6 @@ DynamicObject::Ptr ConfigItem::GetDynamicObject(void) const
|
|||||||
*/
|
*/
|
||||||
ConfigItem::Ptr ConfigItem::GetObject(const String& type, const String& name)
|
ConfigItem::Ptr ConfigItem::GetObject(const String& type, const String& name)
|
||||||
{
|
{
|
||||||
{
|
|
||||||
recursive_mutex::scoped_lock lockg(Application::GetMutex());
|
|
||||||
|
|
||||||
ConfigCompilerContext *context = ConfigCompilerContext::GetContext();
|
|
||||||
|
|
||||||
if (context) {
|
|
||||||
ConfigItem::Ptr item = context->GetItem(type, name);
|
|
||||||
|
|
||||||
if (item)
|
|
||||||
return item;
|
|
||||||
|
|
||||||
/* ignore already active objects while we're in the compiler
|
|
||||||
* context and linking to existing items is disabled. */
|
|
||||||
if ((context->GetFlags() & CompilerLinkExisting) == 0)
|
|
||||||
return ConfigItem::Ptr();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
|
|
||||||
@ -362,7 +373,7 @@ void ConfigItem::Dump(ostream& fp) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @threadsafety Caller must hold the global mutex.
|
* @threadsafety Always.
|
||||||
*/
|
*/
|
||||||
void ConfigItem::UnloadUnit(const String& unit)
|
void ConfigItem::UnloadUnit(const String& unit)
|
||||||
{
|
{
|
||||||
@ -372,15 +383,22 @@ void ConfigItem::UnloadUnit(const String& unit)
|
|||||||
|
|
||||||
vector<ConfigItem::Ptr> obsoleteItems;
|
vector<ConfigItem::Ptr> obsoleteItems;
|
||||||
|
|
||||||
ConfigItem::Ptr item;
|
{
|
||||||
BOOST_FOREACH(tie(tuples::ignore, item), m_Items) {
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
if (item->GetUnit() != unit)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
obsoleteItems.push_back(item);
|
ConfigItem::Ptr item;
|
||||||
|
BOOST_FOREACH(tie(tuples::ignore, item), m_Items) {
|
||||||
|
ObjectLock olock(item);
|
||||||
|
|
||||||
|
if (item->GetUnit() != unit)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
obsoleteItems.push_back(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_FOREACH(item, obsoleteItems) {
|
BOOST_FOREACH(const ConfigItem::Ptr& item, obsoleteItems) {
|
||||||
|
ObjectLock olock(item);
|
||||||
item->Unregister();
|
item->Unregister();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,17 @@ ConfigItem::Ptr ConfigItemBuilder::Compile(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOST_FOREACH(const String& parent, m_Parents) {
|
BOOST_FOREACH(const String& parent, m_Parents) {
|
||||||
ConfigItem::Ptr item = ConfigItem::GetObject(m_Type, parent);
|
ConfigItem::Ptr item;
|
||||||
|
|
||||||
|
ConfigCompilerContext *context = ConfigCompilerContext::GetContext();
|
||||||
|
|
||||||
|
if (context)
|
||||||
|
item = context->GetItem(m_Type, parent);
|
||||||
|
|
||||||
|
/* ignore already active objects while we're in the compiler
|
||||||
|
* context and linking to existing items is disabled. */
|
||||||
|
if (!item && (!context || (context->GetFlags() & CompilerLinkExisting)))
|
||||||
|
item = ConfigItem::GetObject(m_Type, parent);
|
||||||
|
|
||||||
if (!item) {
|
if (!item) {
|
||||||
stringstream msgbuf;
|
stringstream msgbuf;
|
||||||
|
@ -79,11 +79,7 @@ void ExternalCommandProcessor::Execute(double time, const String& command, const
|
|||||||
callback = it->second;
|
callback = it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
callback(time, arguments);
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
callback(time, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -723,7 +719,8 @@ void ExternalCommandProcessor::ScheduleServicegroupHostDowntime(double, const ve
|
|||||||
set<Service::Ptr> services;
|
set<Service::Ptr> services;
|
||||||
|
|
||||||
BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
|
BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
|
||||||
Service::Ptr hcService = service->GetHost()->GetHostCheckService();
|
Host::Ptr host = service->GetHost();
|
||||||
|
Service::Ptr hcService = host->GetHostCheckService();
|
||||||
if (hcService)
|
if (hcService)
|
||||||
services.insert(hcService);
|
services.insert(hcService);
|
||||||
}
|
}
|
||||||
@ -765,9 +762,8 @@ void ExternalCommandProcessor::AddHostComment(double, const vector<String>& argu
|
|||||||
|
|
||||||
Logger::Write(LogInformation, "icinga", "Creating comment for host " + host->GetName());
|
Logger::Write(LogInformation, "icinga", "Creating comment for host " + host->GetName());
|
||||||
Service::Ptr service = host->GetHostCheckService();
|
Service::Ptr service = host->GetHostCheckService();
|
||||||
if (service) {
|
if (service)
|
||||||
(void) service->AddComment(CommentUser, arguments[2], arguments[3], 0);
|
(void) service->AddComment(CommentUser, arguments[2], arguments[3], 0);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExternalCommandProcessor::DelHostComment(double, const vector<String>& arguments)
|
void ExternalCommandProcessor::DelHostComment(double, const vector<String>& arguments)
|
||||||
@ -813,9 +809,8 @@ void ExternalCommandProcessor::DelAllHostComments(double, const vector<String>&
|
|||||||
|
|
||||||
Logger::Write(LogInformation, "icinga", "Removing all comments for host " + host->GetName());
|
Logger::Write(LogInformation, "icinga", "Removing all comments for host " + host->GetName());
|
||||||
Service::Ptr service = host->GetHostCheckService();
|
Service::Ptr service = host->GetHostCheckService();
|
||||||
if (service) {
|
if (service)
|
||||||
service->RemoveAllComments();
|
service->RemoveAllComments();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExternalCommandProcessor::DelAllSvcComments(double, const vector<String>& arguments)
|
void ExternalCommandProcessor::DelAllSvcComments(double, const vector<String>& arguments)
|
||||||
|
@ -352,7 +352,19 @@ void Host::ValidateServiceDictionary(const ScriptTask::Ptr& task, const vector<V
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ConfigItem::GetObject("Service", name)) {
|
ConfigItem::Ptr item;
|
||||||
|
|
||||||
|
ConfigCompilerContext *context = ConfigCompilerContext::GetContext();
|
||||||
|
|
||||||
|
if (context)
|
||||||
|
item = context->GetItem("Service", name);
|
||||||
|
|
||||||
|
/* ignore already active objects while we're in the compiler
|
||||||
|
* context and linking to existing items is disabled. */
|
||||||
|
if (!item && (!context || (context->GetFlags() & CompilerLinkExisting)))
|
||||||
|
item = ConfigItem::GetObject("Service", name);
|
||||||
|
|
||||||
|
if (!item) {
|
||||||
ConfigCompilerContext::GetContext()->AddError(false, "Validation failed for " +
|
ConfigCompilerContext::GetContext()->AddError(false, "Validation failed for " +
|
||||||
location + ": Service '" + name + "' not found.");
|
location + ": Service '" + name + "' not found.");
|
||||||
}
|
}
|
||||||
|
@ -27,13 +27,8 @@ PluginCheckTask::PluginCheckTask(const ScriptTask::Ptr& task, const Process::Ptr
|
|||||||
: m_Task(task), m_Process(process)
|
: m_Task(task), m_Process(process)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
/**
|
|
||||||
* @threadsafety Always.
|
|
||||||
*/
|
|
||||||
void PluginCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector<Value>& arguments)
|
void PluginCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector<Value>& arguments)
|
||||||
{
|
{
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
|
|
||||||
if (arguments.size() < 1)
|
if (arguments.size() < 1)
|
||||||
BOOST_THROW_EXCEPTION(invalid_argument("Missing argument: Service must be specified."));
|
BOOST_THROW_EXCEPTION(invalid_argument("Missing argument: Service must be specified."));
|
||||||
|
|
||||||
@ -41,17 +36,34 @@ void PluginCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector<Value
|
|||||||
if (!vservice.IsObjectType<Service>())
|
if (!vservice.IsObjectType<Service>())
|
||||||
BOOST_THROW_EXCEPTION(invalid_argument("Argument must be a service."));
|
BOOST_THROW_EXCEPTION(invalid_argument("Argument must be a service."));
|
||||||
|
|
||||||
Service::Ptr service = vservice;
|
|
||||||
|
|
||||||
vector<Dictionary::Ptr> macroDicts;
|
vector<Dictionary::Ptr> macroDicts;
|
||||||
macroDicts.push_back(service->GetMacros());
|
Value raw_command;
|
||||||
macroDicts.push_back(service->CalculateDynamicMacros());
|
Host::Ptr host;
|
||||||
macroDicts.push_back(service->GetHost()->GetMacros());
|
|
||||||
macroDicts.push_back(service->GetHost()->CalculateDynamicMacros());
|
{
|
||||||
macroDicts.push_back(IcingaApplication::GetInstance()->GetMacros());
|
Service::Ptr service = vservice;
|
||||||
|
ObjectLock olock(service);
|
||||||
|
macroDicts.push_back(service->GetMacros());
|
||||||
|
macroDicts.push_back(service->CalculateDynamicMacros());
|
||||||
|
raw_command = service->GetCheckCommand();
|
||||||
|
host = service->GetHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
ObjectLock olock(host);
|
||||||
|
macroDicts.push_back(host->GetMacros());
|
||||||
|
macroDicts.push_back(host->CalculateDynamicMacros());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
IcingaApplication::Ptr app = IcingaApplication::GetInstance();
|
||||||
|
ObjectLock olock(app);
|
||||||
|
macroDicts.push_back(app->GetMacros());
|
||||||
|
}
|
||||||
|
|
||||||
Dictionary::Ptr macros = MacroProcessor::MergeMacroDicts(macroDicts);
|
Dictionary::Ptr macros = MacroProcessor::MergeMacroDicts(macroDicts);
|
||||||
|
|
||||||
Value command = MacroProcessor::ResolveMacros(service->GetCheckCommand(), macros);
|
Value command = MacroProcessor::ResolveMacros(raw_command, macros);
|
||||||
|
|
||||||
Process::Ptr process = boost::make_shared<Process>(Process::SplitCommand(command), macros);
|
Process::Ptr process = boost::make_shared<Process>(Process::SplitCommand(command), macros);
|
||||||
|
|
||||||
@ -60,13 +72,8 @@ void PluginCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector<Value
|
|||||||
process->Start(boost::bind(&PluginCheckTask::ProcessFinishedHandler, ct));
|
process->Start(boost::bind(&PluginCheckTask::ProcessFinishedHandler, ct));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @threadsafety Always.
|
|
||||||
*/
|
|
||||||
void PluginCheckTask::ProcessFinishedHandler(PluginCheckTask ct)
|
void PluginCheckTask::ProcessFinishedHandler(PluginCheckTask ct)
|
||||||
{
|
{
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
|
|
||||||
ProcessResult pr;
|
ProcessResult pr;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -33,8 +33,6 @@ PluginNotificationTask::PluginNotificationTask(const ScriptTask::Ptr& task, cons
|
|||||||
*/
|
*/
|
||||||
void PluginNotificationTask::ScriptFunc(const ScriptTask::Ptr& task, const vector<Value>& arguments)
|
void PluginNotificationTask::ScriptFunc(const ScriptTask::Ptr& task, const vector<Value>& arguments)
|
||||||
{
|
{
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
|
|
||||||
if (arguments.size() < 1)
|
if (arguments.size() < 1)
|
||||||
BOOST_THROW_EXCEPTION(invalid_argument("Missing argument: Notification target must be specified."));
|
BOOST_THROW_EXCEPTION(invalid_argument("Missing argument: Notification target must be specified."));
|
||||||
|
|
||||||
@ -44,23 +42,49 @@ void PluginNotificationTask::ScriptFunc(const ScriptTask::Ptr& task, const vecto
|
|||||||
if (!arguments[0].IsObjectType<Notification>())
|
if (!arguments[0].IsObjectType<Notification>())
|
||||||
BOOST_THROW_EXCEPTION(invalid_argument("Argument must be a service."));
|
BOOST_THROW_EXCEPTION(invalid_argument("Argument must be a service."));
|
||||||
|
|
||||||
Notification::Ptr notification = arguments[0];
|
|
||||||
NotificationType type = static_cast<NotificationType>(static_cast<int>(arguments[1]));
|
NotificationType type = static_cast<NotificationType>(static_cast<int>(arguments[1]));
|
||||||
|
|
||||||
vector<Dictionary::Ptr> macroDicts;
|
vector<Dictionary::Ptr> macroDicts;
|
||||||
macroDicts.push_back(notification->GetMacros());
|
Value raw_command;
|
||||||
macroDicts.push_back(notification->GetService()->GetMacros());
|
Service::Ptr service;
|
||||||
macroDicts.push_back(notification->GetService()->CalculateDynamicMacros());
|
Host::Ptr host;
|
||||||
macroDicts.push_back(notification->GetService()->GetHost()->GetMacros());
|
String service_name;
|
||||||
macroDicts.push_back(notification->GetService()->GetHost()->CalculateDynamicMacros());
|
|
||||||
macroDicts.push_back(IcingaApplication::GetInstance()->GetMacros());
|
{
|
||||||
|
Notification::Ptr notification = arguments[0];
|
||||||
|
ObjectLock olock(notification);
|
||||||
|
macroDicts.push_back(notification->GetMacros());
|
||||||
|
raw_command = notification->GetNotificationCommand();
|
||||||
|
service = notification->GetService();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
ObjectLock olock(service);
|
||||||
|
macroDicts.push_back(service->GetMacros());
|
||||||
|
macroDicts.push_back(service->CalculateDynamicMacros());
|
||||||
|
service_name = service->GetName();
|
||||||
|
host = service->GetHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
ObjectLock olock(host);
|
||||||
|
macroDicts.push_back(host->GetMacros());
|
||||||
|
macroDicts.push_back(host->CalculateDynamicMacros());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
IcingaApplication::Ptr app = IcingaApplication::GetInstance();
|
||||||
|
ObjectLock olock(app);
|
||||||
|
macroDicts.push_back(app->GetMacros());
|
||||||
|
}
|
||||||
|
|
||||||
Dictionary::Ptr macros = MacroProcessor::MergeMacroDicts(macroDicts);
|
Dictionary::Ptr macros = MacroProcessor::MergeMacroDicts(macroDicts);
|
||||||
|
|
||||||
Value command = MacroProcessor::ResolveMacros(notification->GetNotificationCommand(), macros);
|
Value command = MacroProcessor::ResolveMacros(raw_command, macros);
|
||||||
|
|
||||||
Process::Ptr process = boost::make_shared<Process>(Process::SplitCommand(command), macros);
|
Process::Ptr process = boost::make_shared<Process>(Process::SplitCommand(command), macros);
|
||||||
|
|
||||||
PluginNotificationTask ct(task, process, notification->GetService()->GetName(), command);
|
PluginNotificationTask ct(task, process, service_name, command);
|
||||||
|
|
||||||
process->Start(boost::bind(&PluginNotificationTask::ProcessFinishedHandler, ct));
|
process->Start(boost::bind(&PluginNotificationTask::ProcessFinishedHandler, ct));
|
||||||
}
|
}
|
||||||
@ -70,8 +94,6 @@ void PluginNotificationTask::ScriptFunc(const ScriptTask::Ptr& task, const vecto
|
|||||||
*/
|
*/
|
||||||
void PluginNotificationTask::ProcessFinishedHandler(PluginNotificationTask ct)
|
void PluginNotificationTask::ProcessFinishedHandler(PluginNotificationTask ct)
|
||||||
{
|
{
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
|
|
||||||
ProcessResult pr;
|
ProcessResult pr;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -535,7 +535,9 @@ void Service::ProcessCheckResult(const Dictionary::Ptr& cr)
|
|||||||
|
|
||||||
rm.SetParams(params);
|
rm.SetParams(params);
|
||||||
|
|
||||||
EndpointManager::GetInstance()->SendMulticastMessage(rm);
|
EndpointManager::Ptr em = EndpointManager::GetInstance();
|
||||||
|
ObjectLock olock(em);
|
||||||
|
em->SendMulticastMessage(rm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Service::UpdateStatistics(const Dictionary::Ptr& cr)
|
void Service::UpdateStatistics(const Dictionary::Ptr& cr)
|
||||||
|
@ -210,11 +210,13 @@ void Service::RemoveExpiredComments(void)
|
|||||||
|
|
||||||
void Service::CommentsExpireTimerHandler(void)
|
void Service::CommentsExpireTimerHandler(void)
|
||||||
{
|
{
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
DynamicType::Ptr dt = DynamicType::GetByName("Service");
|
||||||
|
ObjectLock dlock(dt);
|
||||||
|
|
||||||
DynamicObject::Ptr object;
|
DynamicObject::Ptr object;
|
||||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
|
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
|
||||||
Service::Ptr service = dynamic_pointer_cast<Service>(object);
|
Service::Ptr service = dynamic_pointer_cast<Service>(object);
|
||||||
|
ObjectLock olock(service);
|
||||||
service->RemoveExpiredComments();
|
service->RemoveExpiredComments();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -275,11 +275,13 @@ void Service::RemoveExpiredDowntimes(void)
|
|||||||
|
|
||||||
void Service::DowntimesExpireTimerHandler(void)
|
void Service::DowntimesExpireTimerHandler(void)
|
||||||
{
|
{
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
DynamicType::Ptr dt = DynamicType::GetByName("Service");
|
||||||
|
ObjectLock dlock(dt);
|
||||||
|
|
||||||
DynamicObject::Ptr object;
|
DynamicObject::Ptr object;
|
||||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
|
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
|
||||||
Service::Ptr service = dynamic_pointer_cast<Service>(object);
|
Service::Ptr service = dynamic_pointer_cast<Service>(object);
|
||||||
|
ObjectLock slock(service);
|
||||||
service->RemoveExpiredDowntimes();
|
service->RemoveExpiredDowntimes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,9 +94,8 @@ Service::Ptr Service::GetByName(const String& name)
|
|||||||
Service::Ptr Service::GetByNamePair(const String& hostName, const String& serviceName)
|
Service::Ptr Service::GetByNamePair(const String& hostName, const String& serviceName)
|
||||||
{
|
{
|
||||||
if (!hostName.IsEmpty()) {
|
if (!hostName.IsEmpty()) {
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
|
|
||||||
Host::Ptr host = Host::GetByName(hostName);
|
Host::Ptr host = Host::GetByName(hostName);
|
||||||
|
ObjectLock olock(host);
|
||||||
return host->GetServiceByShortName(serviceName);
|
return host->GetServiceByShortName(serviceName);
|
||||||
} else {
|
} else {
|
||||||
return Service::GetByName(serviceName);
|
return Service::GetByName(serviceName);
|
||||||
|
@ -365,11 +365,7 @@ PyObject *PythonLanguage::PyRegisterFunction(PyObject *self, PyObject *args)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
interp->RegisterPythonFunction(name, object);
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
interp->RegisterPythonFunction(name, object);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return Py_None;
|
return Py_None;
|
||||||
|
@ -277,7 +277,7 @@ void Endpoint::ProcessRequest(const Endpoint::Ptr& sender, const RequestMessage&
|
|||||||
if (it == m_TopicHandlers.end())
|
if (it == m_TopicHandlers.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
(*it->second)(GetSelf(), sender, request);
|
Application::GetEQ().Post(boost::bind(boost::ref(*it->second), GetSelf(), sender, request));
|
||||||
} else {
|
} else {
|
||||||
GetClient()->SendMessage(request);
|
GetClient()->SendMessage(request);
|
||||||
}
|
}
|
||||||
@ -360,4 +360,3 @@ String Endpoint::GetService(void) const
|
|||||||
{
|
{
|
||||||
return Get("service");
|
return Get("service");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,8 +325,6 @@ bool EndpointManager::RequestTimeoutLessComparer(const pair<String, PendingReque
|
|||||||
|
|
||||||
void EndpointManager::SubscriptionTimerHandler(void)
|
void EndpointManager::SubscriptionTimerHandler(void)
|
||||||
{
|
{
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
|
|
||||||
Dictionary::Ptr subscriptions = boost::make_shared<Dictionary>();
|
Dictionary::Ptr subscriptions = boost::make_shared<Dictionary>();
|
||||||
|
|
||||||
DynamicObject::Ptr object;
|
DynamicObject::Ptr object;
|
||||||
@ -351,8 +349,6 @@ void EndpointManager::SubscriptionTimerHandler(void)
|
|||||||
|
|
||||||
void EndpointManager::ReconnectTimerHandler(void)
|
void EndpointManager::ReconnectTimerHandler(void)
|
||||||
{
|
{
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
|
|
||||||
DynamicObject::Ptr object;
|
DynamicObject::Ptr object;
|
||||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Endpoint")->GetObjects()) {
|
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Endpoint")->GetObjects()) {
|
||||||
Endpoint::Ptr endpoint = dynamic_pointer_cast<Endpoint>(object);
|
Endpoint::Ptr endpoint = dynamic_pointer_cast<Endpoint>(object);
|
||||||
@ -377,8 +373,6 @@ void EndpointManager::ReconnectTimerHandler(void)
|
|||||||
|
|
||||||
void EndpointManager::RequestTimerHandler(void)
|
void EndpointManager::RequestTimerHandler(void)
|
||||||
{
|
{
|
||||||
recursive_mutex::scoped_lock lock(Application::GetMutex());
|
|
||||||
|
|
||||||
map<String, PendingRequest>::iterator it;
|
map<String, PendingRequest>::iterator it;
|
||||||
for (it = m_Requests.begin(); it != m_Requests.end(); it++) {
|
for (it = m_Requests.begin(); it != m_Requests.end(); it++) {
|
||||||
if (it->second.HasTimedOut()) {
|
if (it->second.HasTimedOut()) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user