]> granicus.if.org Git - icinga2/commitdiff
Replaced custom event code with Boost.Signals.
authorGunnar Beutner <gunnar.beutner@netways.de>
Thu, 14 Jun 2012 13:16:41 +0000 (15:16 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Thu, 14 Jun 2012 13:16:41 +0000 (15:16 +0200)
35 files changed:
Makefile.am
README
base/Makefile.am
base/application.cpp
base/eventargs.h [moved from base/delegate.h with 58% similarity]
base/i2-base.h
base/object.cpp
base/object.h
base/objectmap.h
base/objectset.h
base/observable.h [deleted file]
base/socket.cpp
base/socket.h
base/tcpclient.cpp
base/tcpclient.h
base/tcpserver.cpp
base/tcpserver.h
base/timer.h
base/tlsclient.h
compat/Makefile.am [deleted file]
components/checker/checkercomponent.cpp
components/configrpc/configrpccomponent.cpp
components/demo/democomponent.cpp
components/discovery/discoverycomponent.cpp
config/ax_boost_signals.m4 [new file with mode: 0644]
configure.ac
icinga/endpoint.h
icinga/endpointmanager.cpp
icinga/endpointmanager.h
icinga/icingaapplication.cpp
icinga/jsonrpcendpoint.cpp
icinga/virtualendpoint.cpp
icinga/virtualendpoint.h
jsonrpc/jsonrpcclient.cpp
jsonrpc/jsonrpcclient.h

index 8b54e69d7ff98d4fa67cb2dff4a3486983b8d2ae..030f64b1efae864b4576e233cb1a19738b04a1ba 100644 (file)
@@ -4,7 +4,6 @@
 include aminclude.am
 
 SUBDIRS = \
-       compat \
        third-party \
        base \
        dyn \
diff --git a/README b/README
index bd56b94a10d4f9009f0c28b9f382193937cc133b..53378e034c3aacd22fd66553a80a0374edcf2fda 100644 (file)
--- 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
 ---------------
 
index a3455a0c8cd006a662a3b4d3afa7c98c407b31e2..f95a3975836f85e7b8f7e7a2eb1a195c88f8c669 100644 (file)
@@ -65,4 +65,5 @@ libbase_la_LDFLAGS = \
 libbase_la_LIBADD = \
        $(LIBLTDL) \
        $(OPENSSL_LIBS) \
+       $(BOOST_SIGNALS_LIB) \
        ${top_builddir}/third-party/mmatch/libmmatch.la
index 77f5dde84bd42161d7345a99f323e6e8d20274e2..a277104d8808ec0f4f4786d347093238dc28748b 100644 (file)
@@ -96,6 +96,8 @@ void Application::RunEventLoop(void)
                fd_set readfds, writefds, exceptfds;
                int nfds = -1;
 
+               Object::ClearHeldObjects();
+
                Timer::CallExpiredTimers();
 
                FD_ZERO(&readfds);
similarity index 58%
rename from base/delegate.h
rename to base/eventargs.h
index be73560369fc6fc6cdb6396dddacbb8d75329676..f913b7e8da69baf00804d57acf5431bf89527b03 100644 (file)
  * 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<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();
-
-       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);
-}
+       Object::Ptr Source; /**< The source of the event. */
+};
 
 }
 
-#endif /* DELEGATE_H */
+#endif /* EVENTARGS_H */
index e57abdf305ac3d9cdf921a38d3b229a2cc22552d..22d94f9c75a6a52e458cf76b8700d447d29a91b1 100644 (file)
@@ -93,7 +93,6 @@
 #include <algorithm>
 
 using namespace std;
-using std::exception;
 
 #ifdef HAVE_STDCXX_0X
 #      include <memory>
@@ -121,6 +120,8 @@ using namespace std::tr1::placeholders;
 #endif /* HAVE_BOOST */
 #endif /* HAVE_STDCXX_0X */
 
+#include <boost/signal.hpp>
+
 #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"
index 8bee4935c48c567c466b8441800a60b5b7aafead..477477f40fb82aecb167b658bf00fbb68d11cc1a 100644 (file)
@@ -21,6 +21,8 @@
 
 using namespace icinga;
 
+vector<Object::Ptr> 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();
+}
+
index f712aad815cc151a159290d9171da01b0628d8d7..cc8507cb7a3100ee712637599519419474e456f2 100644 (file)
@@ -29,7 +29,7 @@ namespace icinga
  *
  * @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:
        typedef shared_ptr<Object> 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<Object::Ptr> m_HeldObjects;
 };
 
 /**
index 2411d542e391a1b0d9ffe14f5957078f77b497ca..9b975412f79684b5dbba9f6488b98cabc176bb66 100644 (file)
@@ -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<TValue>::Iterator it = m_Parent->Begin(); it != m_Parent->End(); it++)
                        AddObject(*it);
index f7bcde34bcdcc6eb02ce1a737f20bd968e83bf09..ad4d41c989c626317c6f75794402d3189b126d75 100644 (file)
@@ -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<ObjectSetEventArgs<TValue> > OnObjectAdded;
-       Observable<ObjectSetEventArgs<TValue> > OnObjectCommitted;
-       Observable<ObjectSetEventArgs<TValue> > OnObjectRemoved;
+       boost::signal<void (const ObjectSetEventArgs<TValue>&)> OnObjectAdded;
+       boost::signal<void (const ObjectSetEventArgs<TValue>&)> OnObjectCommitted;
+       boost::signal<void (const ObjectSetEventArgs<TValue>&)> OnObjectRemoved;
 
        Iterator Begin(void)
        {
diff --git a/base/observable.h b/base/observable.h
deleted file mode 100644 (file)
index 8dc13f3..0000000
+++ /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 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 */
index dba50bf5224086ded59f70c9a9029eff6fdc5945..6cee85988ede4bf3c1e271198dc829f93c2023b7 100644 (file)
@@ -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<Socket>(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;
-       }
+       }*/
 }
 
 /**
index 8bba41e58822f1a20d4896a38f4d4ad01a4112e5..9d111d4a4bea40fc9b946dd1370d8b803a594af2 100644 (file)
@@ -55,12 +55,12 @@ public:
        void SetFD(SOCKET fd);
        SOCKET GetFD(void) const;
 
-       Observable<EventArgs> OnReadable;
-       Observable<EventArgs> OnWritable;
-       Observable<EventArgs> OnException;
+       boost::signal<void (const EventArgs&)> OnReadable;
+       boost::signal<void (const EventArgs&)> OnWritable;
+       boost::signal<void (const EventArgs&)> OnException;
 
-       Observable<SocketErrorEventArgs> OnError;
-       Observable<EventArgs> OnClosed;
+       boost::signal<void (const SocketErrorEventArgs&)> OnError;
+       boost::signal<void (const EventArgs&)> OnClosed;
 
        virtual bool WantsToRead(void) const;
        virtual bool WantsToWrite(void) const;
index 0308e4844e09a1ca32b53c0cf279d75de3eef2ff..655253771ee69b7d8dbbc0a1aea18d00a9e6ee58 100644 (file)
@@ -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));
 }
 
 /**
index 627467712efc3d124fe4c9e4e1415785d6e6bfa5..997c0ce052ac2e3e853d222925431709168c2c67 100644 (file)
@@ -61,7 +61,7 @@ public:
        virtual bool WantsToRead(void) const;
        virtual bool WantsToWrite(void) const;
 
-       Observable<EventArgs> OnDataAvailable;
+       boost::signal<void (const EventArgs&)> OnDataAvailable;
 
 private:
        TcpClientRole m_Role;
index a5c3d6dcdcb9339ece80710241bd1e8c735bacce..f790775dc7e3fddcb30254d8f7e5c631108e862a 100644 (file)
@@ -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));
 }
 
 /**
index bdaf7ab334d0255077602b0444c9349a2bf991b2..260effcd4a2e8e4d0cf89cdc9f94f6c7aee146ce 100644 (file)
@@ -54,7 +54,7 @@ public:
 
        void Listen(void);
 
-       Observable<NewClientEventArgs> OnNewClient;
+       boost::signal<void (const NewClientEventArgs&)> OnNewClient;
 
        virtual bool WantsToRead(void) const;
 
index 136a10bd787f537c8f7974114187d8f24d398090..9bf8bfa4e8d77adc920536f7541cc6386aa7cf8a 100644 (file)
@@ -65,7 +65,7 @@ public:
 
        void Reschedule(time_t next);
 
-       Observable<TimerEventArgs> OnTimerExpired;
+       boost::signal<void (const TimerEventArgs&)> OnTimerExpired;
 
 private:
        EventArgs m_UserArgs; /**< User-specified event arguments. */
index c92c41c20fe716c4b24f993ea1155b721ab6b148..2bc33e7277542a683e33528793b1ce3bd99fd40d 100644 (file)
@@ -55,7 +55,7 @@ public:
        virtual bool WantsToRead(void) const;
        virtual bool WantsToWrite(void) const;
 
-       Observable<VerifyCertificateEventArgs> OnVerifyCertificate;
+       boost::signal<void (const VerifyCertificateEventArgs&)> OnVerifyCertificate;
 
 protected:
        void HandleSSLError(void);
diff --git a/compat/Makefile.am b/compat/Makefile.am
deleted file mode 100644 (file)
index 38a07f7..0000000
+++ /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/
index 56d194aa3cc1eb91fa79fcfe5ec08affa7ab0530..941e4c038f6c2b7a7e2454d396ead44d116f8cb1 100644 (file)
@@ -30,9 +30,9 @@ void CheckerComponent::Start(void)
 {
        m_CheckerEndpoint = make_shared<VirtualEndpoint>();
        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<Timer>();
        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);
index 2504510ce2d0dd494b5e440707da1d715cfb0581..b9fbf8f2f68de191a24ef3befe4ace4b78e58a72 100644 (file)
@@ -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;
 }
index 5bf073cc50a3c711edca3b6d5be055b68030c9ad..ce8449be25d85a4d7fd02bbaa3fca0708bb83052 100644 (file)
@@ -38,13 +38,13 @@ void DemoComponent::Start(void)
 {
        m_DemoEndpoint = make_shared<VirtualEndpoint>();
        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<Timer>();
        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();
 }
 
index b9b50396b0478840f34a38346b4b7f42fdd88dca..616f2791ba915fe5cf752d862d4fe24e6d0c9c2d 100644 (file)
@@ -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<Timer>();
        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 (file)
index 0000000..219bc6d
--- /dev/null
@@ -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
+])
index 11ad8707f3aaf44b5306767da8a6ff489a23adc1..c71c5ea92ac31e5913ef9a5b2e8b0e9baad8fdfe 100644 (file)
@@ -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
index b1cd5982c22a3a25c175a155b5beeddf53adf810..a9bb89168007c3bc66cd456fa76f8d0d53c9aede 100644 (file)
@@ -79,8 +79,8 @@ public:
        ConstTopicIterator BeginPublications(void) const;
        ConstTopicIterator EndPublications(void) const;
 
-       Observable<EventArgs> OnIdentityChanged;
-       Observable<EventArgs> OnSessionEstablished;
+       boost::signal<void (const EventArgs&)> OnIdentityChanged;
+       boost::signal<void (const EventArgs&)> OnSessionEstablished;
 
 private:
        string m_Identity; /**< The identity of this endpoint. */
index 94856bc1dd89fa816863fe89717c09a40c0fe1d4..483dd75b5768ce12d7a29d768250184001ff0442 100644 (file)
@@ -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<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()) {
index 699efd5905bfc79f5d8d46b9fa88a9bb31744819..3a9ac354c8a911143bcd8e3a3106236833ece909 100644 (file)
@@ -105,7 +105,7 @@ public:
 
        Endpoint::Ptr GetEndpointByIdentity(string identity) const;
 
-       Observable<NewEndpointEventArgs> OnNewEndpoint;
+       boost::signal<void (const NewEndpointEventArgs&)> OnNewEndpoint;
 
 private:
        string m_Identity;
index 4cdfb5f6e60408d81074ad1e7092244261bbb8ae..18d3f36768eec24ec5faa3e987acd2a9ccc0aa12 100644 (file)
@@ -54,10 +54,10 @@ int IcingaApplication::Main(const vector<string>& args)
 
        /* register handler for 'component' config objects */
        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());
-       componentObjects->OnObjectAdded += NewComponentHandler;
-       componentObjects->OnObjectCommitted += NewComponentHandler;
-       componentObjects->OnObjectRemoved += bind_weak(&IcingaApplication::DeletedComponentHandler, shared_from_this());
+       function<int (const ObjectSetEventArgs<ConfigObject::Ptr>&)> 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 */
index 2d89a7fb5e27fc8ff3993dae74df915687216d8e..02442ccf9d319c65a4d0647ccd67a49931467a0b 100644 (file)
@@ -45,10 +45,10 @@ void JsonRpcEndpoint::Connect(string node, string service, shared_ptr<SSL_CTX> 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<Endpoint>(shared_from_this()));
+       }
 
        m_Client.reset();
 
index fbb8b76a629649b8d7d9907d9e1c17ee3169e049..ca4951eec1ac0045692ed48ba2eed6afe61fc623 100644 (file)
@@ -40,7 +40,19 @@ bool VirtualEndpoint::IsConnected(void) const
 
 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);
 }
@@ -60,16 +72,17 @@ void VirtualEndpoint::ProcessRequest(Endpoint::Ptr sender, const RequestMessage&
        if (!request.GetMethod(&method))
                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;
 
        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)
index b86bd7e40bb6f09a6ada1c223f4811dcb2dbd90b..19f1ecfa26dc87219fb0712335977416b4268f62 100644 (file)
@@ -59,7 +59,7 @@ public:
        virtual void Stop(void);
 
 private:
-       map< string, Observable<NewRequestEventArgs> > m_TopicHandlers;
+       map< string, shared_ptr<boost::signal<void (const NewRequestEventArgs&)> > > m_TopicHandlers;
 };
 
 }
index 51664269b793a3a7f7d163af340ea30a21b77de2..5cfa7674933d7da30de7007f33f8a912d3700adc 100644 (file)
@@ -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));
 }
 
 /**
index 314ebbb6ca23971b4649a99bc840b0810a526ac9..463481aa56095dc3ea7edff0b0ee01fb62938310 100644 (file)
@@ -50,7 +50,7 @@ public:
 
        virtual void Start(void);
 
-       Observable<NewMessageEventArgs> OnNewMessage;
+       boost::signal<void (const NewMessageEventArgs&)> OnNewMessage;
 
 private:
        int DataAvailableHandler(const EventArgs&);