]> git.saurik.com Git - apple/security.git/blame - securityd/src/structure.cpp
Security-58286.51.6.tar.gz
[apple/security.git] / securityd / src / structure.cpp
CommitLineData
d8f41ccd
A
1/*
2 * Copyright (c) 2000-2001,2004,2009 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25//
26// structure - structural framework for securityd objects
27//
28#include "structure.h"
29
30
31//
32// NodeCore always has a destructor (because it's virtual),
33// but its dump support is conditionally included.
34//
35NodeCore::~NodeCore()
866f8763 36try {
d8f41ccd
A
37#if defined(DEBUGDUMP)
38 StLock<Mutex> _(mCoreLock);
39 mCoreNodes.erase(this);
40#endif //DEBUGDUMP
866f8763
A
41} catch(...) {
42 return;
d8f41ccd
A
43}
44
45
46//
47// Basic object mesh maintainance
48//
49void NodeCore::parent(NodeCore &p)
50{
51 StLock<Mutex> _(*this);
52 mParent = &p;
53}
54
55void NodeCore::referent(NodeCore &r)
56{
57 StLock<Mutex> _(*this);
58 assert(!mReferent);
59 mReferent = &r;
60}
61
62void NodeCore::clearReferent()
63{
64 StLock<Mutex> _(*this);
65 if (mReferent)
66 assert(!mReferent->hasReference(*this));
67 mReferent = NULL;
68}
69
70
71void NodeCore::addReference(NodeCore &p)
72{
73 StLock<Mutex> _(*this);
74 assert(p.mReferent == this);
75 mReferences.insert(&p);
76}
77
78void NodeCore::removeReference(NodeCore &p)
79{
80 StLock<Mutex> _(*this);
81 assert(hasReference(p));
82 mReferences.erase(&p);
83}
84
85#if !defined(NDEBUG)
86
87bool NodeCore::hasReference(NodeCore &p)
88{
89 assert(p.refCountForDebuggingOnly() > 0);
90 return mReferences.find(&p) != mReferences.end();
91}
92
93#endif //NDEBUG
94
95
96//
97// ClearReferences clears the reference set but does not propagate
98// anything; it is NOT recursive.
99//
100void NodeCore::clearReferences()
101{
102 StLock<Mutex> _(*this);
fa7225c8 103 secinfo("ssnode", "%p clearing all %d references",
d8f41ccd
A
104 this, int(mReferences.size()));
105 mReferences.erase(mReferences.begin(), mReferences.end());
106}
107
108
109//
110// Kill should be overloaded by Nodes to implement any cleanup and release
111// operations that should happen at LOGICAL death of the represented object.
112// This is where you should release ports, close files, etc.
113// This default behavior, which you MUST include in your override,
114// propagates kills to all active references, recursively.
115//
116void NodeCore::kill()
117{
118 StLock<Mutex> _(*this);
119 for (ReferenceSet::const_iterator it = mReferences.begin(); it != mReferences.end(); it++)
120 (*it)->kill();
121 clearReferences();
122}
123
124
125void NodeCore::kill(NodeCore &ref)
126{
127 StLock<Mutex> _(*this);
128 assert(hasReference(ref));
129 ref.kill();
130 removeReference(ref);
131}
132
133
134//
135// NodeCore-level support for state dumping.
136// Call NodeCore::dumpAll() to debug-dump all nodes.
137// Note that enabling DEBUGDUMP serializes all node creation/destruction
138// operations, and thus may cause significant shifts in thread interactions.
139//
140#if defined(DEBUGDUMP)
141
142// The (uncounted) set of all known NodeCores in existence, with protective lock
143set<NodeCore *> NodeCore::mCoreNodes;
144Mutex NodeCore::mCoreLock;
145
146// add a new NodeCore to the known set
147NodeCore::NodeCore()
148 : Mutex(Mutex::recursive)
149{
150 StLock<Mutex> _(mCoreLock);
151 mCoreNodes.insert(this);
152}
153
154// partial-line common dump text for any NodeCore
155// override this to add text to your Node type's state dump output
156void NodeCore::dumpNode()
157{
158 Debug::dump("%s@%p rc=%u", Debug::typeName(*this).c_str(), this, unsigned(refCountForDebuggingOnly()));
159 if (mParent)
160 Debug::dump(" parent=%p", mParent.get());
161 if (mReferent)
162 Debug::dump(" referent=%p", mReferent.get());
163}
164
165// full-line dump of a NodeCore
166// override this to completely re-implement the dump format for your Node type
167void NodeCore::dump()
168{
169 dumpNode();
170 if (!mReferences.empty()) {
171 Debug::dump(" {");
172 for (ReferenceSet::const_iterator it = mReferences.begin(); it != mReferences.end(); it++) {
173 Debug::dump(" %p", it->get());
174 if ((*it)->mReferent != this)
175 Debug::dump("!*INVALID*");
176 }
177 Debug::dump(" }");
178 }
179 Debug::dump("\n");
180}
181
182// dump all known nodes
183void NodeCore::dumpAll()
184{
185 StLock<Mutex> _(mCoreLock);
186 time_t now; time(&now);
187 Debug::dump("\nNODE DUMP (%24.24s)\n", ctime(&now));
188 for (set<NodeCore *>::const_iterator it = mCoreNodes.begin(); it != mCoreNodes.end(); it++)
189 (*it)->dump();
190 Debug::dump("END NODE DUMP\n\n");
191}
192
193#endif //DEBUGDUMP