Pinger holds weak_ptr to self, Pingers created through static create functions; IcmpP...
authorChristian Herdtweck <christian.herdtweck@intra2net.com>
Mon, 26 Jan 2015 14:17:32 +0000 (15:17 +0100)
committerChristian Herdtweck <christian.herdtweck@intra2net.com>
Mon, 26 Jan 2015 14:17:32 +0000 (15:17 +0100)
src/host/pinger.cpp
src/host/pinger.h
src/host/pingerfactory.cpp
src/icmp/icmppinger.cpp
src/icmp/icmppinger.h
src/tcp/tcppinger.cpp
src/tcp/tcppinger.h

index df49629..224043a 100644 (file)
@@ -37,3 +37,13 @@ Pinger::Pinger()
 Pinger::~Pinger()
 {
 }
+
+void Pinger::set_myself( const Pinger::WeakPtr &myself)
+{
+    Myself = myself;
+}
+
+Pinger::WeakPtr Pinger::get_myself() const
+{
+    return Myself;
+}
index b8bdd91..705e40e 100644 (file)
@@ -29,6 +29,7 @@
 #include <boost/shared_ptr.hpp>
 #include <boost/utility.hpp>
 #include <boost/asio/io_service.hpp>
+#include <boost/weak_ptr.hpp>
 
 //-----------------------------------------------------------------------------
 // IoServiceItem
@@ -43,10 +44,15 @@ typedef boost::shared_ptr<boost::asio::io_service> IoServiceItem;
 /**
  * @brief Abstract class for pingers.
  * Scope: one object per host.
+ *
+ * Holds a weak_ptr to itself, so can create shared_ptrs from self
+ *   (adapted from amime project)
  */
 class Pinger : boost::noncopyable
 {
 public:
+    typedef boost::weak_ptr<Pinger> WeakPtr;
+
     virtual void ping(
             const std::string &destination_ip,
             const uint16_t destination_port,
@@ -58,8 +64,15 @@ public:
 protected:
     Pinger();
     virtual ~Pinger();
+
+    Pinger::WeakPtr get_myself() const;
+    void set_myself(const Pinger::WeakPtr &myself);
+
+private:
+    Pinger::WeakPtr Myself;
 };
 
+
 //-----------------------------------------------------------------------------
 // PingerItem
 //-----------------------------------------------------------------------------
index 776a8b2..17285a2 100644 (file)
@@ -82,33 +82,31 @@ PingerItem PingerFactory::createPinger(
     {
         if (protocol == PingProtocol_ICMP)
         {
-            PingerItem new_pinger(
-                    new IcmpPinger( io_serv, icmp::v4(), network_interface, ping_reply_timeout )
-            );
-            IcmpPaketDistributor::get_distributor(icmp::v4(), network_interface, io_serv)
-                                  ->register_pinger(new_pinger);
+            PingerItem new_pinger = IcmpPinger::create( io_serv, icmp::v4(),
+                                                         network_interface,
+                                                         ping_reply_timeout );
             return new_pinger;
         }
         else if (protocol == PingProtocol_ICMPv6)
         {
-            PingerItem new_pinger(
-                    new IcmpPinger( io_serv, icmp::v6(), network_interface, ping_reply_timeout )
-            );
-            IcmpPaketDistributor::get_distributor(icmp::v6(), network_interface, io_serv)
-                                  ->register_pinger(new_pinger);
+            PingerItem new_pinger = IcmpPinger::create( io_serv, icmp::v6(),
+                                                         network_interface,
+                                                         ping_reply_timeout );
             return new_pinger;
         }
         else if (protocol == PingProtocol_TCP)
         {
-            return PingerItem(
-                    new TcpPinger( io_serv, tcp_raw_protocol::v4(), network_interface, ping_reply_timeout )
-            );
+            PingerItem new_pinger = TcpPinger::create( io_serv, tcp_raw_protocol::v4(),
+                                                        network_interface,
+                                                        ping_reply_timeout );
+            return new_pinger;
         }
         else if (protocol == PingProtocol_TCP_IPv6)
         {
-            return PingerItem(
-                    new TcpPinger( io_serv, tcp_raw_protocol::v6(), network_interface, ping_reply_timeout )
-            );
+            PingerItem new_pinger = TcpPinger::create( io_serv, tcp_raw_protocol::v6(),
+                                                        network_interface,
+                                                        ping_reply_timeout );
+            return new_pinger;
         }
         else
         {
index 92b6560..8a43eed 100644 (file)
@@ -131,7 +131,7 @@ void IcmpPinger::ping(
 void IcmpPinger::stop_pinging()
 {
     IcmpPaketDistributor::get_distributor(Protocol, NetInterface.get_name())
-        ->unregister_pinger(PingerItem(this));
+        ->unregister_pinger( get_myself().lock() );
 }
 
 
@@ -390,3 +390,28 @@ void IcmpPinger::set_ping_status( PingStatus ping_status )
     PingerStatus = ping_status;
 }
 
+
+PingerItem IcmpPinger::create(
+        const IoServiceItem io_serv,
+        const icmp::socket::protocol_type &protocol,
+        const string &source_network_interface,
+        const int echo_reply_timeout_in_sec )
+{
+    // create pinger
+    IcmpPinger *ptr = new IcmpPinger(io_serv, protocol, source_network_interface,
+                                           echo_reply_timeout_in_sec);
+    PingerItem shared_ptr(ptr);
+    Pinger::WeakPtr weak_ptr( shared_ptr );
+
+    // keep weak pointer to self
+    ptr->set_myself( weak_ptr );
+    // shared_ptr->set_myself( weak_ptr ); Error: Pinger::set_myself is protected
+
+    // register in distributor
+    IcmpPaketDistributor::get_distributor(icmp::v4(), source_network_interface, io_serv)
+                          ->register_pinger(shared_ptr);
+
+    // done, return shared ptr
+    return shared_ptr;
+}
+
index 61cab02..1ad9b63 100644 (file)
 class IcmpPinger : public Pinger
 {
 public:
-    IcmpPinger(
+    static PingerItem create(
             const IoServiceItem io_serv,
             const boost::asio::ip::icmp::socket::protocol_type &protocol,
             const std::string &source_network_interface,
             const int echo_reply_timeout_in_sec
     );
+
     virtual ~IcmpPinger();
 
     virtual void ping(
@@ -48,6 +49,13 @@ public:
     virtual void stop_pinging();
 
 private:
+    IcmpPinger(
+            const IoServiceItem io_serv,
+            const boost::asio::ip::icmp::socket::protocol_type &protocol,
+            const std::string &source_network_interface,
+            const int echo_reply_timeout_in_sec
+    );
+
     void set_destination_endpoint( const std::string &destination_ip );
 
     bool start_send();
@@ -93,4 +101,6 @@ private:
     bool ReceiveHandlerInPlace;
 };
 
+typedef boost::shared_ptr<IcmpPinger> IcmpPingerItem;
+
 #endif // ICMP_PINGER_H
index 1b43a62..79347f6 100644 (file)
@@ -333,3 +333,22 @@ void TcpPinger::set_ping_status( PingStatus ping_status )
 {
     PingerStatus = ping_status;
 }
+
+PingerItem TcpPinger::create(
+        const IoServiceItem io_serv,
+        const tcp_raw_protocol::socket::protocol_type &protocol,
+        const string &source_network_interface_name,
+        const int rst_reply_timeout_in_sec )
+{
+    TcpPinger *ptr = new TcpPinger(io_serv, protocol, source_network_interface_name,
+                                           rst_reply_timeout_in_sec);
+    PingerItem shared_ptr(ptr);
+    Pinger::WeakPtr weak_ptr( shared_ptr );
+
+    // keep weak pointer to self
+    ptr->set_myself( weak_ptr );
+    // shared_ptr->set_myself( weak_ptr ); Error: Pinger::set_myself is protected
+
+    // done, return shared ptr
+    return shared_ptr;
+}
index d579cd9..8a6329f 100644 (file)
@@ -44,12 +44,6 @@ on this file might be covered by the GNU General Public License.
 class TcpPinger : public Pinger
 {
 public:
-    TcpPinger(
-            const IoServiceItem io_serv,
-            const boost::asio::ip::tcp_raw_protocol::socket::protocol_type &protocol,
-            const std::string &source_network_interface_name,
-            const int rst_reply_timeout_in_sec
-    );
     virtual ~TcpPinger();
 
     virtual void ping(
@@ -60,7 +54,21 @@ public:
 
     virtual void stop_pinging();
 
+    static PingerItem create(
+            const IoServiceItem io_serv,
+            const boost::asio::ip::tcp_raw_protocol::socket::protocol_type &protocol,
+            const std::string &source_network_interface_name,
+            const int rst_reply_timeout_in_sec
+    );
+
 private:
+    TcpPinger(
+            const IoServiceItem io_serv,
+            const boost::asio::ip::tcp_raw_protocol::socket::protocol_type &protocol,
+            const std::string &source_network_interface_name,
+            const int rst_reply_timeout_in_sec
+    );
+
     boost::asio::ip::address get_source_address() const;
     boost::asio::ip::address get_destination_address() const;