#include "structure.h"
NodeCore::~NodeCore()
{
#if defined(DEBUGDUMP)
StLock<Mutex> _(mCoreLock);
mCoreNodes.erase(this);
#endif //DEBUGDUMP
}
void NodeCore::parent(NodeCore &p)
{
StLock<Mutex> _(*this);
mParent = &p;
}
void NodeCore::referent(NodeCore &r)
{
StLock<Mutex> _(*this);
assert(!mReferent);
mReferent = &r;
}
void NodeCore::clearReferent()
{
StLock<Mutex> _(*this);
if (mReferent)
assert(!mReferent->hasReference(*this));
mReferent = NULL;
}
void NodeCore::addReference(NodeCore &p)
{
StLock<Mutex> _(*this);
assert(p.mReferent == this);
mReferences.insert(&p);
}
void NodeCore::removeReference(NodeCore &p)
{
StLock<Mutex> _(*this);
assert(hasReference(p));
mReferences.erase(&p);
}
#if !defined(NDEBUG)
bool NodeCore::hasReference(NodeCore &p)
{
assert(p.refCountForDebuggingOnly() > 0);
return mReferences.find(&p) != mReferences.end();
}
#endif //NDEBUG
void NodeCore::clearReferences()
{
StLock<Mutex> _(*this);
secdebug("ssnode", "%p clearing all %d references",
this, int(mReferences.size()));
mReferences.erase(mReferences.begin(), mReferences.end());
}
void NodeCore::kill()
{
StLock<Mutex> _(*this);
for (ReferenceSet::const_iterator it = mReferences.begin(); it != mReferences.end(); it++)
(*it)->kill();
clearReferences();
}
void NodeCore::kill(NodeCore &ref)
{
StLock<Mutex> _(*this);
assert(hasReference(ref));
ref.kill();
removeReference(ref);
}
#if defined(DEBUGDUMP)
set<NodeCore *> NodeCore::mCoreNodes;
Mutex NodeCore::mCoreLock;
NodeCore::NodeCore()
: Mutex(Mutex::recursive)
{
StLock<Mutex> _(mCoreLock);
mCoreNodes.insert(this);
}
void NodeCore::dumpNode()
{
Debug::dump("%s@%p rc=%u", Debug::typeName(*this).c_str(), this, unsigned(refCountForDebuggingOnly()));
if (mParent)
Debug::dump(" parent=%p", mParent.get());
if (mReferent)
Debug::dump(" referent=%p", mReferent.get());
}
void NodeCore::dump()
{
dumpNode();
if (!mReferences.empty()) {
Debug::dump(" {");
for (ReferenceSet::const_iterator it = mReferences.begin(); it != mReferences.end(); it++) {
Debug::dump(" %p", it->get());
if ((*it)->mReferent != this)
Debug::dump("!*INVALID*");
}
Debug::dump(" }");
}
Debug::dump("\n");
}
void NodeCore::dumpAll()
{
StLock<Mutex> _(mCoreLock);
time_t now; time(&now);
Debug::dump("\nNODE DUMP (%24.24s)\n", ctime(&now));
for (set<NodeCore *>::const_iterator it = mCoreNodes.begin(); it != mCoreNodes.end(); it++)
(*it)->dump();
Debug::dump("END NODE DUMP\n\n");
}
#endif //DEBUGDUMP