timer.h \
unix.cpp \
unix.h \
+ utility.cpp \
+ utility.h \
variant.cpp \
variant.h \
win32.cpp \
Application::~Application(void)
{
- Timer::StopAllTimers();
- Socket::CloseAllSockets();
-
- for (map<string, Component::Ptr>::iterator i = m_Components.begin(); i != m_Components.end(); i++) {
+ for (map<string, Component::Ptr>::iterator i = m_Components.begin();
+ i != m_Components.end(); i++) {
i->second->Stop();
}
FD_ZERO(&exceptfds);
Socket::CollectionType::iterator prev, i;
- for (i = Socket::Sockets.begin(); i != Socket::Sockets.end(); ) {
+ for (i = Socket::Sockets.begin();
+ i != Socket::Sockets.end(); ) {
Socket::Ptr socket = i->lock();
prev = i;
Sleep(tv.tv_sec * 1000 + tv.tv_usec);
ready = 0;
} else
- ready = select(nfds + 1, &readfds, &writefds, &exceptfds, &tv);
+ ready = select(nfds + 1, &readfds, &writefds,
+ &exceptfds, &tv);
if (ready < 0)
break;
EventArgs ea;
ea.Source = shared_from_this();
- for (i = Socket::Sockets.begin(); i != Socket::Sockets.end(); ) {
+ for (i = Socket::Sockets.begin();
+ i != Socket::Sockets.end(); ) {
Socket::Ptr socket = i->lock();
prev = i;
continue;
}
- int fd = socket->GetFD();
+ int fd;
- if (FD_ISSET(fd, &writefds) && socket->GetFD() != INVALID_SOCKET)
+ fd = socket->GetFD();
+ if (fd != INVALID_SOCKET && FD_ISSET(fd, &writefds))
socket->OnWritable(ea);
- if (FD_ISSET(fd, &readfds) && socket->GetFD() != INVALID_SOCKET)
+ fd = socket->GetFD();
+ if (fd != INVALID_SOCKET && FD_ISSET(fd, &readfds))
socket->OnReadable(ea);
- if (FD_ISSET(fd, &exceptfds) && socket->GetFD() != INVALID_SOCKET)
+ fd = socket->GetFD();
+ if (fd != INVALID_SOCKET && FD_ISSET(fd, &exceptfds))
socket->OnException(ea);
}
}
}
-bool Application::Daemonize(void) {
-#ifndef _WIN32
- pid_t pid;
- pid_t sid;
- int fd;
-
- pid = fork();
- if (pid == -1) {
- return false;
- }
-
- if (pid) {
- fprintf(stdout, "DONE\n");
- exit(0);
- }
-
- fd = open("/dev/null", O_RDWR);
- if (fd) {
- if (fd != 0) {
- dup2(fd, 0);
- }
-
- if (fd != 1) {
- dup2(fd, 1);
- }
-
- if (fd != 2) {
- dup2(fd, 2);
- }
-
- if (fd > 2) {
- close(fd);
- }
- }
-
- sid = setsid();
- if (sid == -1) {
- return false;
- }
-#endif
-
- return true;
-}
-
void Application::Shutdown(void)
{
m_ShuttingDown = true;
}
-ConfigHive::Ptr Application::GetConfigHive(void)
+ConfigHive::Ptr Application::GetConfigHive(void) const
{
return m_ConfigHive;
}
-Component::Ptr Application::LoadComponent(const string& path, const ConfigObject::Ptr& componentConfig)
+Component::Ptr Application::LoadComponent(const string& path,
+ const ConfigObject::Ptr& componentConfig)
{
Component::Ptr component;
Component *(*pCreateComponent)();
throw ComponentLoadException("Could not load module");
#ifdef _WIN32
- pCreateComponent = (Component *(*)())GetProcAddress(hModule, "CreateComponent");
+ pCreateComponent = (CreateComponentFunction)GetProcAddress(hModule,
+ "CreateComponent");
#else /* _WIN32 */
- pCreateComponent = (Component *(*)())lt_dlsym(hModule, "CreateComponent");
+ pCreateComponent = (CreateComponentFunction)lt_dlsym(hModule,
+ "CreateComponent");
#endif /* _WIN32 */
if (pCreateComponent == NULL)
- throw ComponentLoadException("Loadable module does not contain CreateComponent function");
+ throw ComponentLoadException("Loadable module does not "
+ "contain CreateComponent function");
component = Component::Ptr(pCreateComponent());
component->SetConfig(componentConfig);
m_Arguments = arguments;
}
-const vector<string>& Application::GetArguments(void)
+const vector<string>& Application::GetArguments(void) const
{
return m_Arguments;
}
-const string& Application::GetExeDirectory(void)
+string Application::GetExeDirectory(void) const
{
static string ExePath;
return m_Debugging;
}
-void Application::SigIntHandler(int signum)
+#ifndef _WIN32
+static void ApplicationSigIntHandler(int signum)
{
Application::Instance->Shutdown();
-#ifndef _WIN32
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_DFL;
sigaction(SIGINT, &sa, NULL);
-#endif /* _WIN32 */
-}
-
-static void application_sigint_handler(int signum)
-{
- Application::Instance->SigIntHandler(signum);
}
+#endif /* _WIN32 */
-int application_main(int argc, char **argv, Application *instance)
+int icinga::RunApplication(int argc, char **argv, Application *instance)
{
int result;
#ifndef _WIN32
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
- sa.sa_handler = application_sigint_handler;
+ sa.sa_handler = ApplicationSigIntHandler;
sigaction(SIGINT, &sa, NULL);
#endif /* _WIN32 */
result = Application::Instance->Main(args);
} catch (const Exception& ex) {
cerr << "---" << endl;
-
- string klass = typeid(ex).name();
-
-#ifdef HAVE_GCC_ABI_DEMANGLE
- int status;
- char *realname = abi::__cxa_demangle(klass.c_str(), 0, 0, &status);
-
- if (realname != NULL) {
- klass = string(realname);
- free(realname);
- }
-#endif /* HAVE_GCC_ABI_DEMANGLE */
-
- cerr << "Exception: " << klass << endl;
+ cerr << "Exception: " << Utility::GetTypeName(ex) << endl;
cerr << "Message: " << ex.GetMessage() << endl;
return EXIT_FAILURE;
}
}
- Application::Instance.reset();
-
- assert(Object::ActiveObjects == 0);
-
return result;
}
vector<string> m_Arguments;
bool m_Debugging;
+protected:
+ void RunEventLoop(void);
+ string GetExeDirectory(void) const;
+
public:
typedef shared_ptr<Application> Ptr;
typedef weak_ptr<Application> WeakPtr;
virtual int Main(const vector<string>& args) = 0;
void SetArguments(const vector<string>& arguments);
- const vector<string>& GetArguments(void);
+ const vector<string>& GetArguments(void) const;
- void RunEventLoop(void);
- bool Daemonize(void);
void Shutdown(void);
void Log(const char *format, ...);
- ConfigHive::Ptr GetConfigHive(void);
+ ConfigHive::Ptr GetConfigHive(void) const;
- shared_ptr<Component> LoadComponent(const string& path, const ConfigObject::Ptr& componentConfig);
+ shared_ptr<Component> LoadComponent(const string& path,
+ const ConfigObject::Ptr& componentConfig);
void RegisterComponent(shared_ptr<Component> component);
void UnregisterComponent(shared_ptr<Component> component);
shared_ptr<Component> GetComponent(const string& name);
void AddComponentSearchDir(const string& componentDirectory);
- const string& GetExeDirectory(void);
-
bool IsDebugging(void) const;
- void SigIntHandler(int signum);
};
-}
+int I2_EXPORT RunApplication(int argc, char **argv, Application *instance);
-int I2_EXPORT application_main(int argc, char **argv, icinga::Application *instance);
+}
#define IMPLEMENT_ENTRY_POINT(klass) \
- int main(int argc, char **argv) { \
- klass *instance = new klass(); \
- return application_main(argc, argv, instance); \
+ int main(int argc, char **argv) { \
+ klass *instance = new klass(); \
+ return icinga::RunApplication(argc, argv, instance); \
}
#endif /* APPLICATION_H */
<ClCompile Include="thread.cpp" />
<ClCompile Include="timer.cpp" />
<ClCompile Include="unix.cpp" />
+ <ClCompile Include="utility.cpp" />
<ClCompile Include="variant.cpp" />
<ClCompile Include="win32.cpp" />
</ItemGroup>
<ClInclude Include="thread.h" />
<ClInclude Include="timer.h" />
<ClInclude Include="unix.h" />
+ <ClInclude Include="utility.h" />
<ClInclude Include="variant.h" />
<ClInclude Include="win32.h" />
</ItemGroup>
virtual void Stop(void) = 0;
};
+typedef Component *(*CreateComponentFunction)(void);
+
#define EXPORT_COMPONENT(klass) \
extern "C" I2_EXPORT icinga::Component *CreateComponent(void) \
- { \
- return new klass(); \
+ { \
+ return new klass(); \
}
}
namespace icinga
{
+/**
+ * CondVar
+ *
+ * A wrapper around OS-specific condition variable functionality.
+ */
class I2_BASE_API CondVar
{
private:
Event<EventArgs> OnObjectCreated;
Event<EventArgs> OnObjectRemoved;
- Event<DictionaryPropertyChangedEventArgs> OnPropertyChanged;
+ Event<PropertyChangedEventArgs> OnPropertyChanged;
};
}
return ci->second;
}
-void ConfigHive::ForEachObject(const string& type, function<int (const EventArgs&)> callback)
+void ConfigHive::ForEachObject(const string& type,
+ function<int (const EventArgs&)> callback)
{
CollectionIterator ci = Collections.find(type);
void AddObject(const ConfigObject::Ptr& object);
void RemoveObject(const ConfigObject::Ptr& object);
- ConfigObject::Ptr GetObject(const string& collection, const string& name = string());
+ ConfigObject::Ptr GetObject(const string& collection,
+ const string& name = string());
ConfigCollection::Ptr GetCollection(const string& collection);
- void ForEachObject(const string& type, function<int (const EventArgs&)> callback);
+ void ForEachObject(const string& type,
+ function<int (const EventArgs&)> callback);
Event<EventArgs> OnObjectCreated;
Event<EventArgs> OnObjectRemoved;
- Event<DictionaryPropertyChangedEventArgs> OnPropertyChanged;
+ Event<PropertyChangedEventArgs> OnPropertyChanged;
};
}
return m_Replicated;
}
-int ConfigObject::PropertyChangedHandler(const DictionaryPropertyChangedEventArgs dpcea)
+int ConfigObject::PropertyChangedHandler(const PropertyChangedEventArgs& dpcea)
{
ConfigHive::Ptr hive = m_Hive.lock();
if (hive) {
string m_Type;
bool m_Replicated;
- int PropertyChangedHandler(const DictionaryPropertyChangedEventArgs dpcea);
+ int PropertyChangedHandler(const PropertyChangedEventArgs& dpcea);
public:
typedef shared_ptr<ConfigObject> Ptr;
template<class TObject, class TArgs>
function<int (TArgs)> bind_weak(int (TObject::*function)(TArgs), const weak_ptr<TObject>& wref)
{
- return bind<int>(delegate_fwd<TObject, TArgs>, function, wref, _1);
+ return bind(delegate_fwd<TObject, TArgs>, function, wref, _1);
}
template<class TObject, class TArgs>
m_Data[key] = value;
- DictionaryPropertyChangedEventArgs dpce;
+ PropertyChangedEventArgs dpce;
dpce.Source = shared_from_this();
dpce.Property = key;
dpce.OldValue = oldValue;
typedef map<string, Variant>::const_iterator ConstDictionaryIterator;
typedef map<string, Variant>::iterator DictionaryIterator;
-struct I2_BASE_API DictionaryPropertyChangedEventArgs : public EventArgs
+struct I2_BASE_API PropertyChangedEventArgs : public EventArgs
{
string Property;
Variant OldValue;
DictionaryIterator Begin(void);
DictionaryIterator End(void);
- Event<DictionaryPropertyChangedEventArgs> OnPropertyChanged;
+ Event<PropertyChangedEventArgs> OnPropertyChanged;
};
}
typedef function<int (const TArgs&)> DelegateType;
private:
- list<DelegateType> m_Delegates;
+ vector<DelegateType> m_Delegates;
public:
- void Hook(const DelegateType& delegate)
- {
- m_Delegates.push_front(delegate);
- }
-
- void Unhook(const DelegateType& delegate)
- {
- m_Delegates.remove(delegate);
- }
-
Event<TArgs>& operator +=(const DelegateType& rhs)
{
- Hook(rhs);
+ m_Delegates.push_back(rhs);
return *this;
}
Event<TArgs>& operator -=(const DelegateType& rhs)
{
- Unhook(rhs);
+ m_Delegates.erase(rhs);
return *this;
}
void operator()(const TArgs& args)
{
- typename list<DelegateType>::iterator prev, i;
+ typename vector<DelegateType>::iterator prev, i;
for (i = m_Delegates.begin(); i != m_Delegates.end(); ) {
prev = i;
Exception::Exception(const string& message)
{
- m_Message = message;
+ SetMessage(message);
}
-Exception::~Exception(void)
+string Exception::GetMessage(void) const
{
+ return m_Message;
}
-string Exception::GetMessage(void) const
+void Exception::SetMessage(string message)
{
- return m_Message;
+ m_Message = message;
+}
+
+#ifdef _WIN32
+string Win32Exception::FormatErrorCode(int code)
+{
+ char *message;
+ string result = "Unknown error.";
+
+ DWORD rc = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM, NULL, code, 0, (char *)&message,
+ 0, NULL);
+
+ if (rc != 0) {
+ result = string(message);
+ LocalFree(message);
+ }
+
+ return result;
}
+#endif /* _WIN32 */
+
+string PosixException::FormatErrorCode(int code)
+{
+ return strerror(code);
+}
\ No newline at end of file
namespace icinga
{
+/**
+ * Exception
+ *
+ * Base class for all exceptions.
+ */
class I2_BASE_API Exception
{
private:
string m_Message;
-public:
- typedef shared_ptr<Exception> Ptr;
- typedef weak_ptr<Exception> WeakPtr;
+protected:
+ void SetMessage(string message);
+public:
Exception(void);
Exception(const string& message);
- virtual ~Exception(void);
+ /**
+ * ~Exception
+ *
+ * Required for RTTI.
+ */
+ virtual ~Exception(void)
+ {
+ }
string GetMessage(void) const;
};
class klass : public Exception \
{ \
public: \
- typedef shared_ptr<klass> Ptr; \
- typedef weak_ptr<klass> WeakPtr; \
- \
inline klass(void) : Exception() \
{ \
} \
DEFINE_EXCEPTION_CLASS(NotImplementedException);
DEFINE_EXCEPTION_CLASS(InvalidArgumentException);
+#ifdef _WIN32
+class Win32Exception : public Exception
+{
+public:
+ inline Win32Exception(const string& message, int errorCode)
+ {
+ SetMessage(message + ": " + FormatErrorCode(errorCode));
+ }
+
+ static string FormatErrorCode(int code);
+};
+#endif /* _WIN32 */
+
+class PosixException : public Exception
+{
+public:
+ inline PosixException(const string& message, int errorCode)
+ {
+ SetMessage(message + ": " + FormatErrorCode(errorCode));
+ }
+
+ static string FormatErrorCode(int code);
+};
+
}
#endif /* EXCEPTION_H */
#include "mutex.h"
#include "condvar.h"
#include "thread.h"
+#include "utility.h"
#include "object.h"
#include "exception.h"
#include "memory.h"
void *ptr = malloc(size);
if (size != 0 && ptr == NULL)
- throw OutOfMemoryException();
+ throw OutOfMemoryException("malloc failed.");
return ptr;
}
void *new_ptr = realloc(ptr, size);
if (size != 0 && new_ptr == NULL)
- throw OutOfMemoryException();
+ throw OutOfMemoryException("realloc failed.");
return new_ptr;
}
char *new_str = strdup(str);
if (str == NULL)
- throw OutOfMemoryException();
+ throw OutOfMemoryException("strdup failed.");
return new_str;
}
DEFINE_EXCEPTION_CLASS(OutOfMemoryException);
+/**
+ * Memory
+ *
+ * Singleton class which implements memory allocation helpers.
+ */
class I2_BASE_API Memory
{
private:
namespace icinga
{
+/**
+ * Mutex
+ *
+ * A wrapper around OS-specific mutex functionality.
+ */
class I2_BASE_API Mutex
{
private:
#include "i2-base.h"
using namespace icinga;
-
-unsigned long Object::ActiveObjects;
-
-Object::Object(void) {
- ActiveObjects++;
-}
-
-Object::~Object(void) {
- ActiveObjects--;
-}
namespace icinga
{
+/**
+ * Object
+ *
+ * Base class for all heap-allocated objects. At least one of its methods
+ * has to be virtual for RTTI to work.
+ */
class I2_BASE_API Object : public enable_shared_from_this<Object>
{
private:
- Object(const Object &other);
+ Object(const Object& other);
protected:
- Object(void);
- virtual ~Object(void);
+ inline Object(void)
+ {
+ }
+
+ inline virtual ~Object(void)
+ {
+ }
public:
typedef shared_ptr<Object> Ptr;
typedef weak_ptr<Object> WeakPtr;
-
- static unsigned long ActiveObjects;
};
template<class T>
typedef function<Object::Ptr ()> factory_function;
+/**
+ * factory<T>
+ *
+ * Returns a new object of type T.
+ */
template<class T>
Object::Ptr factory(void)
{
closesocket(m_FD);
m_FD = INVALID_SOCKET;
- /* nobody can possibly have a valid event subscription when the destructor has been called */
+ /* nobody can possibly have a valid event subscription when the
+ destructor has been called */
if (!from_dtor) {
EventArgs ea;
ea.Source = shared_from_this();
Stop();
}
-string Socket::FormatErrorCode(int code)
-{
- char *message;
- string result = "Unknown socket error.";
-
-#ifdef _WIN32
- if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, code, 0, (char *)&message, 0, NULL) != 0) {
- result = string(message);
- LocalFree(message);
- }
-#else /* _WIN32 */
- if (code != 0)
- message = strerror(code);
-
- result = string(message);
-#endif /* _WIN32 */
-
- return result;
-}
-
-int Socket::ExceptionEventHandler(const EventArgs& ea)
+void Socket::HandleSocketError(void)
{
int opt;
socklen_t optlen = sizeof(opt);
int rc = getsockopt(GetFD(), SOL_SOCKET, SO_ERROR, (char *)&opt, &optlen);
- if (rc < 0) {
- Close();
- return 0;
- }
-
- if (opt != 0) {
+ if (rc >= 0 && opt != 0) {
SocketErrorEventArgs sea;
sea.Code = opt;
- sea.Message = FormatErrorCode(sea.Code);
+#ifdef _WIN32
+ sea.Message = Win32Exception::FormatErrorCode(sea.Code);
+#else /* _WIN32 */
+ sea.Message = PosixException::FormatErrorCode(sea.Code);
+#endif /* _WIN32 */
OnError(sea);
-
- Close();
}
- return 0;
+ Close();
+ return;
}
-void Socket::CloseAllSockets(void)
+int Socket::ExceptionEventHandler(const EventArgs& ea)
{
- for (Socket::CollectionType::iterator i = Sockets.begin(); i != Sockets.end(); ) {
- Socket::Ptr socket = i->lock();
-
- i++;
-
- if (socket == NULL)
- continue;
+ HandleSocketError();
- socket->Close();
- }
+ return 0;
}
bool Socket::WantsToRead(void) const
int ExceptionEventHandler(const EventArgs& ea);
-protected:
- string FormatErrorCode(int errorCode);
-
protected:
Socket(void);
+ void HandleSocketError(void);
void Close(bool from_dtor);
public:
void SetFD(SOCKET fd);
SOCKET GetFD(void) const;
- static void CloseAllSockets(void);
-
Event<EventArgs> OnReadable;
Event<EventArgs> OnWritable;
Event<EventArgs> OnException;
#else /* _WIN32 */
if (rc < 0 && errno != EINPROGRESS) {
#endif /* _WIN32 */
- SocketErrorEventArgs sea;
-#ifdef _WIN32
- sea.Code = WSAGetLastError();
-#else /* _WIN32 */
- sea.Code = errno;
-#endif /* _WIN32 */
- sea.Message = FormatErrorCode(sea.Code);
-
- OnError(sea);
-
- Close();
+ HandleSocketError();
}
m_PeerHost = hostname;
return 0;
if (rc <= 0) {
- if (rc < 0) {
- SocketErrorEventArgs sea;
-#ifdef _WIN32
- sea.Code = WSAGetLastError();
-#else /* _WIN32 */
- sea.Code = errno;
-#endif /* _WIN32 */
- sea.Message = FormatErrorCode(sea.Code);
-
- OnError(sea);
- }
-
- Close();
+ HandleSocketError();
return 0;
}
rc = send(GetFD(), (const char *)m_SendQueue->GetReadBuffer(), m_SendQueue->GetSize(), 0);
if (rc <= 0) {
- if (rc < 0) {
- SocketErrorEventArgs sea;
-#ifdef _WIN32
- sea.Code = WSAGetLastError();
-#else /* _WIN32 */
- sea.Code = errno;
-#endif /* _WIN32 */
- sea.Message = FormatErrorCode(sea.Code);
-
- OnError(sea);
- }
-
- Close();
+ HandleSocketError();
return 0;
}
fd = accept(GetFD(), (sockaddr *)&addr, &addrlen);
- if (fd == INVALID_SOCKET) {
- SocketErrorEventArgs sea;
-#ifdef _WIN32
- sea.Code = WSAGetLastError();
-#else /* _WIN32 */
- sea.Code = errno;
-#endif /* _WIN32 */
- sea.Message = FormatErrorCode(sea.Code);
-
- OnError(sea);
-
- Close();
+ if (fd < 0) {
+ HandleSocketError();
+ return 0;
}
NewClientEventArgs nea;
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd == INVALID_SOCKET) {
- SocketErrorEventArgs sea;
-#ifdef _WIN32
- sea.Code = WSAGetLastError();
-#else /* _WIN32 */
- sea.Code = errno;
-#endif /* _WIN32 */
- sea.Message = FormatErrorCode(sea.Code);
- OnError(sea);
+ HandleSocketError();
+
+ return;
}
SetFD(fd);
sin.sin_addr.s_addr = hostname ? inet_addr(hostname) : htonl(INADDR_ANY);
sin.sin_port = htons(port);
- int rc = ::bind(GetFD(), (sockaddr *)&sin, sizeof(sin));
-
- if (rc < 0) {
- SocketErrorEventArgs sea;
-#ifdef _WIN32
- sea.Code = WSAGetLastError();
-#else /* _WIN32 */
- sea.Code = errno;
-#endif /* _WIN32 */
- sea.Message = FormatErrorCode(sea.Code);
-
- OnError(sea);
-
- Close();
- }
+ if (::bind(GetFD(), (sockaddr *)&sin, sizeof(sin)) < 0)
+ HandleSocketError();
}
void *param;
} threadparam_t;
+/**
+ * ThreadStartProc
+ *
+ * Helper function that deals with OS-specific differences in the thread
+ * proc's function signature.
+ */
#ifdef _WIN32
static DWORD WINAPI ThreadStartProc(LPVOID param)
{
}
#endif /* _WIN32 */
-
+/**
+ * Thread
+ *
+ * Constructor for the thread class. Creates a new thread that begins
+ * executing immediately.
+ */
Thread::Thread(ThreadProc callback)
{
threadparam_t *tparam = new threadparam_t();
if (tparam == NULL)
- throw exception(/*"Out of memory"*/);
+ throw OutOfMemoryException("Out of memory");
#ifdef _WIN32
m_Thread = CreateThread(NULL, 0, ThreadStartProc, tparam, CREATE_SUSPENDED, NULL);
+
+ if (m_Thread == NULL)
+ throw Win32Exception("CreateThread failed.", GetLastError());
#else /* _WIN32 */
pthread_create(&m_Thread, NULL, ThreadStartProc, &tparam);
#endif /* _WIN32 */
}
+/**
+ * ~Thread
+ *
+ * Destructor for the Thread class. Cleans up the resources associated
+ * with the thread.
+ */
Thread::~Thread(void)
{
#ifdef _WIN32
#endif
}
+/**
+ * Join
+ *
+ * Waits until the thread has finished executing.
+ */
void Thread::Join(void)
{
#ifdef _WIN32
typedef void (*ThreadProc)(void *);
+/**
+ * Thread
+ *
+ * A wrapper around OS-specific thread functionality.
+ */
class I2_BASE_API Thread
{
private:
#endif
public:
- Thread(void (*callback)(void *));
+ Thread(ThreadProc callback);
~Thread(void);
- void Start(void);
void Join(void);
};
}
}
-void Timer::StopAllTimers(void)
-{
- for (Timer::CollectionType::iterator i = Timers.begin(); i != Timers.end(); ) {
- Timer::Ptr timer = i->lock();
-
- i++;
-
- if (timer == NULL)
- continue;
-
- timer->Stop();
- }
-}
-
/* Note: the timer delegate must not call Disable() on any other timers than
* the timer that originally invoked the delegate */
void Timer::Call(void)
static time_t GetNextCall(void);
static void CallExpiredTimers(void);
- static void StopAllTimers(void);
void Start(void);
void Stop(void);
--- /dev/null
+#include "i2-base.h"
+
+using namespace icinga;
+
+/**
+ * Daemonize
+ *
+ * Detaches from the controlling terminal.
+ */
+void Utility::Daemonize(void) {
+#ifndef _WIN32
+ pid_t pid;
+ pid_t sid;
+ int fd;
+
+ pid = fork();
+ if (pid == -1) {
+ return false;
+ }
+
+ if (pid)
+ exit(0);
+
+ fd = open("/dev/null", O_RDWR);
+ if (fd) {
+ if (fd != 0) {
+ dup2(fd, 0);
+ }
+
+ if (fd != 1) {
+ dup2(fd, 1);
+ }
+
+ if (fd != 2) {
+ dup2(fd, 2);
+ }
+
+ if (fd > 2) {
+ close(fd);
+ }
+ }
+
+ sid = setsid();
+ if (sid == -1) {
+ return false;
+ }
+#endif
+}
--- /dev/null
+#ifndef UTILITY_H
+#define UTILITY_H
+
+namespace icinga
+{
+
+/**
+ * Utility
+ *
+ * Utility functions.
+ */
+class I2_BASE_API Utility
+{
+private:
+ Utility(void);
+
+public:
+ /**
+ * GetTypeName
+ *
+ * Returns the type name of an object (using RTTI).
+ */
+ template<class T>
+ static string GetTypeName(const T& value)
+ {
+ string klass = typeid(value).name();
+
+#ifdef HAVE_GCC_ABI_DEMANGLE
+ int status;
+ char *realname = abi::__cxa_demangle(klass.c_str(), 0, 0, &status);
+
+ if (realname != NULL) {
+ klass = string(realname);
+ free(realname);
+ }
+#endif /* HAVE_GCC_ABI_DEMANGLE */
+
+ return klass;
+ }
+
+ static void Daemonize(void);
+};
+
+}
+
+#endif /* UTILITY_H */
return 0;
}
-int ConfigRpcComponent::LocalPropertyChangedHandler(const DictionaryPropertyChangedEventArgs& ea)
+int ConfigRpcComponent::LocalPropertyChangedHandler(const PropertyChangedEventArgs& ea)
{
ConfigObject::Ptr object = static_pointer_cast<ConfigObject>(ea.Source);
int LocalObjectCreatedHandler(const EventArgs& ea);
int LocalObjectRemovedHandler(const EventArgs& ea);
- int LocalPropertyChangedHandler(const DictionaryPropertyChangedEventArgs& ea);
+ int LocalPropertyChangedHandler(const PropertyChangedEventArgs& ea);
int FetchObjectsHandler(const NewRequestEventArgs& ea);
int RemoteObjectUpdatedHandler(const NewRequestEventArgs& ea);