Replaced custom event code with Boost.Signals.

This commit is contained in:
Gunnar Beutner 2012-06-14 15:16:41 +02:00
parent b0a372c5f8
commit 1e1bb43dea
35 changed files with 245 additions and 236 deletions

View File

@ -4,7 +4,6 @@
include aminclude.am include aminclude.am
SUBDIRS = \ SUBDIRS = \
compat \
third-party \ third-party \
base \ base \
dyn \ dyn \

15
README
View File

@ -6,6 +6,7 @@ application using a dist tarball:
* C++ compiler * C++ compiler
* OpenSSL library and header files * OpenSSL library and header files
* Boost library and header files
* Doxygen (only if you plan on building the internal code documentation) * Doxygen (only if you plan on building the internal code documentation)
Packaging Requirements Packaging Requirements
@ -15,24 +16,10 @@ In order to build a dist tarball for the application the following external
software components need to be installed in addition to the build requirements software components need to be installed in addition to the build requirements
mentioned above: mentioned above:
* Boost library
* GNU Automake * GNU Automake
* GNU Autoconf * GNU Autoconf
* GNU Libtool * GNU Libtool
"make dist" extracts the following components from the Boost library (using
bcp):
* tr1
* smart_ptr
* bind
* function
* make_shared
These components are only used on the target system if your C++ compiler does
not at least support TR1 and there's no other system-wide installation of the
Boost library.
Debian Packages Debian Packages
--------------- ---------------

View File

@ -65,4 +65,5 @@ libbase_la_LDFLAGS = \
libbase_la_LIBADD = \ libbase_la_LIBADD = \
$(LIBLTDL) \ $(LIBLTDL) \
$(OPENSSL_LIBS) \ $(OPENSSL_LIBS) \
$(BOOST_SIGNALS_LIB) \
${top_builddir}/third-party/mmatch/libmmatch.la ${top_builddir}/third-party/mmatch/libmmatch.la

View File

@ -96,6 +96,8 @@ void Application::RunEventLoop(void)
fd_set readfds, writefds, exceptfds; fd_set readfds, writefds, exceptfds;
int nfds = -1; int nfds = -1;
Object::ClearHeldObjects();
Timer::CallExpiredTimers(); Timer::CallExpiredTimers();
FD_ZERO(&readfds); FD_ZERO(&readfds);

View File

@ -17,49 +17,22 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#ifndef DELEGATE_H #ifndef EVENTARGS_H
#define DELEGATE_H #define EVENTARGS_H
namespace icinga namespace icinga
{ {
template<class TObject, class TArgs> /**
int delegate_fwd(int (TObject::*function)(TArgs), weak_ptr<TObject> wref, TArgs args) * Base class for event arguments.
*
* @ingroup base
*/
struct I2_BASE_API EventArgs
{ {
shared_ptr<TObject> ref = wref.lock(); Object::Ptr Source; /**< The source of the event. */
};
if (!ref)
return -1;
return (ref.get()->*function)(args);
}
template<class TObject, class TArgs>
function<int (TArgs)> bind_weak(int (TObject::*function)(TArgs), const weak_ptr<TObject>& wref)
{
return bind(&delegate_fwd<TObject, TArgs>, function, wref,
#ifdef HAVE_BOOST
_1
#else /* HAVE_BOOST */
placeholders::_1
#endif /* HAVE_BOOST */
);
}
template<class TObject, class TArgs>
function<int (TArgs)> bind_weak(int (TObject::*function)(TArgs), shared_ptr<TObject> ref)
{
weak_ptr<TObject> wref = weak_ptr<TObject>(ref);
return bind_weak(function, wref);
}
template<class TObject, class TArgs>
function<int (TArgs)> bind_weak(int (TObject::*function)(TArgs), shared_ptr<Object> ref)
{
weak_ptr<TObject> wref = weak_ptr<TObject>(static_pointer_cast<TObject>(ref));
return bind_weak(function, wref);
}
} }
#endif /* DELEGATE_H */ #endif /* EVENTARGS_H */

View File

@ -93,7 +93,6 @@
#include <algorithm> #include <algorithm>
using namespace std; using namespace std;
using std::exception;
#ifdef HAVE_STDCXX_0X #ifdef HAVE_STDCXX_0X
# include <memory> # include <memory>
@ -121,6 +120,8 @@ using namespace std::tr1::placeholders;
#endif /* HAVE_BOOST */ #endif /* HAVE_BOOST */
#endif /* HAVE_STDCXX_0X */ #endif /* HAVE_STDCXX_0X */
#include <boost/signal.hpp>
#if defined(__APPLE__) && defined(__MACH__) #if defined(__APPLE__) && defined(__MACH__)
# pragma GCC diagnostic ignored "-Wdeprecated-declarations" # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif #endif
@ -143,9 +144,8 @@ using namespace std::tr1::placeholders;
#include "object.h" #include "object.h"
#include "exception.h" #include "exception.h"
#include "memory.h" #include "memory.h"
#include "delegate.h"
#include "observable.h"
#include "variant.h" #include "variant.h"
#include "eventargs.h"
#include "dictionary.h" #include "dictionary.h"
#include "timer.h" #include "timer.h"
#include "fifo.h" #include "fifo.h"

View File

@ -21,6 +21,8 @@
using namespace icinga; using namespace icinga;
vector<Object::Ptr> Object::m_HeldObjects;
/** /**
* Default constructor for the Object class. * Default constructor for the Object class.
*/ */
@ -35,3 +37,22 @@ Object::~Object(void)
{ {
} }
/**
* Temporarily holds onto a reference for an object. This can
* be used to safely clear the last reference to an object
* in an event handler.
*/
void Object::Hold(void)
{
m_HeldObjects.push_back(shared_from_this());
}
/**
* Clears all temporarily held objects.
*/
void Object::ClearHeldObjects(void)
{
cout << "Cleared " << m_HeldObjects.size() << " held objects." << endl;
m_HeldObjects.clear();
}

View File

@ -29,7 +29,7 @@ namespace icinga
* *
* @ingroup base * @ingroup base
*/ */
class I2_BASE_API Object : public enable_shared_from_this<Object> class I2_BASE_API Object : public enable_shared_from_this<Object>, boost::signals::trackable
{ {
public: public:
typedef shared_ptr<Object> Ptr; typedef shared_ptr<Object> Ptr;
@ -39,9 +39,16 @@ protected:
Object(void); Object(void);
virtual ~Object(void); virtual ~Object(void);
static void ClearHeldObjects(void);
protected:
void Hold(void);
private: private:
Object(const Object& other); Object(const Object& other);
Object operator=(const Object& rhs); Object operator=(const Object& rhs);
static vector<Object::Ptr> m_HeldObjects;
}; };
/** /**

View File

@ -43,9 +43,9 @@ public:
void Start(void) void Start(void)
{ {
m_Parent->OnObjectAdded += bind_weak(&ObjectMap::ObjectAddedHandler, shared_from_this()); m_Parent->OnObjectAdded.connect(bind(&ObjectMap::ObjectAddedHandler, this, _1));
m_Parent->OnObjectCommitted += bind_weak(&ObjectMap::ObjectCommittedHandler, shared_from_this()); m_Parent->OnObjectCommitted.connect(bind(&ObjectMap::ObjectCommittedHandler, this, _1));
m_Parent->OnObjectRemoved += bind_weak(&ObjectMap::ObjectRemovedHandler, shared_from_this()); m_Parent->OnObjectRemoved.connect(bind(&ObjectMap::ObjectRemovedHandler, this, _1));
for (typename ObjectSet<TValue>::Iterator it = m_Parent->Begin(); it != m_Parent->End(); it++) for (typename ObjectSet<TValue>::Iterator it = m_Parent->Begin(); it != m_Parent->End(); it++)
AddObject(*it); AddObject(*it);

View File

@ -49,9 +49,9 @@ public:
void Start(void) void Start(void)
{ {
if (m_Parent) { if (m_Parent) {
m_Parent->OnObjectAdded += bind_weak(&ObjectSet::ObjectAddedOrCommittedHandler, shared_from_this()); m_Parent->OnObjectAdded.connect(bind(&ObjectSet::ObjectAddedOrCommittedHandler, this, _1));
m_Parent->OnObjectCommitted += bind_weak(&ObjectSet::ObjectAddedOrCommittedHandler, shared_from_this()); m_Parent->OnObjectCommitted.connect(bind(&ObjectSet::ObjectAddedOrCommittedHandler, this, _1));
m_Parent->OnObjectRemoved += bind_weak(&ObjectSet::ObjectRemovedHandler, shared_from_this()); m_Parent->OnObjectRemoved.connect(bind(&ObjectSet::ObjectRemovedHandler, this, _1));
for (ObjectSet::Iterator it = m_Parent->Begin(); it != m_Parent->End(); it++) for (ObjectSet::Iterator it = m_Parent->Begin(); it != m_Parent->End(); it++)
CheckObject(*it); CheckObject(*it);
@ -107,9 +107,9 @@ public:
} }
} }
Observable<ObjectSetEventArgs<TValue> > OnObjectAdded; boost::signal<void (const ObjectSetEventArgs<TValue>&)> OnObjectAdded;
Observable<ObjectSetEventArgs<TValue> > OnObjectCommitted; boost::signal<void (const ObjectSetEventArgs<TValue>&)> OnObjectCommitted;
Observable<ObjectSetEventArgs<TValue> > OnObjectRemoved; boost::signal<void (const ObjectSetEventArgs<TValue>&)> OnObjectRemoved;
Iterator Begin(void) Iterator Begin(void)
{ {

View File

@ -1,104 +0,0 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012 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 OBSERVABLE_H
#define OBSERVABLE_H
namespace icinga
{
/**
* Base class for event arguments.
*
* @ingroup base
*/
struct I2_BASE_API EventArgs
{
Object::Ptr Source; /**< The source of the event. */
};
/**
* An observable event. Observers can be registered for it.
*
* @ingroup base
*/
template<class TArgs>
class Observable
{
public:
typedef function<int (const TArgs&)> ObserverType;
/**
* Adds an observer to this event.
*
* @param rhs The observer.
*/
Observable<TArgs>& operator +=(const ObserverType& rhs)
{
m_Observers.push_back(rhs);
return *this;
}
/**
* Removes an observer from this event.
*
* @param rhs The observer.
*/
Observable<TArgs>& operator -=(const ObserverType& rhs)
{
m_Observers.erase(rhs);
return *this;
}
/**
* Invokes each observer function that is registered for this event. Any
* observer function which returns -1 is removed.
*
* @param args Event arguments.
*/
void operator()(const TArgs& args)
{
typename vector<ObserverType>::size_type i = 0;
for (i = 0; i < m_Observers.size(); ) {
int result = m_Observers[i](args);
if (result == -1)
m_Observers.erase(m_Observers.begin() + i);
else
i++;
}
}
/**
* Checks whether there's at least one observer.
*
* @returns true if there are one or more observers, false otherwise.
*/
bool HasObservers(void) const
{
return !m_Observers.empty();
}
private:
vector<ObserverType> m_Observers;
};
}
#endif /* OBSERVABLE_H */

View File

@ -50,7 +50,7 @@ void Socket::Start(void)
{ {
assert(m_FD != INVALID_SOCKET); assert(m_FD != INVALID_SOCKET);
OnException += bind_weak(&Socket::ExceptionEventHandler, shared_from_this()); OnException.connect(bind(&Socket::ExceptionEventHandler, this, _1));
Sockets.push_back(static_pointer_cast<Socket>(shared_from_this())); Sockets.push_back(static_pointer_cast<Socket>(shared_from_this()));
} }
@ -171,14 +171,15 @@ int Socket::GetLastSocketError(void)
*/ */
void Socket::HandleSocketError(const std::exception& ex) void Socket::HandleSocketError(const std::exception& ex)
{ {
if (OnError.HasObservers()) { // XXX, TODO: add SetErrorHandling() function
/* if (OnError.HasObservers()) {*/
SocketErrorEventArgs sea(ex); SocketErrorEventArgs sea(ex);
OnError(sea); OnError(sea);
Close(); Close();
} else { /* } else {
throw ex; throw ex;
} }*/
} }
/** /**

View File

@ -55,12 +55,12 @@ public:
void SetFD(SOCKET fd); void SetFD(SOCKET fd);
SOCKET GetFD(void) const; SOCKET GetFD(void) const;
Observable<EventArgs> OnReadable; boost::signal<void (const EventArgs&)> OnReadable;
Observable<EventArgs> OnWritable; boost::signal<void (const EventArgs&)> OnWritable;
Observable<EventArgs> OnException; boost::signal<void (const EventArgs&)> OnException;
Observable<SocketErrorEventArgs> OnError; boost::signal<void (const SocketErrorEventArgs&)> OnError;
Observable<EventArgs> OnClosed; boost::signal<void (const EventArgs&)> OnClosed;
virtual bool WantsToRead(void) const; virtual bool WantsToRead(void) const;
virtual bool WantsToWrite(void) const; virtual bool WantsToWrite(void) const;

View File

@ -51,8 +51,8 @@ void TcpClient::Start(void)
{ {
TcpSocket::Start(); TcpSocket::Start();
OnReadable += bind_weak(&TcpClient::ReadableEventHandler, shared_from_this()); OnReadable.connect(bind(&TcpClient::ReadableEventHandler, this, _1));
OnWritable += bind_weak(&TcpClient::WritableEventHandler, shared_from_this()); OnWritable.connect(bind(&TcpClient::WritableEventHandler, this, _1));
} }
/** /**

View File

@ -61,7 +61,7 @@ public:
virtual bool WantsToRead(void) const; virtual bool WantsToRead(void) const;
virtual bool WantsToWrite(void) const; virtual bool WantsToWrite(void) const;
Observable<EventArgs> OnDataAvailable; boost::signal<void (const EventArgs&)> OnDataAvailable;
private: private:
TcpClientRole m_Role; TcpClientRole m_Role;

View File

@ -56,7 +56,7 @@ void TcpServer::Start(void)
{ {
TcpSocket::Start(); TcpSocket::Start();
OnReadable += bind_weak(&TcpServer::ReadableEventHandler, shared_from_this()); OnReadable.connect(bind(&TcpServer::ReadableEventHandler, this, _1));
} }
/** /**

View File

@ -54,7 +54,7 @@ public:
void Listen(void); void Listen(void);
Observable<NewClientEventArgs> OnNewClient; boost::signal<void (const NewClientEventArgs&)> OnNewClient;
virtual bool WantsToRead(void) const; virtual bool WantsToRead(void) const;

View File

@ -65,7 +65,7 @@ public:
void Reschedule(time_t next); void Reschedule(time_t next);
Observable<TimerEventArgs> OnTimerExpired; boost::signal<void (const TimerEventArgs&)> OnTimerExpired;
private: private:
EventArgs m_UserArgs; /**< User-specified event arguments. */ EventArgs m_UserArgs; /**< User-specified event arguments. */

View File

@ -55,7 +55,7 @@ public:
virtual bool WantsToRead(void) const; virtual bool WantsToRead(void) const;
virtual bool WantsToWrite(void) const; virtual bool WantsToWrite(void) const;
Observable<VerifyCertificateEventArgs> OnVerifyCertificate; boost::signal<void (const VerifyCertificateEventArgs&)> OnVerifyCertificate;
protected: protected:
void HandleSSLError(void); void HandleSSLError(void);

View File

@ -1,7 +0,0 @@
EXTRA_DIST=include
include:
rm -Rf boost && mkdir -p boost && \
bcp --boost=$(BOOST_PATH)/include tr1 smart_ptr bind function make_shared boost && \
rm -Rf include && mkdir include && \
mv boost/boost include/

View File

@ -30,9 +30,9 @@ void CheckerComponent::Start(void)
{ {
m_CheckerEndpoint = make_shared<VirtualEndpoint>(); m_CheckerEndpoint = make_shared<VirtualEndpoint>();
m_CheckerEndpoint->RegisterTopicHandler("checker::AssignService", m_CheckerEndpoint->RegisterTopicHandler("checker::AssignService",
bind_weak(&CheckerComponent::AssignServiceRequestHandler, shared_from_this())); bind(&CheckerComponent::AssignServiceRequestHandler, this, _1));
m_CheckerEndpoint->RegisterTopicHandler("checker::RevokeService", m_CheckerEndpoint->RegisterTopicHandler("checker::RevokeService",
bind_weak(&CheckerComponent::AssignServiceRequestHandler, shared_from_this())); bind(&CheckerComponent::AssignServiceRequestHandler, this, _1));
m_CheckerEndpoint->RegisterPublication("checker::CheckResult"); m_CheckerEndpoint->RegisterPublication("checker::CheckResult");
GetEndpointManager()->RegisterEndpoint(m_CheckerEndpoint); GetEndpointManager()->RegisterEndpoint(m_CheckerEndpoint);
@ -41,11 +41,11 @@ void CheckerComponent::Start(void)
GetEndpointManager()->SendAPIMessage(m_CheckerEndpoint, rm, bind(&CheckerComponent::TestResponseHandler, this, _1)); GetEndpointManager()->SendAPIMessage(m_CheckerEndpoint, rm, bind(&CheckerComponent::TestResponseHandler, this, _1));
// TODO: get rid of this // TODO: get rid of this
ConfigObject::GetAllObjects()->OnObjectAdded += bind_weak(&CheckerComponent::NewServiceHandler, shared_from_this()); ConfigObject::GetAllObjects()->OnObjectAdded.connect(bind(&CheckerComponent::NewServiceHandler, this, _1));
m_CheckTimer = make_shared<Timer>(); m_CheckTimer = make_shared<Timer>();
m_CheckTimer->SetInterval(10); m_CheckTimer->SetInterval(10);
m_CheckTimer->OnTimerExpired += bind_weak(&CheckerComponent::CheckTimerHandler, shared_from_this()); m_CheckTimer->OnTimerExpired.connect(bind(&CheckerComponent::CheckTimerHandler, this, _1));
m_CheckTimer->Start(); m_CheckTimer->Start();
CheckTask::RegisterType("nagios", NagiosCheckTask::CreateTask); CheckTask::RegisterType("nagios", NagiosCheckTask::CreateTask);

View File

@ -35,23 +35,23 @@ void ConfigRpcComponent::Start(void)
long configSource; long configSource;
if (GetConfig()->GetProperty("configSource", &configSource) && configSource != 0) { if (GetConfig()->GetProperty("configSource", &configSource) && configSource != 0) {
m_ConfigRpcEndpoint->RegisterTopicHandler("config::FetchObjects", m_ConfigRpcEndpoint->RegisterTopicHandler("config::FetchObjects",
bind_weak(&ConfigRpcComponent::FetchObjectsHandler, shared_from_this())); bind(&ConfigRpcComponent::FetchObjectsHandler, this, _1));
ConfigObject::GetAllObjects()->OnObjectAdded += bind_weak(&ConfigRpcComponent::LocalObjectCommittedHandler, shared_from_this()); ConfigObject::GetAllObjects()->OnObjectAdded.connect(bind(&ConfigRpcComponent::LocalObjectCommittedHandler, this, _1));
ConfigObject::GetAllObjects()->OnObjectCommitted += bind_weak(&ConfigRpcComponent::LocalObjectCommittedHandler, shared_from_this()); ConfigObject::GetAllObjects()->OnObjectCommitted.connect(bind(&ConfigRpcComponent::LocalObjectCommittedHandler, this, _1));
ConfigObject::GetAllObjects()->OnObjectRemoved += bind_weak(&ConfigRpcComponent::LocalObjectRemovedHandler, shared_from_this()); ConfigObject::GetAllObjects()->OnObjectRemoved.connect(bind(&ConfigRpcComponent::LocalObjectRemovedHandler, this, _1));
m_ConfigRpcEndpoint->RegisterPublication("config::ObjectCommitted"); m_ConfigRpcEndpoint->RegisterPublication("config::ObjectCommitted");
m_ConfigRpcEndpoint->RegisterPublication("config::ObjectRemoved"); m_ConfigRpcEndpoint->RegisterPublication("config::ObjectRemoved");
} }
endpointManager->OnNewEndpoint += bind_weak(&ConfigRpcComponent::NewEndpointHandler, shared_from_this()); endpointManager->OnNewEndpoint.connect(bind(&ConfigRpcComponent::NewEndpointHandler, this, _1));
m_ConfigRpcEndpoint->RegisterPublication("config::FetchObjects"); m_ConfigRpcEndpoint->RegisterPublication("config::FetchObjects");
m_ConfigRpcEndpoint->RegisterTopicHandler("config::ObjectCommitted", m_ConfigRpcEndpoint->RegisterTopicHandler("config::ObjectCommitted",
bind_weak(&ConfigRpcComponent::RemoteObjectCommittedHandler, shared_from_this())); bind(&ConfigRpcComponent::RemoteObjectCommittedHandler, this, _1));
m_ConfigRpcEndpoint->RegisterTopicHandler("config::ObjectRemoved", m_ConfigRpcEndpoint->RegisterTopicHandler("config::ObjectRemoved",
bind_weak(&ConfigRpcComponent::RemoteObjectRemovedHandler, shared_from_this())); bind(&ConfigRpcComponent::RemoteObjectRemovedHandler, this, _1));
endpointManager->RegisterEndpoint(m_ConfigRpcEndpoint); endpointManager->RegisterEndpoint(m_ConfigRpcEndpoint);
} }
@ -66,7 +66,7 @@ void ConfigRpcComponent::Stop(void)
int ConfigRpcComponent::NewEndpointHandler(const NewEndpointEventArgs& ea) int ConfigRpcComponent::NewEndpointHandler(const NewEndpointEventArgs& ea)
{ {
ea.Endpoint->OnSessionEstablished += bind_weak(&ConfigRpcComponent::SessionEstablishedHandler, shared_from_this()); ea.Endpoint->OnSessionEstablished.connect(bind(&ConfigRpcComponent::SessionEstablishedHandler, this, _1));
return 0; return 0;
} }

View File

@ -38,13 +38,13 @@ void DemoComponent::Start(void)
{ {
m_DemoEndpoint = make_shared<VirtualEndpoint>(); m_DemoEndpoint = make_shared<VirtualEndpoint>();
m_DemoEndpoint->RegisterTopicHandler("demo::HelloWorld", m_DemoEndpoint->RegisterTopicHandler("demo::HelloWorld",
bind_weak(&DemoComponent::HelloWorldRequestHandler, shared_from_this())); bind(&DemoComponent::HelloWorldRequestHandler, this, _1));
m_DemoEndpoint->RegisterPublication("demo::HelloWorld"); m_DemoEndpoint->RegisterPublication("demo::HelloWorld");
GetEndpointManager()->RegisterEndpoint(m_DemoEndpoint); GetEndpointManager()->RegisterEndpoint(m_DemoEndpoint);
m_DemoTimer = make_shared<Timer>(); m_DemoTimer = make_shared<Timer>();
m_DemoTimer->SetInterval(5); m_DemoTimer->SetInterval(5);
m_DemoTimer->OnTimerExpired += bind_weak(&DemoComponent::DemoTimerHandler, shared_from_this()); m_DemoTimer->OnTimerExpired.connect(bind(&DemoComponent::DemoTimerHandler, this, _1));
m_DemoTimer->Start(); m_DemoTimer->Start();
} }

View File

@ -40,24 +40,24 @@ void DiscoveryComponent::Start(void)
m_DiscoveryEndpoint->RegisterPublication("discovery::RegisterComponent"); m_DiscoveryEndpoint->RegisterPublication("discovery::RegisterComponent");
m_DiscoveryEndpoint->RegisterTopicHandler("discovery::RegisterComponent", m_DiscoveryEndpoint->RegisterTopicHandler("discovery::RegisterComponent",
bind_weak(&DiscoveryComponent::RegisterComponentMessageHandler, shared_from_this())); bind(&DiscoveryComponent::RegisterComponentMessageHandler, this, _1));
m_DiscoveryEndpoint->RegisterPublication("discovery::NewComponent"); m_DiscoveryEndpoint->RegisterPublication("discovery::NewComponent");
m_DiscoveryEndpoint->RegisterTopicHandler("discovery::NewComponent", m_DiscoveryEndpoint->RegisterTopicHandler("discovery::NewComponent",
bind_weak(&DiscoveryComponent::NewComponentMessageHandler, shared_from_this())); bind(&DiscoveryComponent::NewComponentMessageHandler, this, _1));
m_DiscoveryEndpoint->RegisterTopicHandler("discovery::Welcome", m_DiscoveryEndpoint->RegisterTopicHandler("discovery::Welcome",
bind_weak(&DiscoveryComponent::WelcomeMessageHandler, shared_from_this())); bind(&DiscoveryComponent::WelcomeMessageHandler, this, _1));
GetEndpointManager()->ForEachEndpoint(bind(&DiscoveryComponent::NewEndpointHandler, this, _1)); GetEndpointManager()->ForEachEndpoint(bind(&DiscoveryComponent::NewEndpointHandler, this, _1));
GetEndpointManager()->OnNewEndpoint += bind_weak(&DiscoveryComponent::NewEndpointHandler, shared_from_this()); GetEndpointManager()->OnNewEndpoint.connect(bind(&DiscoveryComponent::NewEndpointHandler, this, _1));
GetEndpointManager()->RegisterEndpoint(m_DiscoveryEndpoint); GetEndpointManager()->RegisterEndpoint(m_DiscoveryEndpoint);
/* create the reconnect timer */ /* create the reconnect timer */
m_DiscoveryTimer = make_shared<Timer>(); m_DiscoveryTimer = make_shared<Timer>();
m_DiscoveryTimer->SetInterval(30); m_DiscoveryTimer->SetInterval(30);
m_DiscoveryTimer->OnTimerExpired += bind_weak(&DiscoveryComponent::DiscoveryTimerHandler, shared_from_this()); m_DiscoveryTimer->OnTimerExpired.connect(bind(&DiscoveryComponent::DiscoveryTimerHandler, this, _1));
m_DiscoveryTimer->Start(); m_DiscoveryTimer->Start();
/* call the timer as soon as possible */ /* call the timer as soon as possible */
@ -109,7 +109,7 @@ int DiscoveryComponent::CheckExistingEndpoint(Endpoint::Ptr endpoint, const NewE
*/ */
int DiscoveryComponent::NewEndpointHandler(const NewEndpointEventArgs& neea) int DiscoveryComponent::NewEndpointHandler(const NewEndpointEventArgs& neea)
{ {
neea.Endpoint->OnIdentityChanged += bind_weak(&DiscoveryComponent::NewIdentityHandler, shared_from_this()); neea.Endpoint->OnIdentityChanged.connect(bind(&DiscoveryComponent::NewIdentityHandler, this, _1));
/* accept discovery::RegisterComponent messages from any endpoint */ /* accept discovery::RegisterComponent messages from any endpoint */
neea.Endpoint->RegisterPublication("discovery::RegisterComponent"); neea.Endpoint->RegisterPublication("discovery::RegisterComponent");

114
config/ax_boost_signals.m4 Normal file
View File

@ -0,0 +1,114 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_boost_signals.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_BOOST_SIGNALS
#
# DESCRIPTION
#
# Test for Signals library from the Boost C++ libraries. The macro
# requires a preceding call to AX_BOOST_BASE. Further documentation is
# available at <http://randspringer.de/boost/index.html>.
#
# This macro calls:
#
# AC_SUBST(BOOST_SIGNALS_LIB)
#
# And sets:
#
# HAVE_BOOST_SIGNALS
#
# LICENSE
#
# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
# Copyright (c) 2008 Michael Tindal
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 21
AC_DEFUN([AX_BOOST_SIGNALS],
[
AC_ARG_WITH([boost-signals],
AS_HELP_STRING([--with-boost-signals@<:@=special-lib@:>@],
[use the Signals library from boost - it is possible to specify a certain library for the linker
e.g. --with-boost-signals=boost_signals-gcc-mt-d ]),
[
if test "$withval" = "no"; then
want_boost="no"
elif test "$withval" = "yes"; then
want_boost="yes"
ax_boost_user_signals_lib=""
else
want_boost="yes"
ax_boost_user_signals_lib="$withval"
fi
],
[want_boost="yes"]
)
if test "x$want_boost" = "xyes"; then
AC_REQUIRE([AC_PROG_CC])
CPPFLAGS_SAVED="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
export CPPFLAGS
LDFLAGS_SAVED="$LDFLAGS"
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
export LDFLAGS
AC_CACHE_CHECK(whether the Boost::Signals library is available,
ax_cv_boost_signals,
[AC_LANG_PUSH([C++])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/signal.hpp>
]],
[[boost::signal<void ()> sig;
return 0;
]])],
ax_cv_boost_signals=yes, ax_cv_boost_signals=no)
AC_LANG_POP([C++])
])
if test "x$ax_cv_boost_signals" = "xyes"; then
AC_DEFINE(HAVE_BOOST_SIGNALS,,[define if the Boost::Signals library is available])
BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
if test "x$ax_boost_user_signals_lib" = "x"; then
for libextension in `ls $BOOSTLIBDIR/libboost_signals*.so* $BOOSTLIBDIR/libboost_signals*.dylib* $BOOSTLIBDIR/libboost_signals*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_signals.*\)\.so.*$;\1;' -e 's;^lib\(boost_signals.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_signals.*\)\.a.*$;\1;'` ; do
ax_lib=${libextension}
AC_CHECK_LIB($ax_lib, exit,
[BOOST_SIGNALS_LIB="-l$ax_lib"; AC_SUBST(BOOST_SIGNALS_LIB) link_signals="yes"; break],
[link_signals="no"])
done
if test "x$link_signals" != "xyes"; then
for libextension in `ls $BOOSTLIBDIR/boost_signals*.dll* $BOOSTLIBDIR/boost_signals*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_signals.*\)\.dll.*$;\1;' -e 's;^\(boost_signals.*\)\.a*$;\1;'` ; do
ax_lib=${libextension}
AC_CHECK_LIB($ax_lib, exit,
[BOOST_SIGNALS_LIB="-l$ax_lib"; AC_SUBST(BOOST_SIGNALS_LIB) link_signals="yes"; break],
[link_signals="no"])
done
fi
else
for ax_lib in $ax_boost_user_signals_lib boost_signals-$ax_boost_user_signals_lib; do
AC_CHECK_LIB($ax_lib, main,
[BOOST_SIGNALS_LIB="-l$ax_lib"; AC_SUBST(BOOST_SIGNALS_LIB) link_signals="yes"; break],
[link_signals="no"])
done
fi
if test "x$ax_lib" = "x"; then
AC_MSG_ERROR(Could not find a version of the library!)
fi
if test "x$link_signals" != "xyes"; then
AC_MSG_ERROR(Could not link against $ax_lib !)
fi
fi
CPPFLAGS="$CPPFLAGS_SAVED"
LDFLAGS="$LDFLAGS_SAVED"
fi
])

View File

@ -53,6 +53,7 @@ AX_CXX_COMPILE_STDCXX_0X
AX_CXX_GCC_ABI_DEMANGLE AX_CXX_GCC_ABI_DEMANGLE
AX_PTHREAD AX_PTHREAD
AX_BOOST_BASE AX_BOOST_BASE
AX_BOOST_SIGNALS
AX_BOOST_UNIT_TEST_FRAMEWORK AX_BOOST_UNIT_TEST_FRAMEWORK
AX_CHECK_OPENSSL([], [AC_MSG_ERROR([You need the OpenSSL headers and libraries in order to build this application])]) AX_CHECK_OPENSSL([], [AC_MSG_ERROR([You need the OpenSSL headers and libraries in order to build this application])])
AC_CHECK_LIB(ssl, SSL_new) AC_CHECK_LIB(ssl, SSL_new)
@ -66,7 +67,6 @@ AC_CHECK_LIB(shlwapi, PathRemoveFileSpecA)
AC_CONFIG_FILES([ AC_CONFIG_FILES([
Makefile Makefile
compat/Makefile
base/Makefile base/Makefile
components/Makefile components/Makefile
components/checker/Makefile components/checker/Makefile

View File

@ -79,8 +79,8 @@ public:
ConstTopicIterator BeginPublications(void) const; ConstTopicIterator BeginPublications(void) const;
ConstTopicIterator EndPublications(void) const; ConstTopicIterator EndPublications(void) const;
Observable<EventArgs> OnIdentityChanged; boost::signal<void (const EventArgs&)> OnIdentityChanged;
Observable<EventArgs> OnSessionEstablished; boost::signal<void (const EventArgs&)> OnSessionEstablished;
private: private:
string m_Identity; /**< The identity of this endpoint. */ string m_Identity; /**< The identity of this endpoint. */

View File

@ -109,8 +109,8 @@ void EndpointManager::AddConnection(string node, string service)
void EndpointManager::RegisterServer(JsonRpcServer::Ptr server) void EndpointManager::RegisterServer(JsonRpcServer::Ptr server)
{ {
m_Servers.push_back(server); m_Servers.push_back(server);
server->OnNewClient += bind_weak(&EndpointManager::NewClientHandler, server->OnNewClient.connect(bind(&EndpointManager::NewClientHandler,
shared_from_this()); this, _1));
} }
/** /**
@ -327,7 +327,7 @@ void EndpointManager::RescheduleRequestTimer(void)
if (!m_RequestTimer) { if (!m_RequestTimer) {
m_RequestTimer = make_shared<Timer>(); m_RequestTimer = make_shared<Timer>();
m_RequestTimer->OnTimerExpired += bind_weak(&EndpointManager::RequestTimerHandler, shared_from_this()); m_RequestTimer->OnTimerExpired.connect(bind(&EndpointManager::RequestTimerHandler, this, _1));
} }
if (it != m_Requests.end()) { if (it != m_Requests.end()) {

View File

@ -105,7 +105,7 @@ public:
Endpoint::Ptr GetEndpointByIdentity(string identity) const; Endpoint::Ptr GetEndpointByIdentity(string identity) const;
Observable<NewEndpointEventArgs> OnNewEndpoint; boost::signal<void (const NewEndpointEventArgs&)> OnNewEndpoint;
private: private:
string m_Identity; string m_Identity;

View File

@ -54,10 +54,10 @@ int IcingaApplication::Main(const vector<string>& args)
/* register handler for 'component' config objects */ /* register handler for 'component' config objects */
static ConfigObject::Set::Ptr componentObjects = make_shared<ConfigObject::Set>(ConfigObject::GetAllObjects(), ConfigObject::MakeTypePredicate("component")); static ConfigObject::Set::Ptr componentObjects = make_shared<ConfigObject::Set>(ConfigObject::GetAllObjects(), ConfigObject::MakeTypePredicate("component"));
function<int (const ObjectSetEventArgs<ConfigObject::Ptr>&)> NewComponentHandler = bind_weak(&IcingaApplication::NewComponentHandler, shared_from_this()); function<int (const ObjectSetEventArgs<ConfigObject::Ptr>&)> NewComponentHandler = bind(&IcingaApplication::NewComponentHandler, this, _1);
componentObjects->OnObjectAdded += NewComponentHandler; componentObjects->OnObjectAdded.connect(NewComponentHandler);
componentObjects->OnObjectCommitted += NewComponentHandler; componentObjects->OnObjectCommitted.connect(NewComponentHandler);
componentObjects->OnObjectRemoved += bind_weak(&IcingaApplication::DeletedComponentHandler, shared_from_this()); componentObjects->OnObjectRemoved.connect(bind(&IcingaApplication::DeletedComponentHandler, this, _1));
componentObjects->Start(); componentObjects->Start();
/* load config file */ /* load config file */

View File

@ -45,10 +45,10 @@ void JsonRpcEndpoint::Connect(string node, string service, shared_ptr<SSL_CTX> s
void JsonRpcEndpoint::SetClient(JsonRpcClient::Ptr client) void JsonRpcEndpoint::SetClient(JsonRpcClient::Ptr client)
{ {
m_Client = client; m_Client = client;
client->OnNewMessage += bind_weak(&JsonRpcEndpoint::NewMessageHandler, shared_from_this()); client->OnNewMessage.connect(bind(&JsonRpcEndpoint::NewMessageHandler, this, _1));
client->OnClosed += bind_weak(&JsonRpcEndpoint::ClientClosedHandler, shared_from_this()); client->OnClosed.connect(bind(&JsonRpcEndpoint::ClientClosedHandler, this, _1));
client->OnError += bind_weak(&JsonRpcEndpoint::ClientErrorHandler, shared_from_this()); client->OnError.connect(bind(&JsonRpcEndpoint::ClientErrorHandler, this, _1));
client->OnVerifyCertificate += bind_weak(&JsonRpcEndpoint::VerifyCertificateHandler, shared_from_this()); client->OnVerifyCertificate.connect(bind(&JsonRpcEndpoint::VerifyCertificateHandler, this, _1));
} }
bool JsonRpcEndpoint::IsLocal(void) const bool JsonRpcEndpoint::IsLocal(void) const
@ -122,8 +122,10 @@ int JsonRpcEndpoint::ClientClosedHandler(const EventArgs&)
ClearPublications(); ClearPublications();
// remove the endpoint if there are no more subscriptions */ // remove the endpoint if there are no more subscriptions */
if (BeginSubscriptions() == EndSubscriptions()) if (BeginSubscriptions() == EndSubscriptions()) {
Hold();
GetEndpointManager()->UnregisterEndpoint(static_pointer_cast<Endpoint>(shared_from_this())); GetEndpointManager()->UnregisterEndpoint(static_pointer_cast<Endpoint>(shared_from_this()));
}
m_Client.reset(); m_Client.reset();

View File

@ -40,7 +40,19 @@ bool VirtualEndpoint::IsConnected(void) const
void VirtualEndpoint::RegisterTopicHandler(string topic, function<int (const NewRequestEventArgs&)> callback) void VirtualEndpoint::RegisterTopicHandler(string topic, function<int (const NewRequestEventArgs&)> callback)
{ {
m_TopicHandlers[topic] += callback; map<string, shared_ptr<boost::signal<void (const NewRequestEventArgs&)> > >::iterator it;
it = m_TopicHandlers.find(topic);
shared_ptr<boost::signal<void (const NewRequestEventArgs&)> > sig;
if (it == m_TopicHandlers.end()) {
sig = make_shared<boost::signal<void (const NewRequestEventArgs&)> >();
m_TopicHandlers.insert(make_pair(topic, sig));
} else {
sig = it->second;
}
sig->connect(callback);
RegisterSubscription(topic); RegisterSubscription(topic);
} }
@ -60,16 +72,17 @@ void VirtualEndpoint::ProcessRequest(Endpoint::Ptr sender, const RequestMessage&
if (!request.GetMethod(&method)) if (!request.GetMethod(&method))
return; return;
map<string, Observable<NewRequestEventArgs> >::iterator i = m_TopicHandlers.find(method); map<string, shared_ptr<boost::signal<void (const NewRequestEventArgs&)> > >::iterator it;
it = m_TopicHandlers.find(method);
if (i == m_TopicHandlers.end()) if (it == m_TopicHandlers.end())
return; return;
NewRequestEventArgs nrea; NewRequestEventArgs nrea;
nrea.Source = shared_from_this(); nrea.Source = shared_from_this();
nrea.Sender = sender; nrea.Sender = sender;
nrea.Request = request; nrea.Request = request;
i->second(nrea); (*it->second)(nrea);
} }
void VirtualEndpoint::ProcessResponse(Endpoint::Ptr sender, const ResponseMessage& response) void VirtualEndpoint::ProcessResponse(Endpoint::Ptr sender, const ResponseMessage& response)

View File

@ -59,7 +59,7 @@ public:
virtual void Stop(void); virtual void Stop(void);
private: private:
map< string, Observable<NewRequestEventArgs> > m_TopicHandlers; map< string, shared_ptr<boost::signal<void (const NewRequestEventArgs&)> > > m_TopicHandlers;
}; };
} }

View File

@ -34,7 +34,7 @@ void JsonRpcClient::Start(void)
{ {
TlsClient::Start(); TlsClient::Start();
OnDataAvailable += bind_weak(&JsonRpcClient::DataAvailableHandler, shared_from_this()); OnDataAvailable.connect(bind(&JsonRpcClient::DataAvailableHandler, this, _1));
} }
/** /**

View File

@ -50,7 +50,7 @@ public:
virtual void Start(void); virtual void Start(void);
Observable<NewMessageEventArgs> OnNewMessage; boost::signal<void (const NewMessageEventArgs&)> OnNewMessage;
private: private:
int DataAvailableHandler(const EventArgs&); int DataAvailableHandler(const EventArgs&);