From: Gunnar Beutner Date: Fri, 15 Mar 2013 10:19:52 +0000 (+0100) Subject: Fix --disable-shared X-Git-Tag: v0.0.2~239 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ee46731f41a967a02bb2a24a44e92c2b786aa219;p=icinga2 Fix --disable-shared Fixes #3852 --- diff --git a/components/replication/replicationcomponent.cpp b/components/replication/replicationcomponent.cpp index 060d22176..559c1d202 100644 --- a/components/replication/replicationcomponent.cpp +++ b/components/replication/replicationcomponent.cpp @@ -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) diff --git a/icinga-app/Makefile.am b/icinga-app/Makefile.am index 5ab2c55be..6a83d397b 100644 --- a/icinga-app/Makefile.am +++ b/icinga-app/Makefile.am @@ -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 diff --git a/lib/base/Makefile.am b/lib/base/Makefile.am index a4e0502ab..b0d180d8a 100644 --- a/lib/base/Makefile.am +++ b/lib/base/Makefile.am @@ -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 \ diff --git a/lib/base/dynamicobject.cpp b/lib/base/dynamicobject.cpp index a6a4a6d40..38e9b380e 100644 --- a/lib/base/dynamicobject.cpp +++ b/lib/base/dynamicobject.cpp @@ -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.")); diff --git a/lib/base/dynamictype.h b/lib/base/dynamictype.h index abae27660..e1a427082 100644 --- a/lib/base/dynamictype.h +++ b/lib/base/dynamictype.h @@ -68,6 +68,14 @@ private: static boost::mutex& GetStaticMutex(void); }; +/** + * A registry for DynamicType objects. + * + * @ingroup base + */ +class DynamicTypeRegistry : public Registry +{ }; + /** * Helper class for registering DynamicObject implementation classes. * diff --git a/lib/base/i2-base.h b/lib/base/i2-base.h index fb59d848e..6010fc9bf 100644 --- a/lib/base/i2-base.h +++ b/lib/base/i2-base.h @@ -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" diff --git a/lib/base/registry.h b/lib/base/registry.h new file mode 100644 index 000000000..8bbf5882d --- /dev/null +++ b/lib/base/registry.h @@ -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 +class I2_BASE_API Registry +{ +public: + typedef map ItemMap; + + static Registry *GetInstance(void) + { + return Singleton >::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 OnRegistered; + static signals2::signal OnUnregistered; + +private: + mutable boost::mutex m_Mutex; + typename Registry::ItemMap m_Items; +}; + +template +signals2::signal Registry::OnRegistered; + +template +signals2::signal Registry::OnUnregistered; + +} + +#endif /* REGISTRY_H */ diff --git a/lib/base/scriptfunction.cpp b/lib/base/scriptfunction.cpp index 3bfc9c87a..dfa8904e4 100644 --- a/lib/base/scriptfunction.cpp +++ b/lib/base/scriptfunction.cpp @@ -21,52 +21,10 @@ using namespace icinga; -signals2::signal ScriptFunction::OnRegistered; -signals2::signal 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::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& ar { m_Callback(task, arguments); } - -/** - * @threadsafety Always. - */ -map 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& ScriptFunction::InternalGetFunctions(void) -{ - static map functions; - return functions; -} - -/** - * @threadsafety Always. - */ -boost::mutex& ScriptFunction::GetMutex(void) -{ - static boost::mutex mtx; - return mtx; -} diff --git a/lib/base/scriptfunction.h b/lib/base/scriptfunction.h index 074c2fedc..511415aee 100644 --- a/lib/base/scriptfunction.h +++ b/lib/base/scriptfunction.h @@ -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 GetFunctions(void); - - static signals2::signal OnRegistered; - static signals2::signal OnUnregistered; - private: Callback m_Callback; - static map& InternalGetFunctions(void); - static boost::mutex& GetMutex(void); - void Invoke(const shared_ptr& task, const vector& arguments); friend class ScriptTask; }; +/** + * A registry for script functions. + * + * @ingroup base + */ +class I2_BASE_API ScriptFunctionRegistry : public Registry +{ }; + /** * 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(function); - ScriptFunction::Register(name, func); - } + ScriptFunction::Ptr func = boost::make_shared(function); + ScriptFunctionRegistry::GetInstance()->Register(name, func); } }; diff --git a/lib/base/scriptinterpreter.cpp b/lib/base/scriptinterpreter.cpp index 235c9fac7..9929823f3 100644 --- a/lib/base/scriptinterpreter.cpp +++ b/lib/base/scriptinterpreter.cpp @@ -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(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); } diff --git a/lib/base/singleton.h b/lib/base/singleton.h new file mode 100644 index 000000000..4f65da04a --- /dev/null +++ b/lib/base/singleton.h @@ -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 +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 +T *Singleton::m_Instance = NULL; + +} + +#endif /* SINGLETON_H */ diff --git a/lib/config/configcompiler.cpp b/lib/config/configcompiler.cpp index 487b714f6..4dfae8edc 100644 --- a/lib/config/configcompiler.cpp +++ b/lib/config/configcompiler.cpp @@ -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& ConfigCompiler::GetConfigFragments(void) -{ - static map fragments; - return fragments; -} diff --git a/lib/config/configcompiler.h b/lib/config/configcompiler.h index 6481a7bb7..fcd809c2a 100644 --- a/lib/config/configcompiler.h +++ b/lib/config/configcompiler.h @@ -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& GetConfigFragments(void); - private: String m_Path; istream *m_Input; @@ -75,6 +72,9 @@ private: void DestroyScanner(void); }; +class ConfigFragmentRegistry : public Registry +{ }; + /** * 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); } }; diff --git a/lib/config/configtype.cpp b/lib/config/configtype.cpp index f20041d6c..318c4a65c 100644 --- a/lib/config/configtype.cpp +++ b/lib/config/configtype.cpp @@ -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.")); diff --git a/lib/remoting/endpointmanager.cpp b/lib/remoting/endpointmanager.cpp index 001921a5c..008db7411 100644 --- a/lib/remoting/endpointmanager.cpp +++ b/lib/remoting/endpointmanager.cpp @@ -399,8 +399,8 @@ void EndpointManager::RequestTimerHandler(void) map::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(); - - return instance; + return Singleton::GetInstance(); } diff --git a/lib/remoting/endpointmanager.h b/lib/remoting/endpointmanager.h index bcdb14c14..adc236424 100644 --- a/lib/remoting/endpointmanager.h +++ b/lib/remoting/endpointmanager.h @@ -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 APICallback; + typedef function 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 OnNewEndpoint; + signals2::signal OnNewEndpoint; private: String m_Identity; @@ -84,7 +84,7 @@ private: { double Timeout; RequestMessage Request; - function Callback; + function Callback; bool HasTimedOut(void) const {