};
static void *devpoll_init (struct event_base *);
-static int devpoll_add(struct event_base *, int fd, short old, short events);
-static int devpoll_del(struct event_base *, int fd, short old, short events);
+static int devpoll_add(struct event_base *, int fd, short old, short events, void *);
+static int devpoll_del(struct event_base *, int fd, short old, short events, void *);
static int devpoll_dispatch (struct event_base *, struct timeval *);
static void devpoll_dealloc (struct event_base *);
devpoll_dealloc,
1, /* need reinit */
EV_FEATURE_FDS|EV_FEATURE_O1,
+ 0
};
#define NEVENT 32000
static int
-devpoll_add(struct event_base *base, int fd, short old, short events)
+devpoll_add(struct event_base *base, int fd, short old, short events, void *p)
{
struct devpollop *devpollop = base->evbase;
struct evdevpoll *evdp;
int events;
+ (void)p;
/*
* It's not necessary to OR the existing read/write events that we
}
static int
-devpoll_del(struct event_base *base, int fd, short old, short events)
+devpoll_del(struct event_base *base, int fd, short old, short events, void *p)
{
struct devpollop *devpollop = base->evbase;
struct evdevpoll *evdp;
int events;
int needwritedelete = 1, needreaddelete = 1;
+ (void)p;
events = 0;
if (events & EV_READ)
};
static void *epoll_init (struct event_base *);
-static int epoll_add(struct event_base *, int fd, short old, short events);
-static int epoll_del(struct event_base *, int fd, short old, short events);
+static int epoll_add(struct event_base *, int fd, short old, short events, void *);
+static int epoll_del(struct event_base *, int fd, short old, short events, void *);
static int epoll_dispatch (struct event_base *, struct timeval *);
static void epoll_dealloc (struct event_base *);
epoll_dealloc,
1, /* need reinit */
EV_FEATURE_ET|EV_FEATURE_O1,
+ 0
};
#ifdef HAVE_SETFD
}
static int
-epoll_add(struct event_base *base, int fd, short old, short events)
+epoll_add(struct event_base *base, int fd, short old, short events, void *p)
{
struct epollop *epollop = base->evbase;
struct epoll_event epev = {0, {0}};
int op, res;
+ (void)p;
op = EPOLL_CTL_ADD;
res = 0;
}
static int
-epoll_del(struct event_base *base, int fd, short old, short events)
+epoll_del(struct event_base *base, int fd, short old, short events, void *p)
{
struct epollop *epollop = base->evbase;
struct epoll_event epev = {0, {0}};
int res, op;
+ (void) p;
op = EPOLL_CTL_DEL;
struct eventop {
const char *name;
void *(*init)(struct event_base *);
- int (*add)(struct event_base *, evutil_socket_t fd, short old, short events);
- int (*del)(struct event_base *, evutil_socket_t fd, short old, short events);
+ int (*add)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo);
+ int (*del)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo);
int (*dispatch)(struct event_base *, struct timeval *);
void (*dealloc)(struct event_base *);
/* set if we need to reinitialize the event base */
int need_reinit;
enum event_method_feature features;
+ size_t fdinfo_len;
};
#ifdef WIN32
int evmap_signal_del(struct event_base *base, int signum, struct event *ev);
void evmap_signal_active(struct event_base *base, int fd, int ncalls);
+void *evmap_io_get_fdinfo(struct event_io_map *ctx, evutil_socket_t fd);
+
#endif /* _EVMAP_H_ */
struct event_map_entry _key, *_ent; \
_key.fd = slot; \
_ent = HT_FIND(event_io_map, map, &_key); \
- (x) = &_ent->ent.type; \
+ (x) = _ent ? &_ent->ent.type : NULL; \
} while (0);
-#define GET_IO_SLOT_AND_CTOR(x, map, slot, type, ctor) \
+#define GET_IO_SLOT_AND_CTOR(x, map, slot, type, ctor, fdinfo_len) \
do { \
struct event_map_entry _key, *_ent; \
_key.fd = slot; \
_ent = *ptr; \
}, \
{ \
- _ent = mm_malloc(sizeof(struct event_map_entry)); \
+ _ent = mm_calloc(1,sizeof(struct event_map_entry)+fdinfo_len); \
assert(_ent); \
_ent->fd = slot; \
(ctor)(&_ent->ent.type); \
by allocating enough memory for a 'struct type', and initializing the new
value by calling the function 'ctor' on it.
*/
-#define GET_SIGNAL_SLOT_AND_CTOR(x, map, slot, type, ctor) \
- do { \
- if ((map)->entries[slot] == NULL) { \
- assert(ctor != NULL); \
- (map)->entries[slot]=mm_malloc(sizeof(struct type)); \
- assert((map)->entries[slot] != NULL); \
- (ctor)((struct type *)(map)->entries[slot]); \
- } \
- (x) = (struct type *)((map)->entries[slot]); \
+#define GET_SIGNAL_SLOT_AND_CTOR(x, map, slot, type, ctor, fdinfo_len) \
+ do { \
+ if ((map)->entries[slot] == NULL) { \
+ assert(ctor != NULL); \
+ (map)->entries[slot]=mm_calloc(1,sizeof(struct type)+fdinfo_len);\
+ assert((map)->entries[slot] != NULL); \
+ (ctor)((struct type *)(map)->entries[slot]); \
+ } \
+ (x) = (struct type *)((map)->entries[slot]); \
} while (0)
/* If we aren't using hashtables, then define the IO_SLOT macros and functions
as thin aliases over the SIGNAL_SLOT versions. */
#ifndef EVMAP_USE_HT
#define GET_IO_SLOT(x,map,slot,type) GET_SIGNAL_SLOT(x,map,slot,type)
-#define GET_IO_SLOT_AND_CTOR(x,map,slot,type,ctor) \
- GET_SIGNAL_SLOT_AND_CTOR(x,map,slot,type,ctor)
+#define GET_IO_SLOT_AND_CTOR(x,map,slot,type,ctor,fdinfo_len) \
+ GET_SIGNAL_SLOT_AND_CTOR(x,map,slot,type,ctor,fdinfo_len)
+#define FDINFO_OFFSET sizeof(struct evmap_io)
void
evmap_io_initmap(struct event_io_map* ctx)
{
return (-1);
}
#endif
- GET_IO_SLOT_AND_CTOR(ctx, io, fd, evmap_io, evmap_io_init);
+ GET_IO_SLOT_AND_CTOR(ctx, io, fd, evmap_io, evmap_io_init,
+ evsel->fdinfo_len);
nread = ctx->nread;
nwrite = ctx->nwrite;
}
if (res) {
+ void *extra = ((char*)ctx) + sizeof(struct evmap_io);
/* XXX(niels): we cannot mix edge-triggered and
* level-triggered, we should probably assert on
* this. */
if (evsel->add(base, ev->ev_fd,
- old, (ev->ev_events & EV_ET) | res) == -1)
+ old, (ev->ev_events & EV_ET) | res, extra) == -1)
return (-1);
}
}
if (res) {
- if (evsel->del(base, ev->ev_fd, old, res) == -1)
+ void *extra = ((char*)ctx) + sizeof(struct evmap_io);
+ if (evsel->del(base, ev->ev_fd, old, res, extra) == -1)
return (-1);
}
map, sig, sizeof(struct evmap_signal *)) == -1)
return (-1);
}
- GET_SIGNAL_SLOT_AND_CTOR(ctx, map, sig, evmap_signal, evmap_signal_init);
+ GET_SIGNAL_SLOT_AND_CTOR(ctx, map, sig, evmap_signal, evmap_signal_init, 0);
if (TAILQ_EMPTY(&ctx->events)) {
- if (evsel->add(base, EVENT_SIGNAL(ev), 0, EV_SIGNAL) == -1)
+ if (evsel->add(base, EVENT_SIGNAL(ev), 0, EV_SIGNAL, NULL) == -1)
return (-1);
}
GET_SIGNAL_SLOT(ctx, map, sig, evmap_signal);
if (TAILQ_FIRST(&ctx->events) == TAILQ_LAST(&ctx->events, event_list)) {
- if (evsel->del(base, EVENT_SIGNAL(ev), 0, EV_SIGNAL) == -1)
+ if (evsel->del(base, EVENT_SIGNAL(ev), 0, EV_SIGNAL, NULL) == -1)
return (-1);
}
TAILQ_FOREACH(ev, &ctx->events, ev_signal_next)
event_active(ev, EV_SIGNAL, ncalls);
}
+
+void *
+evmap_io_get_fdinfo(struct event_io_map *map, evutil_socket_t fd)
+{
+ struct evmap_io *ctx;
+ GET_IO_SLOT(ctx, map, fd, evmap_io);
+ if (ctx)
+ return ((char*)ctx) + sizeof(struct evmap_io);
+ else
+ return NULL;
+}
};
static void* evport_init (struct event_base *);
-static int evport_add(struct event_base *, int fd, short old, short events);
-static int evport_del(struct event_base *, int fd, short old, short events);
+static int evport_add(struct event_base *, int fd, short old, short events, void *);
+static int evport_del(struct event_base *, int fd, short old, short events, void *);
static int evport_dispatch (struct event_base *, struct timeval *);
static void evport_dealloc (struct event_base *);
evport_del,
evport_dispatch,
evport_dealloc,
- 1 /* need reinit */
+ 1, /* need reinit */
+ 0
};
/*
*/
static int
-evport_add(struct event_base *base, int fd, short old, short events)
+evport_add(struct event_base *base, int fd, short old, short events, void *p)
{
struct evport_data *evpd = base->evbase;
struct fd_info *fdi;
int factor;
+ (void)p;
check_evportop(evpd);
*/
static int
-evport_del(struct event_base *base, int fd, short old, short events)
+evport_del(struct event_base *base, int fd, short old, short events, void *p)
{
struct evport_data *evpd = base->evbase;
struct fd_info *fdi;
int i;
int associated = 1;
+ (void)p;
check_evportop(evpd);
};
static void *kq_init (struct event_base *);
-static int kq_add (struct event_base *, int, short, short);
-static int kq_del (struct event_base *, int, short, short);
+static int kq_add (struct event_base *, int, short, short, void *);
+static int kq_del (struct event_base *, int, short, short, void *);
static int kq_sig_add (struct event_base *, int, short, short);
static int kq_sig_del (struct event_base *, int, short, short);
static int kq_dispatch (struct event_base *, struct timeval *);
kq_dealloc,
1 /* need reinit */,
EV_FEATURE_ET|EV_FEATURE_O1|EV_FEATURE_FDS,
+ 0
};
static const struct eventop kqsigops = {
NULL,
NULL,
1 /* need reinit */,
+ 0,
0
};
static int
-kq_add(struct event_base *base, int fd, short old, short events)
+kq_add(struct event_base *base, int fd, short old, short events, void *p)
{
struct kqop *kqop = base->evbase;
struct kevent kev;
+ (void) p;
if (events & EV_READ) {
memset(&kev, 0, sizeof(kev));
}
static int
-kq_del(struct event_base *base, int fd, short old, short events)
+kq_del(struct event_base *base, int fd, short old, short events, void *p)
{
struct kqop *kqop = base->evbase;
struct kevent kev;
+ (void) p;
if (events & EV_READ) {
memset(&kev, 0, sizeof(kev));
#include "log-internal.h"
#include "evmap-internal.h"
+struct pollidx {
+ int idxplus1;
+};
+
struct pollop {
int event_count; /* Highest number alloc */
int nfds; /* Size of event_* */
- int fd_count; /* Size of idxplus1_by_fd */
struct pollfd *event_set;
- int *idxplus1_by_fd; /* Index into event_set by fd; we add 1 so
- * that 0 (which is easy to memset) can mean
- * "no entry." */
};
static void *poll_init (struct event_base *);
-static int poll_add(struct event_base *, int, short old, short events);
-static int poll_del(struct event_base *, int, short old, short events);
+static int poll_add(struct event_base *, int, short old, short events, void *_idx);
+static int poll_del(struct event_base *, int, short old, short events, void *_idx);
static int poll_dispatch (struct event_base *, struct timeval *);
static void poll_dealloc (struct event_base *);
poll_dealloc,
0, /* doesn't need_reinit */
EV_FEATURE_FDS,
+ sizeof(struct pollidx),
};
static void *
}
static int
-poll_add(struct event_base *base, int fd, short old, short events)
+poll_add(struct event_base *base, int fd, short old, short events, void *_idx)
{
struct pollop *pop = base->evbase;
struct pollfd *pfd = NULL;
+ struct pollidx *idx = _idx;
int i;
assert((events & EV_SIGNAL) == 0);
pop->event_count = tmp_event_count;
}
- if (fd >= pop->fd_count) {
- int *tmp_idxplus1_by_fd;
- int new_count;
- if (pop->fd_count < 32)
- new_count = 32;
- else
- new_count = pop->fd_count * 2;
- while (new_count <= fd)
- new_count *= 2;
- tmp_idxplus1_by_fd =
- mm_realloc(pop->idxplus1_by_fd, new_count * sizeof(int));
- if (tmp_idxplus1_by_fd == NULL) {
- event_warn("realloc");
- return (-1);
- }
- pop->idxplus1_by_fd = tmp_idxplus1_by_fd;
- memset(pop->idxplus1_by_fd + pop->fd_count,
- 0, sizeof(int)*(new_count - pop->fd_count));
- pop->fd_count = new_count;
- }
- i = pop->idxplus1_by_fd[fd] - 1;
+ i = idx->idxplus1 - 1;
+
if (i >= 0) {
pfd = &pop->event_set[i];
} else {
pfd = &pop->event_set[i];
pfd->events = 0;
pfd->fd = fd;
- pop->idxplus1_by_fd[fd] = i + 1;
+ idx->idxplus1 = i + 1;
}
pfd->revents = 0;
*/
static int
-poll_del(struct event_base *base, int fd, short old, short events)
+poll_del(struct event_base *base, int fd, short old, short events, void *_idx)
{
struct pollop *pop = base->evbase;
struct pollfd *pfd = NULL;
+ struct pollidx *idx = _idx;
int i;
assert((events & EV_SIGNAL) == 0);
return (0);
poll_check_ok(pop);
- i = pop->idxplus1_by_fd[fd] - 1;
+ i = idx->idxplus1 - 1;
if (i < 0)
return (-1);
return (0);
/* Okay, so we aren't interested in that fd anymore. */
- pop->idxplus1_by_fd[fd] = 0;
+ idx->idxplus1 = 0;
--pop->nfds;
if (i != pop->nfds) {
- /*
+ /*
* Shift the last pollfd down into the now-unoccupied
* position.
*/
memcpy(&pop->event_set[i], &pop->event_set[pop->nfds],
sizeof(struct pollfd));
- pop->idxplus1_by_fd[pop->event_set[i].fd] = i + 1;
+ idx = evmap_io_get_fdinfo(&base->io, pop->event_set[i].fd);
+ assert(idx);
+ assert(idx->idxplus1 == pop->nfds + 1);
+ idx->idxplus1 = i + 1;
}
poll_check_ok(pop);
evsig_dealloc(base);
if (pop->event_set)
mm_free(pop->event_set);
- if (pop->idxplus1_by_fd)
- mm_free(pop->idxplus1_by_fd);
memset(pop, 0, sizeof(struct pollop));
mm_free(pop);
};
static void *select_init (struct event_base *);
-static int select_add(struct event_base *, int, short old, short events);
-static int select_del(struct event_base *, int, short old, short events);
+static int select_add(struct event_base *, int, short old, short events, void*);
+static int select_del(struct event_base *, int, short old, short events, void*);
static int select_dispatch (struct event_base *, struct timeval *);
static void select_dealloc (struct event_base *);
select_dealloc,
0, /* doesn't need reinit. */
EV_FEATURE_FDS,
+ 0,
};
static int select_resize(struct selectop *sop, int fdsz);
static int
-select_add(struct event_base *base, int fd, short old, short events)
+select_add(struct event_base *base, int fd, short old, short events, void *p)
{
struct selectop *sop = base->evbase;
+ (void) p;
assert((events & EV_SIGNAL) == 0);
check_selectop(sop);
*/
static int
-select_del(struct event_base *base, int fd, short old, short events)
+select_del(struct event_base *base, int fd, short old, short events, void *p)
{
struct selectop *sop = base->evbase;
+ (void)p;
assert((events & EV_SIGNAL) == 0);
check_selectop(sop);
#include "log-internal.h"
#include "evmap-internal.h"
-static int evsig_add(struct event_base *, int, short, short);
-static int evsig_del(struct event_base *, int, short, short);
+static int evsig_add(struct event_base *, int, short, short, void *);
+static int evsig_del(struct event_base *, int, short, short, void *);
static const struct eventop evsigops = {
"signal",
evsig_del,
NULL,
NULL,
- 0, 0
+ 0, 0, 0
};
struct event_base *evsig_base = NULL;
}
static int
-evsig_add(struct event_base *base, int evsignal, short old, short events)
+evsig_add(struct event_base *base, int evsignal, short old, short events, void *p)
{
struct evsig_info *sig = &base->sig;
+ (void)p;
assert(evsignal >= 0 && evsignal < NSIG);
}
static int
-evsig_del(struct event_base *base, int evsignal, short old, short events)
+evsig_del(struct event_base *base, int evsignal, short old, short events, void *p)
{
assert(evsignal >= 0 && evsignal < NSIG);