mirror of https://github.com/Icinga/icinga2.git
Even more code refactoring.
This commit is contained in:
parent
a6d26a2dc1
commit
be95f3171d
|
@ -109,7 +109,10 @@ void CheckerComponent::CheckThreadProc(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
service->SetForceNextCheck(false);
|
||||
{
|
||||
ObjectLock olock(service);
|
||||
service->SetForceNextCheck(false);
|
||||
}
|
||||
|
||||
Logger::Write(LogDebug, "checker", "Executing service check for '" + service->GetName() + "'");
|
||||
|
||||
|
@ -118,7 +121,7 @@ void CheckerComponent::CheckThreadProc(void)
|
|||
|
||||
try {
|
||||
CheckerComponent::Ptr self = GetSelf();
|
||||
Service::BeginExecuteCheck(service, boost::bind(&CheckerComponent::CheckCompletedHandler, self, service));
|
||||
service->BeginExecuteCheck(boost::bind(&CheckerComponent::CheckCompletedHandler, self, service));
|
||||
} catch (const exception& ex) {
|
||||
Logger::Write(LogCritical, "checker", "Exception occured while checking service '" + service->GetName() + "': " + diagnostic_information(ex));
|
||||
}
|
||||
|
|
|
@ -35,7 +35,14 @@ struct ServiceNextCheckExtractor
|
|||
*/
|
||||
double operator()(const Service::Ptr& service)
|
||||
{
|
||||
return service->GetNextCheck();
|
||||
double next = service->GetNextCheck();
|
||||
|
||||
while (next == 0) {
|
||||
service->UpdateNextCheck();
|
||||
next = service->GetNextCheck();
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -341,7 +341,7 @@ void CompatComponent::DumpHostObject(ostream& fp, const Host::Ptr& host)
|
|||
|
||||
void CompatComponent::DumpServiceStatusAttrs(ostream& fp, const Service::Ptr& service, CompatObjectType type)
|
||||
{
|
||||
ObjectLock olock(service);
|
||||
assert(service->OwnsLock());
|
||||
|
||||
String output;
|
||||
String perfdata;
|
||||
|
@ -413,7 +413,10 @@ void CompatComponent::DumpServiceStatus(ostream& fp, const Service::Ptr& service
|
|||
<< "\t" << "host_name=" << host->GetName() << "\n"
|
||||
<< "\t" << "service_description=" << service->GetShortName() << "\n";
|
||||
|
||||
DumpServiceStatusAttrs(fp, service, CompatTypeService);
|
||||
{
|
||||
ObjectLock olock(service);
|
||||
DumpServiceStatusAttrs(fp, service, CompatTypeService);
|
||||
}
|
||||
|
||||
fp << "\t" << "}" << "\n"
|
||||
<< "\n";
|
||||
|
|
|
@ -144,7 +144,10 @@ void DelegationComponent::DelegationTimerHandler(void)
|
|||
|
||||
/* clear the service's current checker */
|
||||
if (!checker.IsEmpty()) {
|
||||
service->SetCurrentChecker("");
|
||||
{
|
||||
ObjectLock olock(service);
|
||||
service->SetCurrentChecker("");
|
||||
}
|
||||
|
||||
if (oldEndpoint)
|
||||
histogram[oldEndpoint]--;
|
||||
|
@ -156,7 +159,11 @@ void DelegationComponent::DelegationTimerHandler(void)
|
|||
if (histogram[candidate] > avg_services)
|
||||
continue;
|
||||
|
||||
service->SetCurrentChecker(candidate->GetName());
|
||||
{
|
||||
ObjectLock olock(service);
|
||||
service->SetCurrentChecker(candidate->GetName());
|
||||
}
|
||||
|
||||
histogram[candidate]++;
|
||||
|
||||
/* reschedule the service; this avoids "check floods"
|
||||
|
|
|
@ -222,7 +222,7 @@ void ReplicationComponent::RemoteObjectUpdateHandler(const RequestMessage& reque
|
|||
// TODO: sanitize update, disallow __local
|
||||
|
||||
if (!object) {
|
||||
object = DynamicType::CreateObject(dtype, update);
|
||||
object = dtype->CreateObject(update);
|
||||
|
||||
if (source == EndpointManager::GetInstance()->GetIdentity()) {
|
||||
/* the peer sent us an object that was originally created by us -
|
||||
|
|
|
@ -41,13 +41,14 @@ class IcingaSignalPrinter:
|
|||
return '<SIGNAL>'
|
||||
|
||||
def lookup_icinga_type(val):
|
||||
if str(val.type) == 'icinga::String':
|
||||
t = val.type.unqualified()
|
||||
if str(t) == 'icinga::String':
|
||||
return IcingaStringPrinter(val)
|
||||
elif str(val.type) == 'icinga::Value':
|
||||
elif str(t) == 'icinga::Value':
|
||||
return IcingaValuePrinter(val)
|
||||
elif str(val.type) == 'icinga::AttributeBase' or re.match('^icinga::Attribute<.*>$', str(val.type)):
|
||||
elif str(t) == 'icinga::AttributeBase' or re.match('^icinga::Attribute<.*>$', str(t)):
|
||||
return IcingaAttributePrinter(val)
|
||||
elif re.match('^boost::signals2::signal.*<.*>$', str(val.type)):
|
||||
elif re.match('^boost::signals2::signal.*<.*>$', str(t)):
|
||||
return IcingaSignalPrinter(val)
|
||||
|
||||
return None
|
||||
|
|
|
@ -8,6 +8,8 @@ libbase_la_SOURCES = \
|
|||
application.cpp \
|
||||
application.h \
|
||||
asynctask.h \
|
||||
attribute.cpp \
|
||||
attribute.h \
|
||||
component.cpp \
|
||||
component.h \
|
||||
connection.cpp \
|
||||
|
|
|
@ -410,9 +410,11 @@ int Application::Run(void)
|
|||
*/
|
||||
void Application::UpdatePidFile(const String& filename)
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
ObjectLock olock(this);
|
||||
|
||||
ClosePidFile();
|
||||
if (m_PidFile != NULL)
|
||||
fclose(m_PidFile);
|
||||
|
||||
/* There's just no sane way of getting a file descriptor for a
|
||||
* C++ ofstream which is why we're using FILEs here. */
|
||||
|
@ -442,6 +444,7 @@ void Application::UpdatePidFile(const String& filename)
|
|||
*/
|
||||
void Application::ClosePidFile(void)
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (m_PidFile != NULL)
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#include "i2-base.h"
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
boost::mutex AttributeBase::m_Mutex;
|
||||
|
||||
AttributeBase::AttributeBase(void)
|
||||
: m_Value()
|
||||
{ }
|
||||
|
||||
/**
|
||||
* @threadsafety Always.
|
||||
*/
|
||||
void AttributeBase::Set(const Value& value)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
InternalSet(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @threadsafety Always.
|
||||
*/
|
||||
Value AttributeBase::Get(void) const
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
return InternalGet();
|
||||
}
|
||||
|
||||
/**
|
||||
* @threadsafety Always.
|
||||
*/
|
||||
AttributeBase::operator Value(void) const
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
return InternalGet();
|
||||
}
|
||||
|
||||
/**
|
||||
* @threadsafety Always.
|
||||
*/
|
||||
bool AttributeBase::IsEmpty(void) const
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
return InternalGet().IsEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* @threadsafety Caller must hold m_Mutex;
|
||||
*/
|
||||
void AttributeBase::InternalSet(const Value& value)
|
||||
{
|
||||
m_Value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @threadsafety Caller must hold m_Mutex.
|
||||
*/
|
||||
const Value& AttributeBase::InternalGet(void) const
|
||||
{
|
||||
return m_Value;
|
||||
}
|
||||
|
||||
AttributeHolder::AttributeHolder(AttributeType type, AttributeBase *boundAttribute)
|
||||
: m_Type(type), m_Tx(0)
|
||||
{
|
||||
if (boundAttribute) {
|
||||
m_Attribute = boundAttribute;
|
||||
m_OwnsAttribute = false;
|
||||
} else {
|
||||
m_Attribute = new Attribute<Value>();
|
||||
m_OwnsAttribute = true;
|
||||
}
|
||||
}
|
||||
|
||||
AttributeHolder::AttributeHolder(const AttributeHolder& other)
|
||||
{
|
||||
m_Type = other.m_Type;
|
||||
m_Tx = other.m_Tx;
|
||||
m_OwnsAttribute = other.m_OwnsAttribute;
|
||||
|
||||
if (other.m_OwnsAttribute) {
|
||||
m_Attribute = new Attribute<Value>();
|
||||
m_Attribute->Set(other.m_Attribute->Get());
|
||||
} else {
|
||||
m_Attribute = other.m_Attribute;
|
||||
}
|
||||
}
|
||||
|
||||
AttributeHolder::~AttributeHolder(void)
|
||||
{
|
||||
if (m_OwnsAttribute)
|
||||
delete m_Attribute;
|
||||
}
|
||||
|
||||
void AttributeHolder::Bind(AttributeBase *boundAttribute)
|
||||
{
|
||||
assert(m_OwnsAttribute);
|
||||
boundAttribute->Set(m_Attribute->Get());
|
||||
m_Attribute = boundAttribute;
|
||||
m_OwnsAttribute = false;
|
||||
}
|
||||
|
||||
void AttributeHolder::SetValue(double tx, const Value& value)
|
||||
{
|
||||
m_Tx = tx;
|
||||
m_Attribute->Set(value);
|
||||
}
|
||||
|
||||
Value AttributeHolder::GetValue(void) const
|
||||
{
|
||||
return m_Attribute->Get();
|
||||
}
|
||||
|
||||
void AttributeHolder::SetType(AttributeType type)
|
||||
{
|
||||
m_Type = type;
|
||||
}
|
||||
|
||||
AttributeType AttributeHolder::GetType(void) const
|
||||
{
|
||||
return m_Type;
|
||||
}
|
||||
|
||||
void AttributeHolder::SetTx(double tx)
|
||||
{
|
||||
m_Tx = tx;
|
||||
}
|
||||
|
||||
double AttributeHolder::GetTx(void) const
|
||||
{
|
||||
return m_Tx;
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef ATTRIBUTE_H
|
||||
#define ATTRIBUTE_H
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
/**
|
||||
* The type of an attribute for a DynamicObject.
|
||||
*
|
||||
* @ingroup base
|
||||
*/
|
||||
enum AttributeType
|
||||
{
|
||||
Attribute_Transient = 1,
|
||||
|
||||
/* Unlike transient attributes local attributes are persisted
|
||||
* in the program state file. */
|
||||
Attribute_Local = 2,
|
||||
|
||||
/* Replicated attributes are sent to other daemons for which
|
||||
* replication is enabled. */
|
||||
Attribute_Replicated = 4,
|
||||
|
||||
/* Attributes read from the config file are implicitly marked
|
||||
* as config attributes. */
|
||||
Attribute_Config = 8,
|
||||
|
||||
/* Combination of all attribute types */
|
||||
Attribute_All = Attribute_Transient | Attribute_Local | Attribute_Replicated | Attribute_Config
|
||||
};
|
||||
|
||||
class I2_BASE_API AttributeBase
|
||||
{
|
||||
public:
|
||||
AttributeBase(void);
|
||||
|
||||
void Set(const Value& value);
|
||||
Value Get(void) const;
|
||||
operator Value(void) const;
|
||||
bool IsEmpty(void) const;
|
||||
|
||||
protected:
|
||||
void InternalSet(const Value& value);
|
||||
const Value& InternalGet(void) const;
|
||||
|
||||
static boost::mutex m_Mutex;
|
||||
|
||||
private:
|
||||
Value m_Value;
|
||||
|
||||
AttributeBase(const AttributeBase& other);
|
||||
AttributeBase& operator=(const AttributeBase& other);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class Attribute : public AttributeBase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @threadsafety Always.
|
||||
*/
|
||||
void Set(const T& value)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
InternalSet(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @threadsafety Always.
|
||||
*/
|
||||
Attribute<T>& operator=(const T& rhs)
|
||||
{
|
||||
Set(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
T Get(void) const
|
||||
{
|
||||
Value value;
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_Mutex);
|
||||
value = InternalGet();
|
||||
}
|
||||
|
||||
if (value.IsEmpty())
|
||||
return T();
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @threadsafety Always.
|
||||
*/
|
||||
operator T(void) const
|
||||
{
|
||||
return Get();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* An attribute for a DynamicObject.
|
||||
*
|
||||
* @ingroup base
|
||||
*/
|
||||
class I2_BASE_API AttributeHolder
|
||||
{
|
||||
public:
|
||||
AttributeHolder(AttributeType type, AttributeBase *boundAttribute = NULL);
|
||||
AttributeHolder(const AttributeHolder& other);
|
||||
~AttributeHolder(void);
|
||||
|
||||
void Bind(AttributeBase *boundAttribute);
|
||||
|
||||
void SetValue(double tx, const Value& value);
|
||||
Value GetValue(void) const;
|
||||
|
||||
void SetType(AttributeType type);
|
||||
AttributeType GetType(void) const;
|
||||
|
||||
void SetTx(double tx);
|
||||
double GetTx(void) const;
|
||||
|
||||
private:
|
||||
AttributeType m_Type; /**< The type of the attribute. */
|
||||
double m_Tx; /**< The timestamp of the last value change. */
|
||||
bool m_OwnsAttribute; /**< Whether we own the Data pointer. */
|
||||
AttributeBase *m_Attribute; /**< The current value of the attribute. */
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* ATTRIBUTE_H */
|
|
@ -74,8 +74,6 @@ Component::~Component(void)
|
|||
*/
|
||||
void Component::Start(void)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_Impl->SetConfig(GetSelf());
|
||||
m_Impl->Start();
|
||||
}
|
||||
|
@ -104,8 +102,6 @@ void Component::AddSearchDir(const String& componentDirectory)
|
|||
*/
|
||||
DynamicObject::Ptr IComponent::GetConfig(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_Config.lock();
|
||||
}
|
||||
|
||||
|
@ -114,8 +110,6 @@ DynamicObject::Ptr IComponent::GetConfig(void) const
|
|||
*/
|
||||
void IComponent::SetConfig(const DynamicObject::Ptr& config)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_Config = config;
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ Dictionary::Dictionary(void)
|
|||
*/
|
||||
Value Dictionary::Get(const char *key) const
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
ObjectLock olock(this);
|
||||
|
||||
map<String, Value>::const_iterator it;
|
||||
|
@ -103,15 +104,16 @@ Value Dictionary::Get(const String& key) const
|
|||
*/
|
||||
void Dictionary::Set(const String& key, const Value& value)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
assert(!m_Sealed);
|
||||
|
||||
if (value.IsEmpty()) {
|
||||
Remove(key);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(!OwnsLock());
|
||||
ObjectLock olock(this);
|
||||
|
||||
assert(!m_Sealed);
|
||||
|
||||
pair<map<String, Value>::iterator, bool> ret;
|
||||
ret = m_Data.insert(make_pair(key, value));
|
||||
if (!ret.second)
|
||||
|
@ -127,11 +129,12 @@ void Dictionary::Set(const String& key, const Value& value)
|
|||
*/
|
||||
String Dictionary::Add(const Value& value)
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
ObjectLock olock(this);
|
||||
|
||||
Dictionary::Iterator it;
|
||||
String key;
|
||||
long index = GetLength();
|
||||
long index = m_Data.size();
|
||||
do {
|
||||
stringstream s;
|
||||
s << "_" << std::hex << std::setw(8) << std::setfill('0') << index;
|
||||
|
@ -141,7 +144,11 @@ String Dictionary::Add(const Value& value)
|
|||
it = m_Data.find(key);
|
||||
} while (it != m_Data.end());
|
||||
|
||||
Set(key, value);
|
||||
pair<map<String, Value>::iterator, bool> ret;
|
||||
ret = m_Data.insert(make_pair(key, value));
|
||||
if (!ret.second)
|
||||
ret.first->second = value;
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
|
@ -177,6 +184,7 @@ Dictionary::Iterator Dictionary::End(void)
|
|||
*/
|
||||
size_t Dictionary::GetLength(void) const
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_Data.size();
|
||||
|
@ -191,6 +199,7 @@ size_t Dictionary::GetLength(void) const
|
|||
*/
|
||||
bool Dictionary::Contains(const String& key) const
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
ObjectLock olock(this);
|
||||
|
||||
return (m_Data.find(key) != m_Data.end());
|
||||
|
@ -204,6 +213,7 @@ bool Dictionary::Contains(const String& key) const
|
|||
*/
|
||||
void Dictionary::Remove(const String& key)
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
ObjectLock olock(this);
|
||||
|
||||
Dictionary::Iterator it;
|
||||
|
@ -222,6 +232,7 @@ void Dictionary::Remove(const String& key)
|
|||
*/
|
||||
void Dictionary::Remove(Dictionary::Iterator it)
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
ObjectLock olock(this);
|
||||
|
||||
String key = it->first;
|
||||
|
@ -234,6 +245,7 @@ void Dictionary::Remove(Dictionary::Iterator it)
|
|||
*/
|
||||
void Dictionary::Seal(void)
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_Sealed = true;
|
||||
|
@ -246,6 +258,7 @@ void Dictionary::Seal(void)
|
|||
*/
|
||||
bool Dictionary::IsSealed(void) const
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_Sealed;
|
||||
|
@ -259,6 +272,7 @@ bool Dictionary::IsSealed(void) const
|
|||
*/
|
||||
Dictionary::Ptr Dictionary::ShallowClone(void) const
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
ObjectLock olock(this);
|
||||
|
||||
Dictionary::Ptr clone = boost::make_shared<Dictionary>();
|
||||
|
|
|
@ -70,31 +70,35 @@ void DynamicObject::Initialize(void)
|
|||
|
||||
Dictionary::Ptr DynamicObject::BuildUpdate(double sinceTx, int attributeTypes) const
|
||||
{
|
||||
assert(OwnsLock());
|
||||
ObjectLock olock(this);
|
||||
|
||||
DynamicObject::AttributeConstIterator it;
|
||||
|
||||
Dictionary::Ptr attrs = boost::make_shared<Dictionary>();
|
||||
|
||||
for (it = m_Attributes.begin(); it != m_Attributes.end(); it++) {
|
||||
if (it->second.GetType() == Attribute_Transient)
|
||||
continue;
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_AttributeMutex);
|
||||
|
||||
if ((it->second.GetType() & attributeTypes) == 0)
|
||||
continue;
|
||||
for (it = m_Attributes.begin(); it != m_Attributes.end(); it++) {
|
||||
if (it->second.GetType() == Attribute_Transient)
|
||||
continue;
|
||||
|
||||
if (it->second.GetTx() == 0)
|
||||
continue;
|
||||
if ((it->second.GetType() & attributeTypes) == 0)
|
||||
continue;
|
||||
|
||||
if (it->second.GetTx() < sinceTx && !(it->second.GetType() == Attribute_Config && m_ConfigTx >= sinceTx))
|
||||
continue;
|
||||
if (it->second.GetTx() == 0)
|
||||
continue;
|
||||
|
||||
Dictionary::Ptr attr = boost::make_shared<Dictionary>();
|
||||
attr->Set("data", it->second.GetValue());
|
||||
attr->Set("type", it->second.GetType());
|
||||
attr->Set("tx", it->second.GetTx());
|
||||
if (it->second.GetTx() < sinceTx && !(it->second.GetType() == Attribute_Config && m_ConfigTx >= sinceTx))
|
||||
continue;
|
||||
|
||||
attrs->Set(it->first, attr);
|
||||
Dictionary::Ptr attr = boost::make_shared<Dictionary>();
|
||||
attr->Set("data", it->second.GetValue());
|
||||
attr->Set("type", it->second.GetType());
|
||||
attr->Set("tx", it->second.GetTx());
|
||||
|
||||
attrs->Set(it->first, attr);
|
||||
}
|
||||
}
|
||||
|
||||
attrs->Seal();
|
||||
|
@ -121,11 +125,20 @@ void DynamicObject::ApplyUpdate(const Dictionary::Ptr& serializedUpdate,
|
|||
|
||||
Value configTxValue = serializedUpdate->Get("configTx");
|
||||
|
||||
if ((allowedTypes & Attribute_Config) != 0 && !configTxValue.IsEmpty()) {
|
||||
double configTx = configTxValue;
|
||||
boost::mutex::scoped_lock lock(m_AttributeMutex);
|
||||
|
||||
if (configTx > m_ConfigTx)
|
||||
ClearAttributesByType(Attribute_Config);
|
||||
if ((allowedTypes & Attribute_Config) != 0 && !configTxValue.IsEmpty()) {
|
||||
double oldConfigTx, configTx = configTxValue;
|
||||
|
||||
if (configTx > m_ConfigTx) {
|
||||
DynamicObject::AttributeIterator at;
|
||||
for (at = m_Attributes.begin(); at != m_Attributes.end(); at++) {
|
||||
if ((at->second.GetType() & Attribute_Config) == 0)
|
||||
continue;
|
||||
|
||||
at->second.SetValue(0, Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary::Ptr attrs = serializedUpdate->Get("attrs");
|
||||
|
@ -153,10 +166,10 @@ void DynamicObject::ApplyUpdate(const Dictionary::Ptr& serializedUpdate,
|
|||
double tx = attr->Get("tx");
|
||||
|
||||
if (type & Attribute_Config)
|
||||
RegisterAttribute(it->first, Attribute_Config);
|
||||
InternalRegisterAttribute(it->first, Attribute_Config);
|
||||
|
||||
if (!HasAttribute(it->first))
|
||||
RegisterAttribute(it->first, static_cast<AttributeType>(type));
|
||||
if (m_Attributes.find(it->first) == m_Attributes.end())
|
||||
InternalRegisterAttribute(it->first, static_cast<AttributeType>(type));
|
||||
|
||||
InternalSetAttribute(it->first, data, tx, true);
|
||||
}
|
||||
|
@ -165,6 +178,20 @@ void DynamicObject::ApplyUpdate(const Dictionary::Ptr& serializedUpdate,
|
|||
|
||||
void DynamicObject::RegisterAttribute(const String& name,
|
||||
AttributeType type, AttributeBase *boundAttribute)
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
ObjectLock olock(this);
|
||||
|
||||
boost::mutex::scoped_lock lock(m_AttributeMutex);
|
||||
|
||||
InternalRegisterAttribute(name, type, boundAttribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* @threadsafety Caller must hold m_AttributeMutex.
|
||||
*/
|
||||
void DynamicObject::InternalRegisterAttribute(const String& name,
|
||||
AttributeType type, AttributeBase *boundAttribute)
|
||||
{
|
||||
assert(OwnsLock());
|
||||
|
||||
|
@ -186,6 +213,11 @@ void DynamicObject::RegisterAttribute(const String& name,
|
|||
*/
|
||||
void DynamicObject::Set(const String& name, const Value& data)
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
ObjectLock olock(this);
|
||||
|
||||
boost::mutex::scoped_lock lock(m_AttributeMutex);
|
||||
|
||||
InternalSetAttribute(name, data, GetCurrentTx());
|
||||
}
|
||||
|
||||
|
@ -194,7 +226,23 @@ void DynamicObject::Set(const String& name, const Value& data)
|
|||
*/
|
||||
void DynamicObject::Touch(const String& name)
|
||||
{
|
||||
InternalSetAttribute(name, InternalGetAttribute(name), GetCurrentTx());
|
||||
assert(!OwnsLock());
|
||||
|
||||
boost::mutex::scoped_lock lock(m_AttributeMutex);
|
||||
|
||||
AttributeIterator it = m_Attributes.find(name);
|
||||
|
||||
if (it == m_Attributes.end())
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Touch() called for unknown attribute: " + name));
|
||||
|
||||
it->second.SetTx(GetCurrentTx());
|
||||
|
||||
m_ModifiedAttributes.insert(name);
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_TransactionMutex);
|
||||
m_ModifiedObjects.insert(GetSelf());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -202,22 +250,25 @@ void DynamicObject::Touch(const String& name)
|
|||
*/
|
||||
Value DynamicObject::Get(const String& name) const
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
ObjectLock olock(this);
|
||||
|
||||
boost::mutex::scoped_lock lock(m_AttributeMutex);
|
||||
|
||||
return InternalGetAttribute(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @threadsafety Always.
|
||||
* @threadsafety Caller must hold m_AttributeMutex.
|
||||
*/
|
||||
void DynamicObject::InternalSetAttribute(const String& name, const Value& data,
|
||||
double tx, bool allowEditConfig)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
assert(OwnsLock());
|
||||
|
||||
DynamicObject::AttributeIterator it;
|
||||
it = m_Attributes.find(name);
|
||||
|
||||
Value oldValue;
|
||||
|
||||
if (it == m_Attributes.end()) {
|
||||
AttributeHolder attr(Attribute_Transient);
|
||||
attr.SetValue(tx, data);
|
||||
|
@ -227,7 +278,6 @@ void DynamicObject::InternalSetAttribute(const String& name, const Value& data,
|
|||
if (!allowEditConfig && (it->second.GetType() & Attribute_Config))
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Config properties are immutable: '" + name + "'."));
|
||||
|
||||
oldValue = it->second.GetValue();
|
||||
it->second.SetValue(tx, data);
|
||||
|
||||
if (it->second.GetType() & Attribute_Config)
|
||||
|
@ -240,26 +290,21 @@ void DynamicObject::InternalSetAttribute(const String& name, const Value& data,
|
|||
* object to the list of modified objects later on if we can't
|
||||
* do it here. */
|
||||
|
||||
DynamicObject::Ptr self = GetSelf();
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_TransactionMutex);
|
||||
m_ModifiedObjects.insert(self);
|
||||
m_ModifiedObjects.insert(GetSelf());
|
||||
}
|
||||
}
|
||||
|
||||
/* Use insert() rather than [] so we don't overwrite
|
||||
* an existing oldValue if the attribute was previously
|
||||
* changed in the same transaction */
|
||||
m_ModifiedAttributes.insert(make_pair(name, oldValue));
|
||||
m_ModifiedAttributes.insert(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @threadsafety Always.
|
||||
* @threadsafety Caller must hold m_AttributeMutex.
|
||||
*/
|
||||
Value DynamicObject::InternalGetAttribute(const String& name) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
assert(OwnsLock());
|
||||
|
||||
DynamicObject::AttributeConstIterator it;
|
||||
it = m_Attributes.find(name);
|
||||
|
@ -270,36 +315,11 @@ Value DynamicObject::InternalGetAttribute(const String& name) const
|
|||
return it->second.GetValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @threadsafety Always.
|
||||
*/
|
||||
bool DynamicObject::HasAttribute(const String& name) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return (m_Attributes.find(name) != m_Attributes.end());
|
||||
}
|
||||
|
||||
void DynamicObject::ClearAttributesByType(AttributeType type)
|
||||
{
|
||||
assert(OwnsLock());
|
||||
|
||||
DynamicObject::AttributeIterator at;
|
||||
for (at = m_Attributes.begin(); at != m_Attributes.end(); at++) {
|
||||
if (at->second.GetType() != type)
|
||||
continue;
|
||||
|
||||
at->second.SetValue(0, Empty);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @threadsafety Always.
|
||||
*/
|
||||
DynamicType::Ptr DynamicObject::GetType(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return DynamicType::GetByName(m_Type);
|
||||
}
|
||||
|
||||
|
@ -308,8 +328,6 @@ DynamicType::Ptr DynamicObject::GetType(void) const
|
|||
*/
|
||||
String DynamicObject::GetName(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_Name;
|
||||
}
|
||||
|
||||
|
@ -318,8 +336,6 @@ String DynamicObject::GetName(void) const
|
|||
*/
|
||||
bool DynamicObject::IsLocal(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_Local;
|
||||
}
|
||||
|
||||
|
@ -328,8 +344,6 @@ bool DynamicObject::IsLocal(void) const
|
|||
*/
|
||||
bool DynamicObject::IsAbstract(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_Abstract;
|
||||
}
|
||||
|
||||
|
@ -338,8 +352,6 @@ bool DynamicObject::IsAbstract(void) const
|
|||
*/
|
||||
bool DynamicObject::IsRegistered(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_Registered;
|
||||
}
|
||||
|
||||
|
@ -348,8 +360,6 @@ bool DynamicObject::IsRegistered(void) const
|
|||
*/
|
||||
void DynamicObject::SetSource(const String& value)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_Source = value;
|
||||
Touch("__source");
|
||||
}
|
||||
|
@ -359,8 +369,6 @@ void DynamicObject::SetSource(const String& value)
|
|||
*/
|
||||
String DynamicObject::GetSource(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_Source;
|
||||
}
|
||||
|
||||
|
@ -368,45 +376,30 @@ void DynamicObject::Register(void)
|
|||
{
|
||||
assert(!OwnsLock());
|
||||
|
||||
DynamicObject::Ptr self = GetSelf();
|
||||
|
||||
/* Add this new object to the list of modified objects.
|
||||
* We're doing this here because we can't construct
|
||||
* a while WeakPtr from within the object's constructor. */
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_TransactionMutex);
|
||||
m_ModifiedObjects.insert(self);
|
||||
m_ModifiedObjects.insert(GetSelf());
|
||||
}
|
||||
|
||||
{
|
||||
DynamicType::Ptr dtype = GetType();
|
||||
ObjectLock olock(dtype);
|
||||
|
||||
DynamicObject::Ptr dobj = dtype->GetObject(GetName());
|
||||
|
||||
assert(!dobj || dobj == self);
|
||||
|
||||
if (!dobj)
|
||||
dtype->RegisterObject(self);
|
||||
}
|
||||
DynamicType::Ptr dtype = GetType();
|
||||
dtype->RegisterObject(GetSelf());
|
||||
}
|
||||
|
||||
void DynamicObject::OnRegistrationCompleted(void)
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
|
||||
DynamicObject::Ptr object;
|
||||
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
m_Registered = true;
|
||||
|
||||
Start();
|
||||
|
||||
object = GetSelf();
|
||||
}
|
||||
|
||||
OnRegistered(object);
|
||||
Start();
|
||||
|
||||
OnRegistered(GetSelf());
|
||||
}
|
||||
|
||||
void DynamicObject::OnUnregistrationCompleted(void)
|
||||
|
@ -423,7 +416,7 @@ void DynamicObject::OnUnregistrationCompleted(void)
|
|||
|
||||
void DynamicObject::Start(void)
|
||||
{
|
||||
assert(OwnsLock());
|
||||
assert(!OwnsLock());
|
||||
|
||||
/* Nothing to do here. */
|
||||
}
|
||||
|
@ -432,17 +425,12 @@ void DynamicObject::Unregister(void)
|
|||
{
|
||||
assert(!OwnsLock());
|
||||
|
||||
DynamicObject::Ptr self = GetSelf();
|
||||
|
||||
DynamicType::Ptr dtype = GetType();
|
||||
|
||||
if (!dtype)
|
||||
return;
|
||||
|
||||
{
|
||||
ObjectLock olock(dtype);
|
||||
dtype->UnregisterObject(self);
|
||||
}
|
||||
dtype->UnregisterObject(GetSelf());
|
||||
}
|
||||
|
||||
ScriptTask::Ptr DynamicObject::MakeMethodTask(const String& method,
|
||||
|
@ -450,10 +438,7 @@ ScriptTask::Ptr DynamicObject::MakeMethodTask(const String& method,
|
|||
{
|
||||
Dictionary::Ptr methods;
|
||||
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
methods = m_Methods;
|
||||
}
|
||||
methods = m_Methods;
|
||||
|
||||
String funcName = methods->Get(method);
|
||||
|
||||
|
@ -488,8 +473,6 @@ void DynamicObject::DumpObjects(const String& filename)
|
|||
|
||||
BOOST_FOREACH(const DynamicType::Ptr& type, DynamicType::GetTypes()) {
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, type->GetObjects()) {
|
||||
ObjectLock olock(object);
|
||||
|
||||
if (object->IsLocal())
|
||||
continue;
|
||||
|
||||
|
@ -566,7 +549,7 @@ void DynamicObject::RestoreObjects(const String& filename)
|
|||
DynamicObject::Ptr object = dt->GetObject(name);
|
||||
|
||||
if (hasConfig && !object) {
|
||||
object = DynamicType::CreateObject(dt, update);
|
||||
object = dt->DynamicType::CreateObject(update);
|
||||
object->Register();
|
||||
} else if (object) {
|
||||
object->ApplyUpdate(update, Attribute_All);
|
||||
|
@ -633,22 +616,22 @@ void DynamicObject::NewTx(void)
|
|||
if (!object || !object->IsRegistered())
|
||||
continue;
|
||||
|
||||
map<String, Value, string_iless> attrs;
|
||||
set<String, string_iless> attrs;
|
||||
|
||||
{
|
||||
ObjectLock olock(object);
|
||||
attrs.swap(object->m_ModifiedAttributes);
|
||||
}
|
||||
|
||||
map<String, Value, string_iless>::iterator it;
|
||||
for (it = attrs.begin(); it != attrs.end(); it++)
|
||||
object->OnAttributeChanged(it->first, it->second);
|
||||
BOOST_FOREACH(const String& attr, attrs) {
|
||||
object->OnAttributeChanged(attr);
|
||||
}
|
||||
}
|
||||
|
||||
OnTransactionClosing(tx, objects);
|
||||
}
|
||||
|
||||
void DynamicObject::OnAttributeChanged(const String&, const Value&)
|
||||
void DynamicObject::OnAttributeChanged(const String&)
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
}
|
||||
|
|
|
@ -23,170 +23,6 @@
|
|||
namespace icinga
|
||||
{
|
||||
|
||||
/**
|
||||
* The type of an attribute for a DynamicObject.
|
||||
*
|
||||
* @ingroup base
|
||||
*/
|
||||
enum AttributeType
|
||||
{
|
||||
Attribute_Transient = 1,
|
||||
|
||||
/* Unlike transient attributes local attributes are persisted
|
||||
* in the program state file. */
|
||||
Attribute_Local = 2,
|
||||
|
||||
/* Replicated attributes are sent to other daemons for which
|
||||
* replication is enabled. */
|
||||
Attribute_Replicated = 4,
|
||||
|
||||
/* Attributes read from the config file are implicitly marked
|
||||
* as config attributes. */
|
||||
Attribute_Config = 8,
|
||||
|
||||
/* Combination of all attribute types */
|
||||
Attribute_All = Attribute_Transient | Attribute_Local | Attribute_Replicated | Attribute_Config
|
||||
};
|
||||
|
||||
class AttributeBase
|
||||
{
|
||||
public:
|
||||
AttributeBase(void)
|
||||
: m_Value()
|
||||
{ }
|
||||
|
||||
void InternalSet(const Value& value)
|
||||
{
|
||||
m_Value = value;
|
||||
}
|
||||
|
||||
const Value& InternalGet(void) const
|
||||
{
|
||||
return m_Value;
|
||||
}
|
||||
|
||||
operator Value(void) const
|
||||
{
|
||||
return InternalGet();
|
||||
}
|
||||
|
||||
bool IsEmpty(void) const
|
||||
{
|
||||
return InternalGet().IsEmpty();
|
||||
}
|
||||
|
||||
private:
|
||||
Value m_Value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class Attribute : public AttributeBase
|
||||
{
|
||||
public:
|
||||
void Set(const T& value)
|
||||
{
|
||||
InternalSet(value);
|
||||
}
|
||||
|
||||
Attribute<T>& operator=(const T& rhs)
|
||||
{
|
||||
Set(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
T Get(void) const
|
||||
{
|
||||
if (IsEmpty())
|
||||
return T();
|
||||
|
||||
return InternalGet();
|
||||
}
|
||||
|
||||
operator T(void) const
|
||||
{
|
||||
return Get();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* An attribute for a DynamicObject.
|
||||
*
|
||||
* @ingroup base
|
||||
*/
|
||||
struct AttributeHolder
|
||||
{
|
||||
AttributeType m_Type; /**< The type of the attribute. */
|
||||
double m_Tx; /**< The timestamp of the last value change. */
|
||||
bool m_OwnsAttribute; /**< Whether we own the Data pointer. */
|
||||
AttributeBase *m_Attribute; /**< The current value of the attribute. */
|
||||
|
||||
AttributeHolder(AttributeType type, AttributeBase *boundAttribute = NULL)
|
||||
: m_Type(type), m_Tx(0)
|
||||
{
|
||||
if (boundAttribute) {
|
||||
m_Attribute = boundAttribute;
|
||||
m_OwnsAttribute = false;
|
||||
} else {
|
||||
m_Attribute = new Attribute<Value>();
|
||||
m_OwnsAttribute = true;
|
||||
}
|
||||
}
|
||||
|
||||
AttributeHolder(const AttributeHolder& other)
|
||||
{
|
||||
m_Type = other.m_Type;
|
||||
m_Tx = other.m_Tx;
|
||||
m_OwnsAttribute = other.m_OwnsAttribute;
|
||||
|
||||
if (other.m_OwnsAttribute) {
|
||||
m_Attribute = new Attribute<Value>();
|
||||
m_Attribute->InternalSet(other.m_Attribute->InternalGet());
|
||||
} else {
|
||||
m_Attribute = other.m_Attribute;
|
||||
}
|
||||
}
|
||||
|
||||
~AttributeHolder(void)
|
||||
{
|
||||
if (m_OwnsAttribute)
|
||||
delete m_Attribute;
|
||||
}
|
||||
|
||||
void Bind(AttributeBase *boundAttribute)
|
||||
{
|
||||
assert(m_OwnsAttribute);
|
||||
boundAttribute->InternalSet(m_Attribute->InternalGet());
|
||||
m_Attribute = boundAttribute;
|
||||
m_OwnsAttribute = false;
|
||||
}
|
||||
|
||||
void SetValue(double tx, const Value& value)
|
||||
{
|
||||
m_Tx = tx;
|
||||
m_Attribute->InternalSet(value);
|
||||
}
|
||||
|
||||
Value GetValue(void) const
|
||||
{
|
||||
return m_Attribute->InternalGet();
|
||||
}
|
||||
|
||||
void SetType(AttributeType type)
|
||||
{
|
||||
m_Type = type;
|
||||
}
|
||||
|
||||
AttributeType GetType(void) const
|
||||
{
|
||||
return m_Type;
|
||||
}
|
||||
|
||||
double GetTx(void) const
|
||||
{
|
||||
return m_Tx;
|
||||
}
|
||||
};
|
||||
|
||||
class DynamicType;
|
||||
|
||||
/**
|
||||
|
@ -219,8 +55,6 @@ public:
|
|||
void Touch(const String& name);
|
||||
Value Get(const String& name) const;
|
||||
|
||||
bool HasAttribute(const String& name) const;
|
||||
|
||||
void BindAttribute(const String& name, Value *boundValue);
|
||||
|
||||
void ClearAttributesByType(AttributeType type);
|
||||
|
@ -264,15 +98,16 @@ protected:
|
|||
virtual void OnRegistrationCompleted(void);
|
||||
virtual void OnUnregistrationCompleted(void);
|
||||
|
||||
virtual void OnAttributeChanged(const String& name, const Value& oldValue);
|
||||
virtual void OnAttributeChanged(const String& name);
|
||||
|
||||
private:
|
||||
void InternalSetAttribute(const String& name, const Value& data, double tx, bool allowEditConfig = false);
|
||||
Value InternalGetAttribute(const String& name) const;
|
||||
void SendLocalUpdateEvents(void);
|
||||
void InternalRegisterAttribute(const String& name, AttributeType type, AttributeBase *boundAttribute = NULL);
|
||||
|
||||
mutable boost::mutex m_AttributeMutex;
|
||||
AttributeMap m_Attributes;
|
||||
map<String, Value, string_iless> m_ModifiedAttributes;
|
||||
set<String, string_iless> m_ModifiedAttributes;
|
||||
double m_ConfigTx;
|
||||
|
||||
Attribute<String> m_Name;
|
||||
|
|
|
@ -76,8 +76,6 @@ set<DynamicObject::Ptr> DynamicType::GetObjects(void) const
|
|||
|
||||
String DynamicType::GetName(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_Name;
|
||||
}
|
||||
|
||||
|
@ -85,7 +83,8 @@ void DynamicType::RegisterObject(const DynamicObject::Ptr& object)
|
|||
{
|
||||
String name = object->GetName();
|
||||
|
||||
assert(OwnsLock());
|
||||
ObjectLock olock(this);
|
||||
|
||||
ObjectMap::iterator it = m_ObjectMap.find(name);
|
||||
|
||||
if (it != m_ObjectMap.end()) {
|
||||
|
@ -103,7 +102,8 @@ void DynamicType::RegisterObject(const DynamicObject::Ptr& object)
|
|||
|
||||
void DynamicType::UnregisterObject(const DynamicObject::Ptr& object)
|
||||
{
|
||||
assert(OwnsLock());
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_ObjectMap.erase(object->GetName());
|
||||
m_ObjectSet.erase(object);
|
||||
|
||||
|
@ -142,23 +142,21 @@ void DynamicType::RegisterType(const DynamicType::Ptr& type)
|
|||
InternalGetTypeSet().insert(type);
|
||||
}
|
||||
|
||||
DynamicObject::Ptr DynamicType::CreateObject(const DynamicType::Ptr& self, const Dictionary::Ptr& serializedUpdate)
|
||||
DynamicObject::Ptr DynamicType::CreateObject(const Dictionary::Ptr& serializedUpdate)
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
|
||||
ObjectFactory factory;
|
||||
|
||||
{
|
||||
ObjectLock olock(self);
|
||||
factory = self->m_ObjectFactory;
|
||||
ObjectLock olock(this);
|
||||
factory = m_ObjectFactory;
|
||||
}
|
||||
|
||||
DynamicObject::Ptr object = factory(serializedUpdate);
|
||||
|
||||
{
|
||||
ObjectLock olock(object);
|
||||
|
||||
/* apply the object's non-config attributes */
|
||||
object->ApplyUpdate(serializedUpdate, Attribute_All & ~Attribute_Config);
|
||||
}
|
||||
/* apply the object's non-config attributes */
|
||||
object->ApplyUpdate(serializedUpdate, Attribute_All & ~Attribute_Config);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
|
||||
static void RegisterType(const DynamicType::Ptr& type);
|
||||
|
||||
static DynamicObject::Ptr CreateObject(const DynamicType::Ptr& self, const Dictionary::Ptr& serializedUpdate);
|
||||
DynamicObject::Ptr CreateObject(const Dictionary::Ptr& serializedUpdate);
|
||||
DynamicObject::Ptr GetObject(const String& name) const;
|
||||
|
||||
void RegisterObject(const DynamicObject::Ptr& object);
|
||||
|
|
|
@ -214,6 +214,7 @@ namespace signals2 = boost::signals2;
|
|||
#include "process.h"
|
||||
#include "scriptfunction.h"
|
||||
#include "scripttask.h"
|
||||
#include "attribute.h"
|
||||
#include "dynamicobject.h"
|
||||
#include "dynamictype.h"
|
||||
#include "script.h"
|
||||
|
|
|
@ -29,7 +29,9 @@ boost::mutex Object::m_DebugMutex;
|
|||
* Default constructor for the Object class.
|
||||
*/
|
||||
Object::Object(void)
|
||||
: m_LockCount(0)
|
||||
#ifdef _DEBUG
|
||||
: m_Locked(false)
|
||||
#endif /* _DEBUG */
|
||||
{ }
|
||||
|
||||
/**
|
||||
|
@ -46,15 +48,12 @@ Object::~Object(void)
|
|||
*/
|
||||
Object::SharedPtrHolder Object::GetSelf(void)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return Object::SharedPtrHolder(shared_from_this());
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
/**
|
||||
* Checks if the calling thread owns the lock on this object or is currently
|
||||
* in the constructor or destructor and therefore implicitly owns the lock.
|
||||
* Checks if the calling thread owns the lock on this object.
|
||||
*
|
||||
* @returns True if the calling thread owns the lock, false otherwise.
|
||||
*/
|
||||
|
@ -62,18 +61,6 @@ bool Object::OwnsLock(void) const
|
|||
{
|
||||
boost::mutex::scoped_lock lock(m_DebugMutex);
|
||||
|
||||
if (m_LockCount == 0 || m_LockOwner != boost::this_thread::get_id()) {
|
||||
try {
|
||||
shared_from_this();
|
||||
} catch (const boost::bad_weak_ptr& ex) {
|
||||
/* There's no shared_ptr to this object. Either someone created the object
|
||||
* directly (e.g. on the stack) or we're in the constructor or destructor. Not holding the lock is ok here. */
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return (m_Locked && m_LockOwner == boost::this_thread::get_id());
|
||||
}
|
||||
#endif /* _DEBUG */
|
||||
|
|
|
@ -91,8 +91,9 @@ public:
|
|||
holder instance */
|
||||
};
|
||||
|
||||
void VerifyLocked(void) const;
|
||||
void WarnIfLocked(void) const;
|
||||
#ifdef _DEBUG
|
||||
bool OwnsLock(void) const;
|
||||
#endif /* _DEBUG */
|
||||
|
||||
protected:
|
||||
Object(void);
|
||||
|
@ -100,22 +101,22 @@ protected:
|
|||
|
||||
SharedPtrHolder GetSelf(void);
|
||||
|
||||
#ifdef _DEBUG
|
||||
bool OwnsLock(void) const;
|
||||
#endif /* _DEBUG */
|
||||
|
||||
private:
|
||||
Object(const Object& other);
|
||||
Object& operator=(const Object& rhs);
|
||||
|
||||
mutable recursive_mutex m_Mutex;
|
||||
mutable unsigned int m_LockCount;
|
||||
mutable boost::thread::id m_LockOwner;
|
||||
#ifndef _DEBUG
|
||||
typedef boost::mutex MutexType;
|
||||
#else /* _DEBUG */
|
||||
typedef boost::recursive_mutex MutexType;
|
||||
|
||||
#ifdef _DEBUG
|
||||
static boost::mutex m_DebugMutex;
|
||||
mutable bool m_Locked;
|
||||
mutable boost::thread::id m_LockOwner;
|
||||
#endif /* _DEBUG */
|
||||
|
||||
mutable MutexType m_Mutex;
|
||||
|
||||
friend class ObjectLock;
|
||||
};
|
||||
|
||||
|
|
|
@ -21,14 +21,6 @@
|
|||
|
||||
using namespace icinga;
|
||||
|
||||
#ifdef _DEBUG
|
||||
# ifdef _MSC_VER
|
||||
static __declspec(thread) int g_LockCount;
|
||||
# else /* _MSC_VER */
|
||||
static __thread int g_LockCount;
|
||||
# endif /* _MSC_VER */
|
||||
#endif /* _DEBUG */
|
||||
|
||||
ObjectLock::ObjectLock(void)
|
||||
: m_Object(NULL), m_Lock()
|
||||
{ }
|
||||
|
@ -55,19 +47,16 @@ ObjectLock::ObjectLock(const Object *object)
|
|||
void ObjectLock::Lock(void)
|
||||
{
|
||||
assert(!m_Lock.owns_lock() && m_Object != NULL);
|
||||
assert(!m_Object->OwnsLock());
|
||||
|
||||
m_Lock = recursive_mutex::scoped_lock(m_Object->m_Mutex);
|
||||
m_Lock = Object::MutexType::scoped_lock(m_Object->m_Mutex);
|
||||
|
||||
#ifdef _DEBUG
|
||||
{
|
||||
boost::mutex::scoped_lock lock(Object::m_DebugMutex);
|
||||
m_Object->m_LockCount++;
|
||||
m_Object->m_Locked = true;
|
||||
m_Object->m_LockOwner = boost::this_thread::get_id();
|
||||
|
||||
if (m_Object->m_LockCount == 1) {
|
||||
g_LockCount++;
|
||||
m_TS = Utility::GetTime();
|
||||
}
|
||||
m_TS = Utility::GetTime();
|
||||
}
|
||||
#endif /* _DEBUG */
|
||||
}
|
||||
|
@ -79,21 +68,17 @@ void ObjectLock::Unlock(void)
|
|||
boost::mutex::scoped_lock lock(Object::m_DebugMutex);
|
||||
|
||||
if (m_Lock.owns_lock()) {
|
||||
if (m_Object->m_LockCount == 1) {
|
||||
g_LockCount--;
|
||||
double dt = Utility::GetTime() - m_TS;
|
||||
|
||||
double dt = Utility::GetTime() - m_TS;
|
||||
|
||||
if (dt > 0.05) {
|
||||
std::cerr << "Held object lock for " << dt << " seconds at:";
|
||||
Utility::PrintStacktrace(std::cerr);
|
||||
}
|
||||
if (dt > 0.05) {
|
||||
std::cerr << "Held object lock for " << dt << " seconds at:";
|
||||
Utility::PrintStacktrace(std::cerr);
|
||||
}
|
||||
|
||||
m_Object->m_LockCount--;
|
||||
m_Object->m_Locked = false;
|
||||
}
|
||||
}
|
||||
#endif /* _DEBUG */
|
||||
|
||||
m_Lock = recursive_mutex::scoped_lock();
|
||||
m_Lock = Object::MutexType::scoped_lock();
|
||||
}
|
||||
|
|
|
@ -38,7 +38,8 @@ public:
|
|||
|
||||
private:
|
||||
const Object *m_Object;
|
||||
recursive_mutex::scoped_lock m_Lock;
|
||||
Object::MutexType::scoped_lock m_Lock;
|
||||
|
||||
#ifdef _DEBUG
|
||||
double m_TS;
|
||||
#endif /* _DEBUG */
|
||||
|
|
|
@ -68,7 +68,7 @@ String Script::GetCode(void) const
|
|||
/**
|
||||
* @threadsafety Always.
|
||||
*/
|
||||
void Script::OnAttributeUpdate(const String& name, const Value& oldValue)
|
||||
void Script::OnAttributeUpdate(const String& name)
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ public:
|
|||
String GetCode(void) const;
|
||||
|
||||
protected:
|
||||
virtual void OnAttributeUpdate(const String& name, const Value& oldValue);
|
||||
virtual void OnAttributeUpdate(const String& name);
|
||||
|
||||
private:
|
||||
Attribute<String> m_Language;
|
||||
|
|
|
@ -48,8 +48,6 @@ StdioStream::~StdioStream(void)
|
|||
*/
|
||||
void StdioStream::Start(void)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
SetConnected(true);
|
||||
|
||||
Stream::Start();
|
||||
|
@ -120,8 +118,6 @@ void StdioStream::Write(const void *buffer, size_t size)
|
|||
*/
|
||||
void StdioStream::Close(void)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (m_OwnsStream)
|
||||
delete m_InnerStream;
|
||||
|
||||
|
|
|
@ -103,10 +103,12 @@ void Stream::Start(void)
|
|||
*/
|
||||
void Stream::Close(void)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
assert(m_Running);
|
||||
m_Running = false;
|
||||
assert(m_Running);
|
||||
m_Running = false;
|
||||
}
|
||||
|
||||
SetConnected(false);
|
||||
}
|
||||
|
|
|
@ -86,12 +86,16 @@ void Timer::Uninitialize(void)
|
|||
*
|
||||
* @threadsafety Always.
|
||||
*/
|
||||
void Timer::Call(const Timer::Ptr& self)
|
||||
void Timer::Call(void)
|
||||
{
|
||||
self->OnTimerExpired(self);
|
||||
assert(!OwnsLock());
|
||||
|
||||
Timer::Ptr self = GetSelf();
|
||||
|
||||
OnTimerExpired(self);
|
||||
|
||||
/* Re-enable the timer so it can be called again. */
|
||||
self->Start();
|
||||
Start();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -86,7 +86,7 @@ private:
|
|||
static bool m_StopThread;
|
||||
static TimerSet m_Timers;
|
||||
|
||||
static void Call(const Timer::Ptr& self);
|
||||
void Call();
|
||||
|
||||
static void TimerThreadProc(void);
|
||||
|
||||
|
|
|
@ -114,7 +114,6 @@ void ConfigCompilerContext::Validate(void)
|
|||
ConfigType::Ptr ctype;
|
||||
|
||||
{
|
||||
ObjectLock olock(item);
|
||||
ctype = GetType(item->GetType());
|
||||
|
||||
if (!ctype) {
|
||||
|
@ -124,7 +123,6 @@ void ConfigCompilerContext::Validate(void)
|
|||
}
|
||||
}
|
||||
|
||||
ObjectLock olock(ctype);
|
||||
ctype->ValidateItem(item);
|
||||
}
|
||||
|
||||
|
|
|
@ -50,8 +50,6 @@ ConfigItem::ConfigItem(const String& type, const String& name,
|
|||
*/
|
||||
String ConfigItem::GetType(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_Type;
|
||||
}
|
||||
|
||||
|
@ -62,8 +60,6 @@ String ConfigItem::GetType(void) const
|
|||
*/
|
||||
String ConfigItem::GetName(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_Name;
|
||||
}
|
||||
|
||||
|
@ -74,8 +70,6 @@ String ConfigItem::GetName(void) const
|
|||
*/
|
||||
String ConfigItem::GetUnit(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_Unit;
|
||||
}
|
||||
|
||||
|
@ -86,8 +80,6 @@ String ConfigItem::GetUnit(void) const
|
|||
*/
|
||||
DebugInfo ConfigItem::GetDebugInfo(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_DebugInfo;
|
||||
}
|
||||
|
||||
|
@ -98,8 +90,6 @@ DebugInfo ConfigItem::GetDebugInfo(void) const
|
|||
*/
|
||||
ExpressionList::Ptr ConfigItem::GetExpressionList(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_ExpressionList;
|
||||
}
|
||||
|
||||
|
@ -110,18 +100,9 @@ ExpressionList::Ptr ConfigItem::GetExpressionList(void) const
|
|||
*/
|
||||
vector<String> ConfigItem::GetParents(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_Parents;
|
||||
}
|
||||
|
||||
set<ConfigItem::WeakPtr> ConfigItem::GetChildren(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_ChildObjects;
|
||||
}
|
||||
|
||||
Dictionary::Ptr ConfigItem::Link(void) const
|
||||
{
|
||||
Dictionary::Ptr attrs = boost::make_shared<Dictionary>();
|
||||
|
@ -146,12 +127,12 @@ void ConfigItem::InternalLink(const Dictionary::Ptr& dictionary) const
|
|||
ConfigCompilerContext *context = ConfigCompilerContext::GetContext();
|
||||
|
||||
if (context)
|
||||
parent = context->GetItem(GetType(), name);
|
||||
parent = context->GetItem(m_Type, 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);
|
||||
parent = ConfigItem::GetObject(m_Type, name);
|
||||
|
||||
if (!parent) {
|
||||
stringstream message;
|
||||
|
@ -160,7 +141,6 @@ void ConfigItem::InternalLink(const Dictionary::Ptr& dictionary) const
|
|||
BOOST_THROW_EXCEPTION(domain_error(message.str()));
|
||||
}
|
||||
|
||||
ObjectLock olock(parent);
|
||||
parent->InternalLink(dictionary);
|
||||
}
|
||||
|
||||
|
@ -209,7 +189,7 @@ DynamicObject::Ptr ConfigItem::Commit(void)
|
|||
oldItem->UnregisterFromParents();
|
||||
|
||||
/* Steal the old item's children. */
|
||||
children = oldItem->GetChildren();
|
||||
children = oldItem->m_ChildObjects;
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -226,15 +206,15 @@ DynamicObject::Ptr ConfigItem::Commit(void)
|
|||
m_Items[ikey] = self;
|
||||
}
|
||||
|
||||
DynamicObject::Ptr dobj = GetDynamicObject();
|
||||
DynamicObject::Ptr dobj = m_DynamicObject.lock();
|
||||
|
||||
if (!dobj)
|
||||
dobj = dtype->GetObject(GetName());
|
||||
dobj = dtype->GetObject(m_Name);
|
||||
|
||||
/* Register this item with its parents. */
|
||||
BOOST_FOREACH(const String& parentName, GetParents()) {
|
||||
ConfigItem::Ptr parent = GetObject(GetType(), parentName);
|
||||
parent->RegisterChild(self);
|
||||
BOOST_FOREACH(const String& parentName, m_Parents) {
|
||||
ConfigItem::Ptr parent = GetObject(m_Type, parentName);
|
||||
parent->m_ChildObjects.insert(self);
|
||||
}
|
||||
|
||||
/* Create a fake update in the format that
|
||||
|
@ -272,7 +252,7 @@ DynamicObject::Ptr ConfigItem::Commit(void)
|
|||
bool was_null = false;
|
||||
|
||||
if (!dobj) {
|
||||
dobj = DynamicType::CreateObject(dtype, update);
|
||||
dobj = dtype->CreateObject(update);
|
||||
was_null = true;
|
||||
}
|
||||
|
||||
|
@ -300,7 +280,7 @@ DynamicObject::Ptr ConfigItem::Commit(void)
|
|||
child->OnParentCommitted();
|
||||
}
|
||||
|
||||
OnCommitted(GetSelf());
|
||||
OnCommitted(self);
|
||||
|
||||
return dobj;
|
||||
}
|
||||
|
@ -312,7 +292,7 @@ void ConfigItem::Unregister(void)
|
|||
{
|
||||
assert(!OwnsLock());
|
||||
|
||||
DynamicObject::Ptr dobj = GetDynamicObject();
|
||||
DynamicObject::Ptr dobj = m_DynamicObject.lock();
|
||||
|
||||
if (dobj)
|
||||
dobj->Unregister();
|
||||
|
@ -321,40 +301,26 @@ void ConfigItem::Unregister(void)
|
|||
ObjectLock olock(this);
|
||||
|
||||
ConfigItem::ItemMap::iterator it;
|
||||
it = m_Items.find(make_pair(GetType(), GetName()));
|
||||
it = m_Items.find(make_pair(m_Type, m_Name));
|
||||
|
||||
if (it != m_Items.end())
|
||||
m_Items.erase(it);
|
||||
}
|
||||
|
||||
UnregisterFromParents();
|
||||
UnregisterFromParents();
|
||||
}
|
||||
|
||||
OnRemoved(GetSelf());
|
||||
}
|
||||
|
||||
void ConfigItem::RegisterChild(const ConfigItem::Ptr& child)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_ChildObjects.insert(child);
|
||||
}
|
||||
|
||||
void ConfigItem::UnregisterChild(const ConfigItem::Ptr& child)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_ChildObjects.erase(child);
|
||||
}
|
||||
|
||||
void ConfigItem::UnregisterFromParents(void)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
assert(OwnsLock());
|
||||
|
||||
BOOST_FOREACH(const String& parentName, m_Parents) {
|
||||
ConfigItem::Ptr parent = GetObject(GetType(), parentName);
|
||||
|
||||
if (parent)
|
||||
parent->UnregisterChild(GetSelf());
|
||||
parent->m_ChildObjects.erase(GetSelf());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -365,15 +331,10 @@ void ConfigItem::OnParentCommitted(void)
|
|||
{
|
||||
assert(!OwnsLock());
|
||||
|
||||
ConfigItem::Ptr self;
|
||||
ConfigItem::Ptr self = GetSelf();
|
||||
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
self = GetSelf();
|
||||
|
||||
if (GetObject(self->GetType(), self->GetName()) != self)
|
||||
return;
|
||||
}
|
||||
if (GetObject(m_Type, m_Name) != self)
|
||||
return;
|
||||
|
||||
Commit();
|
||||
}
|
||||
|
@ -458,7 +419,7 @@ void ConfigItem::UnloadUnit(const String& unit)
|
|||
BOOST_FOREACH(tie(tuples::ignore, item), m_Items) {
|
||||
ObjectLock olock(item);
|
||||
|
||||
if (item->GetUnit() != unit)
|
||||
if (item->m_Unit != unit)
|
||||
continue;
|
||||
|
||||
obsoleteItems.push_back(item);
|
||||
|
|
|
@ -43,7 +43,6 @@ public:
|
|||
String GetUnit(void) const;
|
||||
|
||||
vector<String> GetParents(void) const;
|
||||
set<ConfigItem::WeakPtr> GetChildren(void) const;
|
||||
|
||||
ExpressionList::Ptr GetExpressionList(void) const;
|
||||
|
||||
|
@ -69,8 +68,6 @@ public:
|
|||
private:
|
||||
void InternalLink(const Dictionary::Ptr& dictionary) const;
|
||||
|
||||
void RegisterChild(const ConfigItem::Ptr& child);
|
||||
void UnregisterChild(const ConfigItem::Ptr& child);
|
||||
void UnregisterFromParents(void);
|
||||
|
||||
void OnParentCommitted(void);
|
||||
|
|
|
@ -52,24 +52,14 @@ DebugInfo ConfigType::GetDebugInfo(void) const
|
|||
|
||||
void ConfigType::ValidateItem(const ConfigItem::Ptr& item) const
|
||||
{
|
||||
String type, name;
|
||||
Dictionary::Ptr attrs;
|
||||
|
||||
{
|
||||
ObjectLock olock(item);
|
||||
attrs = item->Link();
|
||||
type = item->GetType();
|
||||
name = item->GetName();
|
||||
}
|
||||
|
||||
ObjectLock olock(attrs);
|
||||
Dictionary::Ptr attrs = item->Link();
|
||||
|
||||
/* Don't validate abstract items. */
|
||||
if (attrs->Get("__abstract"))
|
||||
return;
|
||||
|
||||
vector<String> locations;
|
||||
locations.push_back("Object '" + name + "' (Type: '" + type + "')");
|
||||
locations.push_back("Object '" + item->GetName() + "' (Type: '" + item->GetType() + "')");
|
||||
|
||||
ConfigType::Ptr parent;
|
||||
if (m_Parent.IsEmpty()) {
|
||||
|
|
|
@ -54,7 +54,6 @@ void Expression::Execute(const Dictionary::Ptr& dictionary) const
|
|||
|
||||
case OperatorSet:
|
||||
if (valueExprl) {
|
||||
ObjectLock olock(valueExprl);
|
||||
dict = boost::make_shared<Dictionary>();
|
||||
valueExprl->Execute(dict);
|
||||
newValue = dict;
|
||||
|
@ -63,10 +62,7 @@ void Expression::Execute(const Dictionary::Ptr& dictionary) const
|
|||
break;
|
||||
|
||||
case OperatorPlus:
|
||||
{
|
||||
ObjectLock olock(dictionary);
|
||||
oldValue = dictionary->Get(m_Key);
|
||||
}
|
||||
oldValue = dictionary->Get(m_Key);
|
||||
|
||||
if (oldValue.IsObjectType<Dictionary>())
|
||||
dict = oldValue;
|
||||
|
@ -87,12 +83,9 @@ void Expression::Execute(const Dictionary::Ptr& dictionary) const
|
|||
newValue = dict;
|
||||
|
||||
if (valueExprl) {
|
||||
ObjectLock olock(valueExprl);
|
||||
|
||||
valueExprl->Execute(dict);
|
||||
} else if (valueDict) {
|
||||
ObjectLock olock(valueDict);
|
||||
ObjectLock dlock(dict);
|
||||
|
||||
String key;
|
||||
Value value;
|
||||
|
@ -112,7 +105,6 @@ void Expression::Execute(const Dictionary::Ptr& dictionary) const
|
|||
BOOST_THROW_EXCEPTION(runtime_error("Not yet implemented."));
|
||||
}
|
||||
|
||||
ObjectLock olock(dictionary);
|
||||
if (m_Key.IsEmpty())
|
||||
dictionary->Add(newValue);
|
||||
else
|
||||
|
|
|
@ -65,8 +65,6 @@ void Host::OnRegistrationCompleted(void)
|
|||
|
||||
String Host::GetDisplayName(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (!m_DisplayName.IsEmpty())
|
||||
return m_DisplayName;
|
||||
else
|
||||
|
@ -85,36 +83,26 @@ Host::Ptr Host::GetByName(const String& name)
|
|||
|
||||
Dictionary::Ptr Host::GetGroups(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_HostGroups;;
|
||||
}
|
||||
|
||||
Dictionary::Ptr Host::GetMacros(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_Macros;
|
||||
}
|
||||
|
||||
Dictionary::Ptr Host::GetHostDependencies(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_HostDependencies;;
|
||||
}
|
||||
|
||||
Dictionary::Ptr Host::GetServiceDependencies(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_ServiceDependencies;
|
||||
}
|
||||
|
||||
String Host::GetHostCheck(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_HostCheck;
|
||||
}
|
||||
|
||||
|
@ -154,6 +142,10 @@ bool Host::IsReachable(void) const
|
|||
|
||||
ObjectLock olock(hc);
|
||||
|
||||
/* ignore soft states */
|
||||
if (hc->GetStateType() == StateTypeSoft)
|
||||
continue;
|
||||
|
||||
/* ignore hosts that are up */
|
||||
if (hc->GetState() == StateOK)
|
||||
continue;
|
||||
|
@ -167,8 +159,6 @@ bool Host::IsReachable(void) const
|
|||
template<bool copyServiceAttrs, typename TDict>
|
||||
static void CopyServiceAttributes(TDict serviceDesc, const ConfigItemBuilder::Ptr& builder)
|
||||
{
|
||||
ObjectLock olock(serviceDesc);
|
||||
|
||||
/* TODO: we only need to copy macros if this is an inline definition,
|
||||
* i.e. "typeid(serviceDesc)" != Service, however for now we just
|
||||
* copy them anyway. */
|
||||
|
@ -253,12 +243,7 @@ void Host::UpdateSlaveServices(void)
|
|||
} else if (svcdesc.IsObjectType<Dictionary>()) {
|
||||
Dictionary::Ptr service = svcdesc;
|
||||
|
||||
Dictionary::Ptr templates;
|
||||
|
||||
{
|
||||
ObjectLock olock(service);
|
||||
templates = service->Get("templates");
|
||||
}
|
||||
Dictionary::Ptr templates = service->Get("templates");
|
||||
|
||||
if (templates) {
|
||||
ObjectLock olock(templates);
|
||||
|
@ -298,11 +283,10 @@ void Host::UpdateSlaveServices(void)
|
|||
|
||||
newServices->Seal();
|
||||
|
||||
ObjectLock olock(this);
|
||||
Set("slave_services", newServices);
|
||||
}
|
||||
|
||||
void Host::OnAttributeChanged(const String& name, const Value&)
|
||||
void Host::OnAttributeChanged(const String& name)
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
|
||||
|
@ -311,15 +295,8 @@ void Host::OnAttributeChanged(const String& name, const Value&)
|
|||
else if (name == "services") {
|
||||
UpdateSlaveServices();
|
||||
} else if (name == "notifications") {
|
||||
set<Service::Ptr> services;
|
||||
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
services = GetServices();
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const Service::Ptr& service, services) {
|
||||
Service::UpdateSlaveNotifications(service);
|
||||
BOOST_FOREACH(const Service::Ptr& service, GetServices()) {
|
||||
service->UpdateSlaveNotifications();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -371,28 +348,14 @@ void Host::RefreshServicesCache(void)
|
|||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
|
||||
const Service::Ptr& service = static_pointer_cast<Service>(object);
|
||||
|
||||
Host::Ptr host;
|
||||
String short_name;
|
||||
|
||||
{
|
||||
ObjectLock olock(service);
|
||||
host = service->GetHost();
|
||||
short_name = service->GetShortName();
|
||||
}
|
||||
Host::Ptr host = service->GetHost();
|
||||
|
||||
if (!host)
|
||||
continue;
|
||||
|
||||
String host_name;
|
||||
|
||||
{
|
||||
ObjectLock olock(host);
|
||||
host_name = host->GetName();
|
||||
}
|
||||
|
||||
// TODO: assert for duplicate short_names
|
||||
|
||||
newServicesCache[host_name][short_name] = service;
|
||||
newServicesCache[host->GetName()][service->GetShortName()] = service;
|
||||
}
|
||||
|
||||
boost::mutex::scoped_lock lock(m_ServiceMutex);
|
||||
|
@ -538,15 +501,10 @@ Dictionary::Ptr Host::CalculateDynamicMacros(void) const
|
|||
assert(!OwnsLock());
|
||||
|
||||
Dictionary::Ptr macros = boost::make_shared<Dictionary>();
|
||||
ObjectLock mlock(macros);
|
||||
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
macros->Set("HOSTNAME", GetName());
|
||||
macros->Set("HOSTDISPLAYNAME", GetDisplayName());
|
||||
macros->Set("HOSTALIAS", GetName());
|
||||
}
|
||||
macros->Set("HOSTNAME", GetName());
|
||||
macros->Set("HOSTDISPLAYNAME", GetDisplayName());
|
||||
macros->Set("HOSTALIAS", GetName());
|
||||
|
||||
Dictionary::Ptr cr;
|
||||
|
||||
|
@ -588,8 +546,6 @@ Dictionary::Ptr Host::CalculateDynamicMacros(void) const
|
|||
macros->Set("HOSTLATENCY", Service::CalculateLatency(cr));
|
||||
macros->Set("HOSTEXECUTIONTIME", Service::CalculateExecutionTime(cr));
|
||||
|
||||
ObjectLock olock(cr);
|
||||
|
||||
macros->Set("HOSTOUTPUT", cr->Get("output"));
|
||||
macros->Set("HOSTPERFDATA", cr->Get("performance_data_raw"));
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ public:
|
|||
|
||||
protected:
|
||||
virtual void OnRegistrationCompleted(void);
|
||||
virtual void OnAttributeChanged(const String& name, const Value& oldValue);
|
||||
virtual void OnAttributeChanged(const String& name);
|
||||
|
||||
private:
|
||||
Attribute<String> m_DisplayName;
|
||||
|
|
|
@ -55,8 +55,6 @@ void HostGroup::OnRegistrationCompleted(void)
|
|||
*/
|
||||
String HostGroup::GetDisplayName(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (!m_DisplayName.IsEmpty())
|
||||
return m_DisplayName;
|
||||
else
|
||||
|
@ -68,8 +66,6 @@ String HostGroup::GetDisplayName(void) const
|
|||
*/
|
||||
String HostGroup::GetNotesUrl(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_NotesUrl;
|
||||
}
|
||||
|
||||
|
@ -78,8 +74,6 @@ String HostGroup::GetNotesUrl(void) const
|
|||
*/
|
||||
String HostGroup::GetActionUrl(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_ActionUrl;
|
||||
}
|
||||
|
||||
|
@ -150,7 +144,6 @@ void HostGroup::RefreshMembersCache(void)
|
|||
|
||||
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();
|
||||
|
|
|
@ -215,7 +215,6 @@ shared_ptr<SSL_CTX> IcingaApplication::GetSSLContext(void) const
|
|||
Dictionary::Ptr IcingaApplication::CalculateDynamicMacros(void)
|
||||
{
|
||||
Dictionary::Ptr macros = boost::make_shared<Dictionary>();
|
||||
ObjectLock mlock(macros);
|
||||
|
||||
double now = Utility::GetTime();
|
||||
|
||||
|
|
|
@ -56,8 +56,6 @@ Value MacroProcessor::ResolveMacros(const Value& cmd, const Dictionary::Ptr& mac
|
|||
*/
|
||||
String MacroProcessor::InternalResolveMacros(const String& str, const Dictionary::Ptr& macros)
|
||||
{
|
||||
ObjectLock olock(macros);
|
||||
|
||||
size_t offset, pos_first, pos_second;
|
||||
offset = 0;
|
||||
|
||||
|
|
|
@ -54,8 +54,6 @@ Notification::Ptr Notification::GetByName(const String& name)
|
|||
*/
|
||||
Service::Ptr Notification::GetService(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
Host::Ptr host = Host::GetByName(m_HostName);
|
||||
|
||||
if (!host)
|
||||
|
@ -72,8 +70,6 @@ Service::Ptr Notification::GetService(void) const
|
|||
*/
|
||||
Value Notification::GetNotificationCommand(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_NotificationCommand;
|
||||
}
|
||||
|
||||
|
@ -82,8 +78,6 @@ Value Notification::GetNotificationCommand(void) const
|
|||
*/
|
||||
Dictionary::Ptr Notification::GetMacros(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_Macros;
|
||||
}
|
||||
|
||||
|
@ -94,12 +88,7 @@ set<User::Ptr> Notification::GetUsers(void) const
|
|||
{
|
||||
set<User::Ptr> result;
|
||||
|
||||
Dictionary::Ptr users;
|
||||
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
users = m_Users;
|
||||
}
|
||||
Dictionary::Ptr users = m_Users;
|
||||
|
||||
if (users) {
|
||||
ObjectLock olock(users);
|
||||
|
@ -125,12 +114,7 @@ set<UserGroup::Ptr> Notification::GetGroups(void) const
|
|||
{
|
||||
set<UserGroup::Ptr> result;
|
||||
|
||||
Dictionary::Ptr groups;
|
||||
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
groups = m_Groups;
|
||||
}
|
||||
Dictionary::Ptr groups = m_Groups;
|
||||
|
||||
if (groups) {
|
||||
ObjectLock olock(groups);
|
||||
|
@ -221,14 +205,7 @@ void Notification::BeginExecuteNotification(NotificationType type)
|
|||
}
|
||||
|
||||
BOOST_FOREACH(const User::Ptr& user, allUsers) {
|
||||
String user_name;
|
||||
|
||||
{
|
||||
ObjectLock olock(user);
|
||||
user_name = user->GetName();
|
||||
}
|
||||
|
||||
Logger::Write(LogDebug, "icinga", "Sending notification for user " + user_name);
|
||||
Logger::Write(LogDebug, "icinga", "Sending notification for user " + user->GetName());
|
||||
BeginExecuteNotificationHelper(macros, type, user);
|
||||
}
|
||||
|
||||
|
@ -289,7 +266,11 @@ void Notification::NotificationCompletedHandler(const ScriptTask::Ptr& task)
|
|||
{
|
||||
assert(!OwnsLock());
|
||||
|
||||
m_Tasks.erase(task);
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_Tasks.erase(task);
|
||||
}
|
||||
|
||||
try {
|
||||
task->GetResult();
|
||||
|
@ -308,7 +289,7 @@ void Notification::NotificationCompletedHandler(const ScriptTask::Ptr& task)
|
|||
/**
|
||||
* @threadsafety Always.
|
||||
*/
|
||||
void Notification::OnAttributeChanged(const String& name, const Value& oldValue)
|
||||
void Notification::OnAttributeChanged(const String& name)
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ public:
|
|||
static String NotificationTypeToString(NotificationType type);
|
||||
|
||||
protected:
|
||||
void OnAttributeChanged(const String& name, const Value& oldValue);
|
||||
void OnAttributeChanged(const String& name);
|
||||
|
||||
private:
|
||||
Attribute<Value> m_NotificationCommand;
|
||||
|
|
|
@ -38,12 +38,11 @@ PerfdataWriter::~PerfdataWriter(void)
|
|||
/**
|
||||
* @threadsafety Always.
|
||||
*/
|
||||
void PerfdataWriter::OnAttributeChanged(const String& name, const Value& oldValue)
|
||||
void PerfdataWriter::OnAttributeChanged(const String& name)
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
|
||||
if (name == "rotation_interval") {
|
||||
ObjectLock olock(this);
|
||||
m_RotationTimer->SetInterval(GetRotationInterval());
|
||||
}
|
||||
}
|
||||
|
@ -53,16 +52,9 @@ void PerfdataWriter::OnAttributeChanged(const String& name, const Value& oldValu
|
|||
*/
|
||||
void PerfdataWriter::Start(void)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_Endpoint = Endpoint::MakeEndpoint("perfdata_" + GetName(), false);
|
||||
|
||||
{
|
||||
ObjectLock olock(m_Endpoint);
|
||||
|
||||
m_Endpoint->RegisterTopicHandler("checker::CheckResult",
|
||||
boost::bind(&PerfdataWriter::CheckResultRequestHandler, this, _3));
|
||||
}
|
||||
m_Endpoint->RegisterTopicHandler("checker::CheckResult",
|
||||
boost::bind(&PerfdataWriter::CheckResultRequestHandler, this, _3));
|
||||
|
||||
m_RotationTimer = boost::make_shared<Timer>();
|
||||
m_RotationTimer->OnTimerExpired.connect(boost::bind(&PerfdataWriter::RotationTimerHandler, this));
|
||||
|
@ -87,8 +79,6 @@ PerfdataWriter::Ptr PerfdataWriter::GetByName(const String& name)
|
|||
*/
|
||||
String PerfdataWriter::GetPathPrefix(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (!m_PathPrefix.IsEmpty())
|
||||
return m_PathPrefix;
|
||||
else
|
||||
|
@ -100,8 +90,6 @@ String PerfdataWriter::GetPathPrefix(void) const
|
|||
*/
|
||||
String PerfdataWriter::GetFormatTemplate(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (!m_FormatTemplate.IsEmpty()) {
|
||||
return m_FormatTemplate;
|
||||
} else {
|
||||
|
@ -123,8 +111,6 @@ String PerfdataWriter::GetFormatTemplate(void) const
|
|||
*/
|
||||
double PerfdataWriter::GetRotationInterval(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (!m_RotationInterval.IsEmpty())
|
||||
return m_RotationInterval;
|
||||
else
|
||||
|
|
|
@ -44,7 +44,7 @@ public:
|
|||
double GetRotationInterval(void) const;
|
||||
|
||||
protected:
|
||||
virtual void OnAttributeChanged(const String& name, const Value& oldValue);
|
||||
virtual void OnAttributeChanged(const String& name);
|
||||
virtual void Start(void);
|
||||
|
||||
private:
|
||||
|
|
|
@ -25,16 +25,14 @@ const int Service::DefaultMaxCheckAttempts = 3;
|
|||
const int Service::DefaultCheckInterval = 5 * 60;
|
||||
const int Service::CheckIntervalDivisor = 5;
|
||||
|
||||
signals2::signal<void (const Service::Ptr&, const String&)> Service::OnCheckerChanged;
|
||||
signals2::signal<void (const Service::Ptr&, const Value&)> Service::OnNextCheckChanged;
|
||||
signals2::signal<void (const Service::Ptr&)> Service::OnCheckerChanged;
|
||||
signals2::signal<void (const Service::Ptr&)> Service::OnNextCheckChanged;
|
||||
|
||||
/**
|
||||
* @threadsafety Always.
|
||||
*/
|
||||
Value Service::GetCheckCommand(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_CheckCommand;
|
||||
}
|
||||
|
||||
|
@ -43,8 +41,6 @@ Value Service::GetCheckCommand(void) const
|
|||
*/
|
||||
long Service::GetMaxCheckAttempts(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (m_MaxCheckAttempts.IsEmpty())
|
||||
return DefaultMaxCheckAttempts;
|
||||
|
||||
|
@ -56,8 +52,6 @@ long Service::GetMaxCheckAttempts(void) const
|
|||
*/
|
||||
double Service::GetCheckInterval(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (m_CheckInterval.IsEmpty())
|
||||
return DefaultCheckInterval;
|
||||
|
||||
|
@ -69,8 +63,6 @@ double Service::GetCheckInterval(void) const
|
|||
*/
|
||||
double Service::GetRetryInterval(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (m_RetryInterval.IsEmpty())
|
||||
return GetCheckInterval() / CheckIntervalDivisor;
|
||||
|
||||
|
@ -82,8 +74,6 @@ double Service::GetRetryInterval(void) const
|
|||
*/
|
||||
Dictionary::Ptr Service::GetCheckers(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_Checkers;
|
||||
}
|
||||
|
||||
|
@ -92,8 +82,6 @@ Dictionary::Ptr Service::GetCheckers(void) const
|
|||
*/
|
||||
void Service::SetSchedulingOffset(long offset)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_SchedulingOffset = offset;
|
||||
}
|
||||
|
||||
|
@ -102,8 +90,6 @@ void Service::SetSchedulingOffset(long offset)
|
|||
*/
|
||||
long Service::GetSchedulingOffset(void)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_SchedulingOffset;
|
||||
}
|
||||
|
||||
|
@ -112,8 +98,6 @@ long Service::GetSchedulingOffset(void)
|
|||
*/
|
||||
void Service::SetNextCheck(double nextCheck)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_NextCheck = nextCheck;
|
||||
Touch("next_check");
|
||||
}
|
||||
|
@ -123,15 +107,6 @@ void Service::SetNextCheck(double nextCheck)
|
|||
*/
|
||||
double Service::GetNextCheck(void)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (m_NextCheck.IsEmpty()) {
|
||||
UpdateNextCheck();
|
||||
|
||||
if (m_NextCheck.IsEmpty())
|
||||
BOOST_THROW_EXCEPTION(runtime_error("Failed to schedule next check."));
|
||||
}
|
||||
|
||||
return m_NextCheck;
|
||||
}
|
||||
|
||||
|
@ -163,8 +138,6 @@ void Service::UpdateNextCheck(void)
|
|||
*/
|
||||
void Service::SetCurrentChecker(const String& checker)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_CurrentChecker = checker;
|
||||
Touch("current_checker");
|
||||
}
|
||||
|
@ -174,8 +147,6 @@ void Service::SetCurrentChecker(const String& checker)
|
|||
*/
|
||||
String Service::GetCurrentChecker(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_CurrentChecker;
|
||||
}
|
||||
|
||||
|
@ -184,8 +155,6 @@ String Service::GetCurrentChecker(void) const
|
|||
*/
|
||||
void Service::SetCurrentCheckAttempt(long attempt)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_CheckAttempt = attempt;
|
||||
Touch("check_attempt");
|
||||
}
|
||||
|
@ -195,8 +164,6 @@ void Service::SetCurrentCheckAttempt(long attempt)
|
|||
*/
|
||||
long Service::GetCurrentCheckAttempt(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (m_CheckAttempt.IsEmpty())
|
||||
return 1;
|
||||
|
||||
|
@ -208,8 +175,6 @@ long Service::GetCurrentCheckAttempt(void) const
|
|||
*/
|
||||
void Service::SetState(ServiceState state)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_State = static_cast<long>(state);
|
||||
Touch("state");
|
||||
}
|
||||
|
@ -219,8 +184,6 @@ void Service::SetState(ServiceState state)
|
|||
*/
|
||||
ServiceState Service::GetState(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (m_State.IsEmpty())
|
||||
return StateUnknown;
|
||||
|
||||
|
@ -233,8 +196,6 @@ ServiceState Service::GetState(void) const
|
|||
*/
|
||||
void Service::SetStateType(ServiceStateType type)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_StateType = static_cast<long>(type);
|
||||
Touch("state_type");
|
||||
}
|
||||
|
@ -244,8 +205,6 @@ void Service::SetStateType(ServiceStateType type)
|
|||
*/
|
||||
ServiceStateType Service::GetStateType(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (m_StateType.IsEmpty())
|
||||
return StateTypeSoft;
|
||||
|
||||
|
@ -258,8 +217,6 @@ ServiceStateType Service::GetStateType(void) const
|
|||
*/
|
||||
void Service::SetLastCheckResult(const Dictionary::Ptr& result)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_LastResult = result;
|
||||
Touch("last_result");
|
||||
}
|
||||
|
@ -269,8 +226,6 @@ void Service::SetLastCheckResult(const Dictionary::Ptr& result)
|
|||
*/
|
||||
Dictionary::Ptr Service::GetLastCheckResult(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_LastResult;
|
||||
}
|
||||
|
||||
|
@ -279,8 +234,6 @@ Dictionary::Ptr Service::GetLastCheckResult(void) const
|
|||
*/
|
||||
void Service::SetLastStateChange(double ts)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_LastStateChange = ts;
|
||||
Touch("last_state_change");
|
||||
}
|
||||
|
@ -290,8 +243,6 @@ void Service::SetLastStateChange(double ts)
|
|||
*/
|
||||
double Service::GetLastStateChange(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (m_LastStateChange.IsEmpty())
|
||||
return IcingaApplication::GetInstance()->GetStartTime();
|
||||
|
||||
|
@ -303,8 +254,6 @@ double Service::GetLastStateChange(void) const
|
|||
*/
|
||||
void Service::SetLastHardStateChange(double ts)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_LastHardStateChange = ts;
|
||||
Touch("last_hard_state_change");
|
||||
}
|
||||
|
@ -314,8 +263,6 @@ void Service::SetLastHardStateChange(double ts)
|
|||
*/
|
||||
double Service::GetLastHardStateChange(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (m_LastHardStateChange.IsEmpty())
|
||||
return IcingaApplication::GetInstance()->GetStartTime();
|
||||
|
||||
|
@ -327,8 +274,6 @@ double Service::GetLastHardStateChange(void) const
|
|||
*/
|
||||
bool Service::GetEnableActiveChecks(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (m_EnableActiveChecks.IsEmpty())
|
||||
return true;
|
||||
else
|
||||
|
@ -340,8 +285,6 @@ bool Service::GetEnableActiveChecks(void) const
|
|||
*/
|
||||
void Service::SetEnableActiveChecks(bool enabled)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_EnableActiveChecks = enabled ? 1 : 0;
|
||||
Touch("enable_active_checks");
|
||||
}
|
||||
|
@ -351,8 +294,6 @@ void Service::SetEnableActiveChecks(bool enabled)
|
|||
*/
|
||||
bool Service::GetEnablePassiveChecks(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (m_EnablePassiveChecks.IsEmpty())
|
||||
return true;
|
||||
else
|
||||
|
@ -364,8 +305,6 @@ bool Service::GetEnablePassiveChecks(void) const
|
|||
*/
|
||||
void Service::SetEnablePassiveChecks(bool enabled)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_EnablePassiveChecks = enabled ? 1 : 0;
|
||||
Touch("enable_passive_checks");
|
||||
}
|
||||
|
@ -375,8 +314,6 @@ void Service::SetEnablePassiveChecks(bool enabled)
|
|||
*/
|
||||
bool Service::GetForceNextCheck(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (m_ForceNextCheck.IsEmpty())
|
||||
return false;
|
||||
|
||||
|
@ -388,8 +325,6 @@ bool Service::GetForceNextCheck(void) const
|
|||
*/
|
||||
void Service::SetForceNextCheck(bool forced)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_ForceNextCheck = forced ? 1 : 0;
|
||||
Touch("force_next_check");
|
||||
}
|
||||
|
@ -455,6 +390,7 @@ void Service::ProcessCheckResult(const Dictionary::Ptr& cr)
|
|||
|
||||
/* reschedule service dependencies */
|
||||
BOOST_FOREACH(const Service::Ptr& parent, GetParentServices()) {
|
||||
ObjectLock olock(parent);
|
||||
parent->SetNextCheck(Utility::GetTime());
|
||||
}
|
||||
|
||||
|
@ -462,7 +398,7 @@ void Service::ProcessCheckResult(const Dictionary::Ptr& cr)
|
|||
BOOST_FOREACH(const Host::Ptr& parent, GetParentHosts()) {
|
||||
Service::Ptr service = parent->GetHostCheckService();
|
||||
|
||||
if (service) {
|
||||
if (service && service->GetName() != GetName()) {
|
||||
ObjectLock olock(service);
|
||||
service->SetNextCheck(Utility::GetTime());
|
||||
}
|
||||
|
@ -582,13 +518,14 @@ bool Service::IsAllowedChecker(const String& checker) const
|
|||
/**
|
||||
* @threadsafety Always.
|
||||
*/
|
||||
void Service::BeginExecuteCheck(const Service::Ptr& self, const function<void (void)>& callback)
|
||||
void Service::BeginExecuteCheck(const function<void (void)>& callback)
|
||||
{
|
||||
ObjectLock slock(self);
|
||||
assert(!OwnsLock());
|
||||
ObjectLock olock(this);
|
||||
|
||||
/* don't run another check if there is one pending */
|
||||
if (self->m_CurrentTask) {
|
||||
slock.Unlock();
|
||||
if (m_CurrentTask) {
|
||||
olock.Unlock();
|
||||
|
||||
/* we need to call the callback anyway */
|
||||
callback();
|
||||
|
@ -598,18 +535,19 @@ void Service::BeginExecuteCheck(const Service::Ptr& self, const function<void (v
|
|||
|
||||
/* keep track of scheduling info in case the check type doesn't provide its own information */
|
||||
Dictionary::Ptr checkInfo = boost::make_shared<Dictionary>();
|
||||
checkInfo->Set("schedule_start", self->GetNextCheck());
|
||||
checkInfo->Set("schedule_start", GetNextCheck());
|
||||
checkInfo->Set("execution_start", Utility::GetTime());
|
||||
|
||||
vector<Dictionary::Ptr> macroDicts;
|
||||
macroDicts.push_back(self->GetMacros());
|
||||
macroDicts.push_back(self->CalculateDynamicMacros());
|
||||
macroDicts.push_back(GetMacros());
|
||||
|
||||
Value raw_command = self->GetCheckCommand();
|
||||
Value raw_command = GetCheckCommand();
|
||||
|
||||
Host::Ptr host = self->GetHost();
|
||||
Host::Ptr host = GetHost();
|
||||
|
||||
slock.Unlock();
|
||||
olock.Unlock();
|
||||
|
||||
macroDicts.push_back(CalculateDynamicMacros());
|
||||
|
||||
macroDicts.push_back(host->GetMacros());
|
||||
macroDicts.push_back(host->CalculateDynamicMacros());
|
||||
|
@ -623,15 +561,16 @@ void Service::BeginExecuteCheck(const Service::Ptr& self, const function<void (v
|
|||
|
||||
checkInfo->Set("macros", macros);
|
||||
|
||||
Service::Ptr self = GetSelf();
|
||||
|
||||
vector<Value> arguments;
|
||||
arguments.push_back(self);
|
||||
arguments.push_back(macros);
|
||||
|
||||
ScriptTask::Ptr task;
|
||||
ScriptTask::Ptr task = MakeMethodTask("check", arguments);
|
||||
|
||||
{
|
||||
ObjectLock olock(self);
|
||||
task = self->MakeMethodTask("check", arguments);
|
||||
ObjectLock slock(this);
|
||||
self->m_CurrentTask = task;
|
||||
}
|
||||
|
||||
|
@ -691,8 +630,6 @@ void Service::CheckCompletedHandler(const Dictionary::Ptr& checkInfo,
|
|||
|
||||
if (!result->Contains("current_checker")) {
|
||||
EndpointManager::Ptr em = EndpointManager::GetInstance();
|
||||
ObjectLock olock(em);
|
||||
|
||||
result->Set("current_checker", em->GetIdentity());
|
||||
}
|
||||
|
||||
|
@ -768,5 +705,4 @@ double Service::CalculateLatency(const Dictionary::Ptr& cr)
|
|||
}
|
||||
|
||||
return (schedule_end - schedule_start) - CalculateExecutionTime(cr);
|
||||
|
||||
}
|
||||
|
|
|
@ -43,8 +43,6 @@ int Service::GetNextCommentID(void)
|
|||
*/
|
||||
Dictionary::Ptr Service::GetComments(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_Comments;
|
||||
}
|
||||
|
||||
|
@ -70,17 +68,22 @@ String Service::AddComment(CommentType entryType, const String& author,
|
|||
|
||||
comment->Set("legacy_id", legacy_id);
|
||||
|
||||
ObjectLock olock(this);
|
||||
Dictionary::Ptr comments;
|
||||
|
||||
Dictionary::Ptr comments = GetComments();
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (!comments)
|
||||
comments = boost::make_shared<Dictionary>();
|
||||
comments = GetComments();
|
||||
|
||||
if (!comments)
|
||||
comments = boost::make_shared<Dictionary>();
|
||||
|
||||
m_Comments = comments;
|
||||
}
|
||||
|
||||
String id = Utility::NewUUID();
|
||||
comments->Set(id, comment);
|
||||
|
||||
m_Comments = comments;
|
||||
Touch("comments");
|
||||
|
||||
return id;
|
||||
|
@ -91,8 +94,6 @@ String Service::AddComment(CommentType entryType, const String& author,
|
|||
*/
|
||||
void Service::RemoveAllComments(void)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_Comments = Empty;
|
||||
Touch("comments");
|
||||
}
|
||||
|
@ -107,8 +108,6 @@ void Service::RemoveComment(const String& id)
|
|||
if (!owner)
|
||||
return;
|
||||
|
||||
ObjectLock olock(owner);
|
||||
|
||||
Dictionary::Ptr comments = owner->GetComments();
|
||||
|
||||
if (comments) {
|
||||
|
@ -203,12 +202,7 @@ void Service::RefreshCommentsCache(void)
|
|||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
|
||||
Service::Ptr service = dynamic_pointer_cast<Service>(object);
|
||||
|
||||
Dictionary::Ptr comments;
|
||||
|
||||
{
|
||||
ObjectLock olock(service);
|
||||
comments = service->GetComments();
|
||||
}
|
||||
Dictionary::Ptr comments = service->GetComments();
|
||||
|
||||
if (!comments)
|
||||
continue;
|
||||
|
@ -218,8 +212,6 @@ void Service::RefreshCommentsCache(void)
|
|||
String id;
|
||||
Dictionary::Ptr comment;
|
||||
BOOST_FOREACH(tie(id, comment), comments) {
|
||||
ObjectLock clock(comment);
|
||||
|
||||
int legacy_id = comment->Get("legacy_id");
|
||||
|
||||
if (legacy_id >= m_NextCommentID)
|
||||
|
@ -257,8 +249,6 @@ void Service::RefreshCommentsCache(void)
|
|||
*/
|
||||
void Service::RemoveExpiredComments(void)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
Dictionary::Ptr comments = GetComments();
|
||||
|
||||
if (!comments)
|
||||
|
@ -266,17 +256,19 @@ void Service::RemoveExpiredComments(void)
|
|||
|
||||
vector<String> expiredComments;
|
||||
|
||||
ObjectLock dlock(comments);
|
||||
{
|
||||
ObjectLock olock(comments);
|
||||
|
||||
String id;
|
||||
Dictionary::Ptr comment;
|
||||
BOOST_FOREACH(tie(id, comment), comments) {
|
||||
if (IsCommentExpired(comment))
|
||||
expiredComments.push_back(id);
|
||||
String id;
|
||||
Dictionary::Ptr comment;
|
||||
BOOST_FOREACH(tie(id, comment), comments) {
|
||||
if (IsCommentExpired(comment))
|
||||
expiredComments.push_back(id);
|
||||
}
|
||||
}
|
||||
|
||||
if (expiredComments.size() > 0) {
|
||||
BOOST_FOREACH(id, expiredComments) {
|
||||
BOOST_FOREACH(const String& id, expiredComments) {
|
||||
comments->Remove(id);
|
||||
}
|
||||
|
||||
|
|
|
@ -83,15 +83,22 @@ String Service::AddDowntime(const String& author, const String& comment,
|
|||
otherOwner->Touch("downtimes");
|
||||
}
|
||||
|
||||
Dictionary::Ptr downtimes = m_Downtimes;
|
||||
Dictionary::Ptr downtimes;
|
||||
|
||||
if (!downtimes)
|
||||
downtimes = boost::make_shared<Dictionary>();
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
downtimes = m_Downtimes;
|
||||
|
||||
if (!downtimes)
|
||||
downtimes = boost::make_shared<Dictionary>();
|
||||
|
||||
m_Downtimes = downtimes;
|
||||
}
|
||||
|
||||
String id = Utility::NewUUID();
|
||||
downtimes->Set(id, downtime);
|
||||
|
||||
m_Downtimes = downtimes;
|
||||
Touch("downtimes");
|
||||
|
||||
return id;
|
||||
|
@ -107,8 +114,6 @@ void Service::RemoveDowntime(const String& id)
|
|||
if (!owner)
|
||||
return;
|
||||
|
||||
ObjectLock olock(owner);
|
||||
|
||||
Dictionary::Ptr downtimes = owner->GetDowntimes();
|
||||
|
||||
if (!downtimes)
|
||||
|
@ -149,8 +154,6 @@ void Service::TriggerDowntime(const String& id)
|
|||
|
||||
double now = Utility::GetTime();
|
||||
|
||||
ObjectLock olock(downtime);
|
||||
|
||||
if (now < downtime->Get("start_time") ||
|
||||
now > downtime->Get("end_time"))
|
||||
return;
|
||||
|
@ -159,7 +162,7 @@ void Service::TriggerDowntime(const String& id)
|
|||
downtime->Set("trigger_time", now);
|
||||
|
||||
Dictionary::Ptr triggers = downtime->Get("triggers");
|
||||
ObjectLock tlock(triggers);
|
||||
ObjectLock olock(triggers);
|
||||
String tid;
|
||||
BOOST_FOREACH(tie(tid, tuples::ignore), triggers) {
|
||||
TriggerDowntime(tid);
|
||||
|
@ -217,8 +220,6 @@ bool Service::IsDowntimeActive(const Dictionary::Ptr& downtime)
|
|||
{
|
||||
double now = Utility::GetTime();
|
||||
|
||||
ObjectLock olock(downtime);
|
||||
|
||||
if (now < downtime->Get("start_time") ||
|
||||
now > downtime->Get("end_time"))
|
||||
return false;
|
||||
|
@ -275,12 +276,7 @@ void Service::RefreshDowntimesCache(void)
|
|||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
|
||||
Service::Ptr service = dynamic_pointer_cast<Service>(object);
|
||||
|
||||
Dictionary::Ptr downtimes;
|
||||
|
||||
{
|
||||
ObjectLock olock(service);
|
||||
downtimes = service->GetDowntimes();
|
||||
}
|
||||
Dictionary::Ptr downtimes = service->GetDowntimes();
|
||||
|
||||
if (!downtimes)
|
||||
continue;
|
||||
|
@ -290,7 +286,6 @@ void Service::RefreshDowntimesCache(void)
|
|||
String id;
|
||||
Dictionary::Ptr downtime;
|
||||
BOOST_FOREACH(tie(id, downtime), downtimes) {
|
||||
ObjectLock dlock(downtime);
|
||||
int legacy_id = downtime->Get("legacy_id");
|
||||
|
||||
if (legacy_id >= m_NextDowntimeID)
|
||||
|
@ -327,8 +322,6 @@ void Service::RefreshDowntimesCache(void)
|
|||
*/
|
||||
void Service::RemoveExpiredDowntimes(void)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
Dictionary::Ptr downtimes = GetDowntimes();
|
||||
|
||||
if (!downtimes)
|
||||
|
@ -336,17 +329,19 @@ void Service::RemoveExpiredDowntimes(void)
|
|||
|
||||
vector<String> expiredDowntimes;
|
||||
|
||||
ObjectLock dlock(downtimes);
|
||||
{
|
||||
ObjectLock olock(downtimes);
|
||||
|
||||
String id;
|
||||
Dictionary::Ptr downtime;
|
||||
BOOST_FOREACH(tie(id, downtime), downtimes) {
|
||||
if (IsDowntimeExpired(downtime))
|
||||
expiredDowntimes.push_back(id);
|
||||
String id;
|
||||
Dictionary::Ptr downtime;
|
||||
BOOST_FOREACH(tie(id, downtime), downtimes) {
|
||||
if (IsDowntimeExpired(downtime))
|
||||
expiredDowntimes.push_back(id);
|
||||
}
|
||||
}
|
||||
|
||||
if (expiredDowntimes.size() > 0) {
|
||||
BOOST_FOREACH(id, expiredDowntimes) {
|
||||
BOOST_FOREACH(const String& id, expiredDowntimes) {
|
||||
downtimes->Remove(id);
|
||||
}
|
||||
|
||||
|
|
|
@ -149,8 +149,6 @@ set<Notification::Ptr> Service::GetNotifications(void) const
|
|||
template<typename TDict>
|
||||
static void CopyNotificationAttributes(TDict notificationDesc, const ConfigItemBuilder::Ptr& builder)
|
||||
{
|
||||
ObjectLock olock(notificationDesc);
|
||||
|
||||
/* TODO: we only need to copy macros if this is an inline definition,
|
||||
* i.e. "typeid(notificationDesc)" != Notification, however for now we just
|
||||
* copy them anyway. */
|
||||
|
@ -171,52 +169,35 @@ static void CopyNotificationAttributes(TDict notificationDesc, const ConfigItemB
|
|||
builder->AddExpression("notification_interval", OperatorSet, notificationInterval);*/
|
||||
}
|
||||
|
||||
void Service::UpdateSlaveNotifications(const Service::Ptr& self)
|
||||
void Service::UpdateSlaveNotifications(void)
|
||||
{
|
||||
Dictionary::Ptr oldNotifications;
|
||||
Host::Ptr host;
|
||||
vector<Dictionary::Ptr> notificationDescsList;
|
||||
String service_name, short_name;
|
||||
ConfigItem::Ptr item;
|
||||
|
||||
{
|
||||
ObjectLock olock(self);
|
||||
item = ConfigItem::GetObject("Service", GetName());
|
||||
|
||||
item = ConfigItem::GetObject("Service", self->GetName());
|
||||
|
||||
/* Don't create slave notifications unless we own this object
|
||||
* and it's not a template. */
|
||||
if (!item || self->IsAbstract())
|
||||
return;
|
||||
|
||||
service_name = self->GetName();
|
||||
short_name = self->GetShortName();
|
||||
oldNotifications = self->m_SlaveNotifications;
|
||||
host = self->GetHost();
|
||||
|
||||
notificationDescsList.push_back(self->Get("notifications"));
|
||||
}
|
||||
|
||||
DebugInfo debug_info;
|
||||
/* Don't create slave notifications unless we own this object
|
||||
* and it's not a template. */
|
||||
if (!item || IsAbstract())
|
||||
return;
|
||||
|
||||
{
|
||||
ObjectLock ilock(item);
|
||||
debug_info = item->GetDebugInfo();
|
||||
ObjectLock olock(this);
|
||||
oldNotifications = m_SlaveNotifications;
|
||||
}
|
||||
|
||||
notificationDescsList.push_back(Get("notifications"));
|
||||
|
||||
Dictionary::Ptr newNotifications;
|
||||
newNotifications = boost::make_shared<Dictionary>();
|
||||
|
||||
ObjectLock nlock(newNotifications);
|
||||
Host::Ptr host = GetHost();
|
||||
|
||||
String host_name;
|
||||
if (!host)
|
||||
return;
|
||||
|
||||
{
|
||||
ObjectLock olock(host);
|
||||
|
||||
notificationDescsList.push_back(host->Get("notifications"));
|
||||
host_name = host->GetName();
|
||||
}
|
||||
notificationDescsList.push_back(host->Get("notifications"));
|
||||
|
||||
BOOST_FOREACH(const Dictionary::Ptr& notificationDescs, notificationDescsList) {
|
||||
if (!notificationDescs)
|
||||
|
@ -231,22 +212,21 @@ void Service::UpdateSlaveNotifications(const Service::Ptr& self)
|
|||
nfcname = nfcdesc;
|
||||
|
||||
stringstream namebuf;
|
||||
namebuf << service_name << "-" << nfcname;
|
||||
namebuf << GetName() << "-" << nfcname;
|
||||
String name = namebuf.str();
|
||||
|
||||
ConfigItemBuilder::Ptr builder = boost::make_shared<ConfigItemBuilder>(debug_info);
|
||||
ConfigItemBuilder::Ptr builder = boost::make_shared<ConfigItemBuilder>(item->GetDebugInfo());
|
||||
builder->SetType("Notification");
|
||||
builder->SetName(name);
|
||||
builder->AddExpression("host_name", OperatorSet, host_name);
|
||||
builder->AddExpression("service", OperatorSet, short_name);
|
||||
builder->AddExpression("host_name", OperatorSet, host->GetName());
|
||||
builder->AddExpression("service", OperatorSet, GetShortName());
|
||||
|
||||
CopyNotificationAttributes(self, builder);
|
||||
CopyNotificationAttributes(this, builder);
|
||||
|
||||
if (nfcdesc.IsScalar()) {
|
||||
builder->AddParent(nfcdesc);
|
||||
} else if (nfcdesc.IsObjectType<Dictionary>()) {
|
||||
Dictionary::Ptr notification = nfcdesc;
|
||||
ObjectLock nlock(notification);
|
||||
|
||||
Dictionary::Ptr templates = notification->Get("templates");
|
||||
|
||||
|
@ -287,8 +267,8 @@ void Service::UpdateSlaveNotifications(const Service::Ptr& self)
|
|||
}
|
||||
|
||||
{
|
||||
ObjectLock olock(self);
|
||||
self->m_SlaveNotifications = newNotifications;
|
||||
ObjectLock olock(this);
|
||||
m_SlaveNotifications = newNotifications;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -297,8 +277,6 @@ void Service::UpdateSlaveNotifications(const Service::Ptr& self)
|
|||
*/
|
||||
double Service::GetLastNotification(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (m_LastNotification.IsEmpty())
|
||||
return 0;
|
||||
else
|
||||
|
@ -310,8 +288,6 @@ double Service::GetLastNotification(void) const
|
|||
*/
|
||||
void Service::SetLastNotification(double time)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_LastNotification = time;
|
||||
Touch("last_notification");
|
||||
}
|
||||
|
@ -321,8 +297,6 @@ void Service::SetLastNotification(double time)
|
|||
*/
|
||||
bool Service::GetEnableNotifications(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (m_EnableNotifications.IsEmpty())
|
||||
return true;
|
||||
else
|
||||
|
@ -334,8 +308,6 @@ bool Service::GetEnableNotifications(void) const
|
|||
*/
|
||||
void Service::SetEnableNotifications(bool enabled)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_EnableNotifications = enabled;
|
||||
Touch("enable_notifications");
|
||||
}
|
||||
|
@ -345,8 +317,6 @@ void Service::SetEnableNotifications(bool enabled)
|
|||
*/
|
||||
double Service::GetNotificationInterval(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (m_NotificationInterval.IsEmpty())
|
||||
return 300;
|
||||
else
|
||||
|
|
|
@ -93,8 +93,6 @@ void Service::OnRegistrationCompleted(void)
|
|||
*/
|
||||
String Service::GetDisplayName(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (m_DisplayName.IsEmpty())
|
||||
return GetShortName();
|
||||
else
|
||||
|
@ -136,8 +134,6 @@ Service::Ptr Service::GetByNamePair(const String& hostName, const String& servic
|
|||
*/
|
||||
Host::Ptr Service::GetHost(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return Host::GetByName(m_HostName);
|
||||
}
|
||||
|
||||
|
@ -146,8 +142,6 @@ Host::Ptr Service::GetHost(void) const
|
|||
*/
|
||||
Dictionary::Ptr Service::GetMacros(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_Macros;
|
||||
}
|
||||
|
||||
|
@ -156,8 +150,6 @@ Dictionary::Ptr Service::GetMacros(void) const
|
|||
*/
|
||||
Dictionary::Ptr Service::GetHostDependencies(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_HostDependencies;
|
||||
}
|
||||
|
||||
|
@ -166,8 +158,6 @@ Dictionary::Ptr Service::GetHostDependencies(void) const
|
|||
*/
|
||||
Dictionary::Ptr Service::GetServiceDependencies(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_ServiceDependencies;
|
||||
}
|
||||
|
||||
|
@ -176,8 +166,6 @@ Dictionary::Ptr Service::GetServiceDependencies(void) const
|
|||
*/
|
||||
Dictionary::Ptr Service::GetGroups(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_ServiceGroups;
|
||||
}
|
||||
|
||||
|
@ -186,8 +174,6 @@ Dictionary::Ptr Service::GetGroups(void) const
|
|||
*/
|
||||
String Service::GetHostName(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_HostName;
|
||||
}
|
||||
|
||||
|
@ -196,8 +182,6 @@ String Service::GetHostName(void) const
|
|||
*/
|
||||
String Service::GetShortName(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (m_ShortName.IsEmpty())
|
||||
return GetName();
|
||||
else
|
||||
|
@ -266,8 +250,6 @@ bool Service::IsReachable(void) const
|
|||
*/
|
||||
AcknowledgementType Service::GetAcknowledgement(void)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (m_Acknowledgement.IsEmpty())
|
||||
return AcknowledgementNone;
|
||||
|
||||
|
@ -292,8 +274,6 @@ AcknowledgementType Service::GetAcknowledgement(void)
|
|||
*/
|
||||
void Service::SetAcknowledgement(AcknowledgementType acknowledgement)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_Acknowledgement = acknowledgement;
|
||||
Touch("acknowledgement");
|
||||
}
|
||||
|
@ -311,8 +291,6 @@ bool Service::IsAcknowledged(void)
|
|||
*/
|
||||
double Service::GetAcknowledgementExpiry(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (m_AcknowledgementExpiry.IsEmpty())
|
||||
return 0;
|
||||
|
||||
|
@ -324,8 +302,6 @@ double Service::GetAcknowledgementExpiry(void) const
|
|||
*/
|
||||
void Service::SetAcknowledgementExpiry(double timestamp)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_AcknowledgementExpiry = timestamp;
|
||||
Touch("acknowledgement_expiry");
|
||||
}
|
||||
|
@ -348,6 +324,8 @@ void Service::AcknowledgeProblem(AcknowledgementType type, double expiry)
|
|||
*/
|
||||
void Service::ClearAcknowledgement(void)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
SetAcknowledgement(AcknowledgementNone);
|
||||
SetAcknowledgementExpiry(0);
|
||||
}
|
||||
|
@ -355,43 +333,33 @@ void Service::ClearAcknowledgement(void)
|
|||
/**
|
||||
* @threadsafety Always.
|
||||
*/
|
||||
void Service::OnAttributeChanged(const String& name, const Value& oldValue)
|
||||
void Service::OnAttributeChanged(const String& name)
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
|
||||
Service::Ptr self;
|
||||
String service_name;
|
||||
bool abstract;
|
||||
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
self = GetSelf();
|
||||
service_name = GetName();
|
||||
abstract = IsAbstract();
|
||||
}
|
||||
Service::Ptr self = GetSelf();
|
||||
|
||||
if (name == "current_checker")
|
||||
OnCheckerChanged(self, oldValue);
|
||||
OnCheckerChanged(self);
|
||||
else if (name == "next_check")
|
||||
OnNextCheckChanged(self, oldValue);
|
||||
OnNextCheckChanged(self);
|
||||
else if (name == "servicegroups")
|
||||
ServiceGroup::InvalidateMembersCache();
|
||||
else if (name == "host_name" || name == "short_name") {
|
||||
Host::InvalidateServicesCache();
|
||||
|
||||
UpdateSlaveNotifications(self);
|
||||
UpdateSlaveNotifications();
|
||||
} else if (name == "downtimes")
|
||||
Service::InvalidateDowntimesCache();
|
||||
else if (name == "comments")
|
||||
Service::InvalidateCommentsCache();
|
||||
else if (name == "notifications")
|
||||
UpdateSlaveNotifications(self);
|
||||
UpdateSlaveNotifications();
|
||||
else if (name == "check_interval") {
|
||||
ObjectLock olock(this);
|
||||
ConfigItem::Ptr item = ConfigItem::GetObject("Service", service_name);
|
||||
ConfigItem::Ptr item = ConfigItem::GetObject("Service", GetName());
|
||||
|
||||
/* update the next check timestamp if we're the owner of this service */
|
||||
if (item && !abstract)
|
||||
if (item && !IsAbstract())
|
||||
UpdateNextCheck();
|
||||
}
|
||||
}
|
||||
|
@ -481,11 +449,11 @@ Dictionary::Ptr Service::CalculateDynamicMacros(void) const
|
|||
}
|
||||
|
||||
if (cr) {
|
||||
assert(cr->IsSealed());
|
||||
|
||||
macros->Set("SERVICELATENCY", Service::CalculateLatency(cr));
|
||||
macros->Set("SERVICEEXECUTIONTIME", Service::CalculateExecutionTime(cr));
|
||||
|
||||
ObjectLock olock(cr);
|
||||
|
||||
macros->Set("SERVICEOUTPUT", cr->Get("output"));
|
||||
macros->Set("SERVICEPERFDATA", cr->Get("performance_data_raw"));
|
||||
}
|
||||
|
|
|
@ -170,7 +170,7 @@ public:
|
|||
void AcknowledgeProblem(AcknowledgementType type, double expiry = 0);
|
||||
void ClearAcknowledgement(void);
|
||||
|
||||
static void BeginExecuteCheck(const Service::Ptr& self, const function<void (void)>& callback);
|
||||
void BeginExecuteCheck(const function<void (void)>& callback);
|
||||
void ProcessCheckResult(const Dictionary::Ptr& cr);
|
||||
|
||||
static double CalculateExecutionTime(const Dictionary::Ptr& cr);
|
||||
|
@ -182,8 +182,8 @@ public:
|
|||
static ServiceStateType StateTypeFromString(const String& state);
|
||||
static String StateTypeToString(ServiceStateType state);
|
||||
|
||||
static signals2::signal<void (const Service::Ptr&, const String&)> OnCheckerChanged;
|
||||
static signals2::signal<void (const Service::Ptr&, const Value&)> OnNextCheckChanged;
|
||||
static signals2::signal<void (const Service::Ptr&)> OnCheckerChanged;
|
||||
static signals2::signal<void (const Service::Ptr&)> OnNextCheckChanged;
|
||||
|
||||
/* Downtimes */
|
||||
static int GetNextDowntimeID(void);
|
||||
|
@ -243,14 +243,14 @@ public:
|
|||
|
||||
static void InvalidateNotificationsCache(void);
|
||||
|
||||
static void UpdateSlaveNotifications(const Service::Ptr& self);
|
||||
void UpdateSlaveNotifications(void);
|
||||
|
||||
double GetLastNotification(void) const;
|
||||
void SetLastNotification(double time);
|
||||
|
||||
protected:
|
||||
virtual void OnRegistrationCompleted(void);
|
||||
virtual void OnAttributeChanged(const String& name, const Value& oldValue);
|
||||
virtual void OnAttributeChanged(const String& name);
|
||||
|
||||
private:
|
||||
Dictionary::Ptr m_SlaveNotifications;
|
||||
|
|
|
@ -55,8 +55,6 @@ void ServiceGroup::OnRegistrationCompleted(void)
|
|||
*/
|
||||
String ServiceGroup::GetDisplayName(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (!m_DisplayName.Get().IsEmpty())
|
||||
return m_DisplayName;
|
||||
else
|
||||
|
@ -68,8 +66,6 @@ String ServiceGroup::GetDisplayName(void) const
|
|||
*/
|
||||
String ServiceGroup::GetNotesUrl(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_NotesUrl;
|
||||
}
|
||||
|
||||
|
@ -78,8 +74,6 @@ String ServiceGroup::GetNotesUrl(void) const
|
|||
*/
|
||||
String ServiceGroup::GetActionUrl(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_ActionUrl;
|
||||
}
|
||||
|
||||
|
@ -150,7 +144,6 @@ void ServiceGroup::RefreshMembersCache(void)
|
|||
|
||||
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();
|
||||
|
|
|
@ -39,7 +39,7 @@ User::~User(void)
|
|||
/**
|
||||
* @threadsafety Always.
|
||||
*/
|
||||
void User::OnAttributeChanged(const String& name, const Value& oldValue)
|
||||
void User::OnAttributeChanged(const String& name)
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
|
||||
|
@ -62,8 +62,6 @@ User::Ptr User::GetByName(const String& name)
|
|||
*/
|
||||
String User::GetDisplayName(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (!m_DisplayName.IsEmpty())
|
||||
return m_DisplayName;
|
||||
else
|
||||
|
@ -75,8 +73,6 @@ String User::GetDisplayName(void) const
|
|||
*/
|
||||
Dictionary::Ptr User::GetGroups(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_Groups;
|
||||
}
|
||||
|
||||
|
@ -85,8 +81,6 @@ Dictionary::Ptr User::GetGroups(void) const
|
|||
*/
|
||||
Dictionary::Ptr User::GetMacros(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_Macros;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
Dictionary::Ptr CalculateDynamicMacros(void) const;
|
||||
|
||||
protected:
|
||||
void OnAttributeChanged(const String& name, const Value& oldValue);
|
||||
virtual void OnAttributeChanged(const String& name);
|
||||
|
||||
private:
|
||||
Attribute<String> m_DisplayName;
|
||||
|
|
|
@ -53,8 +53,6 @@ void UserGroup::OnRegistrationCompleted(void)
|
|||
*/
|
||||
String UserGroup::GetDisplayName(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
if (!m_DisplayName.IsEmpty())
|
||||
return m_DisplayName;
|
||||
else
|
||||
|
@ -128,7 +126,6 @@ void UserGroup::RefreshMembersCache(void)
|
|||
|
||||
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("User")) {
|
||||
const User::Ptr& user = static_pointer_cast<User>(object);
|
||||
ObjectLock olock(user);
|
||||
|
||||
Dictionary::Ptr dict;
|
||||
dict = user->GetGroups();
|
||||
|
|
|
@ -25,8 +25,6 @@ REGISTER_TYPE(Endpoint);
|
|||
|
||||
signals2::signal<void (const Endpoint::Ptr&)> Endpoint::OnConnected;
|
||||
signals2::signal<void (const Endpoint::Ptr&)> Endpoint::OnDisconnected;
|
||||
signals2::signal<void (const Endpoint::Ptr&, const String& topic)> Endpoint::OnSubscriptionRegistered;
|
||||
signals2::signal<void (const Endpoint::Ptr&, const String& topic)> Endpoint::OnSubscriptionUnregistered;
|
||||
|
||||
/**
|
||||
* Constructor for the Endpoint class.
|
||||
|
@ -43,6 +41,9 @@ Endpoint::Endpoint(const Dictionary::Ptr& serializedUpdate)
|
|||
RegisterAttribute("subscriptions", Attribute_Replicated, &m_Subscriptions);
|
||||
}
|
||||
|
||||
Endpoint::~Endpoint(void)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Retrieves an endpoint by name.
|
||||
*
|
||||
|
@ -84,8 +85,6 @@ Endpoint::Ptr Endpoint::MakeEndpoint(const String& name, bool replicated, bool l
|
|||
*/
|
||||
bool Endpoint::IsLocalEndpoint(void) const
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
return m_Local;
|
||||
}
|
||||
|
||||
|
@ -141,6 +140,8 @@ void Endpoint::RegisterSubscription(const String& topic)
|
|||
if (!subscriptions->Contains(topic)) {
|
||||
Dictionary::Ptr newSubscriptions = subscriptions->ShallowClone();
|
||||
newSubscriptions->Set(topic, topic);
|
||||
|
||||
ObjectLock olock(this);
|
||||
SetSubscriptions(newSubscriptions);
|
||||
}
|
||||
}
|
||||
|
@ -182,8 +183,6 @@ bool Endpoint::HasSubscription(const String& topic) const
|
|||
*/
|
||||
void Endpoint::ClearSubscriptions(void)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
m_Subscriptions = Empty;
|
||||
Touch("subscriptions");
|
||||
}
|
||||
|
@ -195,8 +194,6 @@ Dictionary::Ptr Endpoint::GetSubscriptions(void) const
|
|||
|
||||
void Endpoint::SetSubscriptions(const Dictionary::Ptr& subscriptions)
|
||||
{
|
||||
ObjectLock olock(this);
|
||||
|
||||
subscriptions->Seal();
|
||||
m_Subscriptions = subscriptions;
|
||||
Touch("subscriptions");
|
||||
|
@ -220,6 +217,8 @@ void Endpoint::RegisterTopicHandler(const String& topic, const function<Endpoint
|
|||
|
||||
sig->connect(callback);
|
||||
|
||||
olock.Unlock();
|
||||
|
||||
RegisterSubscription(topic);
|
||||
}
|
||||
|
||||
|
@ -232,44 +231,6 @@ void Endpoint::UnregisterTopicHandler(const String& topic, const function<Endpoi
|
|||
BOOST_THROW_EXCEPTION(NotImplementedException());
|
||||
}
|
||||
|
||||
void Endpoint::OnAttributeChanged(const String& name, const Value& oldValue)
|
||||
{
|
||||
assert(!OwnsLock());
|
||||
|
||||
if (name == "subscriptions") {
|
||||
Dictionary::Ptr oldSubscriptions, newSubscriptions;
|
||||
|
||||
if (oldValue.IsObjectType<Dictionary>())
|
||||
oldSubscriptions = oldValue;
|
||||
|
||||
newSubscriptions = GetSubscriptions();
|
||||
|
||||
if (oldSubscriptions) {
|
||||
ObjectLock olock(oldSubscriptions);
|
||||
|
||||
String subscription;
|
||||
BOOST_FOREACH(tie(tuples::ignore, subscription), oldSubscriptions) {
|
||||
if (!newSubscriptions || !newSubscriptions->Contains(subscription)) {
|
||||
Logger::Write(LogInformation, "remoting", "Removed subscription for '" + GetName() + "': " + subscription);
|
||||
OnSubscriptionUnregistered(GetSelf(), subscription);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (newSubscriptions) {
|
||||
ObjectLock olock(newSubscriptions);
|
||||
|
||||
String subscription;
|
||||
BOOST_FOREACH(tie(tuples::ignore, subscription), newSubscriptions) {
|
||||
if (!oldSubscriptions || !oldSubscriptions->Contains(subscription)) {
|
||||
Logger::Write(LogDebug, "remoting", "New subscription for '" + GetName() + "': " + subscription);
|
||||
OnSubscriptionRegistered(GetSelf(), subscription);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Endpoint::ProcessRequest(const Endpoint::Ptr& sender, const RequestMessage& request)
|
||||
{
|
||||
if (!IsConnected()) {
|
||||
|
|
|
@ -39,6 +39,7 @@ public:
|
|||
typedef void (Callback)(const Endpoint::Ptr&, const Endpoint::Ptr&, const RequestMessage&);
|
||||
|
||||
Endpoint(const Dictionary::Ptr& serializedUpdate);
|
||||
~Endpoint(void);
|
||||
|
||||
static Endpoint::Ptr GetByName(const String& name);
|
||||
|
||||
|
@ -63,8 +64,6 @@ public:
|
|||
void RegisterTopicHandler(const String& topic, const function<Callback>& callback);
|
||||
void UnregisterTopicHandler(const String& topic, const function<Callback>& callback);
|
||||
|
||||
virtual void OnAttributeChanged(const String& name, const Value& oldValue);
|
||||
|
||||
String GetNode(void) const;
|
||||
String GetService(void) const;
|
||||
|
||||
|
@ -73,9 +72,6 @@ public:
|
|||
static signals2::signal<void (const Endpoint::Ptr&)> OnConnected;
|
||||
static signals2::signal<void (const Endpoint::Ptr&)> OnDisconnected;
|
||||
|
||||
static signals2::signal<void (const Endpoint::Ptr&, const String& topic)> OnSubscriptionRegistered;
|
||||
static signals2::signal<void (const Endpoint::Ptr&, const String& topic)> OnSubscriptionUnregistered;
|
||||
|
||||
private:
|
||||
Attribute<bool> m_Local;
|
||||
Attribute<Dictionary::Ptr> m_Subscriptions;
|
||||
|
|
Loading…
Reference in New Issue