ioloop-epoll.c revision c8920d5f3df9663668ccd6412218eb28008f4e9a
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2004-2016 Dovecot authors, see the included COPYING file */
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainenvoid io_loop_handler_init(struct ioloop *ioloop, unsigned int initial_fd_count)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen ioloop->handler_context = ctx = i_new(struct ioloop_handler_context, 1);
7fa573e6ea36024f618492e7d3649a69c1b41028Timo Sirainen i_array_init(&ctx->fd_index, initial_fd_count);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen i_fatal("epoll_create(): %m (you may need to increase "
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainenvoid io_loop_handler_deinit(struct ioloop *ioloop)
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen struct ioloop_handler_context *ctx = ioloop->handler_context;
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen unsigned int i, count;
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch list = array_get_modifiable(&ctx->fd_index, &count);
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch for (i = 0; i < count; i++)
8ac6623677005256bf99ab33a2ed98c69c1d656cStephan Bosch array_free(&ioloop->handler_context->fd_index);
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen#define IO_EPOLL_INPUT (EPOLLIN | EPOLLPRI | IO_EPOLL_ERROR)
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen#define IO_EPOLL_OUTPUT (EPOLLOUT | IO_EPOLL_ERROR)
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainenstatic int epoll_event_mask(struct io_list *list)
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen for (i = 0; i < IOLOOP_IOLIST_IOS_PER_FD; i++) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct ioloop_handler_context *ctx = io->io.ioloop->handler_context;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen list = array_idx_modifiable(&ctx->fd_index, io->fd);
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen if (epoll_ctl(ctx->epfd, op, io->fd, &event) < 0) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen " - instead of '<file', try 'cat file|'");
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen /* allow epoll_wait() to return the maximum number of events
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen by keeping space allocated for each file descriptor */
00fa8dcbc66f56daa737487c9dec7166c37de79eTimo Sirainenvoid io_loop_handle_remove(struct io_file *io, bool closed)
c0a708fa3f7b8f4fbca32052da5faf7a0125189dTimo Sirainen struct ioloop_handler_context *ctx = io->io.ioloop->handler_context;
c5e62353a11087958ea4e619660e084a613e1a37Timo Sirainen list = array_idx_modifiable(&ctx->fd_index, io->fd);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (epoll_ctl(ctx->epfd, op, io->fd, &event) < 0) {
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainen "epoll_ctl(%s, %d) failed: %m",
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen /* since we're not freeing memory in any case, just increase
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen deleted counter so next handle_add() can just decrease it
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen insteading of appending to the events array */
c0a708fa3f7b8f4fbca32052da5faf7a0125189dTimo Sirainenvoid io_loop_handler_run_internal(struct ioloop *ioloop)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct ioloop_handler_context *ctx = ioloop->handler_context;
2dfd08e8aa16dfcc975d8a62bc8d20b2ef849d71Timo Sirainen /* get the time left for next timeout task */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen events = array_get_modifiable(&ctx->events, &events_count);
c49a19168dab6fda80aee16ad799a8a56d3bc18fTimo Sirainen if (ioloop->io_files != NULL && events_count > ctx->deleted_count) {
bf72c930996df0691932fb1143f360d260f27a06Timo Sirainen ret = epoll_wait(ctx->epfd, events, events_count, msecs);
087939d3fa9c4056419386c9d6c81f147de534cdTimo Sirainen /* no I/Os, but we should have some timeouts.
02ccba3d3be96444abd15b5254864c9151bbeb30Timo Sirainen just wait for them. */
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen i_panic("BUG: No IOs or timeouts set. Not waiting for infinity.");
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen /* execute timeout handlers */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen for (i = 0; i < ret; i++) {
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen /* io_loop_handle_add() may cause events array reallocation,
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen so we have use array_idx() */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen for (j = 0; j < IOLOOP_IOLIST_IOS_PER_FD; j++) {
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen if ((event->events & (EPOLLHUP | EPOLLERR)) != 0)
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen#endif /* IOLOOP_EPOLL */