2 * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
28 // EntropyManager - manage entropy on the system.
30 #include "notifications.h"
32 #include <securityd_client/ucspNotify.h>
35 Listener::ListenerMap
Listener::listeners
;
36 Mutex
Listener::setLock
;
39 Listener::Listener(Port port
, NotificationDomain dom
, NotificationMask evs
)
40 : domain(dom
), events(evs
), mPort(port
)
43 Listener::Listener(NotificationDomain dom
, NotificationMask evs
)
44 : domain(dom
), events(evs
)
47 void Listener::setup()
49 assert(events
); // what's the point?
51 // register in listener set
52 StLock
<Mutex
> _(setLock
);
53 listeners
.insert(ListenerMap::value_type(mPort
, this));
58 secdebug("notify", "%p destroyed", this);
63 // Send a notification to all registered listeners
65 void Listener::notify(NotificationDomain domain
,
66 NotificationEvent event
, const CssmData
&data
)
68 for (ListenerMap::const_iterator it
= listeners
.begin();
69 it
!= listeners
.end(); it
++) {
70 Listener
*listener
= it
->second
;
71 if (listener
->domain
== domain
&& listener
->wants(event
))
72 listener
->notifyMe(domain
, event
, data
);
78 // Handle a port death or deallocation by removing all Listeners using that port.
79 // Returns true iff we had one.
81 bool Listener::remove(Port port
)
83 assert(port
); // Listeners with null ports are eternal
84 typedef ListenerMap::iterator Iterator
;
85 StLock
<Mutex
> _(setLock
);
86 pair
<Iterator
, Iterator
> range
= listeners
.equal_range(port
);
87 if (range
.first
== range
.second
)
88 return false; // not one of ours
90 for (Iterator it
= range
.first
; it
!= range
.second
; it
++)
92 listeners
.erase(range
.first
, range
.second
);
94 return true; // got it
99 // Construct a new Listener and hook it up
101 ProcessListener::ProcessListener(Process
&proc
, Port receiver
,
102 NotificationDomain dom
, NotificationMask evs
)
103 : Listener(receiver
, dom
, evs
), process(proc
)
105 // let's get told when the receiver port dies
106 Server::active().notifyIfDead(mPort
);
108 secdebug("notify", "%p created domain %ld events 0x%lx port %d",
109 this, domain
, events
, mPort
.port());
114 // Send a single notification for this listener
116 void ProcessListener::notifyMe(NotificationDomain domain
,
117 NotificationEvent event
, const CssmData
&data
)
119 secdebug("notify", "%p sending domain %ld event 0x%lx to port %d process %d",
120 this, domain
, event
, mPort
.port(), process
.pid());
122 // send mach message (via MIG simpleroutine)
123 if (IFDEBUG(kern_return_t rc
=) ucsp_notify_sender_notify(mPort
,
124 MACH_SEND_TIMEOUT
, 0,
125 domain
, event
, data
.data(), data
.length(),
126 0 /*@@@ placeholder for sender ID */))
127 secdebug("notify", "%p send failed (error=%d)", this, rc
);