]>
git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cdsa_utilities/lib/handletemplates_defs.h
2 * Copyright (c) 2008,2011-2012 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
26 // adjunct to handletemplates.h
28 // this header should only be #included by source files defining
29 // TypedHandle or MappingHandle subclasses
31 // @@@ Should use non-CSSM error codes
33 #ifndef _H_HANDLETEMPLATES_DEFS
34 #define _H_HANDLETEMPLATES_DEFS
36 #include <Security/cssm.h>
37 #include <security_utilities/refcount.h>
38 #include <security_utilities/threading.h>
39 #include <security_utilities/globalizer.h>
40 #include <security_cdsa_utilities/cssmerrors.h>
41 #include <security_cdsa_utilities/handletemplates.h>
49 template <class _Handle
>
50 TypedHandle
<_Handle
>::TypedHandle()
51 : mMyHandle(invalidHandle
), mValid(false)
55 template <class _Handle
>
56 TypedHandle
<_Handle
>::TypedHandle(_Handle h
)
57 : mMyHandle(h
), mValid(true)
63 // MappingHandle instance methods
65 template <class _Handle
>
66 MappingHandle
<_Handle
>::MappingHandle() : TypedHandle
<_Handle
>()
71 template <class _Handle
>
72 void MappingHandle
<_Handle
>::make()
74 StLock
<Mutex
> _(state());
76 _Handle hbase
= (_Handle
)reinterpret_cast<uintptr_t>(this);
78 _Handle handle
= hbase
^ state().nextSeq();
79 if (!state().handleInUse(handle
)) {
80 // assumes sizeof(unsigned long) >= sizeof(handle)
81 secinfo("handleobj", "create %#lx for %p", static_cast<unsigned long>(handle
), this);
82 TypedHandle
<_Handle
>::setHandle(handle
);
83 state().add(handle
, this);
89 // The default locking virtual methods do nothing and succeed.
90 template <class _Handle
>
91 void MappingHandle
<_Handle
>::lock() { }
93 template <class _Handle
>
94 bool MappingHandle
<_Handle
>::tryLock() { return true; }
98 // MappingHandle::State
101 // The default State constructor should not be inlined in a standard
102 // header: its use via ModuleNexus would result in the inlined code
103 // appearing *everywhere* the State object might have to be constructed.
104 template <class _Handle
>
105 MappingHandle
<_Handle
>::State::State()
111 // Check if the handle is already in the map. Caller must already hold
112 // the map lock. Intended for use by a subclass' implementation of
113 // MappingHandle<...>::make().
115 template <class _Handle
>
116 bool MappingHandle
<_Handle
>::State::handleInUse(_Handle h
)
118 return (HandleMap::find(h
) != (*this).end());
122 // Observing proper map locking, locate a handle in the global handle map
123 // and return a pointer to its object. Throw CssmError(error) if it cannot
124 // be found, or it is corrupt.
126 template <class _Handle
>
127 MappingHandle
<_Handle
> *MappingHandle
<_Handle
>::State::find(_Handle h
, CSSM_RETURN error
)
129 StLock
<Mutex
> _(*this);
130 typename
HandleMap::const_iterator it
= HandleMap::find(h
);
131 if (it
== (*this).end())
132 CssmError::throwMe(error
);
133 MappingHandle
<_Handle
> *obj
= it
->second
;
134 if (obj
== NULL
|| obj
->handle() != h
)
135 CssmError::throwMe(error
);
140 // Look up the handle given in the global handle map.
141 // If not found, or if the object is corrupt, throw an exception.
142 // Otherwise, hold the State lock and return an iterator to the map entry.
143 // Caller must release the State lock in a timely manner.
145 template <class _Handle
>
146 typename MappingHandle
<_Handle
>::HandleMap::iterator
147 MappingHandle
<_Handle
>::State::locate(_Handle h
, CSSM_RETURN error
)
149 StLock
<Mutex
> locker(*this);
150 typename
HandleMap::iterator it
= HandleMap::find(h
);
151 if (it
== (*this).end())
152 CssmError::throwMe(error
);
153 MappingHandle
<_Handle
> *obj
= it
->second
;
154 if (obj
== NULL
|| obj
->handle() != h
)
155 CssmError::throwMe(error
);
161 // Add a handle and its associated object to the map. Caller must already
162 // hold the map lock, and is responsible for collision-checking prior to
163 // calling this method. Intended for use by a subclass' implementation of
164 // MappingHandle<...>::make().
166 template <class _Handle
>
167 void MappingHandle
<_Handle
>::State::add(_Handle h
, MappingHandle
<_Handle
> *obj
)
173 // Clean up the handle for an object that dies. Caller must already hold
175 // Note that an object MAY clear its handle before (in which case we do nothing).
176 // In particular, killHandle will do this.
178 template <class _Handle
>
179 void MappingHandle
<_Handle
>::State::erase(MappingHandle
<_Handle
> *obj
)
181 if (obj
->validHandle())
182 HandleMap::erase(obj
->handle());
185 template <class _Handle
>
186 void MappingHandle
<_Handle
>::State::erase(typename
HandleMap::iterator
&it
)
188 if (it
->second
->validHandle())
189 HandleMap::erase(it
);
194 // All explicit instantiations of MappingHandle subclasses get the
195 // generation of their 'state' member for free (if they #include this
198 template <class _Handle
>
199 ModuleNexus
<typename MappingHandle
<_Handle
>::State
> MappingHandle
<_Handle
>::state
;
202 } // end namespace Security
204 #endif //_H_HANDLETEMPLATES_DEFS