2 * Copyright (c) 2000-2004 Apple Computer, 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 // EntropyManager - manage entropy on the system.
28 #include "notifications.h"
30 #include <securityd_client/ucspNotify.h>
33 Listener::ListenerMap
Listener::listeners
;
34 Mutex
Listener::setLock
;
37 Listener::Listener(Port port
, NotificationDomain dom
, NotificationMask evs
)
38 : domain(dom
), events(evs
), mPort(port
)
41 Listener::Listener(NotificationDomain dom
, NotificationMask evs
)
42 : domain(dom
), events(evs
)
45 void Listener::setup()
47 assert(events
); // what's the point?
49 // register in listener set
50 StLock
<Mutex
> _(setLock
);
51 listeners
.insert(ListenerMap::value_type(mPort
, this));
56 secdebug("notify", "%p destroyed", this);
61 // Send a notification to all registered listeners
63 void Listener::notify(NotificationDomain domain
,
64 NotificationEvent event
, const CssmData
&data
)
66 for (ListenerMap::const_iterator it
= listeners
.begin();
67 it
!= listeners
.end(); it
++) {
68 Listener
*listener
= it
->second
;
69 if (listener
->domain
== domain
&& listener
->wants(event
))
70 listener
->notifyMe(domain
, event
, data
);
76 // Handle a port death or deallocation by removing all Listeners using that port.
77 // Returns true iff we had one.
79 bool Listener::remove(Port port
)
81 assert(port
); // Listeners with null ports are eternal
82 typedef ListenerMap::iterator Iterator
;
83 StLock
<Mutex
> _(setLock
);
84 pair
<Iterator
, Iterator
> range
= listeners
.equal_range(port
);
85 if (range
.first
== range
.second
)
86 return false; // not one of ours
88 for (Iterator it
= range
.first
; it
!= range
.second
; it
++)
90 listeners
.erase(range
.first
, range
.second
);
92 return true; // got it
97 // Construct a new Listener and hook it up
99 ProcessListener::ProcessListener(Process
&proc
, Port receiver
,
100 NotificationDomain dom
, NotificationMask evs
)
101 : Listener(receiver
, dom
, evs
), process(proc
)
103 // let's get told when the receiver port dies
104 Server::active().notifyIfDead(mPort
);
106 secdebug("notify", "%p created domain %ld events 0x%lx port %d",
107 this, domain
, events
, mPort
.port());
112 // Send a single notification for this listener
114 void ProcessListener::notifyMe(NotificationDomain domain
,
115 NotificationEvent event
, const CssmData
&data
)
117 secdebug("notify", "%p sending domain %ld event 0x%lx to port %d process %d",
118 this, domain
, event
, mPort
.port(), process
.pid());
120 // send mach message (via MIG simpleroutine)
121 if (IFDEBUG(kern_return_t rc
=) ucsp_notify_sender_notify(mPort
,
122 domain
, event
, data
.data(), data
.length(),
123 0 /*@@@ placeholder for sender ID */))
124 secdebug("notify", "%p send failed (error=%d)", this, rc
);