bug 2119: Fixing memory leaks in FdNetDevice test with DefaultSimulatorImpl due to non-executed events when simulation ends
--- 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.
*/