From: Gunnar Beutner Date: Thu, 14 Jun 2012 13:16:41 +0000 (+0200) Subject: Replaced custom event code with Boost.Signals. X-Git-Tag: v0.0.1~430 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1e1bb43dea1349639b42f51a3258c24aedd6ec5c;p=icinga2 Replaced custom event code with Boost.Signals. --- diff --git a/Makefile.am b/Makefile.am index 8b54e69d7..030f64b1e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,7 +4,6 @@ include aminclude.am SUBDIRS = \ - compat \ third-party \ base \ dyn \ diff --git a/README b/README index bd56b94a1..53378e034 100644 --- a/README +++ b/README @@ -6,6 +6,7 @@ application using a dist tarball: * C++ compiler * OpenSSL library and header files +* Boost library and header files * Doxygen (only if you plan on building the internal code documentation) 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 mentioned above: -* Boost library * GNU Automake * GNU Autoconf * 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 --------------- diff --git a/base/Makefile.am b/base/Makefile.am index a3455a0c8..f95a39758 100644 --- a/base/Makefile.am +++ b/base/Makefile.am @@ -65,4 +65,5 @@ libbase_la_LDFLAGS = \ libbase_la_LIBADD = \ $(LIBLTDL) \ $(OPENSSL_LIBS) \ + $(BOOST_SIGNALS_LIB) \ ${top_builddir}/third-party/mmatch/libmmatch.la diff --git a/base/application.cpp b/base/application.cpp index 77f5dde84..a277104d8 100644 --- a/base/application.cpp +++ b/base/application.cpp @@ -96,6 +96,8 @@ void Application::RunEventLoop(void) fd_set readfds, writefds, exceptfds; int nfds = -1; + Object::ClearHeldObjects(); + Timer::CallExpiredTimers(); FD_ZERO(&readfds); diff --git a/base/delegate.h b/base/eventargs.h similarity index 58% rename from base/delegate.h rename to base/eventargs.h index be7356036..f913b7e8d 100644 --- a/base/delegate.h +++ b/base/eventargs.h @@ -17,49 +17,22 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * ******************************************************************************/ -#ifndef DELEGATE_H -#define DELEGATE_H +#ifndef EVENTARGS_H +#define EVENTARGS_H namespace icinga { -template -int delegate_fwd(int (TObject::*function)(TArgs), weak_ptr wref, TArgs args) +/** + * Base class for event arguments. + * + * @ingroup base + */ +struct I2_BASE_API EventArgs { - shared_ptr ref = wref.lock(); - - if (!ref) - return -1; - - return (ref.get()->*function)(args); -} - -template -function bind_weak(int (TObject::*function)(TArgs), const weak_ptr& wref) -{ - return bind(&delegate_fwd, function, wref, -#ifdef HAVE_BOOST - _1 -#else /* HAVE_BOOST */ - placeholders::_1 -#endif /* HAVE_BOOST */ - ); -} - -template -function bind_weak(int (TObject::*function)(TArgs), shared_ptr ref) -{ - weak_ptr wref = weak_ptr(ref); - return bind_weak(function, wref); -} - -template -function bind_weak(int (TObject::*function)(TArgs), shared_ptr ref) -{ - weak_ptr wref = weak_ptr(static_pointer_cast(ref)); - return bind_weak(function, wref); -} + Object::Ptr Source; /**< The source of the event. */ +}; } -#endif /* DELEGATE_H */ +#endif /* EVENTARGS_H */ diff --git a/base/i2-base.h b/base/i2-base.h index e57abdf30..22d94f9c7 100644 --- a/base/i2-base.h +++ b/base/i2-base.h @@ -93,7 +93,6 @@ #include using namespace std; -using std::exception; #ifdef HAVE_STDCXX_0X # include @@ -121,6 +120,8 @@ using namespace std::tr1::placeholders; #endif /* HAVE_BOOST */ #endif /* HAVE_STDCXX_0X */ +#include + #if defined(__APPLE__) && defined(__MACH__) # pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif @@ -143,9 +144,8 @@ using namespace std::tr1::placeholders; #include "object.h" #include "exception.h" #include "memory.h" -#include "delegate.h" -#include "observable.h" #include "variant.h" +#include "eventargs.h" #include "dictionary.h" #include "timer.h" #include "fifo.h" diff --git a/base/object.cpp b/base/object.cpp index 8bee4935c..477477f40 100644 --- a/base/object.cpp +++ b/base/object.cpp @@ -21,6 +21,8 @@ using namespace icinga; +vector Object::m_HeldObjects; + /** * 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(); +} + diff --git a/base/object.h b/base/object.h index f712aad81..cc8507cb7 100644 --- a/base/object.h +++ b/base/object.h @@ -29,7 +29,7 @@ namespace icinga * * @ingroup base */ -class I2_BASE_API Object : public enable_shared_from_this +class I2_BASE_API Object : public enable_shared_from_this, boost::signals::trackable { public: typedef shared_ptr Ptr; @@ -39,9 +39,16 @@ protected: Object(void); virtual ~Object(void); + static void ClearHeldObjects(void); + +protected: + void Hold(void); + private: Object(const Object& other); Object operator=(const Object& rhs); + + static vector m_HeldObjects; }; /** diff --git a/base/objectmap.h b/base/objectmap.h index 2411d542e..9b975412f 100644 --- a/base/objectmap.h +++ b/base/objectmap.h @@ -43,9 +43,9 @@ public: void Start(void) { - m_Parent->OnObjectAdded += bind_weak(&ObjectMap::ObjectAddedHandler, shared_from_this()); - m_Parent->OnObjectCommitted += bind_weak(&ObjectMap::ObjectCommittedHandler, shared_from_this()); - m_Parent->OnObjectRemoved += bind_weak(&ObjectMap::ObjectRemovedHandler, shared_from_this()); + m_Parent->OnObjectAdded.connect(bind(&ObjectMap::ObjectAddedHandler, this, _1)); + m_Parent->OnObjectCommitted.connect(bind(&ObjectMap::ObjectCommittedHandler, this, _1)); + m_Parent->OnObjectRemoved.connect(bind(&ObjectMap::ObjectRemovedHandler, this, _1)); for (typename ObjectSet::Iterator it = m_Parent->Begin(); it != m_Parent->End(); it++) AddObject(*it); diff --git a/base/objectset.h b/base/objectset.h index f7bcde34b..ad4d41c98 100644 --- a/base/objectset.h +++ b/base/objectset.h @@ -49,9 +49,9 @@ public: void Start(void) { if (m_Parent) { - m_Parent->OnObjectAdded += bind_weak(&ObjectSet::ObjectAddedOrCommittedHandler, shared_from_this()); - m_Parent->OnObjectCommitted += bind_weak(&ObjectSet::ObjectAddedOrCommittedHandler, shared_from_this()); - m_Parent->OnObjectRemoved += bind_weak(&ObjectSet::ObjectRemovedHandler, shared_from_this()); + m_Parent->OnObjectAdded.connect(bind(&ObjectSet::ObjectAddedOrCommittedHandler, this, _1)); + m_Parent->OnObjectCommitted.connect(bind(&ObjectSet::ObjectAddedOrCommittedHandler, this, _1)); + m_Parent->OnObjectRemoved.connect(bind(&ObjectSet::ObjectRemovedHandler, this, _1)); for (ObjectSet::Iterator it = m_Parent->Begin(); it != m_Parent->End(); it++) CheckObject(*it); @@ -107,9 +107,9 @@ public: } } - Observable > OnObjectAdded; - Observable > OnObjectCommitted; - Observable > OnObjectRemoved; + boost::signal&)> OnObjectAdded; + boost::signal&)> OnObjectCommitted; + boost::signal&)> OnObjectRemoved; Iterator Begin(void) { diff --git a/base/observable.h b/base/observable.h deleted file mode 100644 index 8dc13f332..000000000 --- a/base/observable.h +++ /dev/null @@ -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 Observable -{ -public: - typedef function ObserverType; - - /** - * Adds an observer to this event. - * - * @param rhs The observer. - */ - Observable& operator +=(const ObserverType& rhs) - { - m_Observers.push_back(rhs); - return *this; - } - - /** - * Removes an observer from this event. - * - * @param rhs The observer. - */ - Observable& 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::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 m_Observers; -}; - -} - -#endif /* OBSERVABLE_H */ diff --git a/base/socket.cpp b/base/socket.cpp index dba50bf52..6cee85988 100644 --- a/base/socket.cpp +++ b/base/socket.cpp @@ -50,7 +50,7 @@ void Socket::Start(void) { 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(shared_from_this())); } @@ -171,14 +171,15 @@ int Socket::GetLastSocketError(void) */ void Socket::HandleSocketError(const std::exception& ex) { - if (OnError.HasObservers()) { + // XXX, TODO: add SetErrorHandling() function +/* if (OnError.HasObservers()) {*/ SocketErrorEventArgs sea(ex); OnError(sea); Close(); - } else { +/* } else { throw ex; - } + }*/ } /** diff --git a/base/socket.h b/base/socket.h index 8bba41e58..9d111d4a4 100644 --- a/base/socket.h +++ b/base/socket.h @@ -55,12 +55,12 @@ public: void SetFD(SOCKET fd); SOCKET GetFD(void) const; - Observable OnReadable; - Observable OnWritable; - Observable OnException; + boost::signal OnReadable; + boost::signal OnWritable; + boost::signal OnException; - Observable OnError; - Observable OnClosed; + boost::signal OnError; + boost::signal OnClosed; virtual bool WantsToRead(void) const; virtual bool WantsToWrite(void) const; diff --git a/base/tcpclient.cpp b/base/tcpclient.cpp index 0308e4844..655253771 100644 --- a/base/tcpclient.cpp +++ b/base/tcpclient.cpp @@ -51,8 +51,8 @@ void TcpClient::Start(void) { TcpSocket::Start(); - OnReadable += bind_weak(&TcpClient::ReadableEventHandler, shared_from_this()); - OnWritable += bind_weak(&TcpClient::WritableEventHandler, shared_from_this()); + OnReadable.connect(bind(&TcpClient::ReadableEventHandler, this, _1)); + OnWritable.connect(bind(&TcpClient::WritableEventHandler, this, _1)); } /** diff --git a/base/tcpclient.h b/base/tcpclient.h index 627467712..997c0ce05 100644 --- a/base/tcpclient.h +++ b/base/tcpclient.h @@ -61,7 +61,7 @@ public: virtual bool WantsToRead(void) const; virtual bool WantsToWrite(void) const; - Observable OnDataAvailable; + boost::signal OnDataAvailable; private: TcpClientRole m_Role; diff --git a/base/tcpserver.cpp b/base/tcpserver.cpp index a5c3d6dcd..f790775dc 100644 --- a/base/tcpserver.cpp +++ b/base/tcpserver.cpp @@ -56,7 +56,7 @@ void TcpServer::Start(void) { TcpSocket::Start(); - OnReadable += bind_weak(&TcpServer::ReadableEventHandler, shared_from_this()); + OnReadable.connect(bind(&TcpServer::ReadableEventHandler, this, _1)); } /** diff --git a/base/tcpserver.h b/base/tcpserver.h index bdaf7ab33..260effcd4 100644 --- a/base/tcpserver.h +++ b/base/tcpserver.h @@ -54,7 +54,7 @@ public: void Listen(void); - Observable OnNewClient; + boost::signal OnNewClient; virtual bool WantsToRead(void) const; diff --git a/base/timer.h b/base/timer.h index 136a10bd7..9bf8bfa4e 100644 --- a/base/timer.h +++ b/base/timer.h @@ -65,7 +65,7 @@ public: void Reschedule(time_t next); - Observable OnTimerExpired; + boost::signal OnTimerExpired; private: EventArgs m_UserArgs; /**< User-specified event arguments. */ diff --git a/base/tlsclient.h b/base/tlsclient.h index c92c41c20..2bc33e727 100644 --- a/base/tlsclient.h +++ b/base/tlsclient.h @@ -55,7 +55,7 @@ public: virtual bool WantsToRead(void) const; virtual bool WantsToWrite(void) const; - Observable OnVerifyCertificate; + boost::signal OnVerifyCertificate; protected: void HandleSSLError(void); diff --git a/compat/Makefile.am b/compat/Makefile.am deleted file mode 100644 index 38a07f7a4..000000000 --- a/compat/Makefile.am +++ /dev/null @@ -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/ diff --git a/components/checker/checkercomponent.cpp b/components/checker/checkercomponent.cpp index 56d194aa3..941e4c038 100644 --- a/components/checker/checkercomponent.cpp +++ b/components/checker/checkercomponent.cpp @@ -30,9 +30,9 @@ void CheckerComponent::Start(void) { m_CheckerEndpoint = make_shared(); m_CheckerEndpoint->RegisterTopicHandler("checker::AssignService", - bind_weak(&CheckerComponent::AssignServiceRequestHandler, shared_from_this())); + bind(&CheckerComponent::AssignServiceRequestHandler, this, _1)); m_CheckerEndpoint->RegisterTopicHandler("checker::RevokeService", - bind_weak(&CheckerComponent::AssignServiceRequestHandler, shared_from_this())); + bind(&CheckerComponent::AssignServiceRequestHandler, this, _1)); m_CheckerEndpoint->RegisterPublication("checker::CheckResult"); GetEndpointManager()->RegisterEndpoint(m_CheckerEndpoint); @@ -41,11 +41,11 @@ void CheckerComponent::Start(void) GetEndpointManager()->SendAPIMessage(m_CheckerEndpoint, rm, bind(&CheckerComponent::TestResponseHandler, this, _1)); // 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(); 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(); CheckTask::RegisterType("nagios", NagiosCheckTask::CreateTask); diff --git a/components/configrpc/configrpccomponent.cpp b/components/configrpc/configrpccomponent.cpp index 2504510ce..b9fbf8f2f 100644 --- a/components/configrpc/configrpccomponent.cpp +++ b/components/configrpc/configrpccomponent.cpp @@ -35,23 +35,23 @@ void ConfigRpcComponent::Start(void) long configSource; if (GetConfig()->GetProperty("configSource", &configSource) && configSource != 0) { 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()->OnObjectCommitted += bind_weak(&ConfigRpcComponent::LocalObjectCommittedHandler, shared_from_this()); - ConfigObject::GetAllObjects()->OnObjectRemoved += bind_weak(&ConfigRpcComponent::LocalObjectRemovedHandler, shared_from_this()); + ConfigObject::GetAllObjects()->OnObjectAdded.connect(bind(&ConfigRpcComponent::LocalObjectCommittedHandler, this, _1)); + ConfigObject::GetAllObjects()->OnObjectCommitted.connect(bind(&ConfigRpcComponent::LocalObjectCommittedHandler, this, _1)); + ConfigObject::GetAllObjects()->OnObjectRemoved.connect(bind(&ConfigRpcComponent::LocalObjectRemovedHandler, this, _1)); m_ConfigRpcEndpoint->RegisterPublication("config::ObjectCommitted"); 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->RegisterTopicHandler("config::ObjectCommitted", - bind_weak(&ConfigRpcComponent::RemoteObjectCommittedHandler, shared_from_this())); + bind(&ConfigRpcComponent::RemoteObjectCommittedHandler, this, _1)); m_ConfigRpcEndpoint->RegisterTopicHandler("config::ObjectRemoved", - bind_weak(&ConfigRpcComponent::RemoteObjectRemovedHandler, shared_from_this())); + bind(&ConfigRpcComponent::RemoteObjectRemovedHandler, this, _1)); endpointManager->RegisterEndpoint(m_ConfigRpcEndpoint); } @@ -66,7 +66,7 @@ void ConfigRpcComponent::Stop(void) 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; } diff --git a/components/demo/democomponent.cpp b/components/demo/democomponent.cpp index 5bf073cc5..ce8449be2 100644 --- a/components/demo/democomponent.cpp +++ b/components/demo/democomponent.cpp @@ -38,13 +38,13 @@ void DemoComponent::Start(void) { m_DemoEndpoint = make_shared(); m_DemoEndpoint->RegisterTopicHandler("demo::HelloWorld", - bind_weak(&DemoComponent::HelloWorldRequestHandler, shared_from_this())); + bind(&DemoComponent::HelloWorldRequestHandler, this, _1)); m_DemoEndpoint->RegisterPublication("demo::HelloWorld"); GetEndpointManager()->RegisterEndpoint(m_DemoEndpoint); m_DemoTimer = make_shared(); 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(); } diff --git a/components/discovery/discoverycomponent.cpp b/components/discovery/discoverycomponent.cpp index b9b50396b..616f2791b 100644 --- a/components/discovery/discoverycomponent.cpp +++ b/components/discovery/discoverycomponent.cpp @@ -40,24 +40,24 @@ void DiscoveryComponent::Start(void) m_DiscoveryEndpoint->RegisterPublication("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->RegisterTopicHandler("discovery::NewComponent", - bind_weak(&DiscoveryComponent::NewComponentMessageHandler, shared_from_this())); + bind(&DiscoveryComponent::NewComponentMessageHandler, this, _1)); 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()->OnNewEndpoint += bind_weak(&DiscoveryComponent::NewEndpointHandler, shared_from_this()); + GetEndpointManager()->OnNewEndpoint.connect(bind(&DiscoveryComponent::NewEndpointHandler, this, _1)); GetEndpointManager()->RegisterEndpoint(m_DiscoveryEndpoint); /* create the reconnect timer */ m_DiscoveryTimer = make_shared(); 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(); /* 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) { - 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 */ neea.Endpoint->RegisterPublication("discovery::RegisterComponent"); diff --git a/config/ax_boost_signals.m4 b/config/ax_boost_signals.m4 new file mode 100644 index 000000000..219bc6d5d --- /dev/null +++ b/config/ax_boost_signals.m4 @@ -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 . +# +# This macro calls: +# +# AC_SUBST(BOOST_SIGNALS_LIB) +# +# And sets: +# +# HAVE_BOOST_SIGNALS +# +# LICENSE +# +# Copyright (c) 2008 Thomas Porschberg +# 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 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 +]) diff --git a/configure.ac b/configure.ac index 11ad8707f..c71c5ea92 100644 --- a/configure.ac +++ b/configure.ac @@ -53,6 +53,7 @@ AX_CXX_COMPILE_STDCXX_0X AX_CXX_GCC_ABI_DEMANGLE AX_PTHREAD AX_BOOST_BASE +AX_BOOST_SIGNALS AX_BOOST_UNIT_TEST_FRAMEWORK 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) @@ -66,7 +67,6 @@ AC_CHECK_LIB(shlwapi, PathRemoveFileSpecA) AC_CONFIG_FILES([ Makefile -compat/Makefile base/Makefile components/Makefile components/checker/Makefile diff --git a/icinga/endpoint.h b/icinga/endpoint.h index b1cd5982c..a9bb89168 100644 --- a/icinga/endpoint.h +++ b/icinga/endpoint.h @@ -79,8 +79,8 @@ public: ConstTopicIterator BeginPublications(void) const; ConstTopicIterator EndPublications(void) const; - Observable OnIdentityChanged; - Observable OnSessionEstablished; + boost::signal OnIdentityChanged; + boost::signal OnSessionEstablished; private: string m_Identity; /**< The identity of this endpoint. */ diff --git a/icinga/endpointmanager.cpp b/icinga/endpointmanager.cpp index 94856bc1d..483dd75b5 100644 --- a/icinga/endpointmanager.cpp +++ b/icinga/endpointmanager.cpp @@ -109,8 +109,8 @@ void EndpointManager::AddConnection(string node, string service) void EndpointManager::RegisterServer(JsonRpcServer::Ptr server) { m_Servers.push_back(server); - server->OnNewClient += bind_weak(&EndpointManager::NewClientHandler, - shared_from_this()); + server->OnNewClient.connect(bind(&EndpointManager::NewClientHandler, + this, _1)); } /** @@ -327,7 +327,7 @@ void EndpointManager::RescheduleRequestTimer(void) if (!m_RequestTimer) { m_RequestTimer = make_shared(); - m_RequestTimer->OnTimerExpired += bind_weak(&EndpointManager::RequestTimerHandler, shared_from_this()); + m_RequestTimer->OnTimerExpired.connect(bind(&EndpointManager::RequestTimerHandler, this, _1)); } if (it != m_Requests.end()) { diff --git a/icinga/endpointmanager.h b/icinga/endpointmanager.h index 699efd590..3a9ac354c 100644 --- a/icinga/endpointmanager.h +++ b/icinga/endpointmanager.h @@ -105,7 +105,7 @@ public: Endpoint::Ptr GetEndpointByIdentity(string identity) const; - Observable OnNewEndpoint; + boost::signal OnNewEndpoint; private: string m_Identity; diff --git a/icinga/icingaapplication.cpp b/icinga/icingaapplication.cpp index 4cdfb5f6e..18d3f3676 100644 --- a/icinga/icingaapplication.cpp +++ b/icinga/icingaapplication.cpp @@ -54,10 +54,10 @@ int IcingaApplication::Main(const vector& args) /* register handler for 'component' config objects */ static ConfigObject::Set::Ptr componentObjects = make_shared(ConfigObject::GetAllObjects(), ConfigObject::MakeTypePredicate("component")); - function&)> NewComponentHandler = bind_weak(&IcingaApplication::NewComponentHandler, shared_from_this()); - componentObjects->OnObjectAdded += NewComponentHandler; - componentObjects->OnObjectCommitted += NewComponentHandler; - componentObjects->OnObjectRemoved += bind_weak(&IcingaApplication::DeletedComponentHandler, shared_from_this()); + function&)> NewComponentHandler = bind(&IcingaApplication::NewComponentHandler, this, _1); + componentObjects->OnObjectAdded.connect(NewComponentHandler); + componentObjects->OnObjectCommitted.connect(NewComponentHandler); + componentObjects->OnObjectRemoved.connect(bind(&IcingaApplication::DeletedComponentHandler, this, _1)); componentObjects->Start(); /* load config file */ diff --git a/icinga/jsonrpcendpoint.cpp b/icinga/jsonrpcendpoint.cpp index 2d89a7fb5..02442ccf9 100644 --- a/icinga/jsonrpcendpoint.cpp +++ b/icinga/jsonrpcendpoint.cpp @@ -45,10 +45,10 @@ void JsonRpcEndpoint::Connect(string node, string service, shared_ptr s void JsonRpcEndpoint::SetClient(JsonRpcClient::Ptr client) { m_Client = client; - client->OnNewMessage += bind_weak(&JsonRpcEndpoint::NewMessageHandler, shared_from_this()); - client->OnClosed += bind_weak(&JsonRpcEndpoint::ClientClosedHandler, shared_from_this()); - client->OnError += bind_weak(&JsonRpcEndpoint::ClientErrorHandler, shared_from_this()); - client->OnVerifyCertificate += bind_weak(&JsonRpcEndpoint::VerifyCertificateHandler, shared_from_this()); + client->OnNewMessage.connect(bind(&JsonRpcEndpoint::NewMessageHandler, this, _1)); + client->OnClosed.connect(bind(&JsonRpcEndpoint::ClientClosedHandler, this, _1)); + client->OnError.connect(bind(&JsonRpcEndpoint::ClientErrorHandler, this, _1)); + client->OnVerifyCertificate.connect(bind(&JsonRpcEndpoint::VerifyCertificateHandler, this, _1)); } bool JsonRpcEndpoint::IsLocal(void) const @@ -122,8 +122,10 @@ int JsonRpcEndpoint::ClientClosedHandler(const EventArgs&) ClearPublications(); // remove the endpoint if there are no more subscriptions */ - if (BeginSubscriptions() == EndSubscriptions()) + if (BeginSubscriptions() == EndSubscriptions()) { + Hold(); GetEndpointManager()->UnregisterEndpoint(static_pointer_cast(shared_from_this())); + } m_Client.reset(); diff --git a/icinga/virtualendpoint.cpp b/icinga/virtualendpoint.cpp index fbb8b76a6..ca4951eec 100644 --- a/icinga/virtualendpoint.cpp +++ b/icinga/virtualendpoint.cpp @@ -40,7 +40,19 @@ bool VirtualEndpoint::IsConnected(void) const void VirtualEndpoint::RegisterTopicHandler(string topic, function callback) { - m_TopicHandlers[topic] += callback; + map > >::iterator it; + it = m_TopicHandlers.find(topic); + + shared_ptr > sig; + + if (it == m_TopicHandlers.end()) { + sig = make_shared >(); + m_TopicHandlers.insert(make_pair(topic, sig)); + } else { + sig = it->second; + } + + sig->connect(callback); RegisterSubscription(topic); } @@ -60,16 +72,17 @@ void VirtualEndpoint::ProcessRequest(Endpoint::Ptr sender, const RequestMessage& if (!request.GetMethod(&method)) return; - map >::iterator i = m_TopicHandlers.find(method); + map > >::iterator it; + it = m_TopicHandlers.find(method); - if (i == m_TopicHandlers.end()) + if (it == m_TopicHandlers.end()) return; NewRequestEventArgs nrea; nrea.Source = shared_from_this(); nrea.Sender = sender; nrea.Request = request; - i->second(nrea); + (*it->second)(nrea); } void VirtualEndpoint::ProcessResponse(Endpoint::Ptr sender, const ResponseMessage& response) diff --git a/icinga/virtualendpoint.h b/icinga/virtualendpoint.h index b86bd7e40..19f1ecfa2 100644 --- a/icinga/virtualendpoint.h +++ b/icinga/virtualendpoint.h @@ -59,7 +59,7 @@ public: virtual void Stop(void); private: - map< string, Observable > m_TopicHandlers; + map< string, shared_ptr > > m_TopicHandlers; }; } diff --git a/jsonrpc/jsonrpcclient.cpp b/jsonrpc/jsonrpcclient.cpp index 51664269b..5cfa76749 100644 --- a/jsonrpc/jsonrpcclient.cpp +++ b/jsonrpc/jsonrpcclient.cpp @@ -34,7 +34,7 @@ void JsonRpcClient::Start(void) { TlsClient::Start(); - OnDataAvailable += bind_weak(&JsonRpcClient::DataAvailableHandler, shared_from_this()); + OnDataAvailable.connect(bind(&JsonRpcClient::DataAvailableHandler, this, _1)); } /** diff --git a/jsonrpc/jsonrpcclient.h b/jsonrpc/jsonrpcclient.h index 314ebbb6c..463481aa5 100644 --- a/jsonrpc/jsonrpcclient.h +++ b/jsonrpc/jsonrpcclient.h @@ -50,7 +50,7 @@ public: virtual void Start(void); - Observable OnNewMessage; + boost::signal OnNewMessage; private: int DataAvailableHandler(const EventArgs&);