mirror of https://github.com/Icinga/icinga2.git
Fine-grained locks (WIP, Part 3).
This commit is contained in:
parent
a4c7052a6e
commit
3dace35cf1
|
@ -91,7 +91,7 @@ String CompatComponent::GetCommandPath(void) const
|
|||
void CompatComponent::Start(void)
|
||||
{
|
||||
m_StatusTimer = boost::make_shared<Timer>();
|
||||
m_StatusTimer->SetInterval(15);
|
||||
m_StatusTimer->SetInterval(5);
|
||||
m_StatusTimer->OnTimerExpired.connect(boost::bind(&CompatComponent::StatusTimerHandler, this));
|
||||
m_StatusTimer->Start();
|
||||
m_StatusTimer->Reschedule(0);
|
||||
|
@ -450,10 +450,18 @@ void CompatComponent::StatusTimerHandler(void)
|
|||
<< "\t" << "}" << "\n"
|
||||
<< "\n";
|
||||
|
||||
double startTime;
|
||||
|
||||
{
|
||||
IcingaApplication::Ptr app = IcingaApplication::GetInstance();
|
||||
ObjectLock olock(app);
|
||||
startTime = app->GetStartTime();
|
||||
}
|
||||
|
||||
statusfp << "programstatus {" << "\n"
|
||||
<< "icinga_pid=" << Utility::GetPid() << "\n"
|
||||
<< "\t" << "daemon_mode=1" << "\n"
|
||||
<< "\t" << "program_start=" << IcingaApplication::GetInstance()->GetStartTime() << "\n"
|
||||
<< "\t" << "program_start=" << startTime << "\n"
|
||||
<< "\t" << "active_service_checks_enabled=1" << "\n"
|
||||
<< "\t" << "passive_service_checks_enabled=1" << "\n"
|
||||
<< "\t" << "active_host_checks_enabled=0" << "\n"
|
||||
|
@ -478,85 +486,61 @@ void CompatComponent::StatusTimerHandler(void)
|
|||
<< "# This file is auto-generated. Do not modify this file." << "\n"
|
||||
<< "\n";
|
||||
|
||||
{
|
||||
DynamicType::Ptr dt = DynamicType::GetByName("Host");
|
||||
ObjectLock dlock(dt);
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Host")) {
|
||||
Host::Ptr host = static_pointer_cast<Host>(object);
|
||||
|
||||
DynamicObject::Ptr object;
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
|
||||
Host::Ptr host = static_pointer_cast<Host>(object);
|
||||
|
||||
DumpHostStatus(statusfp, host);
|
||||
DumpHostObject(objectfp, host);
|
||||
}
|
||||
DumpHostStatus(statusfp, host);
|
||||
DumpHostObject(objectfp, host);
|
||||
}
|
||||
|
||||
{
|
||||
DynamicType::Ptr dt = DynamicType::GetByName("Host");
|
||||
ObjectLock dlock(dt);
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("HostGroup")) {
|
||||
HostGroup::Ptr hg = static_pointer_cast<HostGroup>(object);
|
||||
ObjectLock olock(hg);
|
||||
|
||||
DynamicObject::Ptr object;
|
||||
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 << "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";
|
||||
}
|
||||
objectfp << "\t" << "members" << "\t";
|
||||
DumpNameList(objectfp, hg->GetMembers());
|
||||
objectfp << "\n"
|
||||
<< "}" << "\n";
|
||||
}
|
||||
|
||||
{
|
||||
DynamicType::Ptr dt = DynamicType::GetByName("Service");
|
||||
ObjectLock dlock(dt);
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
|
||||
Service::Ptr service = static_pointer_cast<Service>(object);
|
||||
|
||||
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);
|
||||
}
|
||||
DumpServiceStatus(statusfp, service);
|
||||
DumpServiceObject(objectfp, service);
|
||||
}
|
||||
|
||||
{
|
||||
DynamicType::Ptr dt = DynamicType::GetByName("ServiceGroup");
|
||||
ObjectLock dlock(dt);
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("ServiceGroup")) {
|
||||
ServiceGroup::Ptr sg = static_pointer_cast<ServiceGroup>(object);
|
||||
ObjectLock olock(sg);
|
||||
|
||||
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 << "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";
|
||||
|
||||
objectfp << "\t" << "members" << "\t";
|
||||
vector<String> sglist;
|
||||
BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
|
||||
ObjectLock slock(service);
|
||||
Host::Ptr host = service->GetHost();
|
||||
|
||||
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());
|
||||
|
||||
ObjectLock hlock(host);
|
||||
sglist.push_back(host->GetName());
|
||||
|
||||
sglist.push_back(service->GetShortName());
|
||||
}
|
||||
|
||||
DumpStringList(objectfp, sglist);
|
||||
|
||||
objectfp << "\n"
|
||||
<< "}" << "\n";
|
||||
sglist.push_back(service->GetShortName());
|
||||
}
|
||||
|
||||
DumpStringList(objectfp, sglist);
|
||||
|
||||
objectfp << "\n"
|
||||
<< "}" << "\n";
|
||||
}
|
||||
|
||||
statusfp.close();
|
||||
|
|
|
@ -85,7 +85,7 @@ double CompatIdoComponent::GetReconnectInterval(void) const
|
|||
|
||||
if (interval.IsEmpty())
|
||||
return DefaultReconnectInterval;
|
||||
else
|
||||
else
|
||||
return interval;
|
||||
}
|
||||
|
||||
|
@ -174,7 +174,7 @@ void CompatIdoComponent::OpenIdoSocket(void)
|
|||
#define COMPATIDO_PROTOCOL 2
|
||||
#define COMPATIDO_NAME "ICINGA2 COMPATIDO"
|
||||
#define COMPATIDO_RELEASE_VERSION "2.0"
|
||||
|
||||
|
||||
/* connection is always TCP */
|
||||
/* connecttype is always initial */
|
||||
stringstream msgHello;
|
||||
|
@ -340,7 +340,7 @@ void CompatIdoComponent::DisableServiceObject(const Service::Ptr& service)
|
|||
<< 53 << "=" << service->GetHost()->GetName() << "\n" /* host */
|
||||
<< 114 << "=" << service->GetShortName() << "\n" /* service */
|
||||
<< 999 << "\n\n"; /* enddata */
|
||||
|
||||
|
||||
m_IdoConnection->SendMessage(message.str());
|
||||
}
|
||||
|
||||
|
@ -442,7 +442,7 @@ void CompatIdoComponent::DumpHostStatus(const Host::Ptr& host)
|
|||
state = 2; /* unreachable */
|
||||
else if (!host->IsUp())
|
||||
state = 1; /* down */
|
||||
else
|
||||
else
|
||||
state = 0; /* up */
|
||||
|
||||
stringstream message;
|
||||
|
@ -581,7 +581,7 @@ void CompatIdoComponent::DumpServiceObject(const Service::Ptr& service)
|
|||
* dump service status to ido
|
||||
*
|
||||
* @param service Pointer to Service object
|
||||
*/
|
||||
*/
|
||||
void CompatIdoComponent::DumpServiceStatus(const Service::Ptr& service)
|
||||
{
|
||||
stringstream log;
|
||||
|
@ -673,7 +673,7 @@ void CompatIdoComponent::DumpServiceStatus(const Service::Ptr& service)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* dumps programstatus to ido
|
||||
*/
|
||||
void CompatIdoComponent::DumpProgramStatusData(void)
|
||||
|
@ -738,7 +738,7 @@ void CompatIdoComponent::DumpConfigObjects(void)
|
|||
|
||||
/* hosts and hostgroups */
|
||||
DynamicObject::Ptr object;
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Host")->GetObjects()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Host")) {
|
||||
const Host::Ptr& host = static_pointer_cast<Host>(object);
|
||||
|
||||
DumpHostObject(host);
|
||||
|
@ -746,7 +746,7 @@ void CompatIdoComponent::DumpConfigObjects(void)
|
|||
//DisableHostObject(host);
|
||||
}
|
||||
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("HostGroup")->GetObjects()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("HostGroup")) {
|
||||
const HostGroup::Ptr& hg = static_pointer_cast<HostGroup>(object);
|
||||
|
||||
/* dump the hostgroup and its attributes/members to ido */
|
||||
|
@ -764,14 +764,14 @@ void CompatIdoComponent::DumpConfigObjects(void)
|
|||
}
|
||||
|
||||
SendMessageList(message, hglist, 171); /* hostgroupmember */
|
||||
|
||||
|
||||
message << 999 << "\n\n"; /* enddata */
|
||||
|
||||
m_IdoConnection->SendMessage(message.str());
|
||||
}
|
||||
|
||||
/* services and servicegroups */
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
|
||||
Service::Ptr service = static_pointer_cast<Service>(object);
|
||||
|
||||
DumpServiceObject(service);
|
||||
|
@ -779,7 +779,7 @@ void CompatIdoComponent::DumpConfigObjects(void)
|
|||
//DisableServiceObject(service);
|
||||
}
|
||||
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("ServiceGroup")->GetObjects()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("ServiceGroup")) {
|
||||
const ServiceGroup::Ptr& sg = static_pointer_cast<ServiceGroup>(object);
|
||||
|
||||
/* dump the servicegroup and its attributes/members to ido */
|
||||
|
@ -797,7 +797,7 @@ void CompatIdoComponent::DumpConfigObjects(void)
|
|||
sglist.push_back(service->GetHost()->GetName());
|
||||
sglist.push_back(service->GetShortName());
|
||||
}
|
||||
|
||||
|
||||
SendMessageList(message, sglist, 219); /* servicegroupmember */
|
||||
|
||||
message << 999 << "\n\n"; /* enddata */
|
||||
|
@ -817,13 +817,13 @@ void CompatIdoComponent::DumpConfigObjects(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* process and dump all status data
|
||||
* process and dump all status data
|
||||
*/
|
||||
void CompatIdoComponent::DumpStatusData(void)
|
||||
{
|
||||
/* hosts */
|
||||
DynamicObject::Ptr object;
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Host")->GetObjects()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Host")) {
|
||||
const Host::Ptr& host = static_pointer_cast<Host>(object);
|
||||
|
||||
DumpHostStatus(host);
|
||||
|
@ -831,7 +831,7 @@ void CompatIdoComponent::DumpStatusData(void)
|
|||
|
||||
|
||||
/* services */
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
|
||||
Service::Ptr service = static_pointer_cast<Service>(object);
|
||||
|
||||
DumpServiceStatus(service);
|
||||
|
|
|
@ -52,11 +52,7 @@ set<Endpoint::Ptr> DelegationComponent::GetCheckerCandidates(const Service::Ptr&
|
|||
{
|
||||
set<Endpoint::Ptr> candidates;
|
||||
|
||||
DynamicType::Ptr dt = DynamicType::GetByName("Endpoint");
|
||||
ObjectLock dlock(dt);
|
||||
|
||||
DynamicObject::Ptr object;
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Endpoint")) {
|
||||
Endpoint::Ptr endpoint = dynamic_pointer_cast<Endpoint>(object);
|
||||
ObjectLock olock(endpoint);
|
||||
|
||||
|
@ -88,46 +84,34 @@ void DelegationComponent::DelegationTimerHandler(void)
|
|||
{
|
||||
map<Endpoint::Ptr, int> histogram;
|
||||
|
||||
{
|
||||
DynamicType::Ptr dt = DynamicType::GetByName("Endpoint");
|
||||
ObjectLock dlock(dt);
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Endpoint")) {
|
||||
Endpoint::Ptr endpoint = dynamic_pointer_cast<Endpoint>(object);
|
||||
|
||||
DynamicObject::Ptr object;
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
|
||||
Endpoint::Ptr endpoint = dynamic_pointer_cast<Endpoint>(object);
|
||||
|
||||
histogram[endpoint] = 0;
|
||||
}
|
||||
histogram[endpoint] = 0;
|
||||
}
|
||||
|
||||
vector<Service::Ptr> services;
|
||||
|
||||
{
|
||||
/* build "checker -> service count" histogram */
|
||||
DynamicType::Ptr dt = DynamicType::GetByName("Service");
|
||||
ObjectLock dlock(dt);
|
||||
/* build "checker -> service count" histogram */
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
|
||||
Service::Ptr service = dynamic_pointer_cast<Service>(object);
|
||||
|
||||
DynamicObject::Ptr object;
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
|
||||
Service::Ptr service = dynamic_pointer_cast<Service>(object);
|
||||
if (!service)
|
||||
continue;
|
||||
|
||||
if (!service)
|
||||
continue;
|
||||
services.push_back(service);
|
||||
|
||||
services.push_back(service);
|
||||
ObjectLock olock(service);
|
||||
String checker = service->GetChecker();
|
||||
if (checker.IsEmpty())
|
||||
continue;
|
||||
|
||||
ObjectLock olock(service);
|
||||
String checker = service->GetChecker();
|
||||
if (checker.IsEmpty())
|
||||
continue;
|
||||
if (!Endpoint::Exists(checker))
|
||||
continue;
|
||||
|
||||
if (!Endpoint::Exists(checker))
|
||||
continue;
|
||||
Endpoint::Ptr endpoint = Endpoint::GetByName(checker);
|
||||
|
||||
Endpoint::Ptr endpoint = Endpoint::GetByName(checker);
|
||||
|
||||
histogram[endpoint]++;
|
||||
}
|
||||
histogram[endpoint]++;
|
||||
}
|
||||
|
||||
//std::random_shuffle(services.begin(), services.end());
|
||||
|
|
|
@ -75,23 +75,40 @@ void ReplicationComponent::CheckResultRequestHandler(const RequestMessage& reque
|
|||
|
||||
void ReplicationComponent::EndpointConnectedHandler(const Endpoint::Ptr& endpoint)
|
||||
{
|
||||
/* no need to sync the config with local endpoints */
|
||||
if (endpoint->IsLocalEndpoint())
|
||||
return;
|
||||
{
|
||||
ObjectLock olock(endpoint);
|
||||
|
||||
/* we just assume the other endpoint wants object updates */
|
||||
endpoint->RegisterSubscription("config::ObjectUpdate");
|
||||
endpoint->RegisterSubscription("config::ObjectRemoved");
|
||||
/* no need to sync the config with local endpoints */
|
||||
if (endpoint->IsLocalEndpoint())
|
||||
return;
|
||||
|
||||
/* we just assume the other endpoint wants object updates */
|
||||
endpoint->RegisterSubscription("config::ObjectUpdate");
|
||||
endpoint->RegisterSubscription("config::ObjectRemoved");
|
||||
}
|
||||
|
||||
DynamicType::Ptr type;
|
||||
BOOST_FOREACH(tie(tuples::ignore, type), DynamicType::GetTypes()) {
|
||||
DynamicObject::Ptr object;
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), type->GetObjects()) {
|
||||
BOOST_FOREACH(const DynamicType::Ptr& dt, DynamicType::GetTypes()) {
|
||||
set<DynamicObject::Ptr> objects;
|
||||
|
||||
{
|
||||
ObjectLock olock(dt);
|
||||
objects = dt->GetObjects();
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, objects) {
|
||||
if (!ShouldReplicateObject(object))
|
||||
continue;
|
||||
|
||||
RequestMessage request = MakeObjectMessage(object, "config::ObjectUpdate", 0, true);
|
||||
EndpointManager::GetInstance()->SendUnicastMessage(m_Endpoint, endpoint, request);
|
||||
|
||||
EndpointManager::Ptr em = EndpointManager::GetInstance();
|
||||
|
||||
{
|
||||
ObjectLock elock(em);
|
||||
em->SendUnicastMessage(m_Endpoint, endpoint, request);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
|
||||
local object Component "checker" {}
|
||||
|
||||
local object Component "delegation" {
|
||||
delegation_interval = 120
|
||||
}
|
||||
local object Component "delegation" {}
|
||||
|
||||
local object Component "notification" {}
|
||||
|
|
|
@ -24,7 +24,6 @@ using namespace icinga;
|
|||
Application *Application::m_Instance = NULL;
|
||||
bool Application::m_ShuttingDown = false;
|
||||
bool Application::m_Debugging = false;
|
||||
boost::thread::id Application::m_MainThreadID;
|
||||
String Application::m_PrefixDir;
|
||||
String Application::m_LocalStateDir;
|
||||
String Application::m_PkgLibDir;
|
||||
|
@ -402,6 +401,7 @@ void Application::InstallExceptionHandlers(void)
|
|||
* Runs the application.
|
||||
*
|
||||
* @returns The application's exit code.
|
||||
* @threadsafety Always.
|
||||
*/
|
||||
int Application::Run(void)
|
||||
{
|
||||
|
|
|
@ -93,7 +93,6 @@ private:
|
|||
static char **m_ArgV; /**< Command-line arguments. */
|
||||
FILE *m_PidFile; /**< The PID file */
|
||||
static bool m_Debugging; /**< Whether debugging is enabled. */
|
||||
static boost::thread::id m_MainThreadID; /**< ID of the main thread. */
|
||||
static String m_PrefixDir; /**< The installation prefix. */
|
||||
static String m_LocalStateDir; /**< The local state dir. */
|
||||
static String m_PkgLibDir; /**< The package lib dir. */
|
||||
|
|
|
@ -32,7 +32,7 @@ signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnUnregistered
|
|||
signals2::signal<void (double, const set<DynamicObject *>&)> DynamicObject::OnTransactionClosing;
|
||||
|
||||
DynamicObject::DynamicObject(const Dictionary::Ptr& serializedObject)
|
||||
: m_ConfigTx(0)
|
||||
: m_Events(false), m_ConfigTx(0)
|
||||
{
|
||||
RegisterAttribute("__name", Attribute_Config);
|
||||
RegisterAttribute("__type", Attribute_Config);
|
||||
|
@ -41,13 +41,20 @@ DynamicObject::DynamicObject(const Dictionary::Ptr& serializedObject)
|
|||
RegisterAttribute("__source", Attribute_Local);
|
||||
RegisterAttribute("methods", Attribute_Config);
|
||||
|
||||
if (!serializedObject->Contains("configTx"))
|
||||
BOOST_THROW_EXCEPTION(invalid_argument("Serialized object must contain a config snapshot."));
|
||||
{
|
||||
ObjectLock olock(serializedObject);
|
||||
|
||||
if (!serializedObject->Contains("configTx"))
|
||||
BOOST_THROW_EXCEPTION(invalid_argument("Serialized object must contain a config snapshot."));
|
||||
}
|
||||
|
||||
/* apply config state from the config item/remote update;
|
||||
* The DynamicObject::Create function takes care of restoring
|
||||
* non-config state after the object has been fully constructed */
|
||||
ApplyUpdate(serializedObject, Attribute_Config);
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
ApplyUpdate(serializedObject, Attribute_Config);
|
||||
}
|
||||
|
||||
boost::call_once(m_TransactionOnce, &DynamicObject::Initialize);
|
||||
}
|
||||
|
@ -75,9 +82,12 @@ void DynamicObject::Initialize(void)
|
|||
*/
|
||||
void DynamicObject::SendLocalUpdateEvents(void)
|
||||
{
|
||||
map<String, Value, string_iless>::iterator it;
|
||||
for (it = m_ModifiedAttributes.begin(); it != m_ModifiedAttributes.end(); it++) {
|
||||
OnAttributeChanged(it->first, it->second);
|
||||
/* Check if it's safe to send events. */
|
||||
if (GetEvents()) {
|
||||
map<String, Value, string_iless>::iterator it;
|
||||
for (it = m_ModifiedAttributes.begin(); it != m_ModifiedAttributes.end(); it++) {
|
||||
OnAttributeChanged(it->first, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
m_ModifiedAttributes.clear();
|
||||
|
@ -124,39 +134,50 @@ Dictionary::Ptr DynamicObject::BuildUpdate(double sinceTx, int attributeTypes) c
|
|||
void DynamicObject::ApplyUpdate(const Dictionary::Ptr& serializedUpdate,
|
||||
int allowedTypes)
|
||||
{
|
||||
double configTx = 0;
|
||||
if ((allowedTypes & Attribute_Config) != 0 &&
|
||||
serializedUpdate->Contains("configTx")) {
|
||||
configTx = serializedUpdate->Get("configTx");
|
||||
Dictionary::Ptr attrs;
|
||||
|
||||
if (configTx > m_ConfigTx)
|
||||
ClearAttributesByType(Attribute_Config);
|
||||
{
|
||||
ObjectLock olock(serializedUpdate);
|
||||
|
||||
double configTx = 0;
|
||||
if ((allowedTypes & Attribute_Config) != 0 &&
|
||||
serializedUpdate->Contains("configTx")) {
|
||||
configTx = serializedUpdate->Get("configTx");
|
||||
|
||||
if (configTx > m_ConfigTx)
|
||||
ClearAttributesByType(Attribute_Config);
|
||||
}
|
||||
|
||||
attrs = serializedUpdate->Get("attrs");
|
||||
}
|
||||
|
||||
Dictionary::Ptr attrs = serializedUpdate->Get("attrs");
|
||||
{
|
||||
ObjectLock olock(attrs);
|
||||
|
||||
Dictionary::Iterator it;
|
||||
for (it = attrs->Begin(); it != attrs->End(); it++) {
|
||||
if (!it->second.IsObjectType<Dictionary>())
|
||||
continue;
|
||||
Dictionary::Iterator it;
|
||||
for (it = attrs->Begin(); it != attrs->End(); it++) {
|
||||
if (!it->second.IsObjectType<Dictionary>())
|
||||
continue;
|
||||
|
||||
Dictionary::Ptr attr = it->second;
|
||||
Dictionary::Ptr attr = it->second;
|
||||
ObjectLock alock(attr);
|
||||
|
||||
int type = attr->Get("type");
|
||||
int type = attr->Get("type");
|
||||
|
||||
if ((type & ~allowedTypes) != 0)
|
||||
continue;
|
||||
if ((type & ~allowedTypes) != 0)
|
||||
continue;
|
||||
|
||||
Value data = attr->Get("data");
|
||||
double tx = attr->Get("tx");
|
||||
Value data = attr->Get("data");
|
||||
double tx = attr->Get("tx");
|
||||
|
||||
if (type & Attribute_Config)
|
||||
RegisterAttribute(it->first, Attribute_Config);
|
||||
if (type & Attribute_Config)
|
||||
RegisterAttribute(it->first, Attribute_Config);
|
||||
|
||||
if (!HasAttribute(it->first))
|
||||
RegisterAttribute(it->first, static_cast<DynamicAttributeType>(type));
|
||||
if (!HasAttribute(it->first))
|
||||
RegisterAttribute(it->first, static_cast<DynamicAttributeType>(type));
|
||||
|
||||
InternalSetAttribute(it->first, data, tx, true);
|
||||
InternalSetAttribute(it->first, data, tx, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -296,13 +317,18 @@ String DynamicObject::GetSource(void) const
|
|||
|
||||
void DynamicObject::Register(void)
|
||||
{
|
||||
DynamicType::Ptr dtype = GetType();
|
||||
{
|
||||
DynamicType::Ptr dtype = GetType();
|
||||
ObjectLock olock(dtype);
|
||||
|
||||
DynamicObject::Ptr dobj = dtype->GetObject(GetName());
|
||||
DynamicObject::Ptr self = GetSelf();
|
||||
assert(!dobj || dobj == self);
|
||||
DynamicObject::Ptr dobj = dtype->GetObject(GetName());
|
||||
|
||||
dtype->RegisterObject(self);
|
||||
DynamicObject::Ptr self = GetSelf();
|
||||
assert(!dobj || dobj == self);
|
||||
|
||||
if (!dobj)
|
||||
dtype->RegisterObject(self);
|
||||
}
|
||||
|
||||
OnRegistered(GetSelf());
|
||||
|
||||
|
@ -375,10 +401,9 @@ void DynamicObject::DumpObjects(const String& filename)
|
|||
StdioStream::Ptr sfp = boost::make_shared<StdioStream>(&fp, false);
|
||||
sfp->Start();
|
||||
|
||||
DynamicType::Ptr type;
|
||||
BOOST_FOREACH(tie(tuples::ignore, type), DynamicType::GetTypes()) {
|
||||
DynamicObject::Ptr object;
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), type->GetObjects()) {
|
||||
;
|
||||
BOOST_FOREACH(const DynamicType::Ptr& type, DynamicType::GetTypes()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, type->GetObjects()) {
|
||||
if (object->IsLocal())
|
||||
continue;
|
||||
|
||||
|
@ -472,13 +497,16 @@ void DynamicObject::RestoreObjects(const String& filename)
|
|||
|
||||
void DynamicObject::DeactivateObjects(void)
|
||||
{
|
||||
DynamicType::TypeMap::iterator tt;
|
||||
for (tt = DynamicType::GetTypes().begin(); tt != DynamicType::GetTypes().end(); tt++) {
|
||||
DynamicType::NameMap::iterator nt;
|
||||
BOOST_FOREACH(const DynamicType::Ptr& dt, DynamicType::GetTypes()) {
|
||||
set<DynamicObject::Ptr> objects;
|
||||
|
||||
while ((nt = tt->second->GetObjects().begin()) != tt->second->GetObjects().end()) {
|
||||
DynamicObject::Ptr object = nt->second;
|
||||
{
|
||||
ObjectLock olock(dt);
|
||||
objects = dt->GetObjects();
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, objects) {
|
||||
ObjectLock olock(object);
|
||||
object->Unregister();
|
||||
}
|
||||
}
|
||||
|
@ -543,3 +571,13 @@ const DynamicObject::AttributeMap& DynamicObject::GetAttributes(void) const
|
|||
{
|
||||
return m_Attributes;
|
||||
}
|
||||
|
||||
void DynamicObject::SetEvents(bool events)
|
||||
{
|
||||
m_Events = events;
|
||||
}
|
||||
|
||||
bool DynamicObject::GetEvents(void) const
|
||||
{
|
||||
return m_Events;
|
||||
}
|
||||
|
|
|
@ -122,6 +122,9 @@ public:
|
|||
|
||||
const AttributeMap& GetAttributes(void) const;
|
||||
|
||||
void SetEvents(bool events);
|
||||
bool GetEvents(void) const;
|
||||
|
||||
static DynamicObject::Ptr GetObject(const String& type, const String& name);
|
||||
|
||||
static void DumpObjects(const String& filename);
|
||||
|
@ -144,6 +147,8 @@ private:
|
|||
map<String, Value, string_iless> m_ModifiedAttributes;
|
||||
double m_ConfigTx;
|
||||
|
||||
bool m_Events;
|
||||
|
||||
static double m_CurrentTx;
|
||||
|
||||
/* This has to be a set of raw pointers because the DynamicObject
|
||||
|
|
|
@ -32,9 +32,9 @@ DynamicType::Ptr DynamicType::GetByName(const String& name)
|
|||
{
|
||||
boost::mutex::scoped_lock lock(GetStaticMutex());
|
||||
|
||||
DynamicType::TypeMap::const_iterator tt = GetTypes().find(name);
|
||||
DynamicType::TypeMap::const_iterator tt = InternalGetTypeMap().find(name);
|
||||
|
||||
if (tt == GetTypes().end())
|
||||
if (tt == InternalGetTypeMap().end())
|
||||
return DynamicType::Ptr();
|
||||
|
||||
return tt->second;
|
||||
|
@ -43,18 +43,34 @@ DynamicType::Ptr DynamicType::GetByName(const String& name)
|
|||
/**
|
||||
* @threadsafety Caller must hold DynamicType::GetStaticMutex() while using the map.
|
||||
*/
|
||||
DynamicType::TypeMap& DynamicType::GetTypes(void)
|
||||
DynamicType::TypeMap& DynamicType::InternalGetTypeMap(void)
|
||||
{
|
||||
static DynamicType::TypeMap types;
|
||||
return types;
|
||||
static DynamicType::TypeMap typemap;
|
||||
return typemap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @threadsafety Caller must hold DynamicType::GetStaticMutex() while using the map.
|
||||
*/
|
||||
DynamicType::NameMap& DynamicType::GetObjects(void)
|
||||
DynamicType::TypeSet& DynamicType::InternalGetTypeSet(void)
|
||||
{
|
||||
return m_Objects;
|
||||
static DynamicType::TypeSet typeset;
|
||||
return typeset;
|
||||
}
|
||||
|
||||
DynamicType::TypeSet DynamicType::GetTypes(void)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(GetStaticMutex());
|
||||
return InternalGetTypeSet(); /* Making a copy of the set here. */
|
||||
}
|
||||
|
||||
set<DynamicObject::Ptr> DynamicType::GetObjects(const String& type)
|
||||
{
|
||||
DynamicType::Ptr dt = GetByName(type);
|
||||
ObjectLock olock(dt);
|
||||
return dt->GetObjects();
|
||||
}
|
||||
|
||||
set<DynamicObject::Ptr> DynamicType::GetObjects(void) const
|
||||
{
|
||||
return m_ObjectSet; /* Making a copy of the set here. */
|
||||
}
|
||||
|
||||
String DynamicType::GetName(void) const
|
||||
|
@ -64,19 +80,30 @@ String DynamicType::GetName(void) const
|
|||
|
||||
void DynamicType::RegisterObject(const DynamicObject::Ptr& object)
|
||||
{
|
||||
m_Objects[object->GetName()] = object;
|
||||
ObjectLock olock(object);
|
||||
object->SetEvents(true);
|
||||
|
||||
if (m_ObjectMap.find(object->GetName()) != m_ObjectMap.end())
|
||||
BOOST_THROW_EXCEPTION(runtime_error("RegisterObject() found existing object with the same name: " + object->GetName()));
|
||||
|
||||
m_ObjectMap[object->GetName()] = object;
|
||||
m_ObjectSet.insert(object);
|
||||
}
|
||||
|
||||
void DynamicType::UnregisterObject(const DynamicObject::Ptr& object)
|
||||
{
|
||||
m_Objects.erase(object->GetName());
|
||||
ObjectLock olock(object);
|
||||
object->SetEvents(false);
|
||||
|
||||
m_ObjectMap.erase(object->GetName());
|
||||
m_ObjectSet.erase(object);
|
||||
}
|
||||
|
||||
DynamicObject::Ptr DynamicType::GetObject(const String& name) const
|
||||
{
|
||||
DynamicType::NameMap::const_iterator nt = m_Objects.find(name);
|
||||
DynamicType::ObjectMap::const_iterator nt = m_ObjectMap.find(name);
|
||||
|
||||
if (nt == m_Objects.end())
|
||||
if (nt == m_ObjectMap.end())
|
||||
return DynamicObject::Ptr();
|
||||
|
||||
return nt->second;
|
||||
|
@ -89,18 +116,20 @@ void DynamicType::RegisterType(const DynamicType::Ptr& type)
|
|||
{
|
||||
boost::mutex::scoped_lock lock(GetStaticMutex());
|
||||
|
||||
DynamicType::TypeMap::const_iterator tt = GetTypes().find(type->GetName());
|
||||
DynamicType::TypeMap::const_iterator tt = InternalGetTypeMap().find(type->GetName());
|
||||
|
||||
if (tt != GetTypes().end())
|
||||
if (tt != InternalGetTypeMap().end())
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Cannot register class for type '" +
|
||||
type->GetName() + "': Objects of this type already exist."));
|
||||
|
||||
GetTypes()[type->GetName()] = type;
|
||||
InternalGetTypeMap()[type->GetName()] = type;
|
||||
InternalGetTypeSet().insert(type);
|
||||
}
|
||||
|
||||
DynamicObject::Ptr DynamicType::CreateObject(const Dictionary::Ptr& serializedUpdate) const
|
||||
{
|
||||
DynamicObject::Ptr obj = m_ObjectFactory(serializedUpdate);
|
||||
ObjectLock olock(obj);
|
||||
|
||||
/* register attributes */
|
||||
String name;
|
||||
|
|
|
@ -36,8 +36,6 @@ public:
|
|||
typedef weak_ptr<DynamicType> WeakPtr;
|
||||
|
||||
typedef function<DynamicObject::Ptr (const Dictionary::Ptr&)> ObjectFactory;
|
||||
typedef map<String, DynamicType::Ptr, string_iless> TypeMap;
|
||||
typedef map<String, DynamicObject::Ptr, string_iless> NameMap;
|
||||
|
||||
DynamicType(const String& name, const ObjectFactory& factory);
|
||||
|
||||
|
@ -54,8 +52,10 @@ public:
|
|||
void RegisterObject(const DynamicObject::Ptr& object);
|
||||
void UnregisterObject(const DynamicObject::Ptr& object);
|
||||
|
||||
/* TODO(thread) make private */ static TypeMap& GetTypes(void);
|
||||
/* TODO(thread) make private */ NameMap& GetObjects(void);
|
||||
static set<DynamicType::Ptr> GetTypes(void);
|
||||
set<DynamicObject::Ptr> GetObjects(void) const;
|
||||
|
||||
static set<DynamicObject::Ptr> GetObjects(const String& type);
|
||||
|
||||
void AddAttribute(const String& name, DynamicAttributeType type);
|
||||
void RemoveAttribute(const String& name);
|
||||
|
@ -68,8 +68,17 @@ private:
|
|||
ObjectFactory m_ObjectFactory;
|
||||
map<String, DynamicAttributeType> m_Attributes;
|
||||
|
||||
NameMap m_Objects;
|
||||
typedef map<String, DynamicObject::Ptr, string_iless> ObjectMap;
|
||||
typedef set<DynamicObject::Ptr> ObjectSet;
|
||||
|
||||
ObjectMap m_ObjectMap;
|
||||
ObjectSet m_ObjectSet;
|
||||
|
||||
typedef map<String, DynamicType::Ptr, string_iless> TypeMap;
|
||||
typedef set<DynamicType::Ptr> TypeSet;
|
||||
|
||||
static TypeMap& InternalGetTypeMap(void);
|
||||
static TypeSet& InternalGetTypeSet(void);
|
||||
static boost::mutex& GetStaticMutex(void);
|
||||
};
|
||||
|
||||
|
|
|
@ -107,24 +107,17 @@ void Logger::ForwardLogEntry(const LogEntry& entry)
|
|||
{
|
||||
bool processed = false;
|
||||
|
||||
DynamicType::Ptr dt = DynamicType::GetByName("Logger");
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Logger")) {
|
||||
Logger::Ptr logger = dynamic_pointer_cast<Logger>(object);
|
||||
|
||||
DynamicObject::Ptr object;
|
||||
{
|
||||
ObjectLock llock(logger);
|
||||
|
||||
{
|
||||
ObjectLock olock(dt);
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
|
||||
Logger::Ptr logger = dynamic_pointer_cast<Logger>(object);
|
||||
|
||||
{
|
||||
ObjectLock llock(logger);
|
||||
|
||||
if (entry.Severity >= logger->GetMinSeverity())
|
||||
logger->m_Impl->ProcessLogEntry(entry);
|
||||
}
|
||||
|
||||
processed = true;
|
||||
if (entry.Severity >= logger->GetMinSeverity())
|
||||
logger->m_Impl->ProcessLogEntry(entry);
|
||||
}
|
||||
|
||||
processed = true;
|
||||
}
|
||||
|
||||
LogSeverity defaultLogLevel;
|
||||
|
|
|
@ -112,35 +112,22 @@ private:
|
|||
struct ObjectLock {
|
||||
public:
|
||||
ObjectLock(const Object::Ptr& object)
|
||||
#ifdef _DEBUG
|
||||
: m_Lock(), m_Object(object)
|
||||
#endif /* _DEBUG */
|
||||
: m_Lock()
|
||||
{
|
||||
if (object)
|
||||
m_Lock = recursive_mutex::scoped_lock(object->GetMutex());
|
||||
}
|
||||
|
||||
ObjectLock(const Object *object)
|
||||
#ifdef _DEBUG
|
||||
: m_Lock(), m_Object(object->GetSelf())
|
||||
#endif /* _DEBUG */
|
||||
: m_Lock()
|
||||
{
|
||||
if (object)
|
||||
m_Lock = recursive_mutex::scoped_lock(object->GetMutex());
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
~ObjectLock(void)
|
||||
{
|
||||
assert(m_Object.lock());
|
||||
}
|
||||
#endif /* _DEBUG */
|
||||
|
||||
private:
|
||||
recursive_mutex::scoped_lock m_Lock;
|
||||
#ifdef _DEBUG
|
||||
Object::WeakPtr m_Object;
|
||||
#endif /* _DEBUG */
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* aRingBuffer::SizeType with this program; if not, write to the Free Software Foundation *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
|||
using namespace icinga;
|
||||
|
||||
RingBuffer::RingBuffer(RingBuffer::SizeType slots)
|
||||
: m_Slots(slots, 0), m_Offset(0)
|
||||
: m_Slots(slots, 0), m_TimeValue(0)
|
||||
{ }
|
||||
|
||||
RingBuffer::SizeType RingBuffer::GetLength(void) const
|
||||
|
@ -34,17 +34,23 @@ void RingBuffer::InsertValue(RingBuffer::SizeType tv, int num)
|
|||
{
|
||||
vector<int>::size_type offsetTarget = tv % m_Slots.size();
|
||||
|
||||
/* walk towards the target offset, resetting slots to 0 */
|
||||
while (m_Offset != offsetTarget) {
|
||||
m_Offset++;
|
||||
if (tv > m_TimeValue) {
|
||||
vector<int>::size_type offset = m_TimeValue % m_Slots.size();
|
||||
|
||||
if (m_Offset >= m_Slots.size())
|
||||
m_Offset = 0;
|
||||
/* walk towards the target offset, resetting slots to 0 */
|
||||
while (offset != offsetTarget) {
|
||||
offset++;
|
||||
|
||||
m_Slots[m_Offset] = 0;
|
||||
if (offset >= m_Slots.size())
|
||||
offset = 0;
|
||||
|
||||
m_Slots[offset] = 0;
|
||||
}
|
||||
|
||||
m_TimeValue = tv;
|
||||
}
|
||||
|
||||
m_Slots[m_Offset] += num;
|
||||
m_Slots[offsetTarget] += num;
|
||||
}
|
||||
|
||||
int RingBuffer::GetValues(RingBuffer::SizeType span) const
|
||||
|
@ -52,7 +58,7 @@ int RingBuffer::GetValues(RingBuffer::SizeType span) const
|
|||
if (span > m_Slots.size())
|
||||
span = m_Slots.size();
|
||||
|
||||
int off = m_Offset;
|
||||
int off = m_TimeValue % m_Slots.size();;
|
||||
int sum = 0;
|
||||
while (span > 0) {
|
||||
sum += m_Slots[off];
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
|
||||
private:
|
||||
vector<int> m_Slots;
|
||||
SizeType m_Offset;
|
||||
int m_TimeValue;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -29,5 +29,6 @@ ScriptTask::ScriptTask(const ScriptFunction::Ptr& function,
|
|||
|
||||
void ScriptTask::Run(void)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
m_Function->Invoke(GetSelf(), m_Arguments);
|
||||
}
|
||||
|
|
|
@ -111,14 +111,20 @@ void ConfigCompilerContext::Validate(void)
|
|||
SetContext(this);
|
||||
|
||||
BOOST_FOREACH(const ConfigItem::Ptr& item, m_Items) {
|
||||
ConfigType::Ptr ctype = GetType(item->GetType());
|
||||
ConfigType::Ptr ctype;
|
||||
|
||||
if (!ctype) {
|
||||
AddError(true, "No validation type found for object '" + item->GetName() + "' of type '" + item->GetType() + "'");
|
||||
{
|
||||
ObjectLock olock(item);
|
||||
ctype = GetType(item->GetType());
|
||||
|
||||
continue;
|
||||
if (!ctype) {
|
||||
AddError(true, "No validation type found for object '" + item->GetName() + "' of type '" + item->GetType() + "'");
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
ObjectLock olock(ctype);
|
||||
ctype->ValidateItem(item);
|
||||
}
|
||||
|
||||
|
@ -131,7 +137,7 @@ void ConfigCompilerContext::ActivateItems(void)
|
|||
|
||||
Logger::Write(LogInformation, "config", "Activating config items in compilation unit '" + m_Unit + "'");
|
||||
BOOST_FOREACH(const ConfigItem::Ptr& item, m_Items) {
|
||||
ObjectLock olock(item);
|
||||
item->Commit();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -132,7 +132,11 @@ void ConfigType::ValidateDictionary(const Dictionary::Ptr& dictionary,
|
|||
ScriptTask::Ptr task = boost::make_shared<ScriptTask>(func, arguments);
|
||||
task->Start();
|
||||
task->Wait();
|
||||
task->GetResult();
|
||||
|
||||
{
|
||||
ObjectLock olock(task);
|
||||
task->GetResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -311,8 +311,7 @@ void Host::ValidateServicesCache(void)
|
|||
|
||||
m_ServicesCache.clear();
|
||||
|
||||
DynamicObject::Ptr object;
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
|
||||
const Service::Ptr& service = static_pointer_cast<Service>(object);
|
||||
|
||||
// TODO: assert for duplicate short_names
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
using namespace icinga;
|
||||
|
||||
boost::mutex HostGroup::m_Mutex;
|
||||
map<String, vector<Host::WeakPtr> > HostGroup::m_MembersCache;
|
||||
bool HostGroup::m_MembersCacheValid = true;
|
||||
|
||||
|
@ -77,13 +78,16 @@ set<Host::Ptr> HostGroup::GetMembers(void) const
|
|||
|
||||
ValidateMembersCache();
|
||||
|
||||
BOOST_FOREACH(const Host::WeakPtr& hst, m_MembersCache[GetName()]) {
|
||||
Host::Ptr host = hst.lock();
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
BOOST_FOREACH(const Host::WeakPtr& hst, m_MembersCache[GetName()]) {
|
||||
Host::Ptr host = hst.lock();
|
||||
|
||||
if (!host)
|
||||
continue;
|
||||
if (!host)
|
||||
continue;
|
||||
|
||||
hosts.insert(host);
|
||||
hosts.insert(host);
|
||||
}
|
||||
}
|
||||
|
||||
return hosts;
|
||||
|
@ -91,25 +95,29 @@ set<Host::Ptr> HostGroup::GetMembers(void) const
|
|||
|
||||
void HostGroup::InvalidateMembersCache(void)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
m_MembersCacheValid = false;
|
||||
m_MembersCache.clear();
|
||||
}
|
||||
|
||||
void HostGroup::ValidateMembersCache(void)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
if (m_MembersCacheValid)
|
||||
return;
|
||||
|
||||
m_MembersCache.clear();
|
||||
|
||||
DynamicObject::Ptr object;
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Host")->GetObjects()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Host")) {
|
||||
const Host::Ptr& host = static_pointer_cast<Host>(object);
|
||||
ObjectLock olock(host);
|
||||
|
||||
Dictionary::Ptr dict;
|
||||
dict = host->GetGroups();
|
||||
|
||||
if (dict) {
|
||||
ObjectLock mlock(dict);
|
||||
Value hostgroup;
|
||||
BOOST_FOREACH(tie(tuples::ignore, hostgroup), dict) {
|
||||
if (!HostGroup::Exists(hostgroup))
|
||||
|
|
|
@ -47,6 +47,7 @@ public:
|
|||
static void InvalidateMembersCache(void);
|
||||
|
||||
private:
|
||||
static boost::mutex m_Mutex;
|
||||
static map<String, vector<weak_ptr<Host> > > m_MembersCache;
|
||||
static bool m_MembersCacheValid;
|
||||
|
||||
|
|
|
@ -167,8 +167,7 @@ void Service::ValidateCommentsCache(void)
|
|||
m_CommentsCache.clear();
|
||||
m_LegacyCommentsCache.clear();
|
||||
|
||||
DynamicObject::Ptr object;
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
|
||||
Service::Ptr service = dynamic_pointer_cast<Service>(object);
|
||||
service->AddCommentsToCache();
|
||||
}
|
||||
|
@ -210,11 +209,7 @@ void Service::RemoveExpiredComments(void)
|
|||
|
||||
void Service::CommentsExpireTimerHandler(void)
|
||||
{
|
||||
DynamicType::Ptr dt = DynamicType::GetByName("Service");
|
||||
ObjectLock dlock(dt);
|
||||
|
||||
DynamicObject::Ptr object;
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
|
||||
Service::Ptr service = dynamic_pointer_cast<Service>(object);
|
||||
ObjectLock olock(service);
|
||||
service->RemoveExpiredComments();
|
||||
|
|
|
@ -232,8 +232,7 @@ void Service::ValidateDowntimesCache(void)
|
|||
m_DowntimesCache.clear();
|
||||
m_LegacyDowntimesCache.clear();
|
||||
|
||||
DynamicObject::Ptr object;
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
|
||||
Service::Ptr service = dynamic_pointer_cast<Service>(object);
|
||||
service->AddDowntimesToCache();
|
||||
}
|
||||
|
@ -275,11 +274,7 @@ void Service::RemoveExpiredDowntimes(void)
|
|||
|
||||
void Service::DowntimesExpireTimerHandler(void)
|
||||
{
|
||||
DynamicType::Ptr dt = DynamicType::GetByName("Service");
|
||||
ObjectLock dlock(dt);
|
||||
|
||||
DynamicObject::Ptr object;
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
|
||||
Service::Ptr service = dynamic_pointer_cast<Service>(object);
|
||||
ObjectLock slock(service);
|
||||
service->RemoveExpiredDowntimes();
|
||||
|
|
|
@ -68,8 +68,7 @@ void Service::ValidateNotificationsCache(void)
|
|||
|
||||
m_NotificationsCache.clear();
|
||||
|
||||
DynamicObject::Ptr object;
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Notification")->GetObjects()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Notification")) {
|
||||
const Notification::Ptr& notification = static_pointer_cast<Notification>(object);
|
||||
|
||||
m_NotificationsCache[notification->GetService()->GetName()].insert(notification);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
using namespace icinga;
|
||||
|
||||
boost::mutex ServiceGroup::m_Mutex;
|
||||
map<String, vector<Service::WeakPtr> > ServiceGroup::m_MembersCache;
|
||||
bool ServiceGroup::m_MembersCacheValid;
|
||||
|
||||
|
@ -77,13 +78,16 @@ set<Service::Ptr> ServiceGroup::GetMembers(void) const
|
|||
|
||||
ValidateMembersCache();
|
||||
|
||||
BOOST_FOREACH(const Service::WeakPtr& svc, m_MembersCache[GetName()]) {
|
||||
Service::Ptr service = svc.lock();
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
BOOST_FOREACH(const Service::WeakPtr& svc, m_MembersCache[GetName()]) {
|
||||
Service::Ptr service = svc.lock();
|
||||
|
||||
if (!service)
|
||||
continue;
|
||||
if (!service)
|
||||
continue;
|
||||
|
||||
services.insert(service);
|
||||
services.insert(service);
|
||||
}
|
||||
}
|
||||
|
||||
return services;
|
||||
|
@ -91,25 +95,29 @@ set<Service::Ptr> ServiceGroup::GetMembers(void) const
|
|||
|
||||
void ServiceGroup::InvalidateMembersCache(void)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
m_MembersCacheValid = false;
|
||||
m_MembersCache.clear();
|
||||
}
|
||||
|
||||
void ServiceGroup::ValidateMembersCache(void)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
|
||||
if (m_MembersCacheValid)
|
||||
return;
|
||||
|
||||
m_MembersCache.clear();
|
||||
|
||||
DynamicObject::Ptr object;
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
|
||||
const Service::Ptr& service = static_pointer_cast<Service>(object);
|
||||
ObjectLock olock(service);
|
||||
|
||||
Dictionary::Ptr dict;
|
||||
dict = service->GetGroups();
|
||||
|
||||
if (dict) {
|
||||
ObjectLock mlock(dict);
|
||||
Value servicegroup;
|
||||
BOOST_FOREACH(tie(tuples::ignore, servicegroup), dict) {
|
||||
if (!ServiceGroup::Exists(servicegroup))
|
||||
|
|
|
@ -47,6 +47,7 @@ public:
|
|||
static void InvalidateMembersCache(void);
|
||||
|
||||
private:
|
||||
static boost::mutex m_Mutex;
|
||||
static map<String, vector<weak_ptr<Service> > > m_MembersCache;
|
||||
static bool m_MembersCacheValid;
|
||||
|
||||
|
|
|
@ -232,8 +232,8 @@ void EndpointManager::SendAnycastMessage(const Endpoint::Ptr& sender,
|
|||
BOOST_THROW_EXCEPTION(invalid_argument("Message is missing the 'method' property."));
|
||||
|
||||
vector<Endpoint::Ptr> candidates;
|
||||
DynamicObject::Ptr object;
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Endpoint")->GetObjects()) {
|
||||
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Endpoint")) {
|
||||
Endpoint::Ptr endpoint = dynamic_pointer_cast<Endpoint>(object);
|
||||
/* don't forward messages between non-local endpoints */
|
||||
if ((sender && !sender->IsLocal()) && !endpoint->IsLocal())
|
||||
|
@ -279,8 +279,7 @@ void EndpointManager::SendMulticastMessage(const Endpoint::Ptr& sender,
|
|||
if (!message.GetMethod(&method))
|
||||
BOOST_THROW_EXCEPTION(invalid_argument("Message is missing the 'method' property."));
|
||||
|
||||
DynamicObject::Ptr object;
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Endpoint")->GetObjects()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Endpoint")) {
|
||||
Endpoint::Ptr recipient = dynamic_pointer_cast<Endpoint>(object);
|
||||
|
||||
/* don't forward messages back to the sender */
|
||||
|
@ -327,8 +326,7 @@ void EndpointManager::SubscriptionTimerHandler(void)
|
|||
{
|
||||
Dictionary::Ptr subscriptions = boost::make_shared<Dictionary>();
|
||||
|
||||
DynamicObject::Ptr object;
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Endpoint")->GetObjects()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Endpoint")) {
|
||||
Endpoint::Ptr endpoint = dynamic_pointer_cast<Endpoint>(object);
|
||||
|
||||
/* don't copy subscriptions from non-local endpoints or the identity endpoint */
|
||||
|
@ -349,8 +347,7 @@ void EndpointManager::SubscriptionTimerHandler(void)
|
|||
|
||||
void EndpointManager::ReconnectTimerHandler(void)
|
||||
{
|
||||
DynamicObject::Ptr object;
|
||||
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Endpoint")->GetObjects()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Endpoint")) {
|
||||
Endpoint::Ptr endpoint = dynamic_pointer_cast<Endpoint>(object);
|
||||
|
||||
if (endpoint->IsConnected() || endpoint == m_Endpoint)
|
||||
|
|
Loading…
Reference in New Issue