Fix --disable-shared

Fixes #3852
This commit is contained in:
Gunnar Beutner 2013-03-15 11:19:52 +01:00
parent 9ac731ba8e
commit ee46731f41
16 changed files with 211 additions and 134 deletions

View File

@ -106,13 +106,7 @@ void ReplicationComponent::EndpointConnectedHandler(const Endpoint::Ptr& endpoin
continue;
RequestMessage request = MakeObjectMessage(object, "config::ObjectUpdate", 0, true);
EndpointManager::Ptr em = EndpointManager::GetInstance();
{
ObjectLock elock(em);
em->SendUnicastMessage(m_Endpoint, endpoint, request);
}
EndpointManager::GetInstance()->SendUnicastMessage(m_Endpoint, endpoint, request);
}
}
@ -190,12 +184,7 @@ void ReplicationComponent::FlushObjectHandler(double tx, const DynamicObject::Pt
return;
RequestMessage request = MakeObjectMessage(object, "config::ObjectUpdate", tx, true);
EndpointManager::Ptr em = EndpointManager::GetInstance();
{
ObjectLock olock(em);
em->SendMulticastMessage(m_Endpoint, request);
}
EndpointManager::GetInstance()->SendMulticastMessage(m_Endpoint, request);
}
void ReplicationComponent::RemoteObjectUpdateHandler(const RequestMessage& request)

View File

@ -34,6 +34,7 @@ icinga2_LDADD = \
-dlopen ${top_builddir}/components/compat/libcompat.la \
-dlopen ${top_builddir}/components/delegation/libdelegation.la \
-dlopen ${top_builddir}/components/demo/libdemo.la \
-dlopen ${top_builddir}/components/livestatus/liblivestatus.la \
-dlopen ${top_builddir}/components/notification/libnotification.la
if PYTHON_USE

View File

@ -44,6 +44,7 @@ libbase_la_SOURCES = \
process.h \
qstring.cpp \
qstring.h \
registry.h \
ringbuffer.cpp \
ringbuffer.h \
script.cpp \
@ -56,6 +57,7 @@ libbase_la_SOURCES = \
scriptlanguage.h \
scripttask.cpp \
scripttask.h \
singleton.h \
socket.cpp \
socket.h \
stacktrace.cpp \

View File

@ -439,7 +439,7 @@ ScriptTask::Ptr DynamicObject::MakeMethodTask(const String& method,
if (funcName.IsEmpty())
return ScriptTask::Ptr();
ScriptFunction::Ptr func = ScriptFunction::GetByName(funcName);
ScriptFunction::Ptr func = ScriptFunctionRegistry::GetInstance()->GetItem(funcName);
if (!func)
BOOST_THROW_EXCEPTION(invalid_argument("Function '" + funcName + "' does not exist."));

View File

@ -68,6 +68,14 @@ private:
static boost::mutex& GetStaticMutex(void);
};
/**
* A registry for DynamicType objects.
*
* @ingroup base
*/
class DynamicTypeRegistry : public Registry<DynamicType::Ptr>
{ };
/**
* Helper class for registering DynamicObject implementation classes.
*

View File

@ -223,6 +223,8 @@ namespace signals2 = boost::signals2;
#include "tlsstream.h"
#include "asynctask.h"
#include "process.h"
#include "singleton.h"
#include "registry.h"
#include "scriptfunction.h"
#include "scripttask.h"
#include "attribute.h"

110
lib/base/registry.h Normal file
View File

@ -0,0 +1,110 @@
/******************************************************************************
* 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 REGISTRY_H
#define REGISTRY_H
namespace icinga
{
/**
* A registry.
*
* @ingroup base
*/
template<typename T>
class I2_BASE_API Registry
{
public:
typedef map<String, T, string_iless> ItemMap;
static Registry<T> *GetInstance(void)
{
return Singleton<Registry<T> >::GetInstance();
}
void Register(const String& name, const T& item)
{
bool old_item = false;
{
boost::mutex::scoped_lock lock(m_Mutex);
if (m_Items.erase(name) > 0)
old_item = true;
m_Items[name] = item;
}
if (old_item)
OnUnregistered(name);
OnRegistered(name, item);
}
void Unregister(const String& name)
{
int erased;
{
boost::mutex::scoped_lock lock(m_Mutex);
erased = m_Items.erase(name);
}
if (erased > 0)
OnUnregistered(name);
}
T GetItem(const String& name) const
{
boost::mutex::scoped_lock lock(m_Mutex);
typename ItemMap::const_iterator it;
it = m_Items.find(name);
if (it == m_Items.end())
return T();
return it->second;
}
ItemMap GetItems(void) const
{
boost::mutex::scoped_lock lock(m_Mutex);
return m_Items; /* Makes a copy of the map. */
}
static signals2::signal<void (const String&, const T&)> OnRegistered;
static signals2::signal<void (const String&)> OnUnregistered;
private:
mutable boost::mutex m_Mutex;
typename Registry<T>::ItemMap m_Items;
};
template<typename T>
signals2::signal<void (const String&, const T&)> Registry<T>::OnRegistered;
template<typename T>
signals2::signal<void (const String&)> Registry<T>::OnUnregistered;
}
#endif /* REGISTRY_H */

View File

@ -21,52 +21,10 @@
using namespace icinga;
signals2::signal<void (const String&, const ScriptFunction::Ptr&)> ScriptFunction::OnRegistered;
signals2::signal<void (const String&)> ScriptFunction::OnUnregistered;
ScriptFunction::ScriptFunction(const Callback& function)
: m_Callback(function)
{ }
/**
* @threadsafety Always.
*/
void ScriptFunction::Register(const String& name, const ScriptFunction::Ptr& function)
{
boost::mutex::scoped_lock lock(GetMutex());
InternalGetFunctions()[name] = function;
OnRegistered(name, function);
}
/**
* @threadsafety Always.
*/
void ScriptFunction::Unregister(const String& name)
{
boost::mutex::scoped_lock lock(GetMutex());
InternalGetFunctions().erase(name);
OnUnregistered(name);
}
/**
* @threadsafety Always.
*/
ScriptFunction::Ptr ScriptFunction::GetByName(const String& name)
{
boost::mutex::scoped_lock lock(GetMutex());
map<String, ScriptFunction::Ptr>::iterator it;
it = InternalGetFunctions().find(name);
if (it == InternalGetFunctions().end())
return ScriptFunction::Ptr();
return it->second;
}
/**
* @threadsafety Always.
*/
@ -74,31 +32,3 @@ void ScriptFunction::Invoke(const ScriptTask::Ptr& task, const vector<Value>& ar
{
m_Callback(task, arguments);
}
/**
* @threadsafety Always.
*/
map<String, ScriptFunction::Ptr> ScriptFunction::GetFunctions(void)
{
boost::mutex::scoped_lock lock(GetMutex());
return InternalGetFunctions(); /* makes a copy of the map */
}
/**
* @threadsafety Caller must hold the mutex returned by GetMutex().
*/
map<String, ScriptFunction::Ptr>& ScriptFunction::InternalGetFunctions(void)
{
static map<String, ScriptFunction::Ptr> functions;
return functions;
}
/**
* @threadsafety Always.
*/
boost::mutex& ScriptFunction::GetMutex(void)
{
static boost::mutex mtx;
return mtx;
}

View File

@ -40,26 +40,22 @@ public:
explicit ScriptFunction(const Callback& function);
static void Register(const String& name, const ScriptFunction::Ptr& function);
static void Unregister(const String& name);
static ScriptFunction::Ptr GetByName(const String& name);
static map<String, ScriptFunction::Ptr> GetFunctions(void);
static signals2::signal<void (const String&, const ScriptFunction::Ptr&)> OnRegistered;
static signals2::signal<void (const String&)> OnUnregistered;
private:
Callback m_Callback;
static map<String, ScriptFunction::Ptr>& InternalGetFunctions(void);
static boost::mutex& GetMutex(void);
void Invoke(const shared_ptr<ScriptTask>& task, const vector<Value>& arguments);
friend class ScriptTask;
};
/**
* A registry for script functions.
*
* @ingroup base
*/
class I2_BASE_API ScriptFunctionRegistry : public Registry<ScriptFunction::Ptr>
{ };
/**
* Helper class for registering ScriptFunction implementation classes.
*
@ -70,10 +66,8 @@ class RegisterFunctionHelper
public:
RegisterFunctionHelper(const String& name, const ScriptFunction::Callback& function)
{
if (!ScriptFunction::GetByName(name)) {
ScriptFunction::Ptr func = boost::make_shared<ScriptFunction>(function);
ScriptFunction::Register(name, func);
}
ScriptFunction::Ptr func = boost::make_shared<ScriptFunction>(function);
ScriptFunctionRegistry::GetInstance()->Register(name, func);
}
};

View File

@ -27,7 +27,7 @@ ScriptInterpreter::ScriptInterpreter(const Script::Ptr&)
ScriptInterpreter::~ScriptInterpreter(void)
{
BOOST_FOREACH(const String& function, m_SubscribedFunctions) {
ScriptFunction::Unregister(function);
ScriptFunctionRegistry::GetInstance()->Unregister(function);
}
}
@ -38,7 +38,7 @@ void ScriptInterpreter::SubscribeFunction(const String& name)
m_SubscribedFunctions.insert(name);
ScriptFunction::Ptr sf = boost::make_shared<ScriptFunction>(boost::bind(&ScriptInterpreter::ProcessCall, this, _1, name, _2));
ScriptFunction::Register(name, sf);
ScriptFunctionRegistry::GetInstance()->Register(name, sf);
}
void ScriptInterpreter::UnsubscribeFunction(const String& name)
@ -46,5 +46,5 @@ void ScriptInterpreter::UnsubscribeFunction(const String& name)
ObjectLock olock(this);
m_SubscribedFunctions.erase(name);
ScriptFunction::Unregister(name);
ScriptFunctionRegistry::GetInstance()->Unregister(name);
}

57
lib/base/singleton.h Normal file
View File

@ -0,0 +1,57 @@
/******************************************************************************
* 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 SINGLETON_H
#define SINGLETON_H
namespace icinga
{
/**
* A singleton.
*
* @ingroup base
*/
template<typename T>
class I2_BASE_API Singleton
{
public:
static T *GetInstance(void)
{
/* FIXME: This relies on static initializers being atomic. */
static boost::mutex mutex;
boost::mutex::scoped_lock lock(mutex);
if (!m_Instance)
m_Instance = new T();
return m_Instance;
}
private:
friend T *T::GetInstance(void);
static T *m_Instance;
};
template<typename T>
T *Singleton<T>::m_Instance = NULL;
}
#endif /* SINGLETON_H */

View File

@ -210,14 +210,3 @@ void ConfigCompiler::AddIncludeSearchDir(const String& dir)
m_IncludeSearchDirs.push_back(dir);
}
void ConfigCompiler::RegisterConfigFragment(const String& name, const String& fragment)
{
GetConfigFragments()[name] = fragment;
}
map<String, String>& ConfigCompiler::GetConfigFragments(void)
{
static map<String, String> fragments;
return fragments;
}

View File

@ -58,9 +58,6 @@ public:
size_t ReadInput(char *buffer, size_t max_bytes);
void *GetScanner(void) const;
static void RegisterConfigFragment(const String& name, const String& fragment);
static map<String, String>& GetConfigFragments(void);
private:
String m_Path;
istream *m_Input;
@ -75,6 +72,9 @@ private:
void DestroyScanner(void);
};
class ConfigFragmentRegistry : public Registry<String>
{ };
/**
* Helper class for registering config fragments.
*
@ -85,7 +85,7 @@ class RegisterConfigFragmentHelper
public:
RegisterConfigFragmentHelper(const String& name, const String& fragment)
{
ConfigCompiler::RegisterConfigFragment(name, fragment);
ConfigFragmentRegistry::GetInstance()->Register(name, fragment);
}
};

View File

@ -122,7 +122,7 @@ void ConfigType::ValidateDictionary(const Dictionary::Ptr& dictionary,
String validator = ruleList->GetValidator();
if (!validator.IsEmpty()) {
ScriptFunction::Ptr func = ScriptFunction::GetByName(validator);
ScriptFunction::Ptr func = ScriptFunctionRegistry::GetInstance()->GetItem(validator);
if (!func)
BOOST_THROW_EXCEPTION(invalid_argument("Validator function '" + validator + "' does not exist."));
@ -203,7 +203,7 @@ void ConfigType::ValidateArray(const Array::Ptr& array,
String validator = ruleList->GetValidator();
if (!validator.IsEmpty()) {
ScriptFunction::Ptr func = ScriptFunction::GetByName(validator);
ScriptFunction::Ptr func = ScriptFunctionRegistry::GetInstance()->GetItem(validator);
if (!func)
BOOST_THROW_EXCEPTION(invalid_argument("Validator function '" + validator + "' does not exist."));

View File

@ -399,8 +399,8 @@ void EndpointManager::RequestTimerHandler(void)
map<String, PendingRequest>::iterator it;
for (it = m_Requests.begin(); it != m_Requests.end(); ++it) {
if (it->second.HasTimedOut()) {
it->second.Callback(GetSelf(), Endpoint::Ptr(),
it->second.Request, ResponseMessage(), true);
it->second.Callback(Endpoint::Ptr(), it->second.Request,
ResponseMessage(), true);
m_Requests.erase(it);
@ -424,17 +424,12 @@ void EndpointManager::ProcessResponseMessage(const Endpoint::Ptr& sender,
if (it == m_Requests.end())
return;
it->second.Callback(GetSelf(), sender, it->second.Request, message, false);
it->second.Callback(sender, it->second.Request, message, false);
m_Requests.erase(it);
}
EndpointManager::Ptr EndpointManager::GetInstance(void)
EndpointManager *EndpointManager::GetInstance(void)
{
static EndpointManager::Ptr instance;
if (!instance)
instance = boost::make_shared<EndpointManager>();
return instance;
return Singleton<EndpointManager>::GetInstance();
}

View File

@ -36,7 +36,7 @@ public:
EndpointManager(void);
static EndpointManager::Ptr GetInstance(void);
static EndpointManager *GetInstance(void);
void SetIdentity(const String& identity);
String GetIdentity(void) const;
@ -53,14 +53,14 @@ public:
void SendMulticastMessage(const RequestMessage& message);
void SendMulticastMessage(const Endpoint::Ptr& sender, const RequestMessage& message);
typedef function<void(const EndpointManager::Ptr&, const Endpoint::Ptr, const RequestMessage&, const ResponseMessage&, bool TimedOut)> APICallback;
typedef function<void(const Endpoint::Ptr, const RequestMessage&, const ResponseMessage&, bool TimedOut)> APICallback;
void SendAPIMessage(const Endpoint::Ptr& sender, const Endpoint::Ptr& recipient, RequestMessage& message,
const APICallback& callback, double timeout = 30);
void ProcessResponseMessage(const Endpoint::Ptr& sender, const ResponseMessage& message);
signals2::signal<void (const EndpointManager::Ptr&, const Endpoint::Ptr&)> OnNewEndpoint;
signals2::signal<void (const Endpoint::Ptr&)> OnNewEndpoint;
private:
String m_Identity;
@ -84,7 +84,7 @@ private:
{
double Timeout;
RequestMessage Request;
function<void(const EndpointManager::Ptr&, const Endpoint::Ptr, const RequestMessage&, const ResponseMessage&, bool TimedOut)> Callback;
function<void(const Endpoint::Ptr, const RequestMessage&, const ResponseMessage&, bool TimedOut)> Callback;
bool HasTimedOut(void) const
{