From 554e14934e46f11fcec09d5c69bff5d231db2ea9 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 14 Jan 2009 20:52:32 +0000 Subject: [PATCH] Move per-fd info from eventops into evmap. Not done for win32.c yet. svn:r1008 --- devpoll.c | 11 ++++++---- epoll.c | 11 ++++++---- event-internal.h | 5 +++-- evmap-internal.h | 2 ++ evmap.c | 55 +++++++++++++++++++++++++++++----------------- evport.c | 13 ++++++----- kqueue.c | 12 ++++++---- poll.c | 57 ++++++++++++++++++------------------------------ select.c | 11 ++++++---- signal.c | 11 +++++----- 10 files changed, 104 insertions(+), 84 deletions(-) diff --git a/devpoll.c b/devpoll.c index 0b226e8c..36b29b0a 100644 --- a/devpoll.c +++ b/devpoll.c @@ -62,8 +62,8 @@ struct devpollop { }; 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 *); @@ -76,6 +76,7 @@ const struct eventop devpollops = { devpoll_dealloc, 1, /* need reinit */ EV_FEATURE_FDS|EV_FEATURE_O1, + 0 }; #define NEVENT 32000 @@ -228,11 +229,12 @@ devpoll_dispatch(struct event_base *base, struct timeval *tv) 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 @@ -254,12 +256,13 @@ devpoll_add(struct event_base *base, int fd, short old, short events) } 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) diff --git a/epoll.c b/epoll.c index db0d4d7a..b2369c58 100644 --- a/epoll.c +++ b/epoll.c @@ -60,8 +60,8 @@ struct epollop { }; 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 *); @@ -74,6 +74,7 @@ const struct eventop epollops = { epoll_dealloc, 1, /* need reinit */ EV_FEATURE_ET|EV_FEATURE_O1, + 0 }; #ifdef HAVE_SETFD @@ -195,11 +196,12 @@ epoll_dispatch(struct event_base *base, struct timeval *tv) } 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; @@ -224,11 +226,12 @@ epoll_add(struct event_base *base, int fd, short old, short events) } 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; diff --git a/event-internal.h b/event-internal.h index f0de2ebe..9e879baf 100644 --- a/event-internal.h +++ b/event-internal.h @@ -49,13 +49,14 @@ extern "C" { 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 diff --git a/evmap-internal.h b/evmap-internal.h index 89ee872b..3afeb72f 100644 --- a/evmap-internal.h +++ b/evmap-internal.h @@ -79,4 +79,6 @@ int evmap_signal_add(struct event_base *base, int signum, struct event *ev); 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_ */ diff --git a/evmap.c b/evmap.c index bcbe8b3b..ec312dc6 100644 --- a/evmap.c +++ b/evmap.c @@ -113,10 +113,10 @@ HT_GENERATE(event_io_map, event_map_entry, map_node, hashsocket, eqsocket, 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; \ @@ -126,7 +126,7 @@ HT_GENERATE(event_io_map, event_map_entry, map_node, hashsocket, eqsocket, _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); \ @@ -160,23 +160,24 @@ void evmap_io_clear(struct event_io_map *ctx) 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) { @@ -271,7 +272,8 @@ evmap_io_add(struct event_base *base, int fd, struct event *ev) 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; @@ -291,11 +293,12 @@ evmap_io_add(struct event_base *base, int fd, struct event *ev) } 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); } @@ -346,7 +349,8 @@ evmap_io_del(struct event_base *base, int fd, struct event *ev) } 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); } @@ -397,10 +401,10 @@ evmap_signal_add(struct event_base *base, int sig, struct event *ev) 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); } @@ -422,7 +426,7 @@ evmap_signal_del(struct event_base *base, int sig, struct event *ev) 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); } @@ -444,3 +448,14 @@ evmap_signal_active(struct event_base *base, int sig, int ncalls) 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; +} diff --git a/evport.c b/evport.c index e4f9bba5..55876c89 100644 --- a/evport.c +++ b/evport.c @@ -114,8 +114,8 @@ struct evport_data { }; 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 *); @@ -126,7 +126,8 @@ const struct eventop evportops = { evport_del, evport_dispatch, evport_dealloc, - 1 /* need reinit */ + 1, /* need reinit */ + 0 }; /* @@ -358,11 +359,12 @@ evport_dispatch(struct event_base *base, struct timeval *tv) */ 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); @@ -391,12 +393,13 @@ evport_add(struct event_base *base, int fd, short old, short events) */ 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); diff --git a/kqueue.c b/kqueue.c index 4f02ce56..f52be66d 100644 --- a/kqueue.c +++ b/kqueue.c @@ -74,8 +74,8 @@ struct kqop { }; 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 *); @@ -91,6 +91,7 @@ const struct eventop kqops = { kq_dealloc, 1 /* need reinit */, EV_FEATURE_ET|EV_FEATURE_O1|EV_FEATURE_FDS, + 0 }; static const struct eventop kqsigops = { @@ -101,6 +102,7 @@ static const struct eventop kqsigops = { NULL, NULL, 1 /* need reinit */, + 0, 0 }; @@ -292,10 +294,11 @@ kq_dispatch(struct event_base *base, struct timeval *tv) 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)); @@ -329,10 +332,11 @@ kq_add(struct event_base *base, int fd, short old, short events) } 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)); diff --git a/poll.c b/poll.c index e2752370..f5dd9b56 100644 --- a/poll.c +++ b/poll.c @@ -51,19 +51,19 @@ #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 *); @@ -76,6 +76,7 @@ const struct eventop pollops = { poll_dealloc, 0, /* doesn't need_reinit */ EV_FEATURE_FDS, + sizeof(struct pollidx), }; static void * @@ -168,10 +169,11 @@ poll_dispatch(struct event_base *base, struct timeval *tv) } 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); @@ -199,28 +201,9 @@ poll_add(struct event_base *base, int fd, short old, short events) 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 { @@ -228,7 +211,7 @@ poll_add(struct event_base *base, int fd, short old, short events) 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; @@ -246,10 +229,11 @@ poll_add(struct event_base *base, int fd, short old, short events) */ 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); @@ -257,7 +241,7 @@ poll_del(struct event_base *base, int fd, short old, short events) return (0); poll_check_ok(pop); - i = pop->idxplus1_by_fd[fd] - 1; + i = idx->idxplus1 - 1; if (i < 0) return (-1); @@ -273,17 +257,20 @@ poll_del(struct event_base *base, int fd, short old, short events) 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); @@ -298,8 +285,6 @@ poll_dealloc(struct event_base *base) 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); diff --git a/select.c b/select.c index bc753237..76974798 100644 --- a/select.c +++ b/select.c @@ -67,8 +67,8 @@ struct selectop { }; 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 *); @@ -81,6 +81,7 @@ const struct eventop selectops = { select_dealloc, 0, /* doesn't need reinit. */ EV_FEATURE_FDS, + 0, }; static int select_resize(struct selectop *sop, int fdsz); @@ -207,9 +208,10 @@ 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); @@ -251,9 +253,10 @@ select_add(struct event_base *base, int fd, short old, short events) */ 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); diff --git a/signal.c b/signal.c index dc432fdd..4cbacd4c 100644 --- a/signal.c +++ b/signal.c @@ -65,8 +65,8 @@ #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", @@ -75,7 +75,7 @@ static const struct eventop evsigops = { evsig_del, NULL, NULL, - 0, 0 + 0, 0, 0 }; struct event_base *evsig_base = NULL; @@ -205,9 +205,10 @@ _evsig_set_handler(struct event_base *base, } 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); @@ -259,7 +260,7 @@ _evsig_restore_handler(struct event_base *base, int evsignal) } 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);