ioloop-poll.c revision cd65920767c81e079994df625ade27531f72f5c2
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (c) 2002-2010 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* @UNSAFE: whole file */
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainenvoid io_loop_handler_init(struct ioloop *ioloop, unsigned int initial_fd_count)
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen ioloop->handler_context = ctx = i_new(struct ioloop_handler_context, 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->fds = i_new(struct pollfd, ctx->fds_count);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen memset(ctx->fd_index, 0xff, sizeof(int) * ctx->idx_count);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid io_loop_handler_deinit(struct ioloop *ioloop)
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen#define IO_POLL_ERROR (POLLERR | POLLHUP | POLLNVAL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#define IO_POLL_INPUT (POLLIN | POLLPRI | IO_POLL_ERROR)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#define IO_POLL_OUTPUT (POLLOUT | IO_POLL_ERROR)
41e1c7380edda701719d8ce1fb4d465d2ec4c84dTimo Sirainen struct ioloop_handler_context *ctx = io->io.ioloop->handler_context;
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen enum io_condition condition = io->io.condition;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* grow the fd -> index array */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->idx_count = nearest_power((unsigned int) fd+1);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen sizeof(int) * old_count,
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen /* grow the fd array */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen ctx->fds_count = nearest_power(ctx->fds_count+1);
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen /* update existing pollfd */
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen /* add new pollfd */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen i_assert(ctx->fds[index].events != old_events);
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainenvoid io_loop_handle_remove(struct io_file *io, bool closed ATTR_UNUSED)
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen struct ioloop_handler_context *ctx = io->io.ioloop->handler_context;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen enum io_condition condition = io->io.condition;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen i_assert(index >= 0 && (unsigned int) index < ctx->fds_count);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen /* io_remove() is required to be called before fd is closed.
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen This is required by epoll/kqueue, but since poll is more
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen commonly used while developing, this check here should catch
da985034a708db2f61394b30d117050ae6829ee5Timo Sirainen the error early enough not to cause problems for kqueue
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen i_panic("io_remove(%d) called too late", io->fd);
7d7b5c98f086ffa8ac9c90f21db17748ca607202Timo Sirainen i_error("fcntl(%d, F_GETFD) failed: %m", io->fd);
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen if ((ctx->fds[index].events & (POLLIN|POLLOUT)) == 0) {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen /* remove the whole pollfd */
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen return; /* removing last one */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen /* move the last pollfd over the removed one */
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainenvoid io_loop_handler_run(struct ioloop *ioloop)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen struct ioloop_handler_context *ctx = ioloop->handler_context;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen unsigned int t_id;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen /* get the time left for next timeout task */
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen /* AIX seems to check IO_POLL_ERRORs only at the beginning of
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen the poll() call, not during it. keep timeouts short enough
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen so that we'll notice them pretty quickly. */
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen /* execute timeout handlers */
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen /* no I/O events */
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen for (; io != NULL && ret > 0; io = ioloop->next_io_file) {
003079baf8056c81c25162a176a89f9169cc374fTimo Sirainen call = (pollfd->revents & IO_POLL_INPUT) != 0;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen call = (pollfd->revents & IO_POLL_OUTPUT) != 0;
003079baf8056c81c25162a176a89f9169cc374fTimo Sirainen call = (pollfd->revents & IO_POLL_ERROR) != 0;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen "I/O handler %p",