diff --git a/src/core/model/default-simulator-impl.cc b/src/core/model/default-simulator-impl.cc index 78b3490c4..590fdc599 100644 --- a/src/core/model/default-simulator-impl.cc +++ b/src/core/model/default-simulator-impl.cc @@ -84,6 +84,8 @@ void DefaultSimulatorImpl::DoDispose (void) { NS_LOG_FUNCTION (this); + ProcessEventsWithContext (); + while (!m_events->IsEmpty ()) { Scheduler::Event next = m_events->RemoveNext (); diff --git a/src/fd-net-device/model/fd-net-device.cc b/src/fd-net-device/model/fd-net-device.cc index 5cbe9d060..b09aaf633 100644 --- a/src/fd-net-device/model/fd-net-device.cc +++ b/src/fd-net-device/model/fd-net-device.cc @@ -168,12 +168,12 @@ FdNetDevice::GetTypeId (void) 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 (FdNetDevice const &) FdNetDevice::~FdNetDevice () { NS_LOG_FUNCTION (this); + + { + CriticalSection cs (m_pendingReadMutex); + + while (!m_pendingQueue.empty ()) + { + std::pair next = m_pendingQueue.front (); + m_pendingQueue.pop (); + + free (next.first); + } + } } void @@ -249,7 +261,7 @@ FdNetDevice::StartDevice (void) m_fdReader = Create (); // 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 @@ FdNetDevice::ReceiveCallback (uint8_t *buf, ssize_t len) { 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 @@ RemovePIHeader (uint8_t *&buf, ssize_t &len) } void -FdNetDevice::ForwardUp (uint8_t *buf, ssize_t len) +FdNetDevice::ForwardUp (void) { - NS_LOG_FUNCTION (this << buf << len); - if (m_pendingReadCount > 0) - { - { - CriticalSection cs (m_pendingReadMutex); - --m_pendingReadCount; - } - } + uint8_t *buf = 0; + ssize_t len = 0; + + { + CriticalSection cs (m_pendingReadMutex); + std::pair 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) diff --git a/src/fd-net-device/model/fd-net-device.h b/src/fd-net-device/model/fd-net-device.h index af246cd0c..4fee9d008 100644 --- a/src/fd-net-device/model/fd-net-device.h +++ b/src/fd-net-device/model/fd-net-device.h @@ -36,7 +36,8 @@ #include "ns3/unix-fd-reader.h" #include "ns3/system-mutex.h" -#include +#include +#include namespace ns3 { @@ -63,7 +64,7 @@ public: private: FdReader::Data DoRead (void); - + uint32_t m_bufferSize; //!< size of the read buffer }; @@ -216,7 +217,7 @@ private: /** * 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 @@ private: /** * Number of packets that were received and scheduled for read but not yeat read. */ - uint32_t m_pendingReadCount; - + std::queue< std::pair > 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. */