2 * Copyright (c) 2000-2001,2003-2004,2006,2011-2012,2014 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 // Encapsulate the callback mechanism of CSSM.
31 #include <Security/cssm.h>
32 #include <security_utilities/threading.h>
33 #include <security_cdsa_utilities/cssmpods.h>
40 // A single module-specific callback as requested by the user.
42 class ModuleCallback
{
44 ModuleCallback() : mCallback(0), mContext(0) { }
45 ModuleCallback(CSSM_API_ModuleEventHandler callback
, void *context
)
46 : mCallback(callback
), mContext(context
) { }
48 void operator () (CSSM_MODULE_EVENT event
,
49 const Guid
&guid
, uint32 subId
,
50 CSSM_SERVICE_TYPE serviceType
) const;
52 operator bool () const { return mCallback
|| mContext
; }
53 bool operator ! () const { return !bool(*this); }
55 bool operator == (const ModuleCallback
&cb
) const
56 { return mCallback
== cb
.mCallback
&& mContext
== cb
.mContext
; }
57 bool operator < (const ModuleCallback
&cb
) const
58 { return mCallback
< cb
.mCallback
59 || (mCallback
== cb
.mCallback
&& mContext
< cb
.mContext
); }
62 CSSM_API_ModuleEventHandler mCallback
;
68 // A set of callbacks that can be invoked automatically in a thread-safe manner.
69 // THREADS: The set itself is not interlocked by the ModuleCallbackSet class; you
70 // are responsible for ensuring single access to the set object. The class ensures
71 // that any threads it spawns to execute the callbacks will not step on each other
72 // or on you, and that you will not be able to erase() a callback while it has
73 // activity scheduled against it. This also applies to the invocation method
74 // (operator ()) - you must lock against multiple accesses to it until it returns.
76 class ModuleCallbackSet
{
78 unsigned int size() const { return (int)callbacks
.size(); }
79 void insert(const ModuleCallback
&newCallback
);
80 void erase(const ModuleCallback
&oldCallback
);
82 void operator () (CSSM_MODULE_EVENT event
,
83 const Guid
&guid
, uint32 subId
,
84 CSSM_SERVICE_TYPE serviceType
) const;
87 // note mutex *: we don't want to rely on copy-ability of Mutex objects
88 typedef multimap
<ModuleCallback
, CountingMutex
*> CallbackMap
;
89 mutable CallbackMap callbacks
;
91 struct Runner
: public Thread
{
92 Runner(CallbackMap
&inCallbacks
,
93 CSSM_MODULE_EVENT inEvent
,
96 CSSM_SERVICE_TYPE inServiceType
)
97 : callbacks(inCallbacks
), event(inEvent
), guid(inGuid
),
98 subserviceId(inSSId
), serviceType(inServiceType
) { }
100 CallbackMap callbacks
; // note that we share the CountingMutex * values!
101 const CSSM_MODULE_EVENT event
;
103 const uint32 subserviceId
;
104 const CSSM_SERVICE_TYPE serviceType
;
110 } // end namespace Security