Fine-grained locks (WIP, Part 3).

This commit is contained in:
Gunnar Beutner 2013-02-18 23:44:24 +01:00
parent a4c7052a6e
commit 3dace35cf1
27 changed files with 344 additions and 281 deletions

View File

@ -91,7 +91,7 @@ String CompatComponent::GetCommandPath(void) const
void CompatComponent::Start(void) void CompatComponent::Start(void)
{ {
m_StatusTimer = boost::make_shared<Timer>(); 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->OnTimerExpired.connect(boost::bind(&CompatComponent::StatusTimerHandler, this));
m_StatusTimer->Start(); m_StatusTimer->Start();
m_StatusTimer->Reschedule(0); m_StatusTimer->Reschedule(0);
@ -450,10 +450,18 @@ void CompatComponent::StatusTimerHandler(void)
<< "\t" << "}" << "\n" << "\t" << "}" << "\n"
<< "\n"; << "\n";
double startTime;
{
IcingaApplication::Ptr app = IcingaApplication::GetInstance();
ObjectLock olock(app);
startTime = app->GetStartTime();
}
statusfp << "programstatus {" << "\n" statusfp << "programstatus {" << "\n"
<< "icinga_pid=" << Utility::GetPid() << "\n" << "icinga_pid=" << Utility::GetPid() << "\n"
<< "\t" << "daemon_mode=1" << "\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" << "active_service_checks_enabled=1" << "\n"
<< "\t" << "passive_service_checks_enabled=1" << "\n" << "\t" << "passive_service_checks_enabled=1" << "\n"
<< "\t" << "active_host_checks_enabled=0" << "\n" << "\t" << "active_host_checks_enabled=0" << "\n"
@ -478,25 +486,14 @@ 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";
{ BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Host")) {
DynamicType::Ptr dt = DynamicType::GetByName("Host");
ObjectLock dlock(dt);
DynamicObject::Ptr object;
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
Host::Ptr host = static_pointer_cast<Host>(object); Host::Ptr host = static_pointer_cast<Host>(object);
DumpHostStatus(statusfp, host); DumpHostStatus(statusfp, host);
DumpHostObject(objectfp, host); DumpHostObject(objectfp, host);
} }
}
{ BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("HostGroup")) {
DynamicType::Ptr dt = DynamicType::GetByName("Host");
ObjectLock dlock(dt);
DynamicObject::Ptr object;
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
HostGroup::Ptr hg = static_pointer_cast<HostGroup>(object); HostGroup::Ptr hg = static_pointer_cast<HostGroup>(object);
ObjectLock olock(hg); ObjectLock olock(hg);
@ -510,27 +507,15 @@ void CompatComponent::StatusTimerHandler(void)
objectfp << "\n" objectfp << "\n"
<< "}" << "\n"; << "}" << "\n";
} }
}
{ BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
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); Service::Ptr service = static_pointer_cast<Service>(object);
DumpServiceStatus(statusfp, service); DumpServiceStatus(statusfp, service);
DumpServiceObject(objectfp, service); DumpServiceObject(objectfp, service);
} }
}
{ BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("ServiceGroup")) {
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); ServiceGroup::Ptr sg = static_pointer_cast<ServiceGroup>(object);
ObjectLock olock(sg); ObjectLock olock(sg);
@ -557,7 +542,6 @@ void CompatComponent::StatusTimerHandler(void)
objectfp << "\n" objectfp << "\n"
<< "}" << "\n"; << "}" << "\n";
} }
}
statusfp.close(); statusfp.close();
objectfp.close(); objectfp.close();

View File

@ -738,7 +738,7 @@ void CompatIdoComponent::DumpConfigObjects(void)
/* hosts and hostgroups */ /* hosts and hostgroups */
DynamicObject::Ptr object; 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); const Host::Ptr& host = static_pointer_cast<Host>(object);
DumpHostObject(host); DumpHostObject(host);
@ -746,7 +746,7 @@ void CompatIdoComponent::DumpConfigObjects(void)
//DisableHostObject(host); //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); const HostGroup::Ptr& hg = static_pointer_cast<HostGroup>(object);
/* dump the hostgroup and its attributes/members to ido */ /* dump the hostgroup and its attributes/members to ido */
@ -771,7 +771,7 @@ void CompatIdoComponent::DumpConfigObjects(void)
} }
/* services and servicegroups */ /* 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); Service::Ptr service = static_pointer_cast<Service>(object);
DumpServiceObject(service); DumpServiceObject(service);
@ -779,7 +779,7 @@ void CompatIdoComponent::DumpConfigObjects(void)
//DisableServiceObject(service); //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); const ServiceGroup::Ptr& sg = static_pointer_cast<ServiceGroup>(object);
/* dump the servicegroup and its attributes/members to ido */ /* dump the servicegroup and its attributes/members to ido */
@ -823,7 +823,7 @@ void CompatIdoComponent::DumpStatusData(void)
{ {
/* hosts */ /* hosts */
DynamicObject::Ptr object; 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); const Host::Ptr& host = static_pointer_cast<Host>(object);
DumpHostStatus(host); DumpHostStatus(host);
@ -831,7 +831,7 @@ void CompatIdoComponent::DumpStatusData(void)
/* services */ /* 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); Service::Ptr service = static_pointer_cast<Service>(object);
DumpServiceStatus(service); DumpServiceStatus(service);

View File

@ -52,11 +52,7 @@ set<Endpoint::Ptr> DelegationComponent::GetCheckerCandidates(const Service::Ptr&
{ {
set<Endpoint::Ptr> candidates; set<Endpoint::Ptr> candidates;
DynamicType::Ptr dt = DynamicType::GetByName("Endpoint"); BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Endpoint")) {
ObjectLock dlock(dt);
DynamicObject::Ptr object;
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); ObjectLock olock(endpoint);
@ -88,27 +84,16 @@ void DelegationComponent::DelegationTimerHandler(void)
{ {
map<Endpoint::Ptr, int> histogram; map<Endpoint::Ptr, int> histogram;
{ BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Endpoint")) {
DynamicType::Ptr dt = DynamicType::GetByName("Endpoint");
ObjectLock dlock(dt);
DynamicObject::Ptr object;
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
Endpoint::Ptr endpoint = dynamic_pointer_cast<Endpoint>(object); Endpoint::Ptr endpoint = dynamic_pointer_cast<Endpoint>(object);
histogram[endpoint] = 0; histogram[endpoint] = 0;
} }
}
vector<Service::Ptr> services; vector<Service::Ptr> services;
{
/* build "checker -> service count" histogram */ /* build "checker -> service count" histogram */
DynamicType::Ptr dt = DynamicType::GetByName("Service"); BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
ObjectLock dlock(dt);
DynamicObject::Ptr object;
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
Service::Ptr service = dynamic_pointer_cast<Service>(object); Service::Ptr service = dynamic_pointer_cast<Service>(object);
if (!service) if (!service)
@ -128,7 +113,6 @@ void DelegationComponent::DelegationTimerHandler(void)
histogram[endpoint]++; histogram[endpoint]++;
} }
}
//std::random_shuffle(services.begin(), services.end()); //std::random_shuffle(services.begin(), services.end());

View File

@ -75,6 +75,9 @@ void ReplicationComponent::CheckResultRequestHandler(const RequestMessage& reque
void ReplicationComponent::EndpointConnectedHandler(const Endpoint::Ptr& endpoint) void ReplicationComponent::EndpointConnectedHandler(const Endpoint::Ptr& endpoint)
{ {
{
ObjectLock olock(endpoint);
/* no need to sync the config with local endpoints */ /* no need to sync the config with local endpoints */
if (endpoint->IsLocalEndpoint()) if (endpoint->IsLocalEndpoint())
return; return;
@ -82,16 +85,30 @@ void ReplicationComponent::EndpointConnectedHandler(const Endpoint::Ptr& endpoin
/* we just assume the other endpoint wants object updates */ /* we just assume the other endpoint wants object updates */
endpoint->RegisterSubscription("config::ObjectUpdate"); endpoint->RegisterSubscription("config::ObjectUpdate");
endpoint->RegisterSubscription("config::ObjectRemoved"); endpoint->RegisterSubscription("config::ObjectRemoved");
}
DynamicType::Ptr type; DynamicType::Ptr type;
BOOST_FOREACH(tie(tuples::ignore, type), DynamicType::GetTypes()) { BOOST_FOREACH(const DynamicType::Ptr& dt, DynamicType::GetTypes()) {
DynamicObject::Ptr object; set<DynamicObject::Ptr> objects;
BOOST_FOREACH(tie(tuples::ignore, object), type->GetObjects()) {
{
ObjectLock olock(dt);
objects = dt->GetObjects();
}
BOOST_FOREACH(const DynamicObject::Ptr& object, objects) {
if (!ShouldReplicateObject(object)) if (!ShouldReplicateObject(object))
continue; continue;
RequestMessage request = MakeObjectMessage(object, "config::ObjectUpdate", 0, true); 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);
}
} }
} }
} }

View File

@ -19,8 +19,6 @@
local object Component "checker" {} local object Component "checker" {}
local object Component "delegation" { local object Component "delegation" {}
delegation_interval = 120
}
local object Component "notification" {} local object Component "notification" {}

View File

@ -24,7 +24,6 @@ using namespace icinga;
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;
boost::thread::id Application::m_MainThreadID;
String Application::m_PrefixDir; String Application::m_PrefixDir;
String Application::m_LocalStateDir; String Application::m_LocalStateDir;
String Application::m_PkgLibDir; String Application::m_PkgLibDir;
@ -402,6 +401,7 @@ void Application::InstallExceptionHandlers(void)
* Runs the application. * Runs the application.
* *
* @returns The application's exit code. * @returns The application's exit code.
* @threadsafety Always.
*/ */
int Application::Run(void) int Application::Run(void)
{ {

View File

@ -93,7 +93,6 @@ private:
static char **m_ArgV; /**< Command-line arguments. */ static char **m_ArgV; /**< Command-line arguments. */
FILE *m_PidFile; /**< The PID file */ FILE *m_PidFile; /**< The PID file */
static bool m_Debugging; /**< Whether debugging is enabled. */ 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_PrefixDir; /**< The installation prefix. */
static String m_LocalStateDir; /**< The local state dir. */ static String m_LocalStateDir; /**< The local state dir. */
static String m_PkgLibDir; /**< The package lib dir. */ static String m_PkgLibDir; /**< The package lib dir. */

View File

@ -32,7 +32,7 @@ signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnUnregistered
signals2::signal<void (double, const set<DynamicObject *>&)> DynamicObject::OnTransactionClosing; signals2::signal<void (double, const set<DynamicObject *>&)> DynamicObject::OnTransactionClosing;
DynamicObject::DynamicObject(const Dictionary::Ptr& serializedObject) DynamicObject::DynamicObject(const Dictionary::Ptr& serializedObject)
: m_ConfigTx(0) : m_Events(false), m_ConfigTx(0)
{ {
RegisterAttribute("__name", Attribute_Config); RegisterAttribute("__name", Attribute_Config);
RegisterAttribute("__type", Attribute_Config); RegisterAttribute("__type", Attribute_Config);
@ -41,13 +41,20 @@ DynamicObject::DynamicObject(const Dictionary::Ptr& serializedObject)
RegisterAttribute("__source", Attribute_Local); RegisterAttribute("__source", Attribute_Local);
RegisterAttribute("methods", Attribute_Config); RegisterAttribute("methods", Attribute_Config);
{
ObjectLock olock(serializedObject);
if (!serializedObject->Contains("configTx")) if (!serializedObject->Contains("configTx"))
BOOST_THROW_EXCEPTION(invalid_argument("Serialized object must contain a config snapshot.")); BOOST_THROW_EXCEPTION(invalid_argument("Serialized object must contain a config snapshot."));
}
/* apply config state from the config item/remote update; /* apply config state from the config item/remote update;
* 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 */
{
ObjectLock olock(this);
ApplyUpdate(serializedObject, Attribute_Config); ApplyUpdate(serializedObject, Attribute_Config);
}
boost::call_once(m_TransactionOnce, &DynamicObject::Initialize); boost::call_once(m_TransactionOnce, &DynamicObject::Initialize);
} }
@ -75,10 +82,13 @@ void DynamicObject::Initialize(void)
*/ */
void DynamicObject::SendLocalUpdateEvents(void) void DynamicObject::SendLocalUpdateEvents(void)
{ {
/* Check if it's safe to send events. */
if (GetEvents()) {
map<String, Value, string_iless>::iterator it; map<String, Value, string_iless>::iterator it;
for (it = m_ModifiedAttributes.begin(); it != m_ModifiedAttributes.end(); it++) { for (it = m_ModifiedAttributes.begin(); it != m_ModifiedAttributes.end(); it++) {
OnAttributeChanged(it->first, it->second); OnAttributeChanged(it->first, it->second);
} }
}
m_ModifiedAttributes.clear(); m_ModifiedAttributes.clear();
} }
@ -124,6 +134,11 @@ Dictionary::Ptr DynamicObject::BuildUpdate(double sinceTx, int attributeTypes) c
void DynamicObject::ApplyUpdate(const Dictionary::Ptr& serializedUpdate, void DynamicObject::ApplyUpdate(const Dictionary::Ptr& serializedUpdate,
int allowedTypes) int allowedTypes)
{ {
Dictionary::Ptr attrs;
{
ObjectLock olock(serializedUpdate);
double configTx = 0; double configTx = 0;
if ((allowedTypes & Attribute_Config) != 0 && if ((allowedTypes & Attribute_Config) != 0 &&
serializedUpdate->Contains("configTx")) { serializedUpdate->Contains("configTx")) {
@ -133,7 +148,11 @@ void DynamicObject::ApplyUpdate(const Dictionary::Ptr& serializedUpdate,
ClearAttributesByType(Attribute_Config); ClearAttributesByType(Attribute_Config);
} }
Dictionary::Ptr attrs = serializedUpdate->Get("attrs"); attrs = serializedUpdate->Get("attrs");
}
{
ObjectLock olock(attrs);
Dictionary::Iterator it; Dictionary::Iterator it;
for (it = attrs->Begin(); it != attrs->End(); it++) { for (it = attrs->Begin(); it != attrs->End(); it++) {
@ -141,6 +160,7 @@ void DynamicObject::ApplyUpdate(const Dictionary::Ptr& serializedUpdate,
continue; continue;
Dictionary::Ptr attr = it->second; Dictionary::Ptr attr = it->second;
ObjectLock alock(attr);
int type = attr->Get("type"); int type = attr->Get("type");
@ -158,6 +178,7 @@ void DynamicObject::ApplyUpdate(const Dictionary::Ptr& serializedUpdate,
InternalSetAttribute(it->first, data, tx, true); InternalSetAttribute(it->first, data, tx, true);
} }
}
} }
void DynamicObject::RegisterAttribute(const String& name, void DynamicObject::RegisterAttribute(const String& name,
@ -296,13 +317,18 @@ String DynamicObject::GetSource(void) const
void DynamicObject::Register(void) void DynamicObject::Register(void)
{ {
{
DynamicType::Ptr dtype = GetType(); DynamicType::Ptr dtype = GetType();
ObjectLock olock(dtype);
DynamicObject::Ptr dobj = dtype->GetObject(GetName()); DynamicObject::Ptr dobj = dtype->GetObject(GetName());
DynamicObject::Ptr self = GetSelf(); DynamicObject::Ptr self = GetSelf();
assert(!dobj || dobj == self); assert(!dobj || dobj == self);
if (!dobj)
dtype->RegisterObject(self); dtype->RegisterObject(self);
}
OnRegistered(GetSelf()); OnRegistered(GetSelf());
@ -375,10 +401,9 @@ void DynamicObject::DumpObjects(const String& filename)
StdioStream::Ptr sfp = boost::make_shared<StdioStream>(&fp, false); StdioStream::Ptr sfp = boost::make_shared<StdioStream>(&fp, false);
sfp->Start(); sfp->Start();
DynamicType::Ptr type; ;
BOOST_FOREACH(tie(tuples::ignore, type), DynamicType::GetTypes()) { BOOST_FOREACH(const DynamicType::Ptr& type, DynamicType::GetTypes()) {
DynamicObject::Ptr object; BOOST_FOREACH(const DynamicObject::Ptr& object, type->GetObjects()) {
BOOST_FOREACH(tie(tuples::ignore, object), type->GetObjects()) {
if (object->IsLocal()) if (object->IsLocal())
continue; continue;
@ -472,13 +497,16 @@ void DynamicObject::RestoreObjects(const String& filename)
void DynamicObject::DeactivateObjects(void) void DynamicObject::DeactivateObjects(void)
{ {
DynamicType::TypeMap::iterator tt; BOOST_FOREACH(const DynamicType::Ptr& dt, DynamicType::GetTypes()) {
for (tt = DynamicType::GetTypes().begin(); tt != DynamicType::GetTypes().end(); tt++) { set<DynamicObject::Ptr> objects;
DynamicType::NameMap::iterator nt;
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(); object->Unregister();
} }
} }
@ -543,3 +571,13 @@ const DynamicObject::AttributeMap& DynamicObject::GetAttributes(void) const
{ {
return m_Attributes; return m_Attributes;
} }
void DynamicObject::SetEvents(bool events)
{
m_Events = events;
}
bool DynamicObject::GetEvents(void) const
{
return m_Events;
}

View File

@ -122,6 +122,9 @@ public:
const AttributeMap& GetAttributes(void) const; const AttributeMap& GetAttributes(void) const;
void SetEvents(bool events);
bool GetEvents(void) const;
static DynamicObject::Ptr GetObject(const String& type, const String& name); static DynamicObject::Ptr GetObject(const String& type, const String& name);
static void DumpObjects(const String& filename); static void DumpObjects(const String& filename);
@ -144,6 +147,8 @@ private:
map<String, Value, string_iless> m_ModifiedAttributes; map<String, Value, string_iless> m_ModifiedAttributes;
double m_ConfigTx; double m_ConfigTx;
bool m_Events;
static double m_CurrentTx; static double m_CurrentTx;
/* This has to be a set of raw pointers because the DynamicObject /* This has to be a set of raw pointers because the DynamicObject

View File

@ -32,9 +32,9 @@ DynamicType::Ptr DynamicType::GetByName(const String& name)
{ {
boost::mutex::scoped_lock lock(GetStaticMutex()); 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 DynamicType::Ptr();
return tt->second; return tt->second;
@ -43,18 +43,34 @@ DynamicType::Ptr DynamicType::GetByName(const String& name)
/** /**
* @threadsafety Caller must hold DynamicType::GetStaticMutex() while using the map. * @threadsafety Caller must hold DynamicType::GetStaticMutex() while using the map.
*/ */
DynamicType::TypeMap& DynamicType::GetTypes(void) DynamicType::TypeMap& DynamicType::InternalGetTypeMap(void)
{ {
static DynamicType::TypeMap types; static DynamicType::TypeMap typemap;
return types; return typemap;
} }
/** DynamicType::TypeSet& DynamicType::InternalGetTypeSet(void)
* @threadsafety Caller must hold DynamicType::GetStaticMutex() while using the map.
*/
DynamicType::NameMap& DynamicType::GetObjects(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 String DynamicType::GetName(void) const
@ -64,19 +80,30 @@ String DynamicType::GetName(void) const
void DynamicType::RegisterObject(const DynamicObject::Ptr& object) 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) 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 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 DynamicObject::Ptr();
return nt->second; return nt->second;
@ -89,18 +116,20 @@ void DynamicType::RegisterType(const DynamicType::Ptr& type)
{ {
boost::mutex::scoped_lock lock(GetStaticMutex()); 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 '" + BOOST_THROW_EXCEPTION(runtime_error("Cannot register class for type '" +
type->GetName() + "': Objects of this type already exist.")); 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 DynamicType::CreateObject(const Dictionary::Ptr& serializedUpdate) const
{ {
DynamicObject::Ptr obj = m_ObjectFactory(serializedUpdate); DynamicObject::Ptr obj = m_ObjectFactory(serializedUpdate);
ObjectLock olock(obj);
/* register attributes */ /* register attributes */
String name; String name;

View File

@ -36,8 +36,6 @@ public:
typedef weak_ptr<DynamicType> WeakPtr; typedef weak_ptr<DynamicType> WeakPtr;
typedef function<DynamicObject::Ptr (const Dictionary::Ptr&)> ObjectFactory; 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); DynamicType(const String& name, const ObjectFactory& factory);
@ -54,8 +52,10 @@ public:
void RegisterObject(const DynamicObject::Ptr& object); void RegisterObject(const DynamicObject::Ptr& object);
void UnregisterObject(const DynamicObject::Ptr& object); void UnregisterObject(const DynamicObject::Ptr& object);
/* TODO(thread) make private */ static TypeMap& GetTypes(void); static set<DynamicType::Ptr> GetTypes(void);
/* TODO(thread) make private */ NameMap& GetObjects(void); set<DynamicObject::Ptr> GetObjects(void) const;
static set<DynamicObject::Ptr> GetObjects(const String& type);
void AddAttribute(const String& name, DynamicAttributeType type); void AddAttribute(const String& name, DynamicAttributeType type);
void RemoveAttribute(const String& name); void RemoveAttribute(const String& name);
@ -68,8 +68,17 @@ private:
ObjectFactory m_ObjectFactory; ObjectFactory m_ObjectFactory;
map<String, DynamicAttributeType> m_Attributes; 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); static boost::mutex& GetStaticMutex(void);
}; };

View File

@ -107,13 +107,7 @@ void Logger::ForwardLogEntry(const LogEntry& entry)
{ {
bool processed = false; bool processed = false;
DynamicType::Ptr dt = DynamicType::GetByName("Logger"); BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Logger")) {
DynamicObject::Ptr object;
{
ObjectLock olock(dt);
BOOST_FOREACH(tie(tuples::ignore, object), dt->GetObjects()) {
Logger::Ptr logger = dynamic_pointer_cast<Logger>(object); Logger::Ptr logger = dynamic_pointer_cast<Logger>(object);
{ {
@ -125,7 +119,6 @@ void Logger::ForwardLogEntry(const LogEntry& entry)
processed = true; processed = true;
} }
}
LogSeverity defaultLogLevel; LogSeverity defaultLogLevel;

View File

@ -112,35 +112,22 @@ private:
struct ObjectLock { struct ObjectLock {
public: public:
ObjectLock(const Object::Ptr& object) ObjectLock(const Object::Ptr& object)
#ifdef _DEBUG : m_Lock()
: m_Lock(), m_Object(object)
#endif /* _DEBUG */
{ {
if (object) if (object)
m_Lock = recursive_mutex::scoped_lock(object->GetMutex()); m_Lock = recursive_mutex::scoped_lock(object->GetMutex());
} }
ObjectLock(const Object *object) ObjectLock(const Object *object)
#ifdef _DEBUG : m_Lock()
: m_Lock(), m_Object(object->GetSelf())
#endif /* _DEBUG */
{ {
if (object) if (object)
m_Lock = recursive_mutex::scoped_lock(object->GetMutex()); 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 */
}; };
/** /**

View File

@ -13,7 +13,7 @@
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * 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. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
@ -22,7 +22,7 @@
using namespace icinga; using namespace icinga;
RingBuffer::RingBuffer(RingBuffer::SizeType slots) 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 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(); vector<int>::size_type offsetTarget = tv % m_Slots.size();
if (tv > m_TimeValue) {
vector<int>::size_type offset = m_TimeValue % m_Slots.size();
/* walk towards the target offset, resetting slots to 0 */ /* walk towards the target offset, resetting slots to 0 */
while (m_Offset != offsetTarget) { while (offset != offsetTarget) {
m_Offset++; offset++;
if (m_Offset >= m_Slots.size()) if (offset >= m_Slots.size())
m_Offset = 0; offset = 0;
m_Slots[m_Offset] = 0; m_Slots[offset] = 0;
} }
m_Slots[m_Offset] += num; m_TimeValue = tv;
}
m_Slots[offsetTarget] += num;
} }
int RingBuffer::GetValues(RingBuffer::SizeType span) const int RingBuffer::GetValues(RingBuffer::SizeType span) const
@ -52,7 +58,7 @@ int RingBuffer::GetValues(RingBuffer::SizeType span) const
if (span > m_Slots.size()) if (span > m_Slots.size())
span = m_Slots.size(); span = m_Slots.size();
int off = m_Offset; int off = m_TimeValue % m_Slots.size();;
int sum = 0; int sum = 0;
while (span > 0) { while (span > 0) {
sum += m_Slots[off]; sum += m_Slots[off];

View File

@ -41,7 +41,7 @@ public:
private: private:
vector<int> m_Slots; vector<int> m_Slots;
SizeType m_Offset; int m_TimeValue;
}; };
} }

View File

@ -29,5 +29,6 @@ ScriptTask::ScriptTask(const ScriptFunction::Ptr& function,
void ScriptTask::Run(void) void ScriptTask::Run(void)
{ {
ObjectLock olock(this);
m_Function->Invoke(GetSelf(), m_Arguments); m_Function->Invoke(GetSelf(), m_Arguments);
} }

View File

@ -111,14 +111,20 @@ void ConfigCompilerContext::Validate(void)
SetContext(this); SetContext(this);
BOOST_FOREACH(const ConfigItem::Ptr& item, m_Items) { BOOST_FOREACH(const ConfigItem::Ptr& item, m_Items) {
ConfigType::Ptr ctype = GetType(item->GetType()); ConfigType::Ptr ctype;
{
ObjectLock olock(item);
ctype = GetType(item->GetType());
if (!ctype) { if (!ctype) {
AddError(true, "No validation type found for object '" + item->GetName() + "' of type '" + item->GetType() + "'"); AddError(true, "No validation type found for object '" + item->GetName() + "' of type '" + item->GetType() + "'");
continue; continue;
} }
}
ObjectLock olock(ctype);
ctype->ValidateItem(item); ctype->ValidateItem(item);
} }
@ -131,7 +137,7 @@ void ConfigCompilerContext::ActivateItems(void)
Logger::Write(LogInformation, "config", "Activating config items in compilation unit '" + m_Unit + "'"); Logger::Write(LogInformation, "config", "Activating config items in compilation unit '" + m_Unit + "'");
BOOST_FOREACH(const ConfigItem::Ptr& item, m_Items) { BOOST_FOREACH(const ConfigItem::Ptr& item, m_Items) {
ObjectLock olock(item);
item->Commit(); item->Commit();
} }
} }

View File

@ -132,9 +132,13 @@ void ConfigType::ValidateDictionary(const Dictionary::Ptr& dictionary,
ScriptTask::Ptr task = boost::make_shared<ScriptTask>(func, arguments); ScriptTask::Ptr task = boost::make_shared<ScriptTask>(func, arguments);
task->Start(); task->Start();
task->Wait(); task->Wait();
{
ObjectLock olock(task);
task->GetResult(); task->GetResult();
} }
} }
}
String key; String key;
Value value; Value value;

View File

@ -311,8 +311,7 @@ void Host::ValidateServicesCache(void)
m_ServicesCache.clear(); m_ServicesCache.clear();
DynamicObject::Ptr object; BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
const Service::Ptr& service = static_pointer_cast<Service>(object); const Service::Ptr& service = static_pointer_cast<Service>(object);
// TODO: assert for duplicate short_names // TODO: assert for duplicate short_names

View File

@ -21,6 +21,7 @@
using namespace icinga; using namespace icinga;
boost::mutex HostGroup::m_Mutex;
map<String, vector<Host::WeakPtr> > HostGroup::m_MembersCache; map<String, vector<Host::WeakPtr> > HostGroup::m_MembersCache;
bool HostGroup::m_MembersCacheValid = true; bool HostGroup::m_MembersCacheValid = true;
@ -77,6 +78,8 @@ set<Host::Ptr> HostGroup::GetMembers(void) const
ValidateMembersCache(); ValidateMembersCache();
{
boost::mutex::scoped_lock lock(m_Mutex);
BOOST_FOREACH(const Host::WeakPtr& hst, m_MembersCache[GetName()]) { BOOST_FOREACH(const Host::WeakPtr& hst, m_MembersCache[GetName()]) {
Host::Ptr host = hst.lock(); Host::Ptr host = hst.lock();
@ -85,31 +88,36 @@ set<Host::Ptr> HostGroup::GetMembers(void) const
hosts.insert(host); hosts.insert(host);
} }
}
return hosts; return hosts;
} }
void HostGroup::InvalidateMembersCache(void) void HostGroup::InvalidateMembersCache(void)
{ {
boost::mutex::scoped_lock lock(m_Mutex);
m_MembersCacheValid = false; m_MembersCacheValid = false;
m_MembersCache.clear(); m_MembersCache.clear();
} }
void HostGroup::ValidateMembersCache(void) void HostGroup::ValidateMembersCache(void)
{ {
boost::mutex::scoped_lock lock(m_Mutex);
if (m_MembersCacheValid) if (m_MembersCacheValid)
return; return;
m_MembersCache.clear(); m_MembersCache.clear();
DynamicObject::Ptr object; BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Host")) {
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Host")->GetObjects()) {
const Host::Ptr& host = static_pointer_cast<Host>(object); const Host::Ptr& host = static_pointer_cast<Host>(object);
ObjectLock olock(host);
Dictionary::Ptr dict; Dictionary::Ptr dict;
dict = host->GetGroups(); dict = host->GetGroups();
if (dict) { if (dict) {
ObjectLock mlock(dict);
Value hostgroup; Value hostgroup;
BOOST_FOREACH(tie(tuples::ignore, hostgroup), dict) { BOOST_FOREACH(tie(tuples::ignore, hostgroup), dict) {
if (!HostGroup::Exists(hostgroup)) if (!HostGroup::Exists(hostgroup))

View File

@ -47,6 +47,7 @@ public:
static void InvalidateMembersCache(void); static void InvalidateMembersCache(void);
private: private:
static boost::mutex m_Mutex;
static map<String, vector<weak_ptr<Host> > > m_MembersCache; static map<String, vector<weak_ptr<Host> > > m_MembersCache;
static bool m_MembersCacheValid; static bool m_MembersCacheValid;

View File

@ -167,8 +167,7 @@ void Service::ValidateCommentsCache(void)
m_CommentsCache.clear(); m_CommentsCache.clear();
m_LegacyCommentsCache.clear(); m_LegacyCommentsCache.clear();
DynamicObject::Ptr object; BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
Service::Ptr service = dynamic_pointer_cast<Service>(object); Service::Ptr service = dynamic_pointer_cast<Service>(object);
service->AddCommentsToCache(); service->AddCommentsToCache();
} }
@ -210,11 +209,7 @@ void Service::RemoveExpiredComments(void)
void Service::CommentsExpireTimerHandler(void) void Service::CommentsExpireTimerHandler(void)
{ {
DynamicType::Ptr dt = DynamicType::GetByName("Service"); BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
ObjectLock dlock(dt);
DynamicObject::Ptr object;
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); ObjectLock olock(service);
service->RemoveExpiredComments(); service->RemoveExpiredComments();

View File

@ -232,8 +232,7 @@ void Service::ValidateDowntimesCache(void)
m_DowntimesCache.clear(); m_DowntimesCache.clear();
m_LegacyDowntimesCache.clear(); m_LegacyDowntimesCache.clear();
DynamicObject::Ptr object; BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
Service::Ptr service = dynamic_pointer_cast<Service>(object); Service::Ptr service = dynamic_pointer_cast<Service>(object);
service->AddDowntimesToCache(); service->AddDowntimesToCache();
} }
@ -275,11 +274,7 @@ void Service::RemoveExpiredDowntimes(void)
void Service::DowntimesExpireTimerHandler(void) void Service::DowntimesExpireTimerHandler(void)
{ {
DynamicType::Ptr dt = DynamicType::GetByName("Service"); BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
ObjectLock dlock(dt);
DynamicObject::Ptr object;
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); ObjectLock slock(service);
service->RemoveExpiredDowntimes(); service->RemoveExpiredDowntimes();

View File

@ -68,8 +68,7 @@ void Service::ValidateNotificationsCache(void)
m_NotificationsCache.clear(); m_NotificationsCache.clear();
DynamicObject::Ptr object; BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Notification")) {
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Notification")->GetObjects()) {
const Notification::Ptr& notification = static_pointer_cast<Notification>(object); const Notification::Ptr& notification = static_pointer_cast<Notification>(object);
m_NotificationsCache[notification->GetService()->GetName()].insert(notification); m_NotificationsCache[notification->GetService()->GetName()].insert(notification);

View File

@ -21,6 +21,7 @@
using namespace icinga; using namespace icinga;
boost::mutex ServiceGroup::m_Mutex;
map<String, vector<Service::WeakPtr> > ServiceGroup::m_MembersCache; map<String, vector<Service::WeakPtr> > ServiceGroup::m_MembersCache;
bool ServiceGroup::m_MembersCacheValid; bool ServiceGroup::m_MembersCacheValid;
@ -77,6 +78,8 @@ set<Service::Ptr> ServiceGroup::GetMembers(void) const
ValidateMembersCache(); ValidateMembersCache();
{
boost::mutex::scoped_lock lock(m_Mutex);
BOOST_FOREACH(const Service::WeakPtr& svc, m_MembersCache[GetName()]) { BOOST_FOREACH(const Service::WeakPtr& svc, m_MembersCache[GetName()]) {
Service::Ptr service = svc.lock(); Service::Ptr service = svc.lock();
@ -85,31 +88,36 @@ set<Service::Ptr> ServiceGroup::GetMembers(void) const
services.insert(service); services.insert(service);
} }
}
return services; return services;
} }
void ServiceGroup::InvalidateMembersCache(void) void ServiceGroup::InvalidateMembersCache(void)
{ {
boost::mutex::scoped_lock lock(m_Mutex);
m_MembersCacheValid = false; m_MembersCacheValid = false;
m_MembersCache.clear(); m_MembersCache.clear();
} }
void ServiceGroup::ValidateMembersCache(void) void ServiceGroup::ValidateMembersCache(void)
{ {
boost::mutex::scoped_lock lock(m_Mutex);
if (m_MembersCacheValid) if (m_MembersCacheValid)
return; return;
m_MembersCache.clear(); m_MembersCache.clear();
DynamicObject::Ptr object; BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
const Service::Ptr& service = static_pointer_cast<Service>(object); const Service::Ptr& service = static_pointer_cast<Service>(object);
ObjectLock olock(service);
Dictionary::Ptr dict; Dictionary::Ptr dict;
dict = service->GetGroups(); dict = service->GetGroups();
if (dict) { if (dict) {
ObjectLock mlock(dict);
Value servicegroup; Value servicegroup;
BOOST_FOREACH(tie(tuples::ignore, servicegroup), dict) { BOOST_FOREACH(tie(tuples::ignore, servicegroup), dict) {
if (!ServiceGroup::Exists(servicegroup)) if (!ServiceGroup::Exists(servicegroup))

View File

@ -47,6 +47,7 @@ public:
static void InvalidateMembersCache(void); static void InvalidateMembersCache(void);
private: private:
static boost::mutex m_Mutex;
static map<String, vector<weak_ptr<Service> > > m_MembersCache; static map<String, vector<weak_ptr<Service> > > m_MembersCache;
static bool m_MembersCacheValid; static bool m_MembersCacheValid;

View File

@ -232,8 +232,8 @@ void EndpointManager::SendAnycastMessage(const Endpoint::Ptr& sender,
BOOST_THROW_EXCEPTION(invalid_argument("Message is missing the 'method' property.")); BOOST_THROW_EXCEPTION(invalid_argument("Message is missing the 'method' property."));
vector<Endpoint::Ptr> candidates; 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); Endpoint::Ptr endpoint = dynamic_pointer_cast<Endpoint>(object);
/* don't forward messages between non-local endpoints */ /* don't forward messages between non-local endpoints */
if ((sender && !sender->IsLocal()) && !endpoint->IsLocal()) if ((sender && !sender->IsLocal()) && !endpoint->IsLocal())
@ -279,8 +279,7 @@ void EndpointManager::SendMulticastMessage(const Endpoint::Ptr& sender,
if (!message.GetMethod(&method)) if (!message.GetMethod(&method))
BOOST_THROW_EXCEPTION(invalid_argument("Message is missing the 'method' property.")); BOOST_THROW_EXCEPTION(invalid_argument("Message is missing the 'method' property."));
DynamicObject::Ptr object; BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Endpoint")) {
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Endpoint")->GetObjects()) {
Endpoint::Ptr recipient = dynamic_pointer_cast<Endpoint>(object); Endpoint::Ptr recipient = dynamic_pointer_cast<Endpoint>(object);
/* don't forward messages back to the sender */ /* don't forward messages back to the sender */
@ -327,8 +326,7 @@ void EndpointManager::SubscriptionTimerHandler(void)
{ {
Dictionary::Ptr subscriptions = boost::make_shared<Dictionary>(); Dictionary::Ptr subscriptions = boost::make_shared<Dictionary>();
DynamicObject::Ptr object; BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Endpoint")) {
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);
/* don't copy subscriptions from non-local endpoints or the identity endpoint */ /* don't copy subscriptions from non-local endpoints or the identity endpoint */
@ -349,8 +347,7 @@ void EndpointManager::SubscriptionTimerHandler(void)
void EndpointManager::ReconnectTimerHandler(void) void EndpointManager::ReconnectTimerHandler(void)
{ {
DynamicObject::Ptr object; BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Endpoint")) {
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);
if (endpoint->IsConnected() || endpoint == m_Endpoint) if (endpoint->IsConnected() || endpoint == m_Endpoint)