diff --git a/examples/simple-p2p.cc b/examples/simple-p2p.cc index 43dfb5303..998256168 100644 --- a/examples/simple-p2p.cc +++ b/examples/simple-p2p.cc @@ -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 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 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 diff --git a/samples/main-simple.cc b/samples/main-simple.cc index 675a3d16e..9505f0f16 100644 --- a/samples/main-simple.cc +++ b/samples/main-simple.cc @@ -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 a = new InternetNode (); IUdp *udp; udp = a->QueryInterface (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; } diff --git a/src/applications/application-list.cc b/src/applications/application-list.cc index b75f007eb..33980b840 100644 --- a/src/applications/application-list.cc +++ b/src/applications/application-list.cc @@ -35,12 +35,12 @@ ApplicationList::ApplicationList(Ptr n) void ApplicationList::DoDispose (void) { - for (std::vector::const_iterator i = m_apps.begin(); + for (std::vector >::iterator i = m_apps.begin(); i != m_apps.end(); ++i) { - Application *app = *i; + Ptr 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 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 ApplicationList::Get(uint32_t i) const +{ + if (m_apps.empty()) + { + return 0; + } return m_apps[i]; } diff --git a/src/applications/application-list.h b/src/applications/application-list.h index 78205b843..46576ecf3 100644 --- a/src/applications/application-list.h +++ b/src/applications/application-list.h @@ -26,6 +26,7 @@ #include "application.h" #include "ns3/ns-unknown.h" +#include "ns3/ptr.h" #include namespace ns3 { @@ -37,23 +38,15 @@ public: ApplicationList(Ptr); // 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 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); + uint32_t Count() const; // Number of applications - Application* Get(uint32_t i) const; // Get app by index + Ptr Get(uint32_t i) const; // Get app by index protected: virtual void DoDispose (void); private: - std::vector m_apps; + std::vector > m_apps; }; }//namespace ns3 diff --git a/src/core/ns-unknown.cc b/src/core/ns-unknown.cc index 27a5702b0..b3edea6ad 100644 --- a/src/core/ns-unknown.cc +++ b/src/core/ns-unknown.cc @@ -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 (); } diff --git a/src/core/ns-unknown.h b/src/core/ns-unknown.h index c5c6af1e4..046407a34 100644 --- a/src/core/ns-unknown.h +++ b/src/core/ns-unknown.h @@ -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 diff --git a/src/core/object.cc b/src/core/object.cc index 9c7e8d83e..77bfbe76f 100644 --- a/src/core/object.cc +++ b/src/core/object.cc @@ -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) { diff --git a/src/core/ptr.cc b/src/core/ptr.cc index 610f535b2..f488c51f9 100644 --- a/src/core/ptr.cc +++ b/src/core/ptr.cc @@ -264,6 +264,22 @@ PtrTest::RunTests (void) { ok = false; } + + { + Ptr p0 = new NoCount (cb); + Ptr p1 = new NoCount (cb); + if (p0 == p1) + { + ok = false; + } + if (p0 != p1) + { + } + else + { + ok = false; + } + } return ok; diff --git a/src/core/ptr.h b/src/core/ptr.h index 7ebe43af6..b95ce9c5d 100644 --- a/src/core/ptr.h +++ b/src/core/ptr.h @@ -51,6 +51,7 @@ private: void operator delete (void *); }; friend class Ptr; + void Acquire (void) const; public: /** * Create an empty smart pointer @@ -109,12 +110,29 @@ public: template inline friend bool operator != (T1 const *lhs, Ptr &rhs); + // allow if (sp0 == sp1) + template + inline friend bool operator == (Ptr const &lhs, Ptr const &rhs); + // allow if (sp0 != sp1) + template + inline friend bool operator != (Ptr const &lhs, Ptr const &rhs); + template inline friend Ptr const_pointer_cast (Ptr const&p); }; +template +void +Ptr::Acquire (void) const +{ + if (m_ptr != 0) + { + m_ptr->Ref (); + } +} + template Ptr::Ptr () : m_ptr (0) @@ -123,27 +141,22 @@ Ptr::Ptr () template Ptr::Ptr (T *ptr) : m_ptr (ptr) -{} +{ + Acquire (); +} template Ptr::Ptr (Ptr const&o) - : m_ptr (o.m_ptr) + : m_ptr (o.Peek ()) { - if (m_ptr != 0) - { - m_ptr->Ref(); - } + Acquire (); } template template Ptr::Ptr (Ptr 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 @@ -160,16 +173,15 @@ Ptr & Ptr::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 T * Ptr::Get () const { - m_ptr->Ref(); + Acquire (); return m_ptr; } @@ -246,6 +258,20 @@ operator != (T1 const *lhs, Ptr &rhs) return lhs != rhs.m_ptr; } +template +bool +operator == (Ptr const &lhs, Ptr const &rhs) +{ + return lhs.Get () == rhs.Get (); +} +template +bool +operator != (Ptr const &lhs, Ptr const &rhs) +{ + return lhs.Get () != rhs.Get (); +} + + template Ptr const_pointer_cast (Ptr const&p) diff --git a/src/devices/p2p/p2p-topology.cc b/src/devices/p2p/p2p-topology.cc index 9a1daa9cf..5f024a668 100644 --- a/src/devices/p2p/p2p-topology.cc +++ b/src/devices/p2p/p2p-topology.cc @@ -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); diff --git a/src/internet-node/internet-node.cc b/src/internet-node/internet-node.cc index 2f18becea..abe48a41d 100644 --- a/src/internet-node/internet-node.cc +++ b/src/internet-node/internet-node.cc @@ -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); diff --git a/src/internet-node/udp.cc b/src/internet-node/udp.cc index 0fd2ae18f..96bc58056 100644 --- a/src/internet-node/udp.cc +++ b/src/internet-node/udp.cc @@ -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 *