2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
20 // handleobject - give an object a process-global unique handle
22 #ifndef _H_HANDLEOBJECT
23 #define _H_HANDLEOBJECT
25 #include <Security/cssm.h>
26 #include <Security/utilities.h>
27 #include <Security/threading.h>
28 #include <Security/globalizer.h>
36 // A HandledObject is a trivial mixin class whose only feature is that
37 // it has a *handle*, in the form of (currently) a CSSM_HANDLE of some kind.
38 // Subclasses need to assign such a handle during creation.
42 typedef CSSM_HANDLE Handle
;
43 static const Handle invalidHandle
= 0;
45 Handle
handle() const { return mMyHandle
; }
46 bool validHandle() const { return mValid
; }
49 HandledObject(Handle h
) : mMyHandle(h
), mValid(true) { }
50 HandledObject() { /*IFDEBUG(*/ mMyHandle
= invalidHandle
/*)*/ ; mValid
= false; }
52 void setHandle(Handle h
)
54 assert(!mValid
); // guard against redefinition
59 { assert(mValid
); mValid
= false; }
62 Handle mMyHandle
; // our handle value
63 bool mValid
; // is the handle (still) valid?
68 // Mapping CSSM_HANDLE values to object pointers and back.
69 // A HandleObject is a HandledObject (see above) that makes up its own handle
70 // based on some mechanism that you know nothing about.
72 // Please be very careful about the limits of the object contract here.
73 // We promise to invent a suitable, unique Handle for each HandleObject in
74 // existence within one address space. We promise that if you hand that handle
75 // to the various findHandle<>() variants, we will give you back the HandleObject
76 // that created it. This is the entire contract.
77 // We *will* make some efforts to diagnose invalid handles and throw exceptions on
78 // them, but the find() operation is supposed to be *fast*, so no heroic measures
81 class HandleObject
: public HandledObject
{
83 class State
; friend class State
;
84 template <class Subtype
> friend Subtype
&findHandle(CSSM_HANDLE
, CSSM_RETURN
);
85 template <class Subtype
> friend Subtype
&findHandleAndLock(CSSM_HANDLE
, CSSM_RETURN
);
86 template <class Subtype
> friend Subtype
&killHandle(CSSM_HANDLE
, CSSM_RETURN
);
88 HandleObject() { state().make(this); }
89 virtual ~HandleObject() { state().erase(this); }
93 virtual bool tryLock();
96 enum LocateMode
{ lockTarget
, findTarget
, removeTarget
};
99 typedef hash_map
<CSSM_HANDLE
, HandleObject
*> HandleMap
;
103 void make(HandleObject
*obj
);
104 HandleObject
*locate(Handle h
, LocateMode mode
, CSSM_RETURN error
);
105 void erase(HandleObject
*obj
);
113 static ModuleNexus
<State
> state
;
118 // Type-specific ways to access the HandleObject map in various ways
120 template <class Subclass
>
121 Subclass
&findHandle(CSSM_HANDLE handle
,
122 CSSM_RETURN error
= CSSMERR_CSSM_INVALID_ADDIN_HANDLE
)
125 if (!(sub
= dynamic_cast<Subclass
*>(HandleObject::state().locate(handle
, HandleObject::findTarget
, error
))))
126 CssmError::throwMe(error
);
130 template <class Subclass
>
131 Subclass
&findHandleAndLock(CSSM_HANDLE handle
,
132 CSSM_RETURN error
= CSSMERR_CSSM_INVALID_ADDIN_HANDLE
)
135 if (!(sub
= dynamic_cast<Subclass
*>(HandleObject::state().locate(handle
, HandleObject::lockTarget
, error
))))
136 CssmError::throwMe(error
);
140 template <class Subclass
>
141 Subclass
&killHandle(CSSM_HANDLE handle
,
142 CSSM_RETURN error
= CSSMERR_CSSM_INVALID_ADDIN_HANDLE
)
145 if (!(sub
= dynamic_cast<Subclass
*>(HandleObject::state().locate(handle
, HandleObject::removeTarget
, error
))))
146 CssmError::throwMe(error
);
150 } // end namespace Security
152 #endif //_H_HANDLEOBJECT