fix valgrind warning: UdpSocket must manage carefully its Ipv4EndPoint to avoid double deleting it.
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Thu, 03 May 2007 13:11:50 +0200
changeset 515 e907146a191e
parent 514 7c9a037a32b7
child 516 3d330150ab6d
fix valgrind warning: UdpSocket must manage carefully its Ipv4EndPoint to avoid double deleting it.
src/node/ipv4-end-point-demux.cc
src/node/ipv4-end-point-demux.h
src/node/node.cc
src/node/udp-socket.cc
src/node/udp.cc
src/node/udp.h
--- a/src/node/ipv4-end-point-demux.cc	Thu May 03 12:46:50 2007 +0200
+++ b/src/node/ipv4-end-point-demux.cc	Thu May 03 13:11:50 2007 +0200
@@ -127,6 +127,20 @@
   return endPoint;
 }
 
+void 
+Ipv4EndPointDemux::DeAllocate (Ipv4EndPoint *endPoint)
+{
+  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
+    {
+      if (*i == endPoint)
+        {
+          delete endPoint;
+          m_endPoints.erase (i);
+          break;
+        }
+    }
+}
+
 
 /*
  * If we have an exact match, we return it.
--- a/src/node/ipv4-end-point-demux.h	Thu May 03 12:46:50 2007 +0200
+++ b/src/node/ipv4-end-point-demux.h	Thu May 03 13:11:50 2007 +0200
@@ -51,6 +51,8 @@
                           Ipv4Address peerAddress, 
                           uint16_t peerPort);
 
+  void DeAllocate (Ipv4EndPoint *endPoint);
+
  private:
   uint16_t AllocateEphemeralPort (void);
   typedef std::list<Ipv4EndPoint *> EndPoints;
--- a/src/node/node.cc	Thu May 03 12:46:50 2007 +0200
+++ b/src/node/node.cc	Thu May 03 13:11:50 2007 +0200
@@ -51,7 +51,6 @@
 Node::~Node ()
 {}
 
-
 uint32_t 
 Node::GetId (void) const
 {
@@ -99,7 +98,7 @@
       device->Dispose ();
       device->Unref ();
     }
-  m_devices.erase (m_devices.begin (), m_devices.end ());
+  m_devices.clear ();
   NsUnknown::DoDispose ();
 }
 
--- a/src/node/udp-socket.cc	Thu May 03 12:46:50 2007 +0200
+++ b/src/node/udp-socket.cc	Thu May 03 13:11:50 2007 +0200
@@ -40,7 +40,31 @@
 }
 UdpSocket::~UdpSocket ()
 {
-  Destroy ();
+  if (m_node != 0)
+    {
+      m_node->Unref ();
+      m_node = 0;
+    }
+  if (m_endPoint != 0)
+    {
+      NS_ASSERT (m_udp != 0);
+      /**
+       * Note that this piece of code is a bit tricky:
+       * when DeAllocate is called, it will call into
+       * Ipv4EndPointDemux::Deallocate which triggers
+       * a delete of the associated endPoint which triggers
+       * in turn a call to the method ::Destroy below
+       * will will zero the m_endPoint field.
+       */
+      NS_ASSERT (m_endPoint != 0);
+      m_udp->DeAllocate (m_endPoint);
+      NS_ASSERT (m_endPoint == 0);
+    }
+  if (m_udp != 0)
+    {
+      m_udp->Unref ();
+      m_udp = 0;
+    }
 }
 
 Node *
--- a/src/node/udp.cc	Thu May 03 12:46:50 2007 +0200
+++ b/src/node/udp.cc	Thu May 03 13:11:50 2007 +0200
@@ -107,6 +107,12 @@
 }
 
 void 
+Udp::DeAllocate (Ipv4EndPoint *endPoint)
+{
+  m_endPoints->DeAllocate (endPoint);
+}
+
+void 
 Udp::Receive(Packet& packet, 
              Ipv4Address const &source,
              Ipv4Address const &destination)
--- a/src/node/udp.h	Thu May 03 12:46:50 2007 +0200
+++ b/src/node/udp.h	Thu May 03 13:11:50 2007 +0200
@@ -54,6 +54,8 @@
   Ipv4EndPoint *Allocate (Ipv4Address localAddress, uint16_t localPort,
                          Ipv4Address peerAddress, uint16_t peerPort);
 
+  void DeAllocate (Ipv4EndPoint *endPoint);
+
   // called by UdpSocket.
   void Send (Packet packet,
              Ipv4Address saddr, Ipv4Address daddr,