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>
32 Listener::ListenerMap
Listener::listeners
;
33 Mutex
Listener::setLock
;
36 Listener::Listener(Port port
, NotificationDomain dom
, NotificationMask evs
)
37 : domain(dom
), events(evs
), mPort(port
)
40 Listener::Listener(NotificationDomain dom
, NotificationMask evs
)
41 : domain(dom
), events(evs
)
44 void Listener::setup()
46 assert(events
); // what's the point?
48 // register in listener set
49 StLock
<Mutex
> _(setLock
);
50 listeners
.insert(ListenerMap::value_type(mPort
, this));
55 secdebug("notify", "%p destroyed", this);
60 // Send a notification to all registered listeners
62 void Listener::notify(NotificationDomain domain
,
63 NotificationEvent event
, const CssmData
&data
)
65 for (ListenerMap::const_iterator it
= listeners
.begin();
66 it
!= listeners
.end(); it
++) {
67 Listener
*listener
= it
->second
;
68 if (listener
->domain
== domain
&& listener
->wants(event
))
69 listener
->notifyMe(domain
, event
, data
);
75 // Handle a port death or deallocation by removing all Listeners using that port.
76 // Returns true iff we had one.
78 bool Listener::remove(Port port
)
80 assert(port
); // Listeners with null ports are eternal
81 typedef ListenerMap::iterator Iterator
;
82 StLock
<Mutex
> _(setLock
);
83 pair
<Iterator
, Iterator
> range
= listeners
.equal_range(port
);
84 if (range
.first
== range
.second
)
85 return false; // not one of ours
87 for (Iterator it
= range
.first
; it
!= range
.second
; it
++)
89 listeners
.erase(range
.first
, range
.second
);
91 return true; // got it
96 // Construct a new Listener and hook it up
98 ProcessListener::ProcessListener(Process
&proc
, Port receiver
,
99 NotificationDomain dom
, NotificationMask evs
)
100 : Listener(receiver
, dom
, evs
), process(proc
)
102 // let's get told when the receiver port dies
103 Server::active().notifyIfDead(mPort
);
105 secdebug("notify", "%p created domain %ld events 0x%lx port %d",
106 this, domain
, events
, mPort
.port());
111 // Send a single notification for this listener
113 void ProcessListener::notifyMe(NotificationDomain domain
,
114 NotificationEvent event
, const CssmData
&data
)
116 secdebug("notify", "%p sending domain %ld event 0x%lx to port %d process %d",
117 this, domain
, event
, mPort
.port(), process
.pid());
119 // send mach message (via MIG simpleroutine)
120 if (IFDEBUG(kern_return_t rc
=) ucsp_notify_sender_notify(mPort
,
121 domain
, event
, data
.data(), data
.length(),
122 0 /*@@@ placeholder for sender ID */))
123 secdebug("notify", "%p send failed (error=%d)", this, rc
);