Bug 1377: various memory leaks
authorTommaso Pecorella <tommaso.pecorella@unifi.it>
Sun, 26 Feb 2012 19:51:19 +0100
changeset 7747 53a26ce38807
parent 7746 c1a97d303064
child 7748 1fbd1de4b24d
Bug 1377: various memory leaks
src/internet/model/ipv4-end-point.cc
src/internet/model/ipv6-end-point.cc
src/internet/model/tcp-socket-base.cc
src/internet/model/tcp-socket-base.h
src/internet/model/udp-socket-impl.cc
src/internet/model/udp-socket-impl.h
src/internet/test/ipv6-dual-stack-test-suite.cc
src/network/model/socket.cc
--- a/src/internet/model/ipv4-end-point.cc	Fri Feb 24 11:39:28 2012 +0000
+++ b/src/internet/model/ipv4-end-point.cc	Sun Feb 26 19:51:19 2012 +0100
@@ -40,6 +40,9 @@
     {
       m_destroyCallback ();
     }
+  m_rxCallback.Nullify ();
+  m_icmpCallback.Nullify ();
+  m_destroyCallback.Nullify ();
 }
 
 Ipv4Address 
--- a/src/internet/model/ipv6-end-point.cc	Fri Feb 24 11:39:28 2012 +0000
+++ b/src/internet/model/ipv6-end-point.cc	Sun Feb 26 19:51:19 2012 +0100
@@ -43,6 +43,9 @@
     {
       m_destroyCallback ();
     }
+  m_rxCallback.Nullify ();
+  m_icmpCallback.Nullify ();
+  m_destroyCallback.Nullify ();
 }
 
 Ipv6Address Ipv6EndPoint::GetLocalAddress ()
--- a/src/internet/model/tcp-socket-base.cc	Fri Feb 24 11:39:28 2012 +0000
+++ b/src/internet/model/tcp-socket-base.cc	Sun Feb 26 19:51:19 2012 +0100
@@ -635,7 +635,7 @@
   if (m_endPoint6 != 0)
     {
       m_endPoint6->SetRxCallback (MakeCallback (&TcpSocketBase::ForwardUp6, Ptr<TcpSocketBase> (this)));
-      m_endPoint6->SetDestroyCallback (MakeCallback (&TcpSocketBase::Destroy, Ptr<TcpSocketBase> (this)));
+      m_endPoint6->SetDestroyCallback (MakeCallback (&TcpSocketBase::Destroy6, Ptr<TcpSocketBase> (this)));
     }
 
   return 0;
@@ -1422,8 +1422,27 @@
 TcpSocketBase::Destroy (void)
 {
   NS_LOG_FUNCTION (this);
-  m_node = 0;
   m_endPoint = 0;
+  if (m_tcp != 0)
+    {
+      std::vector<Ptr<TcpSocketBase> >::iterator it
+        = std::find (m_tcp->m_sockets.begin (), m_tcp->m_sockets.end (), this);
+      if (it != m_tcp->m_sockets.end ())
+        {
+          m_tcp->m_sockets.erase (it);
+        }
+    }
+  NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
+                (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
+  CancelAllTimers ();
+}
+
+/** Kill this socket. This is a callback function configured to m_endpoint in
+   SetupCallback(), invoked when the endpoint is destroyed. */
+void
+TcpSocketBase::Destroy6 (void)
+{
+  NS_LOG_FUNCTION (this);
   m_endPoint6 = 0;
   if (m_tcp != 0)
     {
@@ -1433,7 +1452,6 @@
         {
           m_tcp->m_sockets.erase (it);
         }
-      m_tcp = 0;
     }
   NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
                 (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
--- a/src/internet/model/tcp-socket-base.h	Fri Feb 24 11:39:28 2012 +0000
+++ b/src/internet/model/tcp-socket-base.h	Sun Feb 26 19:51:19 2012 +0100
@@ -148,6 +148,7 @@
   int DoClose (void); // Close a socket by sending RST, FIN, or FIN+ACK, depend on the current state
   void CloseAndNotify (void); // To CLOSED state, notify upper layer, and deallocate end point
   void Destroy (void); // Kill this socket by zeroing its attributes
+  void Destroy6 (void); // Kill this socket by zeroing its attributes
   void DeallocateEndPoint (void); // Deallocate m_endPoint
   void PeerClose (Ptr<Packet>, const TcpHeader&); // Received a FIN from peer, notify rx buffer
   void DoPeerClose (void); // FIN is in sequence, notify app and respond with a FIN
--- a/src/internet/model/udp-socket-impl.cc	Fri Feb 24 11:39:28 2012 +0000
+++ b/src/internet/model/udp-socket-impl.cc	Sun Feb 26 19:51:19 2012 +0100
@@ -86,6 +86,11 @@
 
   // XXX todo:  leave any multicast groups that have been joined
   m_node = 0;
+  /**
+   * Note: actually this function is called AFTER
+   * UdpSocketImpl::Destroy or UdpSocketImpl::Destroy6
+   * so the code below is unnecessary in normal operations
+   */
   if (m_endPoint != 0)
     {
       NS_ASSERT (m_udp != 0);
@@ -101,6 +106,21 @@
       m_udp->DeAllocate (m_endPoint);
       NS_ASSERT (m_endPoint == 0);
     }
+  if (m_endPoint6 != 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 UdpSocketImpl::Destroy below
+       * will will zero the m_endPoint field.
+       */
+      NS_ASSERT (m_endPoint6 != 0);
+      m_udp->DeAllocate (m_endPoint6);
+      NS_ASSERT (m_endPoint6 == 0);
+    }
   m_udp = 0;
 }
 
@@ -143,27 +163,37 @@
 UdpSocketImpl::Destroy (void)
 {
   NS_LOG_FUNCTION_NOARGS ();
-  m_node = 0;
   m_endPoint = 0;
-  m_udp = 0;
+}
+
+void
+UdpSocketImpl::Destroy6 (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_endPoint6 = 0;
 }
 
 int
 UdpSocketImpl::FinishBind (void)
 {
   NS_LOG_FUNCTION_NOARGS ();
+  bool done = false;
   if (m_endPoint != 0)
     {
       m_endPoint->SetRxCallback (MakeCallback (&UdpSocketImpl::ForwardUp, Ptr<UdpSocketImpl> (this)));
       m_endPoint->SetIcmpCallback (MakeCallback (&UdpSocketImpl::ForwardIcmp, Ptr<UdpSocketImpl> (this)));
       m_endPoint->SetDestroyCallback (MakeCallback (&UdpSocketImpl::Destroy, Ptr<UdpSocketImpl> (this)));
-      return 0;
+      done = true;
     }
-  else if (m_endPoint6 != 0)
+  if (m_endPoint6 != 0)
     {
       m_endPoint6->SetRxCallback (MakeCallback (&UdpSocketImpl::ForwardUp6, Ptr<UdpSocketImpl> (this)));
       m_endPoint6->SetIcmpCallback (MakeCallback (&UdpSocketImpl::ForwardIcmp6, Ptr<UdpSocketImpl> (this)));
-      m_endPoint6->SetDestroyCallback (MakeCallback (&UdpSocketImpl::Destroy, Ptr<UdpSocketImpl> (this)));
+      m_endPoint6->SetDestroyCallback (MakeCallback (&UdpSocketImpl::Destroy6, Ptr<UdpSocketImpl> (this)));
+      done = true;
+    }
+  if (done)
+    {
       return 0;
     }
   return -1;
--- a/src/internet/model/udp-socket-impl.h	Fri Feb 24 11:39:28 2012 +0000
+++ b/src/internet/model/udp-socket-impl.h	Sun Feb 26 19:51:19 2012 +0100
@@ -108,6 +108,7 @@
                   Ptr<Ipv4Interface> incomingInterface);
   void ForwardUp6 (Ptr<Packet> p, Ipv6Address saddr, Ipv6Address daddr, uint16_t port);
   void Destroy (void);
+  void Destroy6 (void);
   int DoSend (Ptr<Packet> p);
   int DoSendTo (Ptr<Packet> p, const Address &daddr);
   int DoSendTo (Ptr<Packet> p, Ipv4Address daddr, uint16_t dport);
--- a/src/internet/test/ipv6-dual-stack-test-suite.cc	Fri Feb 24 11:39:28 2012 +0000
+++ b/src/internet/test/ipv6-dual-stack-test-suite.cc	Sun Feb 26 19:51:19 2012 +0100
@@ -296,6 +296,7 @@
 void
 DualStackTestCase::DoTeardown (void)
 {
+  Simulator::Destroy ();
 }
 
 
--- a/src/network/model/socket.cc	Fri Feb 24 11:39:28 2012 +0000
+++ b/src/network/model/socket.cc	Sun Feb 26 19:51:19 2012 +0100
@@ -292,6 +292,8 @@
 
   m_connectionSucceeded = MakeNullCallback<void,Ptr<Socket> > ();
   m_connectionFailed = MakeNullCallback<void,Ptr<Socket> > ();
+  m_normalClose = MakeNullCallback<void,Ptr<Socket> > ();
+  m_errorClose = MakeNullCallback<void,Ptr<Socket> > ();
   m_connectionRequest = MakeNullCallback<bool,Ptr<Socket>, const Address &> ();
   m_newConnectionCreated = MakeNullCallback<void,Ptr<Socket>, const Address &> ();
   m_dataSent = MakeNullCallback<void,Ptr<Socket>, uint32_t> ();