Code cleanup

This commit is contained in:
Gunnar Beutner 2012-04-22 16:45:31 +02:00
parent bf1e07b686
commit 69c30c264a
36 changed files with 334 additions and 300 deletions

View File

@ -47,6 +47,8 @@ libbase_la_SOURCES = \
timer.h \
unix.cpp \
unix.h \
utility.cpp \
utility.h \
variant.cpp \
variant.h \
win32.cpp \

View File

@ -31,10 +31,8 @@ Application::Application(void)
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();
}
@ -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<string>& arguments)
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;
@ -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);
}
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;
}

View File

@ -15,6 +15,10 @@ private:
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;
@ -27,36 +31,32 @@ public:
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 */

View File

@ -30,6 +30,7 @@
<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>
@ -56,6 +57,7 @@
<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>

View File

@ -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(); \
}
}

View File

@ -4,6 +4,11 @@
namespace icinga
{
/**
* CondVar
*
* A wrapper around OS-specific condition variable functionality.
*/
class I2_BASE_API CondVar
{
private:

View File

@ -29,7 +29,7 @@ public:
Event<EventArgs> OnObjectCreated;
Event<EventArgs> OnObjectRemoved;
Event<DictionaryPropertyChangedEventArgs> OnPropertyChanged;
Event<PropertyChangedEventArgs> OnPropertyChanged;
};
}

View File

@ -30,7 +30,8 @@ ConfigCollection::Ptr ConfigHive::GetCollection(const string& collection)
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);

View File

@ -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<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;
};
}

View File

@ -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) {

View File

@ -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<ConfigObject> Ptr;

View File

@ -18,7 +18,7 @@ int delegate_fwd(int (TObject::*function)(TArgs), weak_ptr<TObject> wref, const
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>

View File

@ -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;

View File

@ -7,7 +7,7 @@ namespace icinga
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;
@ -41,7 +41,7 @@ public:
DictionaryIterator Begin(void);
DictionaryIterator End(void);
Event<DictionaryPropertyChangedEventArgs> OnPropertyChanged;
Event<PropertyChangedEventArgs> OnPropertyChanged;
};
}

View File

@ -16,34 +16,24 @@ public:
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;

View File

@ -8,14 +8,39 @@ Exception::Exception(void)
Exception::Exception(const string& message)
{
m_Message = message;
}
Exception::~Exception(void)
{
SetMessage(message);
}
string Exception::GetMessage(void) const
{
return m_Message;
}
void Exception::SetMessage(string 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);
}

View File

@ -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<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;
};
@ -25,9 +37,6 @@ public:
class klass : public Exception \
{ \
public: \
typedef shared_ptr<klass> Ptr; \
typedef weak_ptr<klass> 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 */

View File

@ -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"

View File

@ -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;
}

View File

@ -6,6 +6,11 @@ namespace icinga
DEFINE_EXCEPTION_CLASS(OutOfMemoryException);
/**
* Memory
*
* Singleton class which implements memory allocation helpers.
*/
class I2_BASE_API Memory
{
private:

View File

@ -4,6 +4,11 @@
namespace icinga
{
/**
* Mutex
*
* A wrapper around OS-specific mutex functionality.
*/
class I2_BASE_API Mutex
{
private:

View File

@ -1,13 +1,3 @@
#include "i2-base.h"
using namespace icinga;
unsigned long Object::ActiveObjects;
Object::Object(void) {
ActiveObjects++;
}
Object::~Object(void) {
ActiveObjects--;
}

View File

@ -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<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>
@ -37,6 +46,11 @@ public:
typedef function<Object::Ptr ()> factory_function;
/**
* factory<T>
*
* Returns a new object of type T.
*/
template<class T>
Object::Ptr factory(void)
{

View File

@ -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();
HandleSocketError();
i++;
if (socket == NULL)
continue;
socket->Close();
}
return 0;
}
bool Socket::WantsToRead(void) const

View File

@ -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<EventArgs> OnReadable;
Event<EventArgs> OnWritable;
Event<EventArgs> OnException;

View File

@ -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;
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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

View File

@ -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);
};

View File

@ -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)

View File

@ -44,7 +44,6 @@ public:
static time_t GetNextCall(void);
static void CallExpiredTimers(void);
static void StopAllTimers(void);
void Start(void);
void Stop(void);

48
base/utility.cpp Normal file
View File

@ -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
}

46
base/utility.h Normal file
View File

@ -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<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 */

View File

@ -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<ConfigObject>(ea.Source);

View File

@ -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);