Mercurial > dovecot > core-2.2
changeset 3613:c4c1b538d8d0 HEAD
Added IO_ERROR condition that we can watch now.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 25 Sep 2005 13:19:51 +0300 |
parents | c64473977187 |
children | 67703a43b23f |
files | src/lib/ioloop-epoll.c src/lib/ioloop-poll.c src/lib/ioloop-select.c src/lib/ioloop.h |
diffstat | 4 files changed, 68 insertions(+), 37 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/ioloop-epoll.c Sat Sep 24 19:32:54 2005 +0300 +++ b/src/lib/ioloop-epoll.c Sun Sep 25 13:19:51 2005 +0300 @@ -26,6 +26,7 @@ enum { EPOLL_LIST_INPUT, EPOLL_LIST_OUTPUT, + EPOLL_LIST_ERROR, EPOLL_IOS_PER_FD }; @@ -76,8 +77,9 @@ p_free(ioloop->pool, ioloop->handler_context); } -#define IO_EPOLL_INPUT (EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP) -#define IO_EPOLL_OUTPUT (EPOLLOUT | EPOLLERR | EPOLLHUP) +#define IO_EPOLL_ERROR (EPOLLERR | EPOLLHUP) +#define IO_EPOLL_INPUT (EPOLLIN | EPOLLPRI | IO_EPOLL_ERROR) +#define IO_EPOLL_OUTPUT (EPOLLOUT | IO_EPOLL_ERROR) static int epoll_event_mask(struct io_list *list) { @@ -94,6 +96,8 @@ events |= IO_EPOLL_INPUT; if (io->condition & IO_WRITE) events |= IO_EPOLL_OUTPUT; + if (io->condition & IO_ERROR) + events |= IO_EPOLL_ERROR; } return events; @@ -101,34 +105,43 @@ static int iolist_add(struct io_list *list, struct io *io) { - if ((io->condition & IO_READ) != 0) { - i_assert(list->ios[EPOLL_LIST_INPUT] == NULL); - list->ios[EPOLL_LIST_INPUT] = io; - return list->ios[EPOLL_LIST_OUTPUT] == NULL; - } - if ((io->condition & IO_WRITE) != 0) { - i_assert(list->ios[EPOLL_LIST_OUTPUT] == NULL); - list->ios[EPOLL_LIST_OUTPUT] = io; - return list->ios[EPOLL_LIST_INPUT] == NULL; + int i, idx; + + if ((io->condition & IO_READ) != 0) + idx = EPOLL_LIST_INPUT; + else if ((io->condition & IO_WRITE) != 0) + idx = EPOLL_LIST_OUTPUT; + else if ((io->condition & IO_ERROR) != 0) + idx = EPOLL_LIST_ERROR; + else { + i_unreached(); } - i_unreached(); + i_assert(list->ios[idx] == NULL); + list->ios[idx] = io; + + /* check if this was the first one */ + for (i = 0; i < EPOLL_IOS_PER_FD; i++) { + if (i != idx && list->ios[i] != NULL) + return FALSE; + } + return TRUE; } static int iolist_del(struct io_list *list, struct io *io) { - if (list->ios[EPOLL_LIST_INPUT] == io) { - list->ios[EPOLL_LIST_INPUT] = NULL; - return list->ios[EPOLL_LIST_OUTPUT] == NULL; + int i, last = TRUE; + + for (i = 0; i < EPOLL_IOS_PER_FD; i++) { + if (list->ios[i] != NULL) { + if (list->ios[i] == io) + list->ios[i] = NULL; + else + last = TRUE; + } } - if (list->ios[EPOLL_LIST_OUTPUT] == io) { - list->ios[EPOLL_LIST_OUTPUT] = NULL; - return list->ios[EPOLL_LIST_INPUT] == NULL; - } - - i_unreached(); - return TRUE; + return last; } void io_loop_handle_add(struct ioloop *ioloop, struct io *io) @@ -221,13 +234,14 @@ continue; call = FALSE; - if ((event->events & (EPOLLHUP | EPOLLERR)) != 0) { + if ((event->events & (EPOLLHUP | EPOLLERR)) != 0) call = TRUE; - } else if ((io->condition & IO_READ) != 0) { - call = event->events & EPOLLIN; - } else if ((io->condition & IO_WRITE) != 0) { - call = event->events & EPOLLOUT; - } + else if ((io->condition & IO_READ) != 0) + call = (event->events & EPOLLIN) != 0; + else if ((io->condition & IO_WRITE) != 0) + call = (event->events & EPOLLOUT) != 0; + else if ((io->condition & IO_ERROR) != 0) + call = (event->events & IO_EPOLL_ERROR) != 0; if (call) { t_id = t_push();
--- a/src/lib/ioloop-poll.c Sat Sep 24 19:32:54 2005 +0300 +++ b/src/lib/ioloop-poll.c Sun Sep 25 13:19:51 2005 +0300 @@ -42,8 +42,9 @@ p_free(ioloop->pool, ioloop->handler_context); } -#define IO_POLL_INPUT (POLLIN|POLLPRI|POLLERR|POLLHUP|POLLNVAL) -#define IO_POLL_OUTPUT (POLLOUT|POLLERR|POLLHUP|POLLNVAL) +#define IO_POLL_ERROR (POLLERR|POLLHUP|POLLNVAL) +#define IO_POLL_INPUT (POLLIN|POLLPRI|IO_POLL_ERROR) +#define IO_POLL_OUTPUT (POLLOUT|IO_POLL_ERROR) void io_loop_handle_add(struct ioloop *ioloop, struct io *io) { @@ -95,6 +96,8 @@ ctx->fds[index].events |= IO_POLL_INPUT; if (condition & IO_WRITE) ctx->fds[index].events |= IO_POLL_OUTPUT; + if (condition & IO_ERROR) + ctx->fds[index].events |= IO_POLL_ERROR; } void io_loop_handle_remove(struct ioloop *ioloop, struct io *io) @@ -172,6 +175,9 @@ } else if (io->condition & IO_WRITE) { call = (pollfd->revents & IO_POLL_OUTPUT) != 0; pollfd->revents &= ~IO_POLL_OUTPUT; + } else if (io->condition & IO_ERROR) { + call = (pollfd->revents & IO_POLL_ERROR) != 0; + pollfd->revents &= ~IO_POLL_ERROR; } else { call = FALSE; }
--- a/src/lib/ioloop-select.c Sat Sep 24 19:32:54 2005 +0300 +++ b/src/lib/ioloop-select.c Sun Sep 25 13:19:51 2005 +0300 @@ -13,10 +13,10 @@ struct ioloop_handler_context { int highest_fd; - fd_set read_fds, write_fds; + fd_set read_fds, write_fds, except_fds; }; -static fd_set tmp_read_fds, tmp_write_fds; +static fd_set tmp_read_fds, tmp_write_fds, tmp_except_fds; static void update_highest_fd(struct ioloop *ioloop) { @@ -44,6 +44,7 @@ ioloop->handler_context->highest_fd = -1; FD_ZERO(&ioloop->handler_context->read_fds); FD_ZERO(&ioloop->handler_context->write_fds); + FD_ZERO(&ioloop->handler_context->except_fds); } void io_loop_handler_deinit(struct ioloop *ioloop) @@ -65,6 +66,7 @@ FD_SET(fd, &ioloop->handler_context->read_fds); if (condition & IO_WRITE) FD_SET(fd, &ioloop->handler_context->write_fds); + FD_SET(fd, &ioloop->handler_context->except_fds); if (io->fd > ioloop->handler_context->highest_fd) ioloop->handler_context->highest_fd = io->fd; @@ -82,14 +84,20 @@ if (condition & IO_WRITE) FD_CLR(fd, &ioloop->handler_context->write_fds); - /* check if we removed the highest fd */ - if (io->fd == ioloop->handler_context->highest_fd) - update_highest_fd(ioloop); + if (!FD_ISSET(fd, &ioloop->handler_context->read_fds) && + !FD_ISSET(fd, &ioloop->handler_context->write_fds)) { + FD_CLR(fd, &ioloop->handler_context->except_fds); + + /* check if we removed the highest fd */ + if (io->fd == ioloop->handler_context->highest_fd) + update_highest_fd(ioloop); + } } #define io_check_condition(fd, condition) \ ((FD_ISSET((fd), &tmp_read_fds) && ((condition) & IO_READ)) || \ - (FD_ISSET((fd), &tmp_write_fds) && ((condition) & IO_WRITE))) + (FD_ISSET((fd), &tmp_write_fds) && ((condition) & IO_WRITE)) || \ + (FD_ISSET((fd), &tmp_except_fds))) void io_loop_handler_run(struct ioloop *ioloop) { @@ -105,9 +113,11 @@ sizeof(fd_set)); memcpy(&tmp_write_fds, &ioloop->handler_context->write_fds, sizeof(fd_set)); + memcpy(&tmp_except_fds, &ioloop->handler_data->except_fds, + sizeof(fd_set)); ret = select(ioloop->handler_context->highest_fd + 1, - &tmp_read_fds, &tmp_write_fds, NULL, &tv); + &tmp_read_fds, &tmp_write_fds, &tmp_except_fds, &tv); if (ret < 0 && errno != EINTR) i_warning("select() : %m");