#ifndef _H_SELECTOR
#define _H_SELECTOR
#include <Security/utilities.h>
#include <Security/fdsel.h>
#include "timeflow.h"
#include <sys/types.h>
#include <cstdio>
#include <cstdarg>
#include <map>
#include <Security/debugging.h>
namespace Security {
namespace UnixPlusPlus {
class Selector {
public:
class Client; friend class Client;
Selector();
virtual ~Selector();
void operator () (); void operator () (Time::Absolute stopTime);
void operator () (Time::Interval duration)
{ (*this)(Time::now() + duration); }
typedef unsigned int Type;
static const Type none = 0x00;
static const Type input = 0x01;
static const Type output = 0x02;
static const Type critical = 0x04;
static const Type all = input | output | critical;
public:
class Client {
public:
typedef Selector::Type Type;
friend class Selector;
Client() : mSelector(NULL) { }
virtual void notify(int fd, Type type) = 0;
virtual ~Client() { }
bool isActive() const { return mSelector != NULL; }
static const Type input = Selector::input;
static const Type output = Selector::output;
static const Type critical = Selector::critical;
protected:
void events(Type type) { mSelector->set(mFd, type); mEvents = type; }
Type events() const { return mEvents; }
void enable(Type type) { events(events() | type); }
void disable(Type type) { events(events() & ~type); }
template <class Sel> Sel &selectorAs()
{ assert(mSelector); return safer_cast<Sel &>(*mSelector); }
private:
int mFd;
Selector *mSelector;
Type mEvents;
};
void add(int fd, Client &client, Type type = all);
void remove(int fd);
bool isEmpty() const { return clientMap.empty(); }
private:
void set(int fd, Type type);
void singleStep(Time::Interval maxWait);
private:
unsigned int fdSetSize; int fdMin, fdMax; FDSet inSet, outSet, errSet;
private:
typedef map<int, Client *> ClientMap;
ClientMap clientMap;
};
} }
#endif //_H_SELECTOR