net device copy and assignment, reference counted channel.
authorCraig Dowell
Tue, 27 Mar 2007 15:41:08 -0700
changeset 379 ae74e8a7bb44
parent 378 32bd402ea5ea
child 380 41f4634edf5d
net device copy and assignment, reference counted channel.
SConstruct
examples/simple-p2p.cc
src/core/object.cc
src/core/object.h
src/devices/p2p/p2p-net-device.cc
src/devices/p2p/p2p-net-device.h
src/node/channel.h
--- a/SConstruct	Tue Mar 27 13:04:11 2007 -0700
+++ b/SConstruct	Tue Mar 27 15:41:08 2007 -0700
@@ -21,6 +21,7 @@
     'debug.cc',
     'assert.cc',
     'ptr.cc',
+    'object.cc',
     'test.cc',
     'random-variable.cc',
     'rng-stream.cc',
@@ -44,6 +45,7 @@
     'reference-list.h',
     'callback.h',
     'ptr.h',
+    'object.h',
     'debug.h',
     'assert.h',
     'fatal-error.h',
@@ -66,8 +68,6 @@
     return retval
 core.add_config (config_core)
 
-
-
 #
 # The Simu module
 #
--- a/examples/simple-p2p.cc	Tue Mar 27 13:04:11 2007 -0700
+++ b/examples/simple-p2p.cc	Tue Mar 27 15:41:08 2007 -0700
@@ -201,7 +201,8 @@
 
 int main (int argc, char *argv[])
 {
-#if 0
+#if 1
+  DebugComponentEnable("Object");
   DebugComponentEnable("Queue");
   DebugComponentEnable("DropTailQueue");
   DebugComponentEnable("Channel");
@@ -302,4 +303,8 @@
   // or containers or smart pointers
 
   Simulator::Destroy ();
+
+  ch1->Unref ();
+  ch2->Unref ();
+  ch3->Unref ();
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/object.cc	Tue Mar 27 15:41:08 2007 -0700
@@ -0,0 +1,66 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "object.h"
+#include "debug.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("Object");
+
+namespace ns3 {
+
+Object::Object ()
+  : m_count (1)
+{
+}
+
+Object::~Object ()
+{
+}
+
+void 
+Object::Ref (void)
+{
+  NS_DEBUG("Object::Ref (): this == 0x" << this);
+  m_count++;
+  NS_DEBUG("Object::Ref (): m_count bumped to " << m_count);
+}
+
+void 
+Object::Unref (void)
+{
+  NS_DEBUG("Object::Unref (): this == 0x" << this);
+  m_count--;
+  NS_DEBUG("Object::Ref (): m_count dropped to " << m_count);
+
+  if (m_count == 0)
+    {
+      NS_DEBUG("Object::Unref (): delete");
+      delete this;
+    }
+}
+
+bool 
+Object::IsSingle (void)
+{
+  NS_DEBUG("Object::IsSingle (): m_count == " << m_count);
+  return m_count == 1;
+}
+
+}//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/object.h	Tue Mar 27 15:41:08 2007 -0700
@@ -0,0 +1,42 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef OBJECT_H
+#define OBJECT_H
+
+#include <stdint.h>
+
+namespace ns3 {
+
+class Object 
+{
+public:
+  Object ();
+  virtual ~Object ();
+  void Ref (void);
+  void Unref (void);
+  bool IsSingle (void);
+private:
+  uint32_t m_count;
+};
+
+}//namespace ns3
+
+#endif /* OBJECT_H */
--- a/src/devices/p2p/p2p-net-device.cc	Tue Mar 27 13:04:11 2007 -0700
+++ b/src/devices/p2p/p2p-net-device.cc	Tue Mar 27 15:41:08 2007 -0700
@@ -32,13 +32,15 @@
 
 namespace ns3 {
 
-PointToPointNetDevice::PointToPointNetDevice(Node* node) 
+PointToPointNetDevice::PointToPointNetDevice (Node* node) 
 : 
-  NetDevice(node, MacAddress("00:00:00:00:00:00")), 
-  m_txMachineState(READY),
-  m_bps (DataRate(0xffffffff)),
-  m_channel(0), 
-  m_queue(0)
+  NetDevice(node, MacAddress ("00:00:00:00:00:00")), 
+  m_txMachineState (READY),
+  m_bps (DataRate (0xffffffff)),
+  m_tInterframeGap (Seconds(0)),
+  m_channel (0), 
+  m_queue (0),
+  m_rxTrace ()
 {
   NS_DEBUG ("PointToPointNetDevice::PointToPointNetDevice (" << node << ")");
 
@@ -53,6 +55,67 @@
 PointToPointNetDevice::~PointToPointNetDevice()
 {
   NS_DEBUG ("PointToPointNetDevice::~PointToPointNetDevice ()");
+
+  if (m_channel)
+    {
+      m_channel->Unref ();
+      m_channel = 0;
+    }
+}
+
+//
+// Copy constructor for PointToPointNetDevice.
+//
+// We use the underlying NetDevice copy constructor to get the base class
+// copied.  These just remain as is (e.g. you get the same name, the same
+// MAC address).  If you need to fix them up, YOU, the copier need to do 
+// that.
+// 
+// The things we need to be careful of are the channel, the queue and the
+// trace callback.  If the channel pointer is non-zero, we copy the pointer 
+// and add a reference.  If the queue is non-zero, we copy it using the queue
+// assignment operator.  We don't mess with the trace -- we just reset it.
+// We're assuming that the tracing will be set up after the topology creation
+// phase and this won't actually matter.
+//
+PointToPointNetDevice::PointToPointNetDevice (const PointToPointNetDevice& nd)
+: 
+  NetDevice(nd), 
+  m_txMachineState(READY),
+  m_bps (nd.m_bps),
+  m_tInterframeGap (nd.m_tInterframeGap),
+  m_channel(0), 
+  m_queue(0),
+  m_rxTrace ()
+{
+  NS_DEBUG ("PointToPointNetDevice::PointToPointNetDevice (" << &nd << ")");
+
+  if (nd.m_channel)
+    {
+      m_channel = nd.m_channel;
+      m_channel->Ref ();
+    }
+
+  if (nd.m_queue)
+    {
+      m_queue = nd.m_queue;
+    }
+    
+}
+
+//
+// Assignment operator for PointToPointNetDevice.
+//
+// This uses the non-obvious trick of taking the source net device passed by
+// value instead of by reference.  This causes the copy constructor to be
+// invoked (where the real work is done -- see above).  All we have to do
+// here is to return the newly constructed net device.
+//
+  PointToPointNetDevice&
+PointToPointNetDevice::operator= (const PointToPointNetDevice nd)
+{
+  NS_DEBUG ("PointToPointNetDevice::operator= (" << &nd << ")");
+  return *this;
 }
 
   void 
@@ -236,7 +299,14 @@
 {
   NS_DEBUG ("PointToPointNetDevice::Attach (" << &ch << ")");
 
+  if (m_channel)
+    {
+      m_channel->Unref ();
+      m_channel = 0;
+    }
+
   m_channel = ch;
+  m_channel->Ref ();
 
   m_channel->Attach(this);
   m_bps = m_channel->GetDataRate ();
--- a/src/devices/p2p/p2p-net-device.h	Tue Mar 27 13:04:11 2007 -0700
+++ b/src/devices/p2p/p2p-net-device.h	Tue Mar 27 15:41:08 2007 -0700
@@ -43,17 +43,16 @@
     RX,
   };
 
-  PointToPointNetDevice(Node* node);
+  PointToPointNetDevice (Node* node);
+  PointToPointNetDevice (const PointToPointNetDevice& nd);
+
   virtual ~PointToPointNetDevice();
 
+  PointToPointNetDevice& operator= (PointToPointNetDevice nd);
+
   void SetDataRate(DataRate bps);
   void SetInterframeGap(Time t);
   
-private:
-  // Don't let the compiler slip in copy and assignment construction
-  PointToPointNetDevice(const PointToPointNetDevice&);
-  PointToPointNetDevice&operator=(const PointToPointNetDevice&);
-
 public:
   bool Attach(PointToPointChannel* ch);
   void AddQueue(Queue*);
--- a/src/node/channel.h	Tue Mar 27 13:04:11 2007 -0700
+++ b/src/node/channel.h	Tue Mar 27 15:41:08 2007 -0700
@@ -24,6 +24,7 @@
 
 #include <string>
 #include <stdint.h>
+#include "ns3/object.h"
 
 namespace ns3 {
 
@@ -35,12 +36,11 @@
  * A channel is a logical path over which information flows.  The path can
  * be as simple as a short piece of wire, or as complicated as space-time.
  */
-class Channel
+class Channel : public Object
 {
 public:
   Channel ();
   Channel (std::string name);
-  virtual ~Channel ();
 
   void SetName(std::string);
   std::string GetName(void);
@@ -49,6 +49,7 @@
   virtual NetDevice *GetDevice (uint32_t i) const = 0;
 
 protected:
+  virtual ~Channel ();
   std::string m_name;
 
 private: