#include "notifications.h"
#include "server.h"
#include "ucspNotify.h"
Listener::ListenerMap Listener::listeners;
Mutex Listener::setLock;
Listener::Listener(Process &proc, Port receiver, Domain dom, EventMask evs)
: process(proc), domain(dom), events(evs), mNotificationPort(receiver)
{
assert(events);
StLock<Mutex> _(setLock);
listeners.insert(ListenerMap::value_type(receiver, this));
Server::active().notifyIfDead(receiver);
secdebug("notify", "%p created domain %ld events 0x%lx port %d",
this, domain, events, mNotificationPort.port());
}
Listener::~Listener()
{
secdebug("notify", "%p destroyed", this);
}
void Listener::notifyMe(Domain domain, Event event, const CssmData &data)
{
if (domain != this->domain || !(event & events))
return;
secdebug("notify", "%p sending domain %ld event 0x%lx to port %d process %d",
this, domain, event, mNotificationPort.port(), process.pid());
if (IFDEBUG(kern_return_t rc =) ucsp_notify_sender_notify(mNotificationPort,
MACH_SEND_TIMEOUT, 0,
domain, event, data.data(), data.length(),
0 ))
secdebug("notify", "%p send failed (error=%d)", this, rc);
}
void Listener::notify(Domain domain, Event event, const CssmData &data)
{
for (ListenerMap::const_iterator it = listeners.begin();
it != listeners.end(); it++)
it->second->notifyMe(domain, event, data);
}
bool Listener::remove(Port port)
{
typedef ListenerMap::iterator Iterator;
StLock<Mutex> _(setLock);
pair<Iterator, Iterator> range = listeners.equal_range(port);
if (range.first == range.second)
return false;
for (Iterator it = range.first; it != range.second; it++)
delete it->second;
listeners.erase(range.first, range.second);
port.destroy();
return true; }