rework the Node and NodeList classes to manage reference counts correctly

This commit is contained in:
Mathieu Lacage
2007-05-02 13:44:41 +02:00
parent 3cc6ff972b
commit acf2d25cd5
6 changed files with 129 additions and 65 deletions

View File

@@ -97,6 +97,7 @@ simu.add_inst_headers([
'simulator.h',
'scheduler.h',
'scheduler-factory.h',
'simulation-singleton.h',
])
high_precision_as_double = ARGUMENTS.get('high-precision-as-double', 'n')
if high_precision_as_double == 'y':

View File

@@ -151,6 +151,11 @@ int main (int argc, char *argv[])
n0->GetIpv4()->SetDefaultRoute (Ipv4Address ("10.1.1.2"), 1);
n3->GetIpv4()->SetDefaultRoute (Ipv4Address ("10.1.3.1"), 1);
n0->Unref ();
n1->Unref ();
n2->Unref ();
n3->Unref ();
// Configure tracing of all enqueue, dequeue, and NetDevice receive events
// Trace output will be sent to the simple-p2p.tr file
#if 1
@@ -163,16 +168,6 @@ int main (int argc, char *argv[])
#endif
Simulator::Run ();
n0->Dispose ();
n1->Dispose ();
n2->Dispose ();
n3->Dispose ();
delete n0;
delete n1;
delete n2;
delete n3;
Simulator::Destroy ();
}

View File

@@ -22,62 +22,142 @@
#include "ns3/array-trace-resolver.h"
#include "ns3/trace-root.h"
#include "ns3/simulator.h"
#include "ns3/simulation-singleton.h"
#include "node-list.h"
#include "node.h"
namespace {
static class Initialization
{
public:
Initialization ()
{
ns3::TraceRoot::Register ("nodes", ns3::MakeCallback (&ns3::NodeList::CreateTraceResolver));
}
} g_initialization;
}
namespace ns3 {
uint32_t NodeList::g_nextId = 0;
/**
* The private node list used by the static-based API
*/
class NodeListPriv
{
public:
NodeListPriv ();
~NodeListPriv ();
void
NodeList::Add (Node *node)
{
GetNodes ()->push_back (node);
node->SetId(g_nextId++);
}
NodeList::Iterator
NodeList::Begin (void)
{
return GetNodes ()->begin ();
}
NodeList::Iterator
NodeList::End (void)
{
return GetNodes ()->end ();
}
uint32_t Add (Node *node);
NodeList::Iterator Begin (void);
NodeList::Iterator End (void);
TraceResolver *CreateTraceResolver (TraceContext const &context);
Node *GetNode (uint32_t n);
Node *PeekNode (uint32_t n);
uint32_t GetNNodes (void);
std::vector<Node *> *
NodeList::GetNodes (void)
private:
std::vector<Node *> m_nodes;
};
NodeListPriv::NodeListPriv ()
{}
NodeListPriv::~NodeListPriv ()
{
static bool firstTime = true;
if (firstTime)
for (std::vector<Node *>::iterator i = m_nodes.begin ();
i != m_nodes.end (); i++)
{
TraceRoot::Register ("nodes", MakeCallback (&NodeList::CreateTraceResolver));
firstTime = false;
Node *node = *i;
node->Unref ();
}
static std::vector<Node *> nodes;
return &nodes;
m_nodes.erase (m_nodes.begin (), m_nodes.end ());
}
uint32_t
NodeList::GetNNodes (void)
uint32_t
NodeListPriv::Add (Node *node)
{
return GetNodes ()->size ();
uint32_t index = m_nodes.size ();
node->Ref ();
m_nodes.push_back (node);
return index;
}
NodeList::Iterator
NodeListPriv::Begin (void)
{
return m_nodes.begin ();
}
NodeList::Iterator
NodeListPriv::End (void)
{
return m_nodes.end ();
}
Node *
NodeList::GetNode (uint32_t n)
NodeListPriv::GetNode (uint32_t n)
{
return (*GetNodes ())[n];
Node *node = m_nodes[n];
node->Ref ();
return node;
}
uint32_t
NodeListPriv::GetNNodes (void)
{
return m_nodes.size ();
}
Node *
NodeListPriv::PeekNode (uint32_t n)
{
return m_nodes[n];
}
TraceResolver *
NodeList::CreateTraceResolver (TraceContext const &context)
NodeListPriv::CreateTraceResolver (TraceContext const &context)
{
ArrayTraceResolver<Node> *resolver =
new ArrayTraceResolver<Node>
(context,
MakeCallback (&NodeList::GetNNodes),
MakeCallback (&NodeList::GetNode));
MakeCallback (&NodeListPriv::GetNNodes, this),
MakeCallback (&NodeListPriv::PeekNode, this));
return resolver;
}
}
/**
* The implementation of the public static-based API
* which calls into the private implementation through
* the simulation singleton.
*/
namespace ns3 {
uint32_t
NodeList::Add (Node *node)
{
return SimulationSingleton<NodeListPriv>::Get ()->Add (node);
}
NodeList::Iterator
NodeList::Begin (void)
{
return SimulationSingleton<NodeListPriv>::Get ()->Begin ();
}
NodeList::Iterator
NodeList::End (void)
{
return SimulationSingleton<NodeListPriv>::Get ()->End ();
}
TraceResolver *
NodeList::CreateTraceResolver (TraceContext const &context)
{
return SimulationSingleton<NodeListPriv>::Get ()->CreateTraceResolver (context);
}
Node *
NodeList::GetNode (uint32_t n)
{
return SimulationSingleton<NodeListPriv>::Get ()->GetNode (n);
}
}//namespace ns3

View File

@@ -23,13 +23,11 @@
#define NODE_LIST_H
#include <vector>
#include <string>
#include "ns3/array-trace-resolver.h"
namespace ns3 {
class Node;
class CallbackBase;
class TraceResolver;
class TraceContext;
@@ -39,18 +37,12 @@ public:
typedef ArrayTraceResolver<Node>::Index NodeIndex;
typedef std::vector<Node *>::iterator Iterator;
static void Add (Node *node);
static uint32_t Add (Node *node);
static Iterator Begin (void);
static Iterator End (void);
static TraceResolver *CreateTraceResolver (TraceContext const &context);
static Node *GetNode (uint32_t n);
private:
static uint32_t g_nextId; // becomes Node::m_id
static std::vector<Node *> *GetNodes (void);
static uint32_t GetNNodes (void);
};
}//namespace ns3

View File

@@ -30,13 +30,17 @@
namespace ns3{
Node::Node()
: m_id(0), m_sid(0)
: m_id(0),
m_sid(0)
{
m_id = NodeList::Add (this);
}
Node::Node(uint32_t sid)
: m_id(0), m_sid(sid)
: m_id(0),
m_sid(sid)
{
m_id = NodeList::Add (this);
}
Node::~Node ()
@@ -49,12 +53,6 @@ Node::GetId (void) const
return m_id;
}
void
Node::SetId(uint32_t id )
{
m_id = id;
}
uint32_t
Node::GetSystemId (void) const
{

View File

@@ -29,6 +29,7 @@
#include <list>
#include "ns3/smartset.h"
#include "ns3/object.h"
namespace ns3 {
@@ -47,7 +48,8 @@ class TraceContext;
class TraceResolver;
class NetDevice;
class Node {
class Node : public Object
{
friend class NodeList;
friend class SmartSet<Node*>;
@@ -71,9 +73,6 @@ public:
private:
virtual void DoAddDevice (NetDevice *device) const = 0;
protected:
void SetId(uint32_t); // NodeList::Add() calls this
public:
// Virtual "Getters" for each capability.
// These exist to allow owners of a generic Node pointer to get
@@ -90,7 +89,6 @@ public:
virtual Arp * GetArp (void) const;
private:
static uint32_t g_nextId; // Next available ID
uint32_t m_id; // Node id for this node
uint32_t m_sid; // System id for this node
std::vector<NetDevice *> m_devices;