remove leaks and rework the Ptr class to work with a new refcount mechanism
This commit is contained in:
@@ -137,7 +137,7 @@ int main (int argc, char *argv[])
|
||||
|
||||
// Create the OnOff application to send UDP datagrams of size
|
||||
// 210 bytes at a rate of 448 Kb/s
|
||||
OnOffApplication* ooff0 = new OnOffApplication(
|
||||
Ptr<OnOffApplication> ooff0 = new OnOffApplication(
|
||||
n0,
|
||||
Ipv4Address("10.1.3.2"),
|
||||
80,
|
||||
@@ -154,10 +154,9 @@ int main (int argc, char *argv[])
|
||||
// Start the application
|
||||
ooff0->Start(Seconds(1.0));
|
||||
ooff0->Stop (Seconds(10.0));
|
||||
ooff0->Unref ();
|
||||
|
||||
// Create a similar flow from n3 to n1, starting at time 1.1 seconds
|
||||
OnOffApplication* ooff1 = new OnOffApplication(
|
||||
Ptr<OnOffApplication> ooff1 = new OnOffApplication(
|
||||
n3,
|
||||
Ipv4Address("10.1.2.1"),
|
||||
80,
|
||||
@@ -172,7 +171,6 @@ int main (int argc, char *argv[])
|
||||
// Start the application
|
||||
ooff1->Start(Seconds(1.1));
|
||||
ooff1->Stop (Seconds(10.0));
|
||||
ooff1->Unref ();
|
||||
|
||||
// Here, finish off packet routing configuration
|
||||
// This will likely set by some global StaticRouting object in the future
|
||||
|
||||
@@ -35,9 +35,10 @@ PrintTraffic (Socket *socket)
|
||||
socket->RecvDummy (MakeCallback (&SocketPrinter));
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
void
|
||||
RunSimulation (void)
|
||||
{
|
||||
InternetNode *a = new InternetNode ();
|
||||
Ptr<InternetNode> a = new InternetNode ();
|
||||
|
||||
IUdp *udp;
|
||||
udp = a->QueryInterface<IUdp> (IUdp::iid);
|
||||
@@ -60,7 +61,13 @@ int main (int argc, char *argv[])
|
||||
|
||||
sink->Unref ();
|
||||
source->Unref ();
|
||||
a->Unref ();
|
||||
|
||||
std::cout << "o" << std::endl;
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
RunSimulation ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -35,12 +35,12 @@ ApplicationList::ApplicationList(Ptr<Node> n)
|
||||
void
|
||||
ApplicationList::DoDispose (void)
|
||||
{
|
||||
for (std::vector<Application*>::const_iterator i = m_apps.begin();
|
||||
for (std::vector<Ptr<Application> >::iterator i = m_apps.begin();
|
||||
i != m_apps.end(); ++i)
|
||||
{
|
||||
Application *app = *i;
|
||||
Ptr<Application> app = *i;
|
||||
app->Dispose ();
|
||||
app->Unref ();
|
||||
*i = 0;
|
||||
}
|
||||
m_apps.clear ();
|
||||
NsUnknown::DoDispose ();
|
||||
@@ -50,9 +50,8 @@ ApplicationList::~ApplicationList()
|
||||
{}
|
||||
|
||||
void
|
||||
ApplicationList::Add(Application* a)
|
||||
ApplicationList::Add(Ptr<Application> a)
|
||||
{
|
||||
a->Ref ();
|
||||
m_apps.push_back(a);
|
||||
}
|
||||
|
||||
@@ -61,9 +60,12 @@ uint32_t ApplicationList::Count() const
|
||||
return m_apps.size();
|
||||
}
|
||||
|
||||
Application* ApplicationList::Get(uint32_t i) const
|
||||
{ // Get the i'th application. Note, this is linear time in N
|
||||
if (m_apps.empty()) return 0; // List is empty
|
||||
Ptr<Application> ApplicationList::Get(uint32_t i) const
|
||||
{
|
||||
if (m_apps.empty())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return m_apps[i];
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "application.h"
|
||||
#include "ns3/ns-unknown.h"
|
||||
#include "ns3/ptr.h"
|
||||
#include <vector>
|
||||
|
||||
namespace ns3 {
|
||||
@@ -37,23 +38,15 @@ public:
|
||||
ApplicationList(Ptr<Node>);
|
||||
// Copy constructor not needed, default one is correct
|
||||
virtual ~ApplicationList();
|
||||
// Inherited from Capabilty
|
||||
virtual void Add(Application*); // Add an already new'ed app
|
||||
// Manage the list
|
||||
template <typename T> T* AddCopy(const T& t) // Add a new application
|
||||
{
|
||||
T* a = t.Copy();
|
||||
m_apps.push_back(a);
|
||||
return a;
|
||||
}
|
||||
void Remove(Application*); // Application has finished
|
||||
virtual void Add(Ptr<Application> application);
|
||||
|
||||
uint32_t Count() const; // Number of applications
|
||||
Application* Get(uint32_t i) const; // Get app by index
|
||||
Ptr<Application> Get(uint32_t i) const; // Get app by index
|
||||
|
||||
protected:
|
||||
virtual void DoDispose (void);
|
||||
private:
|
||||
std::vector<Application*> m_apps;
|
||||
std::vector<Ptr<Application> > m_apps;
|
||||
};
|
||||
|
||||
}//namespace ns3
|
||||
|
||||
@@ -65,9 +65,10 @@ private:
|
||||
};
|
||||
|
||||
NsUnknownImpl::NsUnknownImpl (Iid iid, NsUnknown *interface)
|
||||
: m_ref (1),
|
||||
: m_ref (0),
|
||||
m_disposed (false)
|
||||
{
|
||||
NS_DEBUG ("new " << this << " ref=" << m_ref);
|
||||
m_list.push_back (std::make_pair (iid, interface));
|
||||
}
|
||||
NsUnknownImpl::~NsUnknownImpl ()
|
||||
@@ -89,10 +90,12 @@ void
|
||||
NsUnknownImpl::RefAll (NsUnknownImpl *other)
|
||||
{
|
||||
m_ref += other->m_ref;
|
||||
NS_DEBUG ("inc all " << this << " o=" << other->m_ref << " ref=" << m_ref);
|
||||
}
|
||||
void
|
||||
NsUnknownImpl::Unref (void)
|
||||
{
|
||||
NS_ASSERT (m_ref > 0);
|
||||
m_ref--;
|
||||
NS_DEBUG ("dec " << this << " ref=" << m_ref);
|
||||
if (m_ref == 0)
|
||||
@@ -103,8 +106,10 @@ NsUnknownImpl::Unref (void)
|
||||
void
|
||||
NsUnknownImpl::UnrefAll (void)
|
||||
{
|
||||
NS_ASSERT (m_ref > 0);
|
||||
m_ref = 0;
|
||||
delete this;
|
||||
NS_DEBUG ("dec all " << this);
|
||||
}
|
||||
void
|
||||
NsUnknownImpl::DoDisposeAll (void)
|
||||
@@ -159,14 +164,15 @@ NsUnknown::NsUnknown (Iid iid)
|
||||
NsUnknown::~NsUnknown ()
|
||||
{
|
||||
m_impl = 0;
|
||||
m_ref = -1;
|
||||
}
|
||||
void
|
||||
NsUnknown::Ref (void)
|
||||
NsUnknown::Ref (void) const
|
||||
{
|
||||
m_impl->Ref ();
|
||||
}
|
||||
void
|
||||
NsUnknown::Unref (void)
|
||||
NsUnknown::Unref (void) const
|
||||
{
|
||||
m_impl->Unref ();
|
||||
}
|
||||
|
||||
@@ -49,8 +49,8 @@ class NsUnknown
|
||||
{
|
||||
public:
|
||||
virtual ~NsUnknown ();
|
||||
void Ref (void);
|
||||
void Unref (void);
|
||||
void Ref (void) const;
|
||||
void Unref (void) const;
|
||||
|
||||
/**
|
||||
* \param iid the NsUnknown id of the requested interface
|
||||
|
||||
@@ -27,9 +27,11 @@ NS_DEBUG_COMPONENT_DEFINE ("Object");
|
||||
namespace ns3 {
|
||||
|
||||
Object::Object ()
|
||||
: m_count (1),
|
||||
: m_count (0),
|
||||
m_disposed (false)
|
||||
{}
|
||||
{
|
||||
NS_DEBUG ("Object::Object: m_count=0");
|
||||
}
|
||||
|
||||
Object::~Object ()
|
||||
{}
|
||||
@@ -37,17 +39,16 @@ Object::~Object ()
|
||||
void
|
||||
Object::Ref (void) const
|
||||
{
|
||||
NS_DEBUG("Object::Ref (): this == 0x" << this);
|
||||
m_count++;
|
||||
NS_DEBUG("Object::Ref (): m_count bumped to " << m_count);
|
||||
NS_DEBUG("Object::Ref (): this == 0x" << this << " m_count=" << m_count);
|
||||
}
|
||||
|
||||
void
|
||||
Object::Unref (void) const
|
||||
{
|
||||
NS_DEBUG("Object::Unref (): this == 0x" << this);
|
||||
NS_ASSERT (m_count > 0);
|
||||
m_count--;
|
||||
NS_DEBUG("Object::Ref (): m_count dropped to " << m_count);
|
||||
NS_DEBUG("Object::Unref (): this == 0x" << this << " m_count=" << m_count);
|
||||
|
||||
if (m_count == 0)
|
||||
{
|
||||
|
||||
@@ -264,6 +264,22 @@ PtrTest::RunTests (void)
|
||||
{
|
||||
ok = false;
|
||||
}
|
||||
|
||||
{
|
||||
Ptr<Object> p0 = new NoCount (cb);
|
||||
Ptr<NoCount> p1 = new NoCount (cb);
|
||||
if (p0 == p1)
|
||||
{
|
||||
ok = false;
|
||||
}
|
||||
if (p0 != p1)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ok;
|
||||
|
||||
@@ -51,6 +51,7 @@ private:
|
||||
void operator delete (void *);
|
||||
};
|
||||
friend class Ptr<const T>;
|
||||
void Acquire (void) const;
|
||||
public:
|
||||
/**
|
||||
* Create an empty smart pointer
|
||||
@@ -109,12 +110,29 @@ public:
|
||||
template <typename T1, typename T2>
|
||||
inline friend bool operator != (T1 const *lhs, Ptr<T2> &rhs);
|
||||
|
||||
// allow if (sp0 == sp1)
|
||||
template <typename T1, typename T2>
|
||||
inline friend bool operator == (Ptr<T1> const &lhs, Ptr<T2> const &rhs);
|
||||
// allow if (sp0 != sp1)
|
||||
template <typename T1, typename T2>
|
||||
inline friend bool operator != (Ptr<T1> const &lhs, Ptr<T2> const &rhs);
|
||||
|
||||
template <typename T1, typename T2>
|
||||
inline friend Ptr<T1> const_pointer_cast (Ptr<T2> const&p);
|
||||
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
Ptr<T>::Acquire (void) const
|
||||
{
|
||||
if (m_ptr != 0)
|
||||
{
|
||||
m_ptr->Ref ();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Ptr<T>::Ptr ()
|
||||
: m_ptr (0)
|
||||
@@ -123,27 +141,22 @@ Ptr<T>::Ptr ()
|
||||
template <typename T>
|
||||
Ptr<T>::Ptr (T *ptr)
|
||||
: m_ptr (ptr)
|
||||
{}
|
||||
{
|
||||
Acquire ();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Ptr<T>::Ptr (Ptr const&o)
|
||||
: m_ptr (o.m_ptr)
|
||||
: m_ptr (o.Peek ())
|
||||
{
|
||||
if (m_ptr != 0)
|
||||
{
|
||||
m_ptr->Ref();
|
||||
}
|
||||
Acquire ();
|
||||
}
|
||||
template <typename T>
|
||||
template <typename U>
|
||||
Ptr<T>::Ptr (Ptr<U> const &o)
|
||||
: m_ptr (o.m_ptr)
|
||||
: m_ptr (o.Peek ())
|
||||
{
|
||||
if (m_ptr != 0)
|
||||
{
|
||||
NS_ASSERT (o.m_ptr != 0);
|
||||
m_ptr->Ref();
|
||||
}
|
||||
Acquire ();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@@ -160,16 +173,15 @@ Ptr<T> &
|
||||
Ptr<T>::operator = (Ptr const& o)
|
||||
{
|
||||
if (&o == this)
|
||||
return *this;
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
if (m_ptr != 0)
|
||||
{
|
||||
m_ptr->Unref();
|
||||
}
|
||||
m_ptr = o.m_ptr;
|
||||
if (m_ptr != 0)
|
||||
{
|
||||
m_ptr->Ref();
|
||||
}
|
||||
Acquire ();
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -184,7 +196,7 @@ template <typename T>
|
||||
T *
|
||||
Ptr<T>::Get () const
|
||||
{
|
||||
m_ptr->Ref();
|
||||
Acquire ();
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
@@ -246,6 +258,20 @@ operator != (T1 const *lhs, Ptr<T2> &rhs)
|
||||
return lhs != rhs.m_ptr;
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
bool
|
||||
operator == (Ptr<T1> const &lhs, Ptr<T2> const &rhs)
|
||||
{
|
||||
return lhs.Get () == rhs.Get ();
|
||||
}
|
||||
template <typename T1, typename T2>
|
||||
bool
|
||||
operator != (Ptr<T1> const &lhs, Ptr<T2> const &rhs)
|
||||
{
|
||||
return lhs.Get () != rhs.Get ();
|
||||
}
|
||||
|
||||
|
||||
template <typename T1, typename T2>
|
||||
Ptr<T1>
|
||||
const_pointer_cast (Ptr<T2> const&p)
|
||||
|
||||
@@ -46,14 +46,19 @@ PointToPointTopology::AddPointToPointLink(
|
||||
const Time& delay)
|
||||
{
|
||||
PointToPointChannel* channel = new PointToPointChannel(bps, delay);
|
||||
channel->Ref ();
|
||||
|
||||
PointToPointNetDevice* net1 = new PointToPointNetDevice(n1);
|
||||
net1->Ref ();
|
||||
|
||||
net1->AddQueue(Queue::Default().Copy());
|
||||
n1->AddDevice (net1);
|
||||
net1->Attach (channel);
|
||||
net1->Unref ();
|
||||
|
||||
PointToPointNetDevice* net2 = new PointToPointNetDevice(n2);
|
||||
net2->Ref ();
|
||||
|
||||
net2->AddQueue(Queue::Default().Copy());
|
||||
n2->AddDevice (net2);
|
||||
net2->Attach (channel);
|
||||
|
||||
@@ -45,10 +45,18 @@ InternetNode::InternetNode()
|
||||
Arp *arp = new Arp (this);
|
||||
Udp *udp = new Udp (this);
|
||||
|
||||
ipv4->Ref ();
|
||||
arp->Ref ();
|
||||
udp->Ref ();
|
||||
|
||||
ApplicationList *applicationList = new ApplicationList(this);
|
||||
L3Demux *l3Demux = new L3Demux(this);
|
||||
Ipv4L4Demux *ipv4L4Demux = new Ipv4L4Demux(this);
|
||||
|
||||
applicationList->Ref ();
|
||||
l3Demux->Ref ();
|
||||
ipv4L4Demux->Ref ();
|
||||
|
||||
l3Demux->Insert (ipv4);
|
||||
l3Demux->Insert (arp);
|
||||
ipv4L4Demux->Insert (udp);
|
||||
@@ -58,6 +66,11 @@ InternetNode::InternetNode()
|
||||
IIpv4Impl *ipv4Impl = new IIpv4Impl (ipv4);
|
||||
IIpv4Private *ipv4Private = new IIpv4Private (ipv4);
|
||||
|
||||
udpImpl->Ref ();
|
||||
arpPrivate->Ref ();
|
||||
ipv4Impl->Ref ();
|
||||
ipv4Private->Ref ();
|
||||
|
||||
NsUnknown::AddInterface (ipv4Private);
|
||||
NsUnknown::AddInterface (ipv4Impl);
|
||||
NsUnknown::AddInterface (arpPrivate);
|
||||
|
||||
@@ -68,7 +68,9 @@ Udp::DoDispose (void)
|
||||
Socket *
|
||||
Udp::CreateSocket (void)
|
||||
{
|
||||
return new UdpSocket (m_node, this);
|
||||
Socket *socket = new UdpSocket (m_node, this);
|
||||
socket->Ref ();
|
||||
return socket;
|
||||
}
|
||||
|
||||
Ipv4EndPoint *
|
||||
|
||||
Reference in New Issue
Block a user