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