Mercurial > dovecot > core-2.2
changeset 3612:c64473977187 HEAD
Don't leak epoll fd to child processes. Memory allocations were wrong for
64bit systems. Changed the code to use array_t.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 24 Sep 2005 19:32:54 +0300 |
parents | 5d92a45fc751 |
children | c4c1b538d8d0 |
files | src/lib/ioloop-epoll.c |
diffstat | 1 files changed, 21 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/ioloop-epoll.c Sat Sep 24 16:41:27 2005 +0300 +++ b/src/lib/ioloop-epoll.c Sat Sep 24 19:32:54 2005 +0300 @@ -12,6 +12,8 @@ /* @UNSAFE: whole file */ #include "lib.h" +#include "array.h" +#include "fd-close-on-exec.h" #include "ioloop-internal.h" #ifdef IOLOOP_EPOLL @@ -34,7 +36,7 @@ struct epoll_event *events; unsigned int idx_size; - struct io_list **fd_index; + array_t ARRAY_DEFINE(fd_index, struct io_list *); }; struct io_list { @@ -54,20 +56,23 @@ ctx->events_size); ctx->idx_size = INITIAL_EPOLL_EVENTS; - ctx->fd_index = p_new(ioloop->pool, struct io_list *, ctx->idx_size); + ARRAY_CREATE(&ctx->fd_index, ioloop->pool, + struct io_list *, ctx->idx_size); ctx->epfd = epoll_create(INITIAL_EPOLL_EVENTS); if (ctx->epfd < 0) i_fatal("epoll_create(): %m"); + fd_close_on_exec(ctx->epfd, TRUE); } void io_loop_handler_deinit(struct ioloop *ioloop) { struct ioloop_handler_context *ctx = ioloop->handler_context; - close(ctx->epfd); + if (close(ctx->epfd) < 0) + i_error("close(epoll) failed: %m"); + array_free(&ioloop->handler_context->fd_index); p_free(ioloop->pool, ioloop->handler_context->events); - p_free(ioloop->pool, ioloop->handler_context->fd_index); p_free(ioloop->pool, ioloop->handler_context); } @@ -129,33 +134,18 @@ void io_loop_handle_add(struct ioloop *ioloop, struct io *io) { struct ioloop_handler_context *ctx = ioloop->handler_context; - struct io_list *list; + struct io_list **list; struct epoll_event event; int ret, first, op, fd = io->fd; - list = ctx->fd_index[fd]; - if (list == NULL) { - if ((unsigned int) fd >= ctx->idx_size) { - /* grow the fd -> iolist array */ - unsigned int old_size = ctx->idx_size; - - ctx->idx_size = nearest_power((unsigned int) fd+1); - - i_assert(ctx->idx_size < (size_t)-1 / sizeof(int)); + list = array_idx_modifyable(&ctx->fd_index, fd); + if (*list == NULL) + *list = p_new(ioloop->pool, struct io_list, 1); - ctx->fd_index = p_realloc(ioloop->pool, ctx->fd_index, - sizeof(int) * old_size, - sizeof(int) * ctx->idx_size); - } + first = iolist_add(*list, io); - ctx->fd_index[fd] = list = - p_new(ioloop->pool, struct io_list, 1); - } - - first = iolist_add(list, io); - - event.data.ptr = list; - event.events = epoll_event_mask(list); + event.data.ptr = *list; + event.events = epoll_event_mask(*list); op = first ? EPOLL_CTL_ADD : EPOLL_CTL_MOD; @@ -177,14 +167,15 @@ void io_loop_handle_remove(struct ioloop *ioloop, struct io *io) { struct ioloop_handler_context *ctx = ioloop->handler_context; - struct io_list *list = ctx->fd_index[io->fd]; + struct io_list **list; struct epoll_event event; int ret, last, op; - last = iolist_del(list, io); + list = array_idx_modifyable(&ctx->fd_index, io->fd); + last = iolist_del(*list, io); - event.data.ptr = list; - event.events = epoll_event_mask(list); + event.data.ptr = *list; + event.events = epoll_event_mask(*list); op = last ? EPOLL_CTL_DEL : EPOLL_CTL_MOD;