#include "base/logger.hpp"
#include "base/timer.hpp"
#include "base/utility.hpp"
+#include "base/loader.hpp"
#include "base/exception.hpp"
#include "base/convert.hpp"
#include "base/scriptglobal.hpp"
LogSeverity logLevel = Logger::GetConsoleLogSeverity();
Logger::SetConsoleLogSeverity(LogWarning);
- Utility::LoadExtensionLibrary("cli");
+ Loader::LoadExtensionLibrary("cli");
po::options_description visibleDesc("Global options");
if (vm.count("library")) {
BOOST_FOREACH(const String& libraryName, vm["library"].as<std::vector<std::string> >()) {
try {
- (void) Utility::LoadExtensionLibrary(libraryName);
+ (void) Loader::LoadExtensionLibrary(libraryName);
} catch (const std::exception& ex) {
Log(LogCritical, "icinga-app")
<< "Could not load library \"" << libraryName << "\": " << DiagnosticInformation(ex);
Logger::SetConsoleLogSeverity(LogWarning);
if (vm.count("app"))
- Utility::LoadExtensionLibrary(vm["app"].as<std::string>());
+ Loader::LoadExtensionLibrary(vm["app"].as<std::string>());
else
- Utility::LoadExtensionLibrary("icinga");
+ Loader::LoadExtensionLibrary("icinga");
Logger::SetConsoleLogSeverity(logLevel);
set(base_SOURCES
application.cpp application-version.cpp application.thpp array.cpp array-script.cpp boolean.cpp boolean-script.cpp console.cpp context.cpp
convert.cpp debuginfo.cpp dictionary.cpp dictionary-script.cpp dynamicobject.cpp dynamicobject.thpp dynamictype.cpp
- exception.cpp fifo.cpp filelogger.cpp filelogger.thpp initialize.cpp json.cpp json-script.cpp logger.cpp logger.thpp math-script.cpp
+ exception.cpp fifo.cpp filelogger.cpp filelogger.thpp initialize.cpp json.cpp json-script.cpp loader.cpp logger.cpp logger.thpp math-script.cpp
netstring.cpp networkstream.cpp number.cpp number-script.cpp object.cpp object-script.cpp primitivetype.cpp process.cpp
ringbuffer.cpp scriptframe.cpp function.cpp function-script.cpp functionwrapper.cpp scriptglobal.cpp
scriptutils.cpp serializer.cpp socket.cpp socketevents.cpp stacktrace.cpp
#include "base/exception.hpp"
#include "base/objectlock.hpp"
#include "base/utility.hpp"
+#include "base/loader.hpp"
#include "base/debug.hpp"
#include "base/type.hpp"
#include "base/convert.hpp"
}
#endif /* _WIN32 */
- Utility::ExecuteDeferredInitializers();
+ Loader::ExecuteDeferredInitializers();
/* make sure the thread pool gets initialized */
GetTP();
******************************************************************************/
#include "base/initialize.hpp"
-#include "base/utility.hpp"
+#include "base/loader.hpp"
using namespace icinga;
-bool icinga::InitializeOnceHelper(void (*func)(void))
+bool icinga::InitializeOnceHelper(void (*func)(void), int priority)
{
- Utility::AddDeferredInitializer(func);
+ Loader::AddDeferredInitializer(func, priority);
return true;
}
namespace icinga
{
-I2_BASE_API bool InitializeOnceHelper(void (*func)(void));
+I2_BASE_API bool InitializeOnceHelper(void (*func)(void), int priority = 0);
-#define INITIALIZE_ONCE(func) \
- namespace { namespace UNIQUE_NAME(io) { \
- I2_EXPORT bool l_InitializeOnce(icinga::InitializeOnceHelper(func)); \
+#define INITIALIZE_ONCE(func) \
+ namespace { namespace UNIQUE_NAME(io) { \
+ I2_EXPORT bool l_InitializeOnce(icinga::InitializeOnceHelper(func)); \
} }
+#define INITIALIZE_ONCE_WITH_PRIORITY(func, priority) \
+ namespace { namespace UNIQUE_NAME(io) { \
+ I2_EXPORT bool l_InitializeOnce(icinga::InitializeOnceHelper(func, priority)); \
+ } }
}
#endif /* INITIALIZE_H */
--- /dev/null
+/******************************************************************************
+ * Icinga 2 *
+ * Copyright (C) 2012-2015 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 "base/loader.hpp"
+#include "base/logger.hpp"
+#include <boost/foreach.hpp>
+
+using namespace icinga;
+
+/**
+ * Loads the specified library.
+ *
+ * @param library The name of the library.
+ */
+void Loader::LoadExtensionLibrary(const String& library)
+{
+ String path;
+#if defined(_WIN32)
+ path = library + ".dll";
+#elif defined(__APPLE__)
+ path = "lib" + library + ".dylib";
+#else /* __APPLE__ */
+ path = "lib" + library + ".so";
+#endif /* _WIN32 */
+
+ Log(LogInformation, "Utility")
+ << "Loading library '" << path << "'";
+
+#ifdef _WIN32
+ HMODULE hModule = LoadLibrary(path.CStr());
+
+ if (hModule == NULL) {
+ BOOST_THROW_EXCEPTION(win32_error()
+ << boost::errinfo_api_function("LoadLibrary")
+ << errinfo_win32_error(GetLastError())
+ << boost::errinfo_file_name(path));
+ }
+#else /* _WIN32 */
+ void *hModule = dlopen(path.CStr(), RTLD_NOW | RTLD_GLOBAL);
+
+ if (hModule == NULL) {
+ BOOST_THROW_EXCEPTION(std::runtime_error("Could not load library '" + path + "': " + dlerror()));
+ }
+#endif /* _WIN32 */
+
+ ExecuteDeferredInitializers();
+}
+
+boost::thread_specific_ptr<std::priority_queue<DeferredInitializer> >& Loader::GetDeferredInitializers(void)
+{
+ static boost::thread_specific_ptr<std::priority_queue<DeferredInitializer> > initializers;
+ return initializers;
+}
+
+void Loader::ExecuteDeferredInitializers(void)
+{
+ if (!GetDeferredInitializers().get())
+ return;
+
+ while (!GetDeferredInitializers().get()->empty()) {
+ DeferredInitializer initializer = GetDeferredInitializers().get()->top();
+ GetDeferredInitializers().get()->pop();
+ initializer();
+ }
+}
+
+void Loader::AddDeferredInitializer(const boost::function<void(void)>& callback, int priority)
+{
+ if (!GetDeferredInitializers().get())
+ GetDeferredInitializers().reset(new std::priority_queue<DeferredInitializer>());
+
+ GetDeferredInitializers().get()->push(DeferredInitializer(callback, priority));
+}
+
--- /dev/null
+/******************************************************************************
+ * Icinga 2 *
+ * Copyright (C) 2012-2015 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 LOADER_H
+#define LOADER_H
+
+#include "base/i2-base.hpp"
+#include "base/string.hpp"
+#include <boost/thread/tss.hpp>
+#include <boost/function.hpp>
+#include <queue>
+
+namespace icinga
+{
+
+struct DeferredInitializer
+{
+public:
+ DeferredInitializer(const boost::function<void (void)>& callback, int priority)
+ : m_Callback(callback), m_Priority(priority)
+ { }
+
+ inline bool operator<(const DeferredInitializer& other) const
+ {
+ return m_Priority < other.m_Priority;
+ }
+
+ inline void operator()(void)
+ {
+ m_Callback();
+ }
+
+private:
+ boost::function<void (void)> m_Callback;
+ int m_Priority;
+};
+
+/**
+ * Loader helper functions.
+ *
+ * @ingroup base
+ */
+class I2_BASE_API Loader
+{
+public:
+ static void LoadExtensionLibrary(const String& library);
+
+ static void AddDeferredInitializer(const boost::function<void(void)>& callback, int priority = 0);
+ static void ExecuteDeferredInitializers(void);
+
+private:
+ Loader(void);
+
+ static boost::thread_specific_ptr<std::priority_queue<DeferredInitializer> >& GetDeferredInitializers(void);
+
+};
+
+}
+
+#endif /* LOADER_H */
icinga::Type::Register(t); \
} \
\
- INITIALIZE_ONCE(RegisterType ## type); \
+ INITIALIZE_ONCE_WITH_PRIORITY(RegisterType ## type, 10); \
} } \
DEFINE_TYPE_INSTANCE(type)
#endif /* _WIN32 */
}
-/**
- * Loads the specified library.
- *
- * @param library The name of the library.
- */
-void Utility::LoadExtensionLibrary(const String& library)
-{
- String path;
-#if defined(_WIN32)
- path = library + ".dll";
-#elif defined(__APPLE__)
- path = "lib" + library + ".dylib";
-#else /* __APPLE__ */
- path = "lib" + library + ".so";
-#endif /* _WIN32 */
-
- Log(LogInformation, "Utility")
- << "Loading library '" << path << "'";
-
-#ifdef _WIN32
- HMODULE hModule = LoadLibrary(path.CStr());
-
- if (hModule == NULL) {
- BOOST_THROW_EXCEPTION(win32_error()
- << boost::errinfo_api_function("LoadLibrary")
- << errinfo_win32_error(GetLastError())
- << boost::errinfo_file_name(path));
- }
-#else /* _WIN32 */
- void *hModule = dlopen(path.CStr(), RTLD_NOW | RTLD_GLOBAL);
-
- if (hModule == NULL) {
- BOOST_THROW_EXCEPTION(std::runtime_error("Could not load library '" + path + "': " + dlerror()));
- }
-#endif /* _WIN32 */
-
- ExecuteDeferredInitializers();
-}
-
-boost::thread_specific_ptr<std::vector<boost::function<void(void)> > >& Utility::GetDeferredInitializers(void)
-{
- static boost::thread_specific_ptr<std::vector<boost::function<void(void)> > > initializers;
- return initializers;
-}
-
-void Utility::ExecuteDeferredInitializers(void)
-{
- if (!GetDeferredInitializers().get())
- return;
-
- BOOST_FOREACH(const boost::function<void(void)>& callback, *GetDeferredInitializers().get()) {
- VERIFY(callback);
- callback();
- }
-
- GetDeferredInitializers().reset();
-}
-
-void Utility::AddDeferredInitializer(const boost::function<void(void)>& callback)
-{
- if (!GetDeferredInitializers().get())
- GetDeferredInitializers().reset(new std::vector<boost::function<void(void)> >());
-
- GetDeferredInitializers().get()->push_back(callback);
-}
-
/**
* Generates a new unique ID.
*
static String FormatDateTime(const char *format, double ts);
static String FormatErrorNumber(int code);
- static void LoadExtensionLibrary(const String& library);
-
- static void AddDeferredInitializer(const boost::function<void(void)>& callback);
- static void ExecuteDeferredInitializers(void);
-
#ifndef _WIN32
static void SetNonBlocking(int fd);
static void SetCloExec(int fd);
static boost::thread_specific_ptr<String> m_ThreadName;
static boost::thread_specific_ptr<unsigned int> m_RandSeed;
- static boost::thread_specific_ptr<std::vector<boost::function<void(void)> > >& GetDeferredInitializers(void);
-
};
}
NodeUtility::PrintNodes(std::cout);
- Utility::LoadExtensionLibrary("icinga");
-
/* cache all existing object configs only once and pass it to AddObject() */
std::vector<String> object_paths = RepositoryUtility::GetObjects();
/* cache all existing changes only once and pass it to AddObject() */
std::vector<String> RepositoryObjectCommand::GetPositionalSuggestions(const String& word) const
{
if (m_Command == RepositoryCommandAdd) {
- Utility::LoadExtensionLibrary("icinga");
Type::Ptr ptype = Type::GetByName(m_Type);
ASSERT(ptype);
return GetFieldCompletionSuggestions(ptype, word);
}
if (m_Command == RepositoryCommandAdd) {
- Utility::LoadExtensionLibrary("icinga");
-
std::vector<String> object_paths = RepositoryUtility::GetObjects();
Array::Ptr changes = new Array();
bool TroubleshootCommand::CheckConfig(void)
{
- /* Not loading the icinga library would make config validation fail.
- * (Depending on the configuration and the speed of your machine.)
- */
- Utility::LoadExtensionLibrary("icinga");
std::vector<std::string> configs;
configs.push_back(Application::GetSysconfDir() + "/icinga2/icinga2.conf");
#include "config/configitem.hpp"
#include "base/logger.hpp"
#include "base/utility.hpp"
+#include "base/loader.hpp"
#include "base/context.hpp"
#include "base/exception.hpp"
#include <fstream>
*/
void ConfigCompiler::HandleLibrary(const String& library)
{
- Utility::LoadExtensionLibrary(library);
+ Loader::LoadExtensionLibrary(library);
}
void ConfigCompiler::CompileHelper(void)
delete expression; \
} \
\
- INITIALIZE_ONCE(RegisterConfigFragment); \
+ INITIALIZE_ONCE_WITH_PRIORITY(RegisterConfigFragment, 5); \
}
#endif /* CONFIGFRAGMENT_H */
#include "base/serializer.hpp"
#include "base/stdiostream.hpp"
#include "base/json.hpp"
+#include "base/loader.hpp"
#include "cli/daemonutility.hpp"
#include <boost/test/unit_test.hpp>
#include <fstream>
Application::DeclareSysconfDir("etc");
Application::DeclareLocalStateDir("var");
- Utility::LoadExtensionLibrary("icinga");
- Utility::LoadExtensionLibrary("methods"); //loaded by ITL
+ Loader::LoadExtensionLibrary("icinga");
+ Loader::LoadExtensionLibrary("methods"); //loaded by ITL
std::vector<std::string> configs;
configs.push_back(TestConfig);