Run INITIALIZE_ONCE() after static initializers.

Refs #6107
This commit is contained in:
Gunnar Beutner 2014-05-04 01:34:53 +02:00 committed by Gunnar Beutner
parent b1dab6c074
commit 0571d8a464
3 changed files with 58 additions and 3 deletions

View File

@ -21,6 +21,7 @@
#define INITIALIZE_H
#include "base/i2-base.h"
#include "base/utility.h"
namespace icinga
{
@ -29,7 +30,10 @@ typedef void (*InitializeFunc)(void);
inline bool InitializeOnceHelper(InitializeFunc func)
{
func();
if (Utility::GetLoadingLibrary())
Utility::AddDeferredInitializer(func);
else
func();
return true;
}

View File

@ -42,6 +42,8 @@ using namespace icinga;
boost::thread_specific_ptr<String> Utility::m_ThreadName;
boost::thread_specific_ptr<unsigned int> Utility::m_RandSeed;
boost::thread_specific_ptr<bool> Utility::m_LoadingLibrary;
boost::thread_specific_ptr<std::vector<boost::function<void(void)> > > Utility::m_DeferredInitializers;
/**
* Demangles a symbol name.
@ -368,8 +370,20 @@ Utility::LoadExtensionLibrary(const String& library)
Log(LogInformation, "base", "Loading library '" + path + "'");
m_DeferredInitializers.reset(new std::vector<boost::function<void(void)> >());
#ifdef _WIN32
HMODULE hModule = LoadLibrary(path.CStr());
HMODULE hModule;
try {
SetLoadingLibrary(true);
hModule = LoadLibrary(path.CStr());
} catch (...) {
SetLoadingLibrary(false);
throw;
}
SetLoadingLibrary(false);
if (hModule == NULL) {
BOOST_THROW_EXCEPTION(win32_error()
@ -378,16 +392,47 @@ Utility::LoadExtensionLibrary(const String& library)
<< boost::errinfo_file_name(path));
}
#else /* _WIN32 */
void *hModule = dlopen(path.CStr(), RTLD_NOW);
void *hModule;
try {
hModule = dlopen(path.CStr(), RTLD_NOW);
} catch (...) {
SetLoadingLibrary(false);
throw;
}
SetLoadingLibrary(false);
if (hModule == NULL) {
BOOST_THROW_EXCEPTION(std::runtime_error("Could not load library '" + path + "': " + dlerror()));
}
#endif /* _WIN32 */
BOOST_FOREACH(const boost::function<void(void)>& callback, *m_DeferredInitializers.get())
callback();
m_DeferredInitializers.reset();
return hModule;
}
bool Utility::GetLoadingLibrary(void)
{
bool *loading = m_LoadingLibrary.get();
return loading && *loading;
}
void Utility::SetLoadingLibrary(bool loading)
{
bool *ploading = new bool(loading);
m_LoadingLibrary.reset(ploading);
}
void Utility::AddDeferredInitializer(const boost::function<void(void)>& callback)
{
m_DeferredInitializers.get()->push_back(callback);
}
/**
* Generates a new unique ID.
*

View File

@ -97,6 +97,10 @@ public:
#endif /* _WIN32 */
LoadExtensionLibrary(const String& library);
static bool GetLoadingLibrary(void);
static void SetLoadingLibrary(bool loading);
static void AddDeferredInitializer(const boost::function<void(void)>& callback);
#ifndef _WIN32
static void SetNonBlocking(int fd);
static void SetCloExec(int fd);
@ -125,6 +129,8 @@ private:
static boost::thread_specific_ptr<String> m_ThreadName;
static boost::thread_specific_ptr<unsigned int> m_RandSeed;
static boost::thread_specific_ptr<bool> m_LoadingLibrary;
static boost::thread_specific_ptr<std::vector<boost::function<void(void)> > > m_DeferredInitializers;
};
}