1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
// --------------------------------------------------------------------------
//
// File
// Name: WaitForEvent.h
// Purpose: Generic waiting for events, using an efficient method (platform dependent)
// Created: 9/3/04
//
// --------------------------------------------------------------------------
#ifndef WAITFOREVENT__H
#define WAITFOREVENT__H
#include <cstdlib>
#ifdef HAVE_KQUEUE
#include <sys/event.h>
#include <sys/time.h>
#else
#include <vector>
#ifndef WIN32
#include <poll.h>
#endif
#endif
#include <cstdlib>
#include "CommonException.h"
#include "MemLeakFindOn.h"
class WaitForEvent
{
public:
WaitForEvent(int Timeout = TimeoutInfinite);
~WaitForEvent();
private:
// No copying.
WaitForEvent(const WaitForEvent &);
WaitForEvent &operator=(const WaitForEvent &);
public:
enum
{
TimeoutInfinite = -1
};
void SetTimeout(int Timeout = TimeoutInfinite);
void *Wait();
#ifndef HAVE_KQUEUE
typedef struct
{
int fd;
short events;
void *item;
} ItemInfo;
#endif
// --------------------------------------------------------------------------
//
// Function
// Name: WaitForEvent::Add(const Type &, int)
// Purpose: Adds an event to the list of items to wait on. The flags are passed to the object.
// Created: 9/3/04
//
// --------------------------------------------------------------------------
template<typename T>
void Add(const T *pItem, int Flags = 0)
{
ASSERT(pItem != 0);
#ifdef HAVE_KQUEUE
struct kevent e;
pItem->FillInKEvent(e, Flags);
// Fill in extra flags to say what to do
e.flags |= EV_ADD;
e.udata = (void*)pItem;
if(::kevent(mKQueue, &e, 1, NULL, 0, NULL) == -1)
{
THROW_EXCEPTION(CommonException, KEventErrorAdd)
}
#else
// Add item
ItemInfo i;
pItem->FillInPoll(i.fd, i.events, Flags);
i.item = (void*)pItem;
mItems.push_back(i);
// Delete any pre-prepared poll info, as it's now out of date
if(mpPollInfo != 0)
{
::free(mpPollInfo);
mpPollInfo = 0;
}
#endif
}
// --------------------------------------------------------------------------
//
// Function
// Name: WaitForEvent::Remove(const Type &, int)
// Purpose: Removes an event from the list of items to wait on. The flags are passed to the object.
// Created: 9/3/04
//
// --------------------------------------------------------------------------
template<typename T>
void Remove(const T *pItem, int Flags = 0)
{
ASSERT(pItem != 0);
#ifdef HAVE_KQUEUE
struct kevent e;
pItem->FillInKEvent(e, Flags);
// Fill in extra flags to say what to do
e.flags |= EV_DELETE;
e.udata = (void*)pItem;
if(::kevent(mKQueue, &e, 1, NULL, 0, NULL) == -1)
{
THROW_EXCEPTION(CommonException, KEventErrorRemove)
}
#else
if(mpPollInfo != 0)
{
::free(mpPollInfo);
mpPollInfo = 0;
}
for(std::vector<ItemInfo>::iterator i(mItems.begin()); i != mItems.end(); ++i)
{
if(i->item == pItem)
{
mItems.erase(i);
return;
}
}
#endif
}
private:
#ifdef HAVE_KQUEUE
int mKQueue;
struct timespec mTimeout;
struct timespec *mpTimeout;
#else
int mTimeout;
std::vector<ItemInfo> mItems;
struct pollfd *mpPollInfo;
#endif
};
#include "MemLeakFindOff.h"
#endif // WAITFOREVENT__H
|