Statistics
| Branch: | Revision:

root / src / sim / cownedobject.cc @ e26d3d25

History | View | Annotate | Download (5.83 KB)

1
//=========================================================================
2
//  COWNEDOBJECT.CC - part of
3
//
4
//                  OMNeT++/OMNEST
5
//           Discrete System Simulation in C++
6
//
7
//  Author: Andras Varga
8
//
9
//=========================================================================
10

    
11
/*--------------------------------------------------------------*
12
  Copyright (C) 1992-2008 Andras Varga
13
  Copyright (C) 2006-2008 OpenSim Ltd.
14

15
  This file is distributed WITHOUT ANY WARRANTY. See the file
16
  `license' for details on this and other legal matters.
17
*--------------------------------------------------------------*/
18

    
19
#include <stdio.h>           // sprintf
20
#include <string.h>          // strcpy, strlen etc.
21
#include "cownedobject.h"
22
#include "csimulation.h"
23
#include "cenvir.h"
24
#include "globals.h"
25
#include "cexception.h"
26
#include "simutil.h"
27
#include "cdefaultlist.h"
28
#include "cclassdescriptor.h"
29
#include "cthreadpool.h"
30
#include "clockeddefaultlist.h"
31

    
32
#ifdef WITH_PARSIM
33
#include "ccommbuffer.h"
34
#endif
35

    
36
NAMESPACE_BEGIN
37

    
38
using std::ostream;
39

    
40
bool cStaticFlag::staticflag;
41
bool cStaticFlag::exitingflag;
42

    
43
Register_Class(cOwnedObject);
44

    
45

    
46
#ifdef DEVELOPER_DEBUG
47
#include <set>
48

    
49
std::set<cOwnedObject*> objectlist;
50
void printAllObjects()
51
{
52
    for (std::set<cOwnedObject*>::iterator it = objectlist.begin(); it != objectlist.end(); ++it)
53
    {
54
        printf(" %p (%s)%s\n", (*it), (*it)->getClassName(), (*it)->getName());
55
    }
56
}
57
#endif
58

    
59

    
60
// static class members
61
//cDefaultList *cOwnedObject::defaultowner = &defaultList;
62
AO_t cOwnedObject::total_objs = 0;
63
AO_t cOwnedObject::live_objs = 0;
64

    
65
cDefaultList defaultList;
66

    
67

    
68
cOwnedObject::cOwnedObject()
69
{
70
    //TODO: in DEBUG mode, assert that this is not a static member / global variable! (using cStaticFlag)
71
#ifdef ENABLE_OWNERSHIP
72
    //defaultowner->doInsert(this);
73
    if (this != &defaultList)
74
    {
75
    cThreadPool::getDefaultOwner()->doInsert(this);
76
    }
77
#else
78
    ownerp = cThreadPool::getDefaultOwner();
79
#endif
80

    
81

    
82
    // statistics
83
    AO_fetch_and_add1(&total_objs);
84
    AO_fetch_and_add1(&live_objs);
85
#ifdef DEVELOPER_DEBUG
86
    objectlist.insert(this);
87
#endif
88
}
89

    
90
cOwnedObject::cOwnedObject(const char *name, bool namepooling) : cNamedObject(name, namepooling)
91
{
92
#ifdef ENABLE_OWNERSHIP
93
    if (this != &defaultList)
94
    {
95
        cThreadPool::getDefaultOwner()->doInsert(this);
96
    }
97
    //defaultowner->doInsert(this);
98
#else
99
    ownerp = cThreadPool::getDefaultOwner();
100
#endif
101
    // statistics
102
    AO_fetch_and_add1(&total_objs);
103
    AO_fetch_and_add1(&live_objs);
104
#ifdef DEVELOPER_DEBUG
105
    objectlist.insert(this);
106
#endif
107
}
108

    
109
cOwnedObject::cOwnedObject(const cOwnedObject& obj)
110
{
111
    setName(obj.getName());
112

    
113
#ifdef ENABLE_OWNERSHIP
114
    //defaultowner->doInsert(this);
115
    if (this != &defaultList)
116
    {
117
    cThreadPool::getDefaultOwner()->doInsert(this);
118
    }
119
#else
120
    ownerp = cThreadPool::getDefaultOwner();
121
#endif
122

    
123
    operator=(obj);
124

    
125
    // statistics
126
    AO_fetch_and_add1(&total_objs);
127
    AO_fetch_and_add1(&live_objs);
128
#ifdef DEVELOPER_DEBUG
129
    objectlist.insert(this);
130
#endif
131
}
132

    
133
cOwnedObject::~cOwnedObject()
134
{
135
#ifdef DEVELOPER_DEBUG
136
    objectlist.erase(this);
137
#endif
138
#ifdef ENABLE_OWNERSHIP
139
    // synchronization side channel problem!
140
    if (ownerp)
141
        ownerp->ownedObjectDeleted(this);
142
#endif
143
    // statistics
144
    AO_fetch_and_sub1(&live_objs);
145
}
146

    
147
void cOwnedObject::removeFromOwnershipTree()
148
{
149
#ifdef ENABLE_OWNERSHIP
150
    // set ownership of this object to null
151
    if (ownerp)
152
        ownerp->yieldOwnership(this, NULL);
153
#else
154
    ownerp = NULL;
155
#endif
156
}
157

    
158
void cOwnedObject::setDefaultOwner(cDefaultList *list)
159
{
160
    ASSERT(list!=NULL);
161
    //defaultowner = list;
162
    cThreadPool::setDefaultOwner(list);
163
}
164

    
165
cDefaultList *cOwnedObject::getDefaultOwner()
166
{
167
        return cThreadPool::getDefaultOwner();
168
    //return defaultowner;
169
}
170

    
171
cOwnedObject& cOwnedObject::operator=(const cOwnedObject& obj)
172
{
173
    // Not too much to do:
174
    // - ownership not affected
175
    // - name string is NOT copied from other object
176
    // - flags are taken over, except for FL_NAMEPOOLING which is preserved
177
    unsigned short namePooling = flags & FL_NAMEPOOLING;
178
    flags = (obj.flags & ~FL_NAMEPOOLING) | namePooling;
179
    return *this;
180
}
181

    
182
void cOwnedObject::parsimPack(cCommBuffer *buffer)
183
{
184
#ifndef WITH_PARSIM
185
    throw cRuntimeError(this,eNOPARSIM);
186
#else
187
    cNamedObject::parsimPack(buffer);
188
#endif
189
}
190

    
191
void cOwnedObject::parsimUnpack(cCommBuffer *buffer)
192
{
193
#ifndef WITH_PARSIM
194
    throw cRuntimeError(this,eNOPARSIM);
195
#else
196
    cNamedObject::parsimUnpack(buffer);
197
#endif
198
}
199

    
200
void cOwnedObject::ignoreOwnerAndDelete(cOwnedObject *obj)
201
{
202
    if (!obj)
203
        return;
204

    
205
    delete obj;
206
}
207

    
208
//-----
209

    
210
cNoncopyableOwnedObject *cNoncopyableOwnedObject::dup() const
211
{
212
    throw cRuntimeError(this, "dup(): %s subclasses from cNoncopyableOwnedObject, "
213
                              "and does not support dup()", getClassName());
214
}
215

    
216
void cNoncopyableOwnedObject::parsimPack(cCommBuffer *buffer)
217
{
218
    throw cRuntimeError(this, "parsimPack(): %s subclasses from cNoncopyableOwnedObject, and "
219
                              "does not support pack/unpack operations", getClassName());
220
}
221

    
222
void cNoncopyableOwnedObject::parsimUnpack(cCommBuffer *buffer)
223
{
224
    throw cRuntimeError(this, "parsimUnpack(): %s subclasses from cNoncopyableOwnedObject, and "
225
                              "does not support pack/unpack operations", getClassName());
226
}
227

    
228
//-----
229

    
230
ostream& operator<< (ostream& os, const cOwnedObject *p)
231
{
232
    if (!p)
233
        return os << "(NULL)";
234
    return os << "(" << p->getClassName() << ")" << p->getFullName();
235
}
236

    
237
ostream& operator<< (ostream& os, const cOwnedObject& o)
238
{
239
    return os << "(" << o.getClassName() << ")" << o.getFullName();
240
}
241

    
242
//-----
243

    
244
/* Debug code:
245
static struct X {
246
    ~X() {if (cStaticFlag::isSet()) printf("<!> Warning: cStaticFlag flag still set while shutting down! Make sure it always gets cleared at latest when exiting main().\n");}
247
} x;
248
*/
249

    
250
NAMESPACE_END