]> git.saurik.com Git - apple/security.git/blob - SecurityServer/notifications.cpp
Security-179.tar.gz
[apple/security.git] / SecurityServer / notifications.cpp
1 /*
2 * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
3 *
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
8 * using this file.
9 *
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.
16 */
17
18
19 //
20 // EntropyManager - manage entropy on the system.
21 //
22 #include "notifications.h"
23 #include "server.h"
24 #include "ucspNotify.h"
25
26
27 Listener::ListenerMap Listener::listeners;
28 Mutex Listener::setLock;
29
30
31 //
32 // Construct a new Listener and hook it up
33 //
34 Listener::Listener(Process &proc, Port receiver, Domain dom, EventMask evs)
35 : process(proc), domain(dom), events(evs), mNotificationPort(receiver)
36 {
37 assert(events); // what's the point?
38
39 // register in listener set
40 StLock<Mutex> _(setLock);
41 listeners.insert(ListenerMap::value_type(receiver, this));
42
43 // let's get told when the receiver port dies
44 Server::active().notifyIfDead(receiver);
45
46 secdebug("notify", "%p created domain %ld events 0x%lx port %d",
47 this, domain, events, mNotificationPort.port());
48 }
49
50
51 //
52 // Destroy a listener. Cleans up.
53 //
54 Listener::~Listener()
55 {
56 secdebug("notify", "%p destroyed", this);
57 }
58
59
60 //
61 // Send a single notification for this listener
62 //
63 void Listener::notifyMe(Domain domain, Event event, const CssmData &data)
64 {
65 if (domain != this->domain || !(event & events))
66 return; // not interested
67
68 secdebug("notify", "%p sending domain %ld event 0x%lx to port %d process %d",
69 this, domain, event, mNotificationPort.port(), process.pid());
70
71 // send mach message (via MIG simpleroutine)
72 if (IFDEBUG(kern_return_t rc =) ucsp_notify_sender_notify(mNotificationPort,
73 MACH_SEND_TIMEOUT, 0,
74 domain, event, data.data(), data.length(),
75 0 /*@@@ placeholder for sender ID */))
76 secdebug("notify", "%p send failed (error=%d)", this, rc);
77 }
78
79
80 //
81 // Send a notification to all registered listeners
82 //
83 void Listener::notify(Domain domain, Event event, const CssmData &data)
84 {
85 for (ListenerMap::const_iterator it = listeners.begin();
86 it != listeners.end(); it++)
87 it->second->notifyMe(domain, event, data);
88 }
89
90
91 //
92 // Handle a port death or deallocation by removing all Listeners using that port.
93 // Returns true iff we had one.
94 //
95 bool Listener::remove(Port port)
96 {
97 typedef ListenerMap::iterator Iterator;
98 StLock<Mutex> _(setLock);
99 pair<Iterator, Iterator> range = listeners.equal_range(port);
100 if (range.first == range.second)
101 return false; // not one of ours
102
103 for (Iterator it = range.first; it != range.second; it++)
104 delete it->second;
105 listeners.erase(range.first, range.second);
106 port.destroy();
107 return true; // got it
108 }