bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2004-2018 Dovecot authors, see the included COPYING file */
dac0b2e5e0f38c6d95ef1a842d891480db580236Timo Sirainenvoid io_loop_handler_init(struct ioloop *ioloop, unsigned int initial_fd_count)
dcc76bb1e1bb287e3e71e6a39a7ca207fab0eaa8Timo Sirainen ioloop->handler_context = ctx = i_new(struct ioloop_handler_context, 1);
dac0b2e5e0f38c6d95ef1a842d891480db580236Timo Sirainen i_array_init(&ctx->fd_index, initial_fd_count);
717a444a466280a84a468220f647fdcb9f3b546fTimo Sirainen i_fatal("epoll_create(): %m (you may need to increase "
c014f12e8268bf37ca2997e632ad7c22b8d04a84Timo Sirainenvoid io_loop_handler_deinit(struct ioloop *ioloop)
797de45dcf6e24642ab347d5033beb92034b779dTimo Sirainen struct ioloop_handler_context *ctx = ioloop->handler_context;
4b8459c6c24b79d4ed5974ab6e3289a3f2b701c0Timo Sirainen list = array_get_modifiable(&ctx->fd_index, &count);
720692523ece4a549f7c589508d5693ee310f6b3Timo Sirainen for (i = 0; i < count; i++)
08f24237ccc177f5b3a09b24d8a725fa47e1ee32Timo Sirainen array_free(&ioloop->handler_context->fd_index);
8d59f06c9422fa49b538e23ffb06eddb23c6add2Timo Sirainen#define IO_EPOLL_INPUT (EPOLLIN | EPOLLPRI | IO_EPOLL_ERROR)
8d59f06c9422fa49b538e23ffb06eddb23c6add2Timo Sirainen#define IO_EPOLL_OUTPUT (EPOLLOUT | IO_EPOLL_ERROR)
c014f12e8268bf37ca2997e632ad7c22b8d04a84Timo Sirainenstatic int epoll_event_mask(struct io_list *list)
35565557e05721a761132cec2ba1d93acacb6c14Timo Sirainen for (i = 0; i < IOLOOP_IOLIST_IOS_PER_FD; i++) {
193f5296d2a6b847970c222d8a261b89aae46331Timo Sirainen struct ioloop_handler_context *ctx = io->io.ioloop->handler_context;
139143f1b798472438b813343a48601f1c564060Sergey Kitov list = array_idx_get_space(&ctx->fd_index, io->fd);
35565557e05721a761132cec2ba1d93acacb6c14Timo Sirainen if (epoll_ctl(ctx->epfd, op, io->fd, &event) < 0) {
4d4cd9cde9e01d4ad9354e6e30ac2f90d13042b2Timo Sirainen " - instead of '<file', try 'cat file|'");
35565557e05721a761132cec2ba1d93acacb6c14Timo Sirainen /* allow epoll_wait() to return the maximum number of events
35565557e05721a761132cec2ba1d93acacb6c14Timo Sirainen by keeping space allocated for each file descriptor */
193f5296d2a6b847970c222d8a261b89aae46331Timo Sirainenvoid io_loop_handle_remove(struct io_file *io, bool closed)
193f5296d2a6b847970c222d8a261b89aae46331Timo Sirainen struct ioloop_handler_context *ctx = io->io.ioloop->handler_context;
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen list = array_idx_modifiable(&ctx->fd_index, io->fd);
745f2c7424d88e368eff0a3a7650b352a9d1f0ddTimo Sirainen if (epoll_ctl(ctx->epfd, op, io->fd, &event) < 0) {
f2767c736d72e6aa9a2aae5d0a9b89abae9e29e9Timo Sirainen "epoll_ctl(%s, %d) failed: %m",
35565557e05721a761132cec2ba1d93acacb6c14Timo Sirainen /* since we're not freeing memory in any case, just increase
35565557e05721a761132cec2ba1d93acacb6c14Timo Sirainen deleted counter so next handle_add() can just decrease it
19557f192d37cd54a1a090a8a26d9d47265e4413Aki Tuomi instead of appending to the events array */
f922ecaf766c60c10f642f3ac2d5f7748ff642b0Timo Sirainenvoid io_loop_handler_run_internal(struct ioloop *ioloop)
797de45dcf6e24642ab347d5033beb92034b779dTimo Sirainen struct ioloop_handler_context *ctx = ioloop->handler_context;
c014f12e8268bf37ca2997e632ad7c22b8d04a84Timo Sirainen /* get the time left for next timeout task */
dba5754de32284b3149ddd5c9bb1701b05707752Timo Sirainen events = array_get_modifiable(&ctx->events, &events_count);
b116c06e4d3609f07f1d9582a932ad3ea9ce7e15Stephan Bosch if (ioloop->io_files != NULL && events_count > ctx->deleted_count) {
eff0f02f2c8320c1bd4df72a281a92051d78b2b1Timo Sirainen ret = epoll_wait(ctx->epfd, events, events_count, msecs);
eff0f02f2c8320c1bd4df72a281a92051d78b2b1Timo Sirainen /* no I/Os, but we should have some timeouts.
eff0f02f2c8320c1bd4df72a281a92051d78b2b1Timo Sirainen just wait for them. */
c8920d5f3df9663668ccd6412218eb28008f4e9aTimo Sirainen i_panic("BUG: No IOs or timeouts set. Not waiting for infinity.");
c014f12e8268bf37ca2997e632ad7c22b8d04a84Timo Sirainen /* execute timeout handlers */
dba5754de32284b3149ddd5c9bb1701b05707752Timo Sirainen for (i = 0; i < ret; i++) {
dba5754de32284b3149ddd5c9bb1701b05707752Timo Sirainen /* io_loop_handle_add() may cause events array reallocation,
dba5754de32284b3149ddd5c9bb1701b05707752Timo Sirainen so we have use array_idx() */
dba5754de32284b3149ddd5c9bb1701b05707752Timo Sirainen for (j = 0; j < IOLOOP_IOLIST_IOS_PER_FD; j++) {
8d59f06c9422fa49b538e23ffb06eddb23c6add2Timo Sirainen if ((event->events & (EPOLLHUP | EPOLLERR)) != 0)
c014f12e8268bf37ca2997e632ad7c22b8d04a84Timo Sirainen#endif /* IOLOOP_EPOLL */