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// selector - I/O stream multiplexing 27// 28#ifndef _H_SELECTOR 29#define _H_SELECTOR 30 31#include <security_utilities/utilities.h> 32#include <security_utilities/fdsel.h> 33#include "timeflow.h" 34#include <sys/types.h> 35#include <cstdio> 36#include <cstdarg> 37#include <map> 38#include <security_utilities/debugging.h> 39 40 41namespace Security { 42namespace UnixPlusPlus { 43 44 45// 46// A Selector is an I/O dispatch facility that can supervise any number of "file descriptors", 47// each of which can perform I/O. Obviously this is geared towards the UNIX facility. 48// 49class Selector { 50public: 51 class Client; friend class Client; 52 53 Selector(); 54 virtual ~Selector(); 55 56 //@@@ preliminary interface 57 void operator () (); // run just once (now) 58 void operator () (Time::Absolute stopTime); 59 void operator () (Time::Interval duration) 60 { (*this)(Time::now() + duration); } 61 62 typedef unsigned int Type; 63 static const Type none = 0x00; 64 static const Type input = 0x01; 65 static const Type output = 0x02; 66 static const Type critical = 0x04; 67 static const Type all = input | output | critical; 68 69public: 70 class Client { 71 public: 72 typedef Selector::Type Type; 73 friend class Selector; 74 75 Client() : mSelector(NULL) { } 76 virtual void notify(int fd, Type type) = 0; 77 virtual ~Client() { } 78 79 bool isActive() const { return mSelector != NULL; } 80 81 static const Type input = Selector::input; 82 static const Type output = Selector::output; 83 static const Type critical = Selector::critical; 84 85 protected: 86 void events(Type type) { mSelector->set(mFd, type); mEvents = type; } 87 Type events() const { return mEvents; } 88 89 void enable(Type type) { events(events() | type); } 90 void disable(Type type) { events(events() & ~type); } 91 92 template <class Sel> Sel &selectorAs() 93 { assert(mSelector); return safer_cast<Sel &>(*mSelector); } 94 95 private: 96 int mFd; 97 Selector *mSelector; 98 Type mEvents; 99 }; 100 101 void add(int fd, Client &client, Type type = all); 102 void remove(int fd); 103 bool isEmpty() const { return clientMap.empty(); } 104 105private: 106 void set(int fd, Type type); // (re)set mask for one client 107 108 void singleStep(Time::Interval maxWait); 109 110private: 111 unsigned int fdSetSize; // number of fd_masks allocated in FDSets 112 int fdMin, fdMax; // highest/lowest fds in use 113 FDSet inSet, outSet, errSet; // current in/out/error select masks 114 115private: 116 typedef map<int, Client *> ClientMap; 117 ClientMap clientMap; 118}; 119 120 121} // end namespace UnixPlusPlus 122} // end namespace Security 123 124 125#endif //_H_SELECTOR 126