From 2e8051f593abd20b961e85c3f99dfa0ac0ee375d Mon Sep 17 00:00:00 2001 From: Niels Provos Date: Tue, 28 Mar 2006 04:40:54 +0000 Subject: [PATCH] introduce a way to free the base from Nick Mathewson svn:r210 --- WIN32-Code/win32.c | 25 ++++++++++++++++++++++++- devpoll.c | 22 +++++++++++++++++++++- epoll.c | 20 +++++++++++++++++++- event.c | 27 +++++++++++++++++++++++++++ event.h | 2 ++ kqueue.c | 19 ++++++++++++++++++- poll.c | 22 +++++++++++++++++++++- select.c | 26 +++++++++++++++++++++++++- 8 files changed, 157 insertions(+), 6 deletions(-) diff --git a/WIN32-Code/win32.c b/WIN32-Code/win32.c index 90a663a5..1978bcae 100644 --- a/WIN32-Code/win32.c +++ b/WIN32-Code/win32.c @@ -81,6 +81,7 @@ int win32_insert (void *, struct event *); int win32_del (void *, struct event *); int win32_recalc (struct event_base *base, void *, int); int win32_dispatch (struct event_base *base, void *, struct timeval *); +void win32_dealloc (void *); struct eventop win32ops = { "win32", @@ -88,7 +89,8 @@ struct eventop win32ops = { win32_insert, win32_del, win32_recalc, - win32_dispatch + win32_dispatch, + win32_dealloc }; #define FD_SET_ALLOC_SIZE(n) ((sizeof(struct win_fd_set) + ((n)-1)*sizeof(SOCKET))) @@ -365,6 +367,27 @@ win32_dispatch(struct event_base *base, struct win32op *win32op, return (0); } +void +win32_dealloc(void *arg) +{ + struct win32op *win32op = arg; + + if (win32op->readset_in) + free(win32op->readset_in); + if (win32op->writeset_in) + free(win32op->writeset_in); + if (win32op->readset_out) + free(win32op->readset_out); + if (win32op->writeset_out) + free(win32op->writeset_out); + if (win32op->exset_out) + free(win32op->exset_out); + if (win32op->events) + free(win32op->events); + + memset(win32op, 0, sizeof(win32op)); + free(win32op); +} static int signal_handler(int sig) diff --git a/devpoll.c b/devpoll.c index 68def058..b4cdae27 100644 --- a/devpoll.c +++ b/devpoll.c @@ -76,6 +76,7 @@ int devpoll_add (void *, struct event *); int devpoll_del (void *, struct event *); int devpoll_recalc (struct event_base *, void *, int); int devpoll_dispatch (struct event_base *, void *, struct timeval *); +void devpoll_dealloc (void *); struct eventop devpollops = { "devpoll", @@ -83,7 +84,8 @@ struct eventop devpollops = { devpoll_add, devpoll_del, devpoll_recalc, - devpoll_dispatch + devpoll_dispatch, + devpoll_dealloc }; #define NEVENT 32000 @@ -401,3 +403,21 @@ devpoll_del(void *arg, struct event *ev) return (0); } + +void +devpoll_dealloc(void *arg) +{ + struct devpollop *devpollop = arg; + + if (devpollop->fds) + free(devpollop->fds); + if (devpollop->events) + free(devpollop->events); + if (devpollop->changes) + free(devpollop->changes); + if (devpollop->dpfd >= 0) + close(devpollop->dpfd); + + memset(devpollop, 0, sizeof(struct devpollop)); + free(devpollop); +} diff --git a/epoll.c b/epoll.c index bdab078b..19a88a1f 100644 --- a/epoll.c +++ b/epoll.c @@ -76,6 +76,7 @@ int epoll_add (void *, struct event *); int epoll_del (void *, struct event *); int epoll_recalc (struct event_base *, void *, int); int epoll_dispatch (struct event_base *, void *, struct timeval *); +void epoll_dealloc (void *); struct eventop epollops = { "epoll", @@ -83,7 +84,8 @@ struct eventop epollops = { epoll_add, epoll_del, epoll_recalc, - epoll_dispatch + epoll_dispatch, + epoll_dealloc }; #ifdef HAVE_SETFD @@ -349,3 +351,19 @@ epoll_del(void *arg, struct event *ev) return (0); } + +void +epoll_dealloc(void *arg) +{ + struct epollop *epollop = arg; + + if (epollop->fds) + free(epollop->fds); + if (epollop->events) + free(epollop->events); + if (epollop->epfd >= 0) + close(epollop->epfd); + + memset(epollop, 0, sizeof(struct epollop)); + free(epollop); +} diff --git a/event.c b/event.c index cbbb4bfb..8cab2659 100644 --- a/event.c +++ b/event.c @@ -196,6 +196,33 @@ event_init(void) return (current_base); } +void +event_base_free(struct event_base *base) +{ + int i; + + if (base == NULL && current_base) + base = current_base; + if (base == current_base) + current_base = NULL; + + assert(base); + assert(TAILQ_EMPTY(&base->eventqueue)); + for (i=0; i < base->nactivequeues; ++i) + assert(TAILQ_EMPTY(base->activequeues[i])); + + assert(RB_EMPTY(&base->timetree)); + + for (i = 0; i < base->nactivequeues; ++i) + free(base->activequeues[i]); + free(base->activequeues); + + if (base->evsel->dealloc != NULL) + base->evsel->dealloc(base->evbase); + + free(base); +} + int event_priority_init(int npriorities) { diff --git a/event.h b/event.h index 6001c40f..4c1b38f0 100644 --- a/event.h +++ b/event.h @@ -135,6 +135,7 @@ struct eventop { int (*del)(void *, struct event *); int (*recalc)(struct event_base *, void *, int); int (*dispatch)(struct event_base *, void *, struct timeval *); + void (*dealloc)(void *); }; #define TIMEOUT_DEFAULT {5, 0} @@ -142,6 +143,7 @@ struct eventop { void *event_init(void); int event_dispatch(void); int event_base_dispatch(struct event_base *); +void event_base_free(struct event_base *); #define _EVENT_LOG_DEBUG 0 #define _EVENT_LOG_MSG 1 diff --git a/kqueue.c b/kqueue.c index d760440c..a92315fe 100644 --- a/kqueue.c +++ b/kqueue.c @@ -75,6 +75,7 @@ int kq_del (void *, struct event *); int kq_recalc (struct event_base *, void *, int); int kq_dispatch (struct event_base *, void *, struct timeval *); int kq_insert (struct kqop *, struct kevent *); +void kq_dealloc (void *); const struct eventop kqops = { "kqueue", @@ -82,7 +83,8 @@ const struct eventop kqops = { kq_add, kq_del, kq_recalc, - kq_dispatch + kq_dispatch, + kq_dealloc }; void * @@ -394,3 +396,18 @@ kq_del(void *arg, struct event *ev) return (0); } + +void +kq_dealloc(void *arg) +{ + struct kqop *kqop = arg; + + if (kqop->changes) + free(kqop->changes); + if (kqop->events) + free(kqop->events); + if (kqop->kq) + close(kqop->kq); + memset(kqop, 0, sizeof(struct kqop)); + free(kqop); +} diff --git a/poll.c b/poll.c index 698bbbf3..f05819e0 100644 --- a/poll.c +++ b/poll.c @@ -74,6 +74,7 @@ int poll_add (void *, struct event *); int poll_del (void *, struct event *); int poll_recalc (struct event_base *, void *, int); int poll_dispatch (struct event_base *, void *, struct timeval *); +void poll_dealloc (void *); const struct eventop pollops = { "poll", @@ -81,7 +82,8 @@ const struct eventop pollops = { poll_add, poll_del, poll_recalc, - poll_dispatch + poll_dispatch, + poll_dealloc }; void * @@ -355,3 +357,21 @@ poll_del(void *arg, struct event *ev) poll_check_ok(pop); return (0); } + +void +poll_dealloc(void *arg) +{ + struct pollop *pop = arg; + + if (pop->event_set) + free(pop->event_set); + if (pop->event_r_back) + free(pop->event_r_back); + if (pop->event_w_back) + free(pop->event_w_back); + if (pop->idxplus1_by_fd) + free(pop->idxplus1_by_fd); + + memset(pop, 0, sizeof(struct pollop)); + free(pop); +} diff --git a/select.c b/select.c index 0f6c29b3..1e039e1f 100644 --- a/select.c +++ b/select.c @@ -76,6 +76,7 @@ int select_add (void *, struct event *); int select_del (void *, struct event *); int select_recalc (struct event_base *, void *, int); int select_dispatch (struct event_base *, void *, struct timeval *); +void select_dealloc (void *); const struct eventop selectops = { "select", @@ -83,7 +84,8 @@ const struct eventop selectops = { select_add, select_del, select_recalc, - select_dispatch + select_dispatch, + select_dealloc }; static int select_resize(struct selectop *sop, int fdsz); @@ -350,3 +352,25 @@ select_del(void *arg, struct event *ev) check_selectop(sop); return (0); } + +void +select_dealloc(void *arg) +{ + struct selectop *sop = arg; + + if (sop->event_readset_in) + free(sop->event_readset_in); + if (sop->event_writeset_in) + free(sop->event_writeset_in); + if (sop->event_readset_out) + free(sop->event_readset_out); + if (sop->event_writeset_out) + free(sop->event_writeset_out); + if (sop->event_r_by_fd) + free(sop->event_r_by_fd); + if (sop->event_w_by_fd) + free(sop->event_w_by_fd); + + memset(sop, 0, sizeof(struct selectop)); + free(sop); +} -- 2.50.1