diff --git a/src/wifi/model/block-ack-manager.h b/src/wifi/model/block-ack-manager.h index 2e308693c..7ad8a7e41 100644 --- a/src/wifi/model/block-ack-manager.h +++ b/src/wifi/model/block-ack-manager.h @@ -33,9 +33,7 @@ namespace ns3 { class MgtAddBaResponseHeader; class MgtAddBaRequestHeader; class MacTxMiddle; -class WifiMacQueueItem; -template class WifiQueue; -typedef WifiQueue WifiMacQueue; +class WifiMacQueue; /** * \ingroup wifi diff --git a/src/wifi/model/mac-low.h b/src/wifi/model/mac-low.h index afc02b3a7..4c622b990 100644 --- a/src/wifi/model/mac-low.h +++ b/src/wifi/model/mac-low.h @@ -41,8 +41,7 @@ class DcaTxop; class EdcaTxopN; class DcfManager; class WifiMacQueueItem; -template class WifiQueue; -typedef WifiQueue WifiMacQueue; +class WifiMacQueue; /** * \brief control how a packet is transmitted. diff --git a/src/wifi/model/wifi-mac-queue.cc b/src/wifi/model/wifi-mac-queue.cc index 279e4188a..fa8016202 100644 --- a/src/wifi/model/wifi-mac-queue.cc +++ b/src/wifi/model/wifi-mac-queue.cc @@ -87,8 +87,8 @@ WifiMacQueueItem::GetSize (void) const NS_OBJECT_TEMPLATE_CLASS_DEFINE (Queue,WifiMacQueueItem); +NS_OBJECT_ENSURE_REGISTERED (WifiMacQueue); -template<> TypeId WifiMacQueue::GetTypeId (void) { @@ -109,19 +109,16 @@ WifiMacQueue::GetTypeId (void) return tid; } -template<> -WifiMacQueue::WifiQueue () +WifiMacQueue::WifiMacQueue () : NS_LOG_TEMPLATE_DEFINE ("WifiMacQueue") { } -template<> -WifiMacQueue::~WifiQueue () +WifiMacQueue::~WifiMacQueue () { NS_LOG_FUNCTION_NOARGS (); } -template<> void WifiMacQueue::SetMaxDelay (Time delay) { @@ -130,7 +127,6 @@ WifiMacQueue::SetMaxDelay (Time delay) m_maxDelay = delay; } -template<> Time WifiMacQueue::GetMaxDelay (void) const { @@ -139,7 +135,6 @@ WifiMacQueue::GetMaxDelay (void) const return m_maxDelay; } -template<> bool WifiMacQueue::TtlExceeded (ConstIterator &it) { @@ -156,7 +151,6 @@ WifiMacQueue::TtlExceeded (ConstIterator &it) return false; } -template<> bool WifiMacQueue::Enqueue (Ptr item) { @@ -184,7 +178,6 @@ WifiMacQueue::Enqueue (Ptr item) return DoEnqueue (Tail (), item); } -template<> bool WifiMacQueue::PushFront (Ptr item) { @@ -212,7 +205,6 @@ WifiMacQueue::PushFront (Ptr item) return DoEnqueue (Head (), item); } -template<> Ptr WifiMacQueue::Dequeue (void) { @@ -229,7 +221,6 @@ WifiMacQueue::Dequeue (void) return 0; } -template<> Ptr WifiMacQueue::DequeueByTidAndAddress (uint8_t tid, WifiMacHeader::AddressType type, Mac48Address dest) @@ -253,7 +244,6 @@ WifiMacQueue::DequeueByTidAndAddress (uint8_t tid, return 0; } -template<> Ptr WifiMacQueue::DequeueFirstAvailable (const Ptr blockedPackets) { @@ -276,7 +266,6 @@ WifiMacQueue::DequeueFirstAvailable (const Ptr blockedPa return 0; } -template<> Ptr WifiMacQueue::Peek (void) const { @@ -295,7 +284,6 @@ WifiMacQueue::Peek (void) const return 0; } -template<> Ptr WifiMacQueue::PeekByTidAndAddress (uint8_t tid, WifiMacHeader::AddressType type, Mac48Address dest) @@ -319,7 +307,6 @@ WifiMacQueue::PeekByTidAndAddress (uint8_t tid, return 0; } -template<> Ptr WifiMacQueue::PeekFirstAvailable (const Ptr blockedPackets) { @@ -342,7 +329,6 @@ WifiMacQueue::PeekFirstAvailable (const Ptr blockedPacke return 0; } -template<> Ptr WifiMacQueue::Remove (void) { @@ -359,7 +345,6 @@ WifiMacQueue::Remove (void) return 0; } -template<> bool WifiMacQueue::Remove (Ptr packet) { @@ -382,7 +367,6 @@ WifiMacQueue::Remove (Ptr packet) return false; } -template<> uint32_t WifiMacQueue::GetNPacketsByTidAndAddress (uint8_t tid, WifiMacHeader::AddressType type, Mac48Address addr) @@ -408,7 +392,6 @@ WifiMacQueue::GetNPacketsByTidAndAddress (uint8_t tid, WifiMacHeader::AddressTyp return nPackets; } -template<> bool WifiMacQueue::IsEmpty (void) { @@ -426,7 +409,6 @@ WifiMacQueue::IsEmpty (void) return true; } -template<> uint32_t WifiMacQueue::GetNPackets (void) { @@ -443,7 +425,6 @@ WifiMacQueue::GetNPackets (void) return QueueBase::GetNPackets (); } -template<> uint32_t WifiMacQueue::GetNBytes (void) { @@ -460,6 +441,4 @@ WifiMacQueue::GetNBytes (void) return QueueBase::GetNBytes (); } -NS_OBJECT_TEMPLATE_CLASS_DEFINE (WifiQueue,WifiMacQueueItem); - } //namespace ns3 diff --git a/src/wifi/model/wifi-mac-queue.h b/src/wifi/model/wifi-mac-queue.h index 0ba602da0..b2761b401 100644 --- a/src/wifi/model/wifi-mac-queue.h +++ b/src/wifi/model/wifi-mac-queue.h @@ -107,6 +107,14 @@ private: }; +// The following explicit template instantiation declaration prevents modules +// including this header file from implicitly instantiating Queue. +// This would cause python examples using wifi to crash at runtime with the +// following error message: "Trying to allocate twice the same uid: +// ns3::Queue" +extern template class Queue; + + /** * \ingroup wifi * @@ -121,32 +129,8 @@ private: * to verify whether or not it should be dropped. If * dot11EDCATableMSDULifetime has elapsed, it is dropped. * Otherwise, it is returned to the caller. - * - * WifiMacQueue could have been declared as a subclass of Queue, - * but this would have caused python examples using wifi to crash at runtime - * with the following error message: "Trying to allocate twice the same uid: - * ns3::Queue". Such an error wasn't fully debugged but it - * may have been due to static initialization order issues. - * - * To avoid such an error, the template class WifiQueue is introduced - * as a subclass of Queue. WifiMacQueue is then declared as a - * specialization of WifiQueue with Item equal to WifiMacQueueItem. - * The methods of the WifiQueue class are left unimplemented for Item other - * than WifiMacQueueItem. - * - * Modules that need to forward declare WifiMacQueue have to include the - * following: - * - * \code - * class WifiMacQueueItem; - * template class WifiQueue; - * typedef WifiQueue WifiMacQueue; - * \endcode - * - * in their header file. */ -template -class WifiQueue : public Queue +class WifiMacQueue : public Queue { public: /** @@ -154,8 +138,8 @@ public: * \return the object TypeId */ static TypeId GetTypeId (void); - WifiQueue (); - ~WifiQueue (); + WifiMacQueue (); + ~WifiMacQueue (); /// drop policy enum DropPolicy @@ -183,20 +167,20 @@ public: * \param item the Wifi MAC queue item to be enqueued at the end * \return true if success, false if the packet has been dropped */ - bool Enqueue (Ptr item); + bool Enqueue (Ptr item); /** * Enqueue the given Wifi MAC queue item at the front of the queue. * * \param item the Wifi MAC queue item to be enqueued at the front * \return true if success, false if the packet has been dropped */ - bool PushFront (Ptr item); + bool PushFront (Ptr item); /** * Dequeue the packet in the front of the queue. * * \return the packet */ - Ptr Dequeue (void); + Ptr Dequeue (void); /** * Search and return, if present in the queue, the first packet having the * address indicated by type equal to addr, and tid @@ -210,7 +194,7 @@ public: * * \return the packet */ - Ptr DequeueByTidAndAddress (uint8_t tid, + Ptr DequeueByTidAndAddress (uint8_t tid, WifiMacHeader::AddressType type, Mac48Address addr); /** @@ -224,13 +208,13 @@ public: * * \return packet */ - Ptr DequeueFirstAvailable (const Ptr blockedPackets); + Ptr DequeueFirstAvailable (const Ptr blockedPackets); /** * Peek the packet in the front of the queue. The packet is not removed. * * \return the packet */ - Ptr Peek (void) const; + Ptr Peek (void) const; /** * Search and return, if present in the queue, the first packet having the * address indicated by type equal to addr, and tid @@ -244,7 +228,7 @@ public: * * \return packet */ - Ptr PeekByTidAndAddress (uint8_t tid, + Ptr PeekByTidAndAddress (uint8_t tid, WifiMacHeader::AddressType type, Mac48Address addr); /** @@ -254,13 +238,13 @@ public: * * \return packet */ - Ptr PeekFirstAvailable (const Ptr blockedPackets); + Ptr PeekFirstAvailable (const Ptr blockedPackets); /** * Remove the packet in the front of the queue. * * \return the packet */ - Ptr Remove (void); + Ptr Remove (void); /** * If exists, removes packet from queue and returns true. Otherwise it * takes no effects and return false. Deletion of the packet is @@ -315,7 +299,7 @@ private: * \param it an iterator pointing to the item * \return true if the item is removed, false otherwise */ - bool TtlExceeded (typename Queue::ConstIterator &it); + bool TtlExceeded (ConstIterator &it); Time m_maxDelay; //!< Time to live for packets in the queue DropPolicy m_dropPolicy; //!< Drop behavior of queue @@ -323,14 +307,6 @@ private: NS_LOG_TEMPLATE_DECLARE; //!< redefinition of the log component }; -/// Forward declare overridden methods to avoid specializing after instantiation -template<> bool WifiQueue::IsEmpty (void); -template<> uint32_t WifiQueue::GetNPackets (void); -template<> uint32_t WifiQueue::GetNBytes (void); - -/// Declare WifiMacQueue as a specialization of template class WifiQueue -typedef WifiQueue WifiMacQueue; - } //namespace ns3 #endif /* WIFI_MAC_QUEUE_H */