remove leaks and rework the Ptr class to work with a new refcount mechanism
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Thu, 10 May 2007 18:33:52 +0200
changeset 567 6fb98941c36f
parent 566 a4ef066d1185
child 568 e1660959ecbb
remove leaks and rework the Ptr class to work with a new refcount mechanism
examples/simple-p2p.cc
samples/main-simple.cc
src/applications/application-list.cc
src/applications/application-list.h
src/core/ns-unknown.cc
src/core/ns-unknown.h
src/core/object.cc
src/core/ptr.cc
src/core/ptr.h
src/devices/p2p/p2p-topology.cc
src/internet-node/internet-node.cc
src/internet-node/udp.cc
--- a/examples/simple-p2p.cc	Thu May 10 09:57:46 2007 +0200
+++ b/examples/simple-p2p.cc	Thu May 10 18:33:52 2007 +0200
@@ -137,7 +137,7 @@
 
   // 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 @@
   // 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 @@
   // 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
--- a/samples/main-simple.cc	Thu May 10 09:57:46 2007 +0200
+++ b/samples/main-simple.cc	Thu May 10 18:33:52 2007 +0200
@@ -35,9 +35,10 @@
   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 @@
 
   sink->Unref ();
   source->Unref ();
-  a->Unref ();
+
+  std::cout << "o" << std::endl;
+}
+
+int main (int argc, char *argv[])
+{
+  RunSimulation ();
 
   return 0;
 }
--- a/src/applications/application-list.cc	Thu May 10 09:57:46 2007 +0200
+++ b/src/applications/application-list.cc	Thu May 10 18:33:52 2007 +0200
@@ -35,12 +35,12 @@
 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 @@
 {}
 
 void
-ApplicationList::Add(Application* a)
+ApplicationList::Add(Ptr<Application> a)
 {
-  a->Ref ();
   m_apps.push_back(a);
 }  
 
@@ -61,9 +60,12 @@
   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];
 }
   
--- a/src/applications/application-list.h	Thu May 10 09:57:46 2007 +0200
+++ b/src/applications/application-list.h	Thu May 10 18:33:52 2007 +0200
@@ -26,6 +26,7 @@
 
 #include "application.h"
 #include "ns3/ns-unknown.h"
+#include "ns3/ptr.h"
 #include <vector>
 
 namespace ns3 {
@@ -37,23 +38,15 @@
   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
--- a/src/core/ns-unknown.cc	Thu May 10 09:57:46 2007 +0200
+++ b/src/core/ns-unknown.cc	Thu May 10 18:33:52 2007 +0200
@@ -65,9 +65,10 @@
 };
 
 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 @@
 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 @@
 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 ()
 {
   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 ();
 }
--- a/src/core/ns-unknown.h	Thu May 10 09:57:46 2007 +0200
+++ b/src/core/ns-unknown.h	Thu May 10 18:33:52 2007 +0200
@@ -49,8 +49,8 @@
 {
 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
--- a/src/core/object.cc	Thu May 10 09:57:46 2007 +0200
+++ b/src/core/object.cc	Thu May 10 18:33:52 2007 +0200
@@ -27,9 +27,11 @@
 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 @@
 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)
     {
--- a/src/core/ptr.cc	Thu May 10 09:57:46 2007 +0200
+++ b/src/core/ptr.cc	Thu May 10 18:33:52 2007 +0200
@@ -264,6 +264,22 @@
     {
       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;
--- a/src/core/ptr.h	Thu May 10 09:57:46 2007 +0200
+++ b/src/core/ptr.h	Thu May 10 18:33:52 2007 +0200
@@ -51,6 +51,7 @@
     void operator delete (void *);
   };
   friend class Ptr<const T>;
+  void Acquire (void) const;
 public:
   /**
    * Create an empty smart pointer
@@ -109,6 +110,13 @@
   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);
 
@@ -116,6 +124,16 @@
 };
 
 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 @@
 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>::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 @@
 T * 
 Ptr<T>::Get () const
 {
-  m_ptr->Ref();
+  Acquire ();
   return m_ptr;
 }
 
@@ -247,6 +259,20 @@
 }
 
 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)
 {
--- a/src/devices/p2p/p2p-topology.cc	Thu May 10 09:57:46 2007 +0200
+++ b/src/devices/p2p/p2p-topology.cc	Thu May 10 18:33:52 2007 +0200
@@ -46,14 +46,19 @@
   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);
--- a/src/internet-node/internet-node.cc	Thu May 10 09:57:46 2007 +0200
+++ b/src/internet-node/internet-node.cc	Thu May 10 18:33:52 2007 +0200
@@ -45,10 +45,18 @@
   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 @@
   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);
--- a/src/internet-node/udp.cc	Thu May 10 09:57:46 2007 +0200
+++ b/src/internet-node/udp.cc	Thu May 10 18:33:52 2007 +0200
@@ -68,7 +68,9 @@
 Socket *
 Udp::CreateSocket (void)
 {
-  return new UdpSocket (m_node, this);
+  Socket *socket = new UdpSocket (m_node, this);
+  socket->Ref ();
+  return socket;
 }
 
 Ipv4EndPoint *