make L3Demux an NsUnknown object.

Mathieu Lacage 2007-05-03 12:33:08 +02:00
parent 20d0136449
commit 0e11e9f7f4
20 changed files with 121 additions and 80 deletions

View File

@ -35,17 +35,20 @@ public:
void RefAll (NsUnknownImpl *other); void RefAll (NsUnknownImpl *other);
void Unref (void); void Unref (void);
void UnrefAll (void); void UnrefAll (void);
NsUnknown *DoQueryInterface (uint32_t iid); NsUnknown *DoQueryInterface (uint32_t iid) const;
void DoDisposeAll (void);
void AddInterface (NsUnknown *interface); void AddInterface (NsUnknown *interface);
void AddSelfInterface (uint32_t iid, NsUnknown *interface); void AddSelfInterface (uint32_t iid, NsUnknown *interface);
private: private:
typedef std::list<std::pair<uint32_t,NsUnknown *> > List; typedef std::list<std::pair<uint32_t,NsUnknown *> > List;
uint32_t m_ref; uint32_t m_ref;
List m_list; List m_list;
bool m_disposed;
}; };
NsUnknownImpl::NsUnknownImpl (uint32_t iid, NsUnknown *interface) NsUnknownImpl::NsUnknownImpl (uint32_t iid, NsUnknown *interface)
: m_ref (1) : m_ref (1),
m_disposed (false)
{ {
m_list.push_back (std::make_pair (iid, interface)); m_list.push_back (std::make_pair (iid, interface));
} }
@ -83,8 +86,20 @@ NsUnknownImpl::UnrefAll (void)
m_ref = 0; m_ref = 0;
delete this; delete this;
} }
void
NsUnknownImpl::DoDisposeAll (void)
{
NS_ASSERT (!m_disposed);
for (List::const_iterator i = m_list.begin ();
i != m_list.end (); i++)
{
NsUnknown *interface = i->second;
interface->DoDispose ();
}
m_disposed = true;
}
NsUnknown * NsUnknown *
NsUnknownImpl::DoQueryInterface (uint32_t iid) NsUnknownImpl::DoQueryInterface (uint32_t iid) const
{ {
for (List::const_iterator i = m_list.begin (); for (List::const_iterator i = m_list.begin ();
i != m_list.end (); i++) i != m_list.end (); i++)
@ -138,6 +153,12 @@ NsUnknown::Unref (void)
void void
NsUnknown::Dispose (void) NsUnknown::Dispose (void)
{
m_impl->DoDisposeAll ();
}
void
NsUnknown::DoDispose (void)
{ {
// we do not do anything by default. // we do not do anything by default.
} }
@ -160,7 +181,7 @@ NsUnknown::UnrefInternal (void)
} }
NsUnknown * NsUnknown *
NsUnknown::DoQueryInterface (uint32_t iid) NsUnknown::DoQueryInterface (uint32_t iid) const
{ {
return m_impl->DoQueryInterface (iid); return m_impl->DoQueryInterface (iid);
} }

View File

@ -47,7 +47,7 @@ public:
* \param iid the NsUnknown id of the requested interface * \param iid the NsUnknown id of the requested interface
*/ */
template <typename T> template <typename T>
T *QueryInterface (uint32_t iid); T *QueryInterface (uint32_t iid) const;
/** /**
* \param interface another interface * \param interface another interface
@ -59,7 +59,7 @@ public:
*/ */
void AddInterface (NsUnknown *interface); void AddInterface (NsUnknown *interface);
virtual void Dispose (void); void Dispose (void);
protected: protected:
/** /**
* \param iid the Interface Id of the interface defined by a direct subclass * \param iid the Interface Id of the interface defined by a direct subclass
@ -79,10 +79,18 @@ protected:
* this method to associate an interface id to your interface. * this method to associate an interface id to your interface.
*/ */
void AddSelfInterface (uint32_t iid, NsUnknown *interface); void AddSelfInterface (uint32_t iid, NsUnknown *interface);
protected:
/**
* Subclasses who want to handle the "dispose" event should
* override this method. They are also responsible for
* "chaining up" to their parent class' DoDispose method
* once they have done their own "dispose".
*/
virtual void DoDispose (void);
private: private:
friend class NsUnknownImpl; friend class NsUnknownImpl;
NsUnknown (); NsUnknown ();
NsUnknown *DoQueryInterface (uint32_t iid); NsUnknown *DoQueryInterface (uint32_t iid) const;
void RefInternal (void); void RefInternal (void);
void UnrefInternal (void); void UnrefInternal (void);
NsUnknownImpl *m_impl; NsUnknownImpl *m_impl;
@ -95,7 +103,7 @@ namespace ns3 {
template <typename T> template <typename T>
T * T *
NsUnknown::QueryInterface (uint32_t iid) NsUnknown::QueryInterface (uint32_t iid) const
{ {
NsUnknown *found = DoQueryInterface (iid); NsUnknown *found = DoQueryInterface (iid);
if (found != 0) if (found != 0)

View File

@ -20,19 +20,19 @@
*/ */
#include "object.h" #include "object.h"
#include "debug.h" #include "debug.h"
#include "assert.h"
NS_DEBUG_COMPONENT_DEFINE ("Object"); NS_DEBUG_COMPONENT_DEFINE ("Object");
namespace ns3 { namespace ns3 {
Object::Object () Object::Object ()
: m_count (1) : m_count (1),
{ m_disposed (false)
} {}
Object::~Object () Object::~Object ()
{ {}
}
void void
Object::Ref (void) const Object::Ref (void) const
@ -65,6 +65,13 @@ Object::IsSingle (void) const
void void
Object::Dispose (void) Object::Dispose (void)
{
NS_ASSERT (!m_disposed);
DoDispose ();
}
void
Object::DoDispose (void)
{} {}
}//namespace ns3 }//namespace ns3

View File

@ -33,9 +33,12 @@ public:
void Ref (void) const; void Ref (void) const;
void Unref (void) const; void Unref (void) const;
bool IsSingle (void) const; bool IsSingle (void) const;
virtual void Dispose (void); void Dispose (void);
protected:
virtual void DoDispose (void);
private: private:
mutable uint32_t m_count; mutable uint32_t m_count;
bool m_disposed;
}; };
}//namespace ns3 }//namespace ns3

View File

@ -48,7 +48,7 @@ Arp::~Arp ()
} }
void void
Arp::Dispose (void) Arp::DoDispose (void)
{ {
for (CacheList::const_iterator i = m_cacheList.begin (); i != m_cacheList.end (); i++) for (CacheList::const_iterator i = m_cacheList.begin (); i != m_cacheList.end (); i++)
{ {
@ -60,6 +60,7 @@ Arp::Dispose (void)
m_node->Unref (); m_node->Unref ();
m_node = 0; m_node = 0;
} }
L3Protocol::DoDispose ();
} }
TraceResolver * TraceResolver *

View File

@ -43,14 +43,14 @@ public:
Arp (Node *node); Arp (Node *node);
~Arp (); ~Arp ();
virtual void Dispose (void);
virtual TraceResolver *CreateTraceResolver (TraceContext const &context); virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
virtual void Receive(Packet& p, NetDevice *device); virtual void Receive(Packet& p, NetDevice *device);
bool Lookup (Packet &p, Ipv4Address destination, bool Lookup (Packet &p, Ipv4Address destination,
NetDevice *device, NetDevice *device,
MacAddress *hardwareDestination); MacAddress *hardwareDestination);
protected:
virtual void DoDispose (void);
private: private:
typedef std::list<ArpCache *> CacheList; typedef std::list<ArpCache *> CacheList;
ArpCache *FindCache (NetDevice *device); ArpCache *FindCache (NetDevice *device);

View File

@ -39,25 +39,25 @@ InternetNode::InternetNode()
{ {
// Instantiate the capabilities // Instantiate the capabilities
m_applicationList = new ApplicationList(this); m_applicationList = new ApplicationList(this);
m_l3Demux = new L3Demux(this); L3Demux *l3Demux = new L3Demux(this);
NsUnknown::AddInterface (l3Demux);
m_ipv4L4Demux = new Ipv4L4Demux(this); m_ipv4L4Demux = new Ipv4L4Demux(this);
Ipv4 *ipv4 = new Ipv4 (this); Ipv4 *ipv4 = new Ipv4 (this);
Arp *arp = new Arp (this); Arp *arp = new Arp (this);
Udp *udp = new Udp (this); Udp *udp = new Udp (this);
m_l3Demux->Insert (ipv4); l3Demux->Insert (ipv4);
m_l3Demux->Insert (arp); l3Demux->Insert (arp);
m_ipv4L4Demux->Insert (udp); m_ipv4L4Demux->Insert (udp);
l3Demux->Unref ();
ipv4->Unref (); ipv4->Unref ();
arp->Unref (); arp->Unref ();
udp->Unref (); udp->Unref ();
} }
InternetNode::~InternetNode () InternetNode::~InternetNode ()
{ {}
Dispose ();
}
void void
InternetNode::SetName (std::string name) InternetNode::SetName (std::string name)
@ -90,14 +90,9 @@ InternetNode::CreateTraceResolver (TraceContext const &context)
return resolver; return resolver;
} }
void InternetNode::Dispose() void
InternetNode::DoDispose()
{ {
if (m_l3Demux != 0)
{
m_l3Demux->Dispose ();
m_l3Demux->Unref ();
m_l3Demux = 0;
}
if (m_ipv4L4Demux != 0) if (m_ipv4L4Demux != 0)
{ {
m_ipv4L4Demux->Dispose (); m_ipv4L4Demux->Dispose ();
@ -112,8 +107,7 @@ void InternetNode::Dispose()
m_applicationList = 0; m_applicationList = 0;
} }
// chain up. Node::DoDispose ();
Node::Dispose ();
} }
ApplicationList* ApplicationList*
@ -123,13 +117,6 @@ InternetNode::GetApplicationList() const
return m_applicationList; return m_applicationList;
} }
L3Demux*
InternetNode::GetL3Demux() const
{
m_l3Demux->Ref ();
return m_l3Demux;
}
Ipv4L4Demux* Ipv4L4Demux*
InternetNode::GetIpv4L4Demux() const InternetNode::GetIpv4L4Demux() const
{ {
@ -140,7 +127,9 @@ InternetNode::GetIpv4L4Demux() const
Ipv4 * Ipv4 *
InternetNode::GetIpv4 (void) const InternetNode::GetIpv4 (void) const
{ {
Ipv4 *ipv4 = static_cast<Ipv4*> (m_l3Demux->PeekProtocol (Ipv4::PROT_NUMBER)); L3Demux *l3Demux = QueryInterface<L3Demux> (L3Demux::iid);
Ipv4 *ipv4 = static_cast<Ipv4*> (l3Demux->PeekProtocol (Ipv4::PROT_NUMBER));
l3Demux->Unref ();
ipv4->Ref (); ipv4->Ref ();
return ipv4; return ipv4;
} }
@ -155,7 +144,9 @@ InternetNode::GetUdp (void) const
Arp * Arp *
InternetNode::GetArp (void) const InternetNode::GetArp (void) const
{ {
Arp *arp = static_cast<Arp*> (m_l3Demux->PeekProtocol (Arp::PROT_NUMBER)); L3Demux *l3Demux = QueryInterface<L3Demux> (L3Demux::iid);
Arp *arp = static_cast<Arp*> (l3Demux->PeekProtocol (Arp::PROT_NUMBER));
l3Demux->Unref ();
arp->Ref (); arp->Ref ();
return arp; return arp;
} }
@ -169,7 +160,7 @@ InternetNode::DoAddDevice (NetDevice *device) const
bool bool
InternetNode::ReceiveFromDevice (NetDevice *device, const Packet &p, uint16_t protocolNumber) const InternetNode::ReceiveFromDevice (NetDevice *device, const Packet &p, uint16_t protocolNumber) const
{ {
L3Demux *demux = GetL3Demux(); L3Demux *demux = QueryInterface<L3Demux> (L3Demux::iid);
L3Protocol *target = demux->PeekProtocol (protocolNumber); L3Protocol *target = demux->PeekProtocol (protocolNumber);
demux->Unref (); demux->Unref ();
if (target != 0) if (target != 0)

View File

@ -44,22 +44,21 @@ public:
InternetNode(); InternetNode();
virtual ~InternetNode (); virtual ~InternetNode ();
virtual TraceResolver *CreateTraceResolver (TraceContext const &context); virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
virtual void Dispose();
// Capability access // Capability access
virtual ApplicationList* GetApplicationList() const; virtual ApplicationList* GetApplicationList() const;
virtual L3Demux* GetL3Demux() const;
virtual Ipv4L4Demux* GetIpv4L4Demux() const; virtual Ipv4L4Demux* GetIpv4L4Demux() const;
virtual Ipv4 * GetIpv4 (void) const; virtual Ipv4 * GetIpv4 (void) const;
virtual Udp * GetUdp (void) const; virtual Udp * GetUdp (void) const;
virtual Arp * GetArp (void) const; virtual Arp * GetArp (void) const;
void SetName(std::string name); void SetName(std::string name);
protected:
virtual void DoDispose(void);
private: private:
virtual void DoAddDevice (NetDevice *device) const; virtual void DoAddDevice (NetDevice *device) const;
bool ReceiveFromDevice (NetDevice *device, const Packet &p, uint16_t protocolNumber) const; bool ReceiveFromDevice (NetDevice *device, const Packet &p, uint16_t protocolNumber) const;
// Capabilities // Capabilities
ApplicationList* m_applicationList; ApplicationList* m_applicationList;
L3Demux* m_l3Demux;
Ipv4L4Demux* m_ipv4L4Demux; Ipv4L4Demux* m_ipv4L4Demux;
std::string m_name; std::string m_name;
}; };

View File

@ -45,4 +45,10 @@ Ipv4L4Protocol::GetVersion() const
return m_version; return m_version;
} }
void
Ipv4L4Protocol::DoDispose (void)
{
Object::DoDispose ();
}
}//namespace ns3 }//namespace ns3

View File

@ -51,8 +51,6 @@ public:
Ipv4L4Protocol(int protocolNumber, int version); Ipv4L4Protocol(int protocolNumber, int version);
virtual ~Ipv4L4Protocol (); virtual ~Ipv4L4Protocol ();
virtual void Dispose (void) = 0;
/** /**
* \returns the protocol number of this protocol. * \returns the protocol number of this protocol.
*/ */
@ -75,8 +73,9 @@ public:
virtual void Receive(Packet& p, virtual void Receive(Packet& p,
Ipv4Address const &source, Ipv4Address const &source,
Ipv4Address const &destination) = 0; Ipv4Address const &destination) = 0;
protected:
private: virtual void DoDispose (void);
private:
int m_protocolNumber; int m_protocolNumber;
int m_version; int m_version;
}; };

View File

@ -56,11 +56,11 @@ Ipv4::Ipv4(Node *node)
} }
Ipv4::~Ipv4 () Ipv4::~Ipv4 ()
{ {
Dispose (); DoDispose ();
} }
void void
Ipv4::Dispose (void) Ipv4::DoDispose (void)
{ {
for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
{ {
@ -89,6 +89,7 @@ Ipv4::Dispose (void)
m_node->Unref (); m_node->Unref ();
m_node = 0; m_node = 0;
} }
L3Protocol::DoDispose ();
} }
void void

View File

@ -61,8 +61,6 @@ public:
Ipv4(Node *node); Ipv4(Node *node);
virtual ~Ipv4 (); virtual ~Ipv4 ();
virtual void Dispose (void);
/** /**
* \param context the trace context to use to construct the * \param context the trace context to use to construct the
* TraceResolver to return * TraceResolver to return
@ -217,7 +215,9 @@ public:
void SetDown (uint32_t i); void SetDown (uint32_t i);
private: protected:
virtual void DoDispose (void);
private:
void SendRealOut (Packet const &packet, Ipv4Header const &ip, Ipv4Route const &route); void SendRealOut (Packet const &packet, Ipv4Header const &ip, Ipv4Route const &route);
bool Forwarding (Packet const &packet, Ipv4Header &ipHeader, NetDevice *device); bool Forwarding (Packet const &packet, Ipv4Header &ipHeader, NetDevice *device);
void ForwardUp (Packet p, Ipv4Header const&ip); void ForwardUp (Packet p, Ipv4Header const&ip);

View File

@ -23,25 +23,27 @@
#include <sstream> #include <sstream>
#include <string> #include <string>
#include "ns3/composite-trace-resolver.h" #include "ns3/composite-trace-resolver.h"
#include "ns3/iid-manager.h"
#include "l3-demux.h" #include "l3-demux.h"
#include "l3-protocol.h" #include "l3-protocol.h"
#include "node.h" #include "node.h"
namespace ns3 { namespace ns3 {
const uint32_t L3Demux::iid = IidManager::Allocate ("L3Demux");
L3Demux::L3Demux (Node *node) L3Demux::L3Demux (Node *node)
: m_node (node) : NsUnknown (L3Demux::iid),
m_node (node)
{ {
m_node->Ref (); m_node->Ref ();
} }
L3Demux::~L3Demux() L3Demux::~L3Demux()
{ {}
Dispose ();
}
void void
L3Demux::Dispose (void) L3Demux::DoDispose (void)
{ {
for (L3Map_t::iterator i = m_protocols.begin(); i != m_protocols.end(); ++i) for (L3Map_t::iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
{ {
@ -54,6 +56,7 @@ L3Demux::Dispose (void)
m_node->Unref (); m_node->Unref ();
m_node = 0; m_node = 0;
} }
NsUnknown::DoDispose ();
} }
TraceResolver * TraceResolver *

View File

@ -28,7 +28,7 @@
#define L3_DEMUX_H #define L3_DEMUX_H
#include <map> #include <map>
#include "ns3/object.h" #include "ns3/ns-unknown.h"
namespace ns3 { namespace ns3 {
@ -40,15 +40,14 @@ class TraceContext;
/** /**
* \brief L3 Demux * \brief L3 Demux
*/ */
class L3Demux : public Object class L3Demux : public NsUnknown
{ {
public: public:
static const uint32_t iid;
typedef int ProtocolTraceType; typedef int ProtocolTraceType;
L3Demux(Node *node); L3Demux(Node *node);
virtual ~L3Demux(); virtual ~L3Demux();
void Dispose (void);
/** /**
* \param context the trace context to use to construct the * \param context the trace context to use to construct the
* TraceResolver to return * TraceResolver to return
@ -86,6 +85,8 @@ public:
* returned from the L3Protocol::Insert method. * returned from the L3Protocol::Insert method.
*/ */
void Erase(ns3::L3Protocol*protocol); void Erase(ns3::L3Protocol*protocol);
protected:
virtual void DoDispose (void);
private: private:
typedef std::map<int, ns3::L3Protocol*> L3Map_t; typedef std::map<int, ns3::L3Protocol*> L3Map_t;

View File

@ -45,4 +45,10 @@ L3Protocol::GetVersion() const
return m_version; return m_version;
} }
void
L3Protocol::DoDispose (void)
{
Object::DoDispose ();
}
}//namespace ns3 }//namespace ns3

View File

@ -46,8 +46,6 @@ public:
int GetProtocolNumber (void) const; int GetProtocolNumber (void) const;
int GetVersion() const; int GetVersion() const;
virtual void Dispose (void) = 0;
virtual TraceResolver *CreateTraceResolver (TraceContext const &context) = 0; virtual TraceResolver *CreateTraceResolver (TraceContext const &context) = 0;
/** /**
* Lower layer calls this method after calling L3Demux::Lookup * Lower layer calls this method after calling L3Demux::Lookup
@ -58,7 +56,9 @@ public:
*/ */
virtual void Receive(Packet& p, NetDevice *device) = 0; virtual void Receive(Packet& p, NetDevice *device) = 0;
private: protected:
virtual void DoDispose (void);
private:
int m_protocolNumber; int m_protocolNumber;
int m_version; int m_version;
}; };

View File

@ -90,7 +90,7 @@ Node::GetNDevices (void) const
return m_devices.size (); return m_devices.size ();
} }
void Node::Dispose() void Node::DoDispose()
{ {
for (std::vector<NetDevice *>::iterator i = m_devices.begin (); for (std::vector<NetDevice *>::iterator i = m_devices.begin ();
i != m_devices.end (); i++) i != m_devices.end (); i++)
@ -100,13 +100,9 @@ void Node::Dispose()
device->Unref (); device->Unref ();
} }
m_devices.erase (m_devices.begin (), m_devices.end ()); m_devices.erase (m_devices.begin (), m_devices.end ());
NsUnknown::DoDispose ();
} }
L3Demux*
Node::GetL3Demux() const
{
return 0;
}
Ipv4L4Demux* Ipv4L4Demux*
Node::GetIpv4L4Demux() const Node::GetIpv4L4Demux() const
{ {

View File

@ -32,7 +32,6 @@
namespace ns3 { namespace ns3 {
class ApplicationList; class ApplicationList;
class L3Demux;
class Ipv4L4Demux; class Ipv4L4Demux;
class Ipv4; class Ipv4;
class Udp; class Udp;
@ -60,9 +59,9 @@ public:
uint32_t AddDevice (NetDevice *device); uint32_t AddDevice (NetDevice *device);
NetDevice *GetDevice (uint32_t index) const; NetDevice *GetDevice (uint32_t index) const;
uint32_t GetNDevices (void) const; uint32_t GetNDevices (void) const;
virtual void Dispose (void);
protected:
virtual void DoDispose (void);
private: private:
virtual void DoAddDevice (NetDevice *device) const = 0; virtual void DoAddDevice (NetDevice *device) const = 0;
@ -74,7 +73,6 @@ public:
// Each of these has a default behavior of returning a null capability // Each of these has a default behavior of returning a null capability
// of the correct type if one exists, or the nil pointer if no // of the correct type if one exists, or the nil pointer if no
// null capability exists. // null capability exists.
virtual L3Demux* GetL3Demux() const;
virtual Ipv4L4Demux* GetIpv4L4Demux() const; virtual Ipv4L4Demux* GetIpv4L4Demux() const;
virtual ApplicationList* GetApplicationList() const; virtual ApplicationList* GetApplicationList() const;
virtual Ipv4 * GetIpv4 (void) const; virtual Ipv4 * GetIpv4 (void) const;

View File

@ -57,7 +57,7 @@ Udp::CreateTraceResolver (TraceContext const &context)
} }
void void
Udp::Dispose (void) Udp::DoDispose (void)
{ {
if (m_endPoints != 0) if (m_endPoints != 0)
{ {
@ -69,6 +69,7 @@ Udp::Dispose (void)
m_node->Unref (); m_node->Unref ();
m_node = 0; m_node = 0;
} }
Ipv4L4Protocol::DoDispose ();
} }
Socket * Socket *

View File

@ -43,8 +43,6 @@ public:
Udp (Node *node); Udp (Node *node);
virtual ~Udp (); virtual ~Udp ();
virtual void Dispose (void);
virtual TraceResolver *CreateTraceResolver (TraceContext const &context); virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
Socket *CreateSocket (void); Socket *CreateSocket (void);
@ -64,7 +62,9 @@ public:
virtual void Receive(Packet& p, virtual void Receive(Packet& p,
Ipv4Address const &source, Ipv4Address const &source,
Ipv4Address const &destination); Ipv4Address const &destination);
private: protected:
virtual void DoDispose (void);
private:
Node *m_node; Node *m_node;
Ipv4EndPointDemux *m_endPoints; Ipv4EndPointDemux *m_endPoints;
}; };