1/* 2 * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 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 11 * file. 12 * 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. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25// 26// notifications - handling of securityd-gated notification messages 27// 28#ifndef _H_NOTIFICATIONS 29#define _H_NOTIFICATIONS 30 31#include <security_utilities/mach++.h> 32#include <security_utilities/machserver.h> 33#include <security_utilities/globalizer.h> 34#include <securityd_client/ssclient.h> 35#include <map> 36#include <queue> 37 38#include "SharedMemoryServer.h" 39 40using MachPlusPlus::Port; 41using MachPlusPlus::MachServer; 42using SecurityServer::NotificationDomain; 43using SecurityServer::NotificationEvent; 44using SecurityServer::NotificationMask; 45 46class SharedMemoryListener; 47 48// 49// A registered receiver of notifications. 50// This is an abstract class; you must subclass to define notifyMe(). 51// 52// All Listeners in existence are collected in an internal map of ports to 53// Listener*s, which makes them eligible to have events delivered to them via 54// their notifyMe() method. There are (only) two viable lifetime management 55// strategies for your Listener subclass: 56// (1) Eternal: don't ever destroy your Listener. All is well. By convention, 57// such Listeners use the null port. 58// (2) Port-based: To get rid of your Listeners, call Listener::remove(port), 59// which will delete(!) all Listeners constructed with that port. 60// Except for the remove() functionality, Listener does not interpret the port. 61// 62// If you need another Listener lifetime management strategy, you will probably 63// have to change things around here. 64// 65class Listener: public RefCount { 66public: 67 Listener(NotificationDomain domain, NotificationMask events, 68 mach_port_t port = MACH_PORT_NULL); 69 virtual ~Listener(); 70 71 // inject an event into the notification system 72 static void notify(NotificationDomain domain, 73 NotificationEvent event, const CssmData &data); 74 static void notify(NotificationDomain domain, 75 NotificationEvent event, uint32 sequence, const CssmData &data); 76 static bool remove(Port port); 77 78 const NotificationDomain domain; 79 const NotificationMask events; 80 81 bool wants(NotificationEvent event) 82 { return (1 << event) & events; } 83 84protected: 85 class Notification : public RefCount { 86 public: 87 Notification(NotificationDomain domain, NotificationEvent event, 88 uint32 seq, const CssmData &data); 89 virtual ~Notification(); 90 91 const NotificationDomain domain; 92 const NotificationEvent event; 93 const uint32 sequence; 94 const CssmAutoData data; 95 96 size_t size() const 97 { return data.length(); } //@@@ add "slop" here for heuristic? 98 }; 99 100 virtual void notifyMe(Notification *message) = 0; 101 102public: 103 class JitterBuffer { 104 public: 105 JitterBuffer() : mNotifyLast(0) { } 106 107 bool inSequence(Notification *message); 108 RefPointer<Notification> popNotification(); 109 110 private: 111 uint32 mNotifyLast; // last notification seq processed 112 typedef std::map<uint32, RefPointer<Notification> > JBuffer; 113 JBuffer mBuffer; // early messages buffer 114 }; 115 116private: 117 static void sendNotification(Notification *message); 118 119private: 120 typedef multimap<mach_port_t, RefPointer<Listener> > ListenerMap; 121 static ListenerMap& listeners; 122 static Mutex setLock; 123}; 124 125 126 127class SharedMemoryListener : public Listener, public SharedMemoryServer, public Security::MachPlusPlus::MachServer::Timer 128{ 129protected: 130 virtual void action (); 131 virtual void notifyMe(Notification *message); 132 133 bool mActive; 134 135public: 136 SharedMemoryListener (const char* serverName, u_int32_t serverSize); 137 virtual ~SharedMemoryListener (); 138}; 139 140#endif 141