/* * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ // // structure - structural framework for securityd objects // #include "structure.h" // // NodeCore always has a destructor (because it's virtual), // but its dump support is conditionally included. // NodeCore::~NodeCore() { #if defined(DEBUGDUMP) StLock _(mCoreLock); mCoreNodes.erase(this); #endif //DEBUGDUMP } // // ClearReferences clears the reference set but does not propagate // anything; it is NOT recursive. // void NodeCore::clearReferences() { StLock _(*this); secdebug("ssnode", "%p clearing all %d references", this, int(mReferences.size())); mReferences.erase(mReferences.begin(), mReferences.end()); } // // Kill should be overloaded by Nodes to implement any cleanup and release // operations that should happen at LOGICAL death of the represented object. // This is where you should release ports, close files, etc. // This default behavior, which you MUST include in your override, // propagates kills to all active references, recursively. // void NodeCore::kill() { StLock _(*this); for (ReferenceSet::const_iterator it = mReferences.begin(); it != mReferences.end(); it++) (*it)->kill(); clearReferences(); } // // NodeCore-level support for state dumping. // Call NodeCore::dumpAll() to debug-dump all nodes. // Note that enabling DEBUGDUMP serializes all node creation/destruction // operations, and thus may cause significant shifts in thread interactions. // #if defined(DEBUGDUMP) // The (uncounted) set of all known NodeCores in existence, with protective lock set NodeCore::mCoreNodes; Mutex NodeCore::mCoreLock; // add a new NodeCore to the known set NodeCore::NodeCore() : Mutex(Mutex::recursive) { StLock _(mCoreLock); mCoreNodes.insert(this); } // partial-line common dump text for any NodeCore // override this to add text to your Node type's state dump output 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()); } // full-line dump of a NodeCore // override this to completely re-implement the dump format for your Node type 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()); Debug::dump(" }"); } Debug::dump("\n"); } // dump all known nodes void NodeCore::dumpAll() { StLock _(mCoreLock); time_t now; time(&now); Debug::dump("\nNODE DUMP (%24.24s)\n", ctime(&now)); for (set::const_iterator it = mCoreNodes.begin(); it != mCoreNodes.end(); it++) (*it)->dump(); Debug::dump("END NODE DUMP\n\n"); } #endif //DEBUGDUMP