From: Gunnar Beutner Date: Sun, 22 Apr 2012 14:45:31 +0000 (+0200) Subject: Code cleanup X-Git-Tag: v0.0.1~605 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=69c30c264ad7e74dc8f63a6d1ee25c7968a83b54;p=icinga2 Code cleanup --- diff --git a/base/Makefile.am b/base/Makefile.am index ef7f2ee0e..c67020e51 100644 --- a/base/Makefile.am +++ b/base/Makefile.am @@ -47,6 +47,8 @@ libbase_la_SOURCES = \ timer.h \ unix.cpp \ unix.h \ + utility.cpp \ + utility.h \ variant.cpp \ variant.h \ win32.cpp \ diff --git a/base/application.cpp b/base/application.cpp index aab9f8e8f..336788af3 100644 --- a/base/application.cpp +++ b/base/application.cpp @@ -31,10 +31,8 @@ Application::Application(void) Application::~Application(void) { - Timer::StopAllTimers(); - Socket::CloseAllSockets(); - - for (map::iterator i = m_Components.begin(); i != m_Components.end(); i++) { + for (map::iterator i = m_Components.begin(); + i != m_Components.end(); i++) { i->second->Stop(); } @@ -60,7 +58,8 @@ void Application::RunEventLoop(void) 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; @@ -102,7 +101,8 @@ void Application::RunEventLoop(void) 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; @@ -112,7 +112,8 @@ void Application::RunEventLoop(void) 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; @@ -123,75 +124,35 @@ void Application::RunEventLoop(void) 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)(); @@ -208,13 +169,16 @@ Component::Ptr Application::LoadComponent(const string& path, const ConfigObject 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); @@ -270,12 +234,12 @@ void Application::SetArguments(const vector& arguments) m_Arguments = arguments; } -const vector& Application::GetArguments(void) +const vector& Application::GetArguments(void) const { return m_Arguments; } -const string& Application::GetExeDirectory(void) +string Application::GetExeDirectory(void) const { static string ExePath; @@ -364,24 +328,19 @@ bool Application::IsDebugging(void) const 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; @@ -390,7 +349,7 @@ int application_main(int argc, char **argv, Application *instance) #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 */ @@ -408,29 +367,12 @@ int application_main(int argc, char **argv, Application *instance) 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; } diff --git a/base/application.h b/base/application.h index 48acddf83..164c0d47c 100644 --- a/base/application.h +++ b/base/application.h @@ -15,6 +15,10 @@ private: vector m_Arguments; bool m_Debugging; +protected: + void RunEventLoop(void); + string GetExeDirectory(void) const; + public: typedef shared_ptr Ptr; typedef weak_ptr WeakPtr; @@ -27,36 +31,32 @@ public: virtual int Main(const vector& args) = 0; void SetArguments(const vector& arguments); - const vector& GetArguments(void); + const vector& 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 LoadComponent(const string& path, const ConfigObject::Ptr& componentConfig); + shared_ptr LoadComponent(const string& path, + const ConfigObject::Ptr& componentConfig); void RegisterComponent(shared_ptr component); void UnregisterComponent(shared_ptr component); shared_ptr 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 */ diff --git a/base/base.vcxproj b/base/base.vcxproj index 9cc9a0e79..964475906 100644 --- a/base/base.vcxproj +++ b/base/base.vcxproj @@ -30,6 +30,7 @@ + @@ -56,6 +57,7 @@ + diff --git a/base/component.h b/base/component.h index 97f1dd870..ccae32221 100644 --- a/base/component.h +++ b/base/component.h @@ -25,10 +25,12 @@ public: 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(); \ } } diff --git a/base/condvar.h b/base/condvar.h index 03c92b332..b515dadfe 100644 --- a/base/condvar.h +++ b/base/condvar.h @@ -4,6 +4,11 @@ namespace icinga { +/** + * CondVar + * + * A wrapper around OS-specific condition variable functionality. + */ class I2_BASE_API CondVar { private: diff --git a/base/configcollection.h b/base/configcollection.h index dfcb3c84b..dd9658c2f 100644 --- a/base/configcollection.h +++ b/base/configcollection.h @@ -29,7 +29,7 @@ public: Event OnObjectCreated; Event OnObjectRemoved; - Event OnPropertyChanged; + Event OnPropertyChanged; }; } diff --git a/base/confighive.cpp b/base/confighive.cpp index fb43ce3af..b51c15d8c 100644 --- a/base/confighive.cpp +++ b/base/confighive.cpp @@ -30,7 +30,8 @@ ConfigCollection::Ptr ConfigHive::GetCollection(const string& collection) return ci->second; } -void ConfigHive::ForEachObject(const string& type, function callback) +void ConfigHive::ForEachObject(const string& type, + function callback) { CollectionIterator ci = Collections.find(type); diff --git a/base/confighive.h b/base/confighive.h index a8654cbd0..e5b3bfb6d 100644 --- a/base/confighive.h +++ b/base/confighive.h @@ -15,14 +15,16 @@ public: 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 callback); + void ForEachObject(const string& type, + function callback); Event OnObjectCreated; Event OnObjectRemoved; - Event OnPropertyChanged; + Event OnPropertyChanged; }; } diff --git a/base/configobject.cpp b/base/configobject.cpp index f256f0ec4..2999a6aa9 100644 --- a/base/configobject.cpp +++ b/base/configobject.cpp @@ -53,7 +53,7 @@ bool ConfigObject::GetReplicated(void) const return m_Replicated; } -int ConfigObject::PropertyChangedHandler(const DictionaryPropertyChangedEventArgs dpcea) +int ConfigObject::PropertyChangedHandler(const PropertyChangedEventArgs& dpcea) { ConfigHive::Ptr hive = m_Hive.lock(); if (hive) { diff --git a/base/configobject.h b/base/configobject.h index d35e1513b..bea58f0d9 100644 --- a/base/configobject.h +++ b/base/configobject.h @@ -17,7 +17,7 @@ private: string m_Type; bool m_Replicated; - int PropertyChangedHandler(const DictionaryPropertyChangedEventArgs dpcea); + int PropertyChangedHandler(const PropertyChangedEventArgs& dpcea); public: typedef shared_ptr Ptr; diff --git a/base/delegate.h b/base/delegate.h index beae350fe..86ded1fb2 100644 --- a/base/delegate.h +++ b/base/delegate.h @@ -18,7 +18,7 @@ int delegate_fwd(int (TObject::*function)(TArgs), weak_ptr wref, const template function bind_weak(int (TObject::*function)(TArgs), const weak_ptr& wref) { - return bind(delegate_fwd, function, wref, _1); + return bind(delegate_fwd, function, wref, _1); } template diff --git a/base/dictionary.cpp b/base/dictionary.cpp index 965278519..6db6d6a59 100644 --- a/base/dictionary.cpp +++ b/base/dictionary.cpp @@ -25,7 +25,7 @@ void Dictionary::SetProperty(string key, const Variant& value) m_Data[key] = value; - DictionaryPropertyChangedEventArgs dpce; + PropertyChangedEventArgs dpce; dpce.Source = shared_from_this(); dpce.Property = key; dpce.OldValue = oldValue; diff --git a/base/dictionary.h b/base/dictionary.h index 127f9d6a6..5c16d1dcb 100644 --- a/base/dictionary.h +++ b/base/dictionary.h @@ -7,7 +7,7 @@ namespace icinga typedef map::const_iterator ConstDictionaryIterator; typedef map::iterator DictionaryIterator; -struct I2_BASE_API DictionaryPropertyChangedEventArgs : public EventArgs +struct I2_BASE_API PropertyChangedEventArgs : public EventArgs { string Property; Variant OldValue; @@ -41,7 +41,7 @@ public: DictionaryIterator Begin(void); DictionaryIterator End(void); - Event OnPropertyChanged; + Event OnPropertyChanged; }; } diff --git a/base/event.h b/base/event.h index a2dbd5e11..725b4a03f 100644 --- a/base/event.h +++ b/base/event.h @@ -16,34 +16,24 @@ public: typedef function DelegateType; private: - list m_Delegates; + vector m_Delegates; public: - void Hook(const DelegateType& delegate) - { - m_Delegates.push_front(delegate); - } - - void Unhook(const DelegateType& delegate) - { - m_Delegates.remove(delegate); - } - Event& operator +=(const DelegateType& rhs) { - Hook(rhs); + m_Delegates.push_back(rhs); return *this; } Event& operator -=(const DelegateType& rhs) { - Unhook(rhs); + m_Delegates.erase(rhs); return *this; } void operator()(const TArgs& args) { - typename list::iterator prev, i; + typename vector::iterator prev, i; for (i = m_Delegates.begin(); i != m_Delegates.end(); ) { prev = i; diff --git a/base/exception.cpp b/base/exception.cpp index f120c5f23..3dcd96bf9 100644 --- a/base/exception.cpp +++ b/base/exception.cpp @@ -8,14 +8,39 @@ Exception::Exception(void) 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 diff --git a/base/exception.h b/base/exception.h index 5cb7f41fe..b97846c92 100644 --- a/base/exception.h +++ b/base/exception.h @@ -4,19 +4,31 @@ namespace icinga { +/** + * Exception + * + * Base class for all exceptions. + */ class I2_BASE_API Exception { private: string m_Message; -public: - typedef shared_ptr Ptr; - typedef weak_ptr 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; }; @@ -25,9 +37,6 @@ public: class klass : public Exception \ { \ public: \ - typedef shared_ptr Ptr; \ - typedef weak_ptr WeakPtr; \ - \ inline klass(void) : Exception() \ { \ } \ @@ -40,6 +49,30 @@ public: 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 */ diff --git a/base/i2-base.h b/base/i2-base.h index 3b0e2a632..96dcbb6b8 100644 --- a/base/i2-base.h +++ b/base/i2-base.h @@ -67,6 +67,7 @@ using namespace std::tr1::placeholders; #include "mutex.h" #include "condvar.h" #include "thread.h" +#include "utility.h" #include "object.h" #include "exception.h" #include "memory.h" diff --git a/base/memory.cpp b/base/memory.cpp index d41d8a5a7..b14505ad6 100644 --- a/base/memory.cpp +++ b/base/memory.cpp @@ -11,7 +11,7 @@ void *Memory::Allocate(size_t size) void *ptr = malloc(size); if (size != 0 && ptr == NULL) - throw OutOfMemoryException(); + throw OutOfMemoryException("malloc failed."); return ptr; } @@ -21,7 +21,7 @@ void *Memory::Reallocate(void *ptr, size_t size) void *new_ptr = realloc(ptr, size); if (size != 0 && new_ptr == NULL) - throw OutOfMemoryException(); + throw OutOfMemoryException("realloc failed."); return new_ptr; } @@ -31,7 +31,7 @@ char *Memory::StrDup(const char *str) char *new_str = strdup(str); if (str == NULL) - throw OutOfMemoryException(); + throw OutOfMemoryException("strdup failed."); return new_str; } diff --git a/base/memory.h b/base/memory.h index 70d5d4e25..6930877c7 100644 --- a/base/memory.h +++ b/base/memory.h @@ -6,6 +6,11 @@ namespace icinga DEFINE_EXCEPTION_CLASS(OutOfMemoryException); +/** + * Memory + * + * Singleton class which implements memory allocation helpers. + */ class I2_BASE_API Memory { private: diff --git a/base/mutex.h b/base/mutex.h index a0ed1c024..8d6c2d11b 100644 --- a/base/mutex.h +++ b/base/mutex.h @@ -4,6 +4,11 @@ namespace icinga { +/** + * Mutex + * + * A wrapper around OS-specific mutex functionality. + */ class I2_BASE_API Mutex { private: diff --git a/base/object.cpp b/base/object.cpp index f0d72ee7c..ab4021951 100644 --- a/base/object.cpp +++ b/base/object.cpp @@ -1,13 +1,3 @@ #include "i2-base.h" using namespace icinga; - -unsigned long Object::ActiveObjects; - -Object::Object(void) { - ActiveObjects++; -} - -Object::~Object(void) { - ActiveObjects--; -} diff --git a/base/object.h b/base/object.h index ffb609bb8..cfb5e15f5 100644 --- a/base/object.h +++ b/base/object.h @@ -4,20 +4,29 @@ 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 { 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 Ptr; typedef weak_ptr WeakPtr; - - static unsigned long ActiveObjects; }; template @@ -37,6 +46,11 @@ public: typedef function factory_function; +/** + * factory + * + * Returns a new object of type T. + */ template Object::Ptr factory(void) { diff --git a/base/socket.cpp b/base/socket.cpp index 4e5a2f00f..135eb5250 100644 --- a/base/socket.cpp +++ b/base/socket.cpp @@ -58,7 +58,8 @@ void Socket::Close(bool from_dtor) 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(); @@ -70,62 +71,33 @@ void Socket::Close(bool from_dtor) 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 diff --git a/base/socket.h b/base/socket.h index 1e8d4ff2d..6ac7228f6 100644 --- a/base/socket.h +++ b/base/socket.h @@ -19,12 +19,10 @@ private: int ExceptionEventHandler(const EventArgs& ea); -protected: - string FormatErrorCode(int errorCode); - protected: Socket(void); + void HandleSocketError(void); void Close(bool from_dtor); public: @@ -40,8 +38,6 @@ public: void SetFD(SOCKET fd); SOCKET GetFD(void) const; - static void CloseAllSockets(void); - Event OnReadable; Event OnWritable; Event OnException; diff --git a/base/tcpclient.cpp b/base/tcpclient.cpp index 0325220f4..ff057a2f6 100644 --- a/base/tcpclient.cpp +++ b/base/tcpclient.cpp @@ -41,17 +41,7 @@ void TCPClient::Connect(const string& hostname, unsigned short port) #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; @@ -95,19 +85,7 @@ int TCPClient::ReadableEventHandler(const EventArgs& ea) 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; } @@ -127,19 +105,7 @@ int TCPClient::WritableEventHandler(const EventArgs& ea) 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; } diff --git a/base/tcpserver.cpp b/base/tcpserver.cpp index b4b7f7b70..2f5f03f52 100644 --- a/base/tcpserver.cpp +++ b/base/tcpserver.cpp @@ -42,18 +42,9 @@ int TCPServer::ReadableEventHandler(const EventArgs& ea) 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; diff --git a/base/tcpsocket.cpp b/base/tcpsocket.cpp index 1d8b6dcba..f1120ce5b 100644 --- a/base/tcpsocket.cpp +++ b/base/tcpsocket.cpp @@ -9,14 +9,9 @@ void TCPSocket::MakeSocket(void) 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); @@ -40,19 +35,6 @@ void TCPSocket::Bind(const char *hostname, unsigned short port) 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(); } diff --git a/base/thread.cpp b/base/thread.cpp index 342c91300..dcc3d00fa 100644 --- a/base/thread.cpp +++ b/base/thread.cpp @@ -8,6 +8,12 @@ typedef struct threadparam_s 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) { @@ -26,21 +32,35 @@ static void *ThreadStartProc(void *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 @@ -50,6 +70,11 @@ Thread::~Thread(void) #endif } +/** + * Join + * + * Waits until the thread has finished executing. + */ void Thread::Join(void) { #ifdef _WIN32 diff --git a/base/thread.h b/base/thread.h index 58c11aa05..8a6cba106 100644 --- a/base/thread.h +++ b/base/thread.h @@ -6,6 +6,11 @@ namespace icinga typedef void (*ThreadProc)(void *); +/** + * Thread + * + * A wrapper around OS-specific thread functionality. + */ class I2_BASE_API Thread { private: @@ -16,10 +21,9 @@ private: #endif public: - Thread(void (*callback)(void *)); + Thread(ThreadProc callback); ~Thread(void); - void Start(void); void Join(void); }; diff --git a/base/timer.cpp b/base/timer.cpp index b7b9f0341..d9d187285 100644 --- a/base/timer.cpp +++ b/base/timer.cpp @@ -61,20 +61,6 @@ void Timer::CallExpiredTimers(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) diff --git a/base/timer.h b/base/timer.h index 22ee8c53d..cd57dae80 100644 --- a/base/timer.h +++ b/base/timer.h @@ -44,7 +44,6 @@ public: static time_t GetNextCall(void); static void CallExpiredTimers(void); - static void StopAllTimers(void); void Start(void); void Stop(void); diff --git a/base/utility.cpp b/base/utility.cpp new file mode 100644 index 000000000..167f70310 --- /dev/null +++ b/base/utility.cpp @@ -0,0 +1,48 @@ +#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 +} diff --git a/base/utility.h b/base/utility.h new file mode 100644 index 000000000..d4c7f8471 --- /dev/null +++ b/base/utility.h @@ -0,0 +1,46 @@ +#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 + 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 */ diff --git a/components/configrpc/configrpccomponent.cpp b/components/configrpc/configrpccomponent.cpp index 365568de8..9a2f66f96 100644 --- a/components/configrpc/configrpccomponent.cpp +++ b/components/configrpc/configrpccomponent.cpp @@ -146,7 +146,7 @@ int ConfigRpcComponent::LocalObjectRemovedHandler(const EventArgs& ea) return 0; } -int ConfigRpcComponent::LocalPropertyChangedHandler(const DictionaryPropertyChangedEventArgs& ea) +int ConfigRpcComponent::LocalPropertyChangedHandler(const PropertyChangedEventArgs& ea) { ConfigObject::Ptr object = static_pointer_cast(ea.Source); diff --git a/components/configrpc/configrpccomponent.h b/components/configrpc/configrpccomponent.h index f86af142d..2f1085bcd 100644 --- a/components/configrpc/configrpccomponent.h +++ b/components/configrpc/configrpccomponent.h @@ -16,7 +16,7 @@ private: 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);