bug 2119: Fixing memory leaks in FdNetDevice test with DefaultSimulatorImpl due to non-executed events when simulation ends
authorAlina Quereilhac <alina.quereilhac@inria.fr>
Tue, 04 Aug 2015 22:45:54 +0200
changeset 11547 941beab1b849
parent 11546 b40fe85d91bd
child 11548 86d5cd8e3b34
bug 2119: Fixing memory leaks in FdNetDevice test with DefaultSimulatorImpl due to non-executed events when simulation ends
src/core/model/default-simulator-impl.cc
src/fd-net-device/model/fd-net-device.cc
src/fd-net-device/model/fd-net-device.h
--- a/src/core/model/default-simulator-impl.cc	Sat Aug 01 19:48:14 2015 +0200
+++ b/src/core/model/default-simulator-impl.cc	Tue Aug 04 22:45:54 2015 +0200
@@ -84,6 +84,8 @@
 DefaultSimulatorImpl::DoDispose (void)
 {
   NS_LOG_FUNCTION (this);
+  ProcessEventsWithContext ();
+
   while (!m_events->IsEmpty ())
     {
       Scheduler::Event next = m_events->RemoveNext ();
--- a/src/fd-net-device/model/fd-net-device.cc	Sat Aug 01 19:48:14 2015 +0200
+++ b/src/fd-net-device/model/fd-net-device.cc	Tue Aug 04 22:45:54 2015 +0200
@@ -168,12 +168,12 @@
 FdNetDevice::FdNetDevice ()
   : m_node (0),
     m_ifIndex (0),
-    m_mtu (1500), // Defaults to Ethernet v2 MTU 
+    // Defaults to Ethernet v2 MTU
+    m_mtu (1500),
     m_fd (-1),
     m_fdReader (0),
     m_isBroadcast (true),
     m_isMulticast (false),
-    m_pendingReadCount (0),
     m_startEvent (),
     m_stopEvent ()
 {
@@ -188,6 +188,18 @@
 FdNetDevice::~FdNetDevice ()
 {
   NS_LOG_FUNCTION (this);
+
+  {
+    CriticalSection cs (m_pendingReadMutex);
+
+    while (!m_pendingQueue.empty ())
+      {
+        std::pair<uint8_t *, ssize_t> next = m_pendingQueue.front ();
+        m_pendingQueue.pop ();
+
+        free (next.first);
+      }
+  }
 }
 
 void
@@ -249,7 +261,7 @@
 
   m_fdReader = Create<FdNetDeviceFdReader> ();
   // 22 bytes covers 14 bytes Ethernet header with possible 8 bytes LLC/SNAP
-  m_fdReader->SetBufferSize(m_mtu + 22);  
+  m_fdReader->SetBufferSize (m_mtu + 22);
   m_fdReader->Start (m_fd, MakeCallback (&FdNetDevice::ReceiveCallback, this));
 
   NotifyLinkUp ();
@@ -281,26 +293,28 @@
 
   {
     CriticalSection cs (m_pendingReadMutex);
-    if (m_pendingReadCount >= m_maxPendingReads)
+    if (m_pendingQueue.size () >= m_maxPendingReads)
       {
         NS_LOG_WARN ("Packet dropped");
         skip = true;
       }
     else
       {
-        ++m_pendingReadCount;
+        m_pendingQueue.push (std::make_pair (buf, len));
       }
   }
 
   if (skip)
     {
-      struct timespec time = { 0, 100000000L }; // 100 ms
+      struct timespec time = {
+        0, 100000000L
+      };                                        // 100 ms
       nanosleep (&time, NULL);
     }
   else
     {
-      Simulator::ScheduleWithContext (m_nodeId, Time (0), MakeEvent (&FdNetDevice::ForwardUp, this, buf, len));
-   }
+      Simulator::ScheduleWithContext (m_nodeId, Time (0), MakeEvent (&FdNetDevice::ForwardUp, this));
+    }
 }
 
 /**
@@ -368,17 +382,22 @@
 }
 
 void
-FdNetDevice::ForwardUp (uint8_t *buf, ssize_t len)
+FdNetDevice::ForwardUp (void)
 {
-  NS_LOG_FUNCTION (this << buf << len);
+
+  uint8_t *buf = 0; 
+  ssize_t len = 0;
 
-  if (m_pendingReadCount > 0)
-    {
-      {
-        CriticalSection cs (m_pendingReadMutex);
-        --m_pendingReadCount;
-      }
-    }
+  {
+    CriticalSection cs (m_pendingReadMutex);
+    std::pair<uint8_t *, ssize_t> next = m_pendingQueue.front ();
+    m_pendingQueue.pop ();
+
+    buf = next.first;
+    len = next.second;
+  }
+
+  NS_LOG_FUNCTION (this << buf << len);
 
   // We need to remove the PI header and ignore it
   if (m_encapMode == DIXPI)
--- a/src/fd-net-device/model/fd-net-device.h	Sat Aug 01 19:48:14 2015 +0200
+++ b/src/fd-net-device/model/fd-net-device.h	Tue Aug 04 22:45:54 2015 +0200
@@ -36,7 +36,8 @@
 #include "ns3/unix-fd-reader.h"
 #include "ns3/system-mutex.h"
 
-#include <string.h>
+#include <utility>
+#include <queue>
 
 namespace ns3 {
 
@@ -63,7 +64,7 @@
 
 private:
   FdReader::Data DoRead (void);
-  
+
   uint32_t m_bufferSize; //!< size of the read buffer
 };
 
@@ -216,7 +217,7 @@
   /**
    * Forward the frame to the appropriate callback for processing
    */
-  void ForwardUp (uint8_t *buf, ssize_t len);
+  void ForwardUp (void);
 
   /**
    * Start Sending a Packet Down the Wire.
@@ -298,14 +299,13 @@
   /**
    * Number of packets that were received and scheduled for read but not yeat read.
    */
-  uint32_t m_pendingReadCount;
-  
+  std::queue< std::pair<uint8_t *, ssize_t> > m_pendingQueue;
+
   /**
    * Maximum number of packets that can be received and scheduled for read but not yeat read.
    */
   uint32_t m_maxPendingReads;
-  
-   
+
   /**
    * Mutex to increase pending read counter.
    */