Even more code refactoring.

This commit is contained in:
Gunnar Beutner 2013-03-04 15:52:42 +01:00
parent a6d26a2dc1
commit be95f3171d
53 changed files with 680 additions and 897 deletions

View File

@ -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));
}

View File

@ -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;
}
};

View File

@ -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";

View File

@ -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"

View File

@ -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 -

View File

@ -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

View File

@ -8,6 +8,8 @@ libbase_la_SOURCES = \
application.cpp \
application.h \
asynctask.h \
attribute.cpp \
attribute.h \
component.cpp \
component.h \
connection.cpp \

View File

@ -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)

151
lib/base/attribute.cpp Normal file
View File

@ -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;
}

152
lib/base/attribute.h Normal file
View File

@ -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 */

View File

@ -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;
}

View File

@ -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>();

View File

@ -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());
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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"

View File

@ -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 */

View File

@ -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;
};

View File

@ -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();
}

View File

@ -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 */

View File

@ -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());

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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();
}
/**

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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()) {

View File

@ -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

View File

@ -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"));
}

View File

@ -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;

View File

@ -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();

View File

@ -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();

View File

@ -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;

View File

@ -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());

View File

@ -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;

View File

@ -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

View File

@ -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:

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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"));
}

View File

@ -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;

View File

@ -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();

View File

@ -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;
}

View File

@ -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;

View File

@ -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();

View File

@ -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()) {

View File

@ -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;