Commit | Line | Data |
---|---|---|
bac41a7b A |
1 | /* |
2 | * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. | |
3 | * | |
4 | * The contents of this file constitute Original Code as defined in and are | |
5 | * subject to the Apple Public Source License Version 1.2 (the 'License'). | |
6 | * You may not use this file except in compliance with the License. Please obtain | |
7 | * a copy of the License at http://www.apple.com/publicsource and read it before | |
8 | * using this file. | |
9 | * | |
10 | * This Original Code and all software distributed under the License are | |
11 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS | |
12 | * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT | |
13 | * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | |
14 | * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the | |
15 | * specific language governing rights and limitations under the License. | |
16 | */ | |
17 | ||
18 | ||
19 | // | |
20 | // handleobject - give an object a process-global unique handle | |
21 | // | |
bac41a7b A |
22 | #include <Security/handleobject.h> |
23 | ||
24 | ||
25 | // | |
26 | // Static members of HandleObject | |
27 | // | |
28 | ModuleNexus<HandleObject::State> HandleObject::state; | |
29 | ||
30 | ||
31 | // | |
32 | // Bring the State constructor out of line | |
33 | // | |
34 | HandleObject::State::State() | |
35 | { } | |
36 | ||
37 | ||
29654253 A |
38 | // |
39 | // HandleObject destructor (virtual) | |
40 | // | |
41 | HandleObject::~HandleObject() | |
42 | { | |
43 | State &st = state(); | |
44 | StLock<Mutex> _(st); | |
45 | st.erase(this); | |
46 | } | |
47 | ||
48 | ||
bac41a7b A |
49 | // |
50 | // Assign a HandleObject's (new) Handle. | |
51 | // | |
52 | void HandleObject::State::make(HandleObject *obj) | |
53 | { | |
29654253 | 54 | StLock<Mutex> _(*this); |
bac41a7b A |
55 | for (;;) { |
56 | Handle handle = reinterpret_cast<uint32>(obj) ^ (++sequence << 19); | |
57 | if (handleMap[handle] == NULL) { | |
df0e469f | 58 | secdebug("handleobj", "create 0x%lx for %p", handle, obj); |
bac41a7b A |
59 | obj->setHandle(handle); |
60 | handleMap[handle] = obj; | |
61 | return; | |
62 | } | |
63 | } | |
64 | } | |
65 | ||
66 | ||
67 | // | |
68 | // Clean up a HandleObject that dies. | |
69 | // Note that an object MAY clear its handle before (in which case we do nothing). | |
70 | // In particular, killHandle will do this. | |
71 | // | |
72 | void HandleObject::State::erase(HandleObject *obj) | |
73 | { | |
bac41a7b A |
74 | if (obj->validHandle()) |
75 | handleMap.erase(obj->handle()); | |
76 | } | |
77 | ||
29654253 A |
78 | void HandleObject::State::erase(HandleMap::iterator &it) |
79 | { | |
80 | if (it->second->validHandle()) | |
81 | handleMap.erase(it); | |
82 | } | |
83 | ||
bac41a7b A |
84 | |
85 | // | |
29654253 A |
86 | // Observing proper map locking, locate a handle in the global handle map |
87 | // and return a pointer to its object. Throw CssmError(error) if it cannot | |
88 | // be found, or it is corrupt. | |
bac41a7b | 89 | // |
29654253 | 90 | HandleObject *HandleObject::State::find(CSSM_HANDLE h, CSSM_RETURN error) |
bac41a7b | 91 | { |
29654253 A |
92 | StLock<Mutex> _(*this); |
93 | HandleMap::const_iterator it = handleMap.find(h); | |
94 | if (it == handleMap.end()) | |
95 | CssmError::throwMe(error); | |
96 | HandleObject *obj = it->second; | |
97 | if (obj == NULL || obj->handle() != h) | |
98 | CssmError::throwMe(error); | |
99 | return obj; | |
100 | } | |
101 | ||
102 | ||
103 | // | |
104 | // Look up the handle given in the global handle map. | |
105 | // If not found, or if the object is corrupt, throw an exception. | |
106 | // Otherwise, hold the State lock and return an iterator to the map entry. | |
107 | // Caller must release the State lock in a timely manner. | |
108 | // | |
109 | HandleObject::HandleMap::iterator HandleObject::State::locate(CSSM_HANDLE h, CSSM_RETURN error) | |
110 | { | |
111 | StLock<Mutex> locker(*this); | |
112 | HandleMap::iterator it = handleMap.find(h); | |
113 | if (it == handleMap.end()) | |
114 | CssmError::throwMe(error); | |
115 | HandleObject *obj = it->second; | |
116 | if (obj == NULL || obj->handle() != h) | |
117 | CssmError::throwMe(error); | |
118 | locker.release(); | |
119 | return it; | |
bac41a7b A |
120 | } |
121 | ||
122 | ||
123 | // | |
124 | // The default locking virtual methods do nothing and succeed. | |
125 | // | |
126 | void HandleObject::lock() { } | |
127 | ||
128 | bool HandleObject::tryLock() { return true; } |