net device copy and assignment, reference counted channel.
--- 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: