remove leaks and rework the Ptr class to work with a new refcount mechanism

This commit is contained in:
Mathieu Lacage
2007-05-10 18:33:52 +02:00
parent 01a20c0a82
commit 349f970d82
12 changed files with 126 additions and 57 deletions

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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];
}

View File

@@ -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

View File

@@ -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 ();
}

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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)

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 *