annotate src/lib/ioloop-epoll.c @ 22664:fea53c2725c0

director: Fix director_max_parallel_moves/kicks type Should be uint, not time.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 09 Nov 2017 12:24:16 +0200
parents f9c89c5172a5
children cb108f786fb4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
21390
2e2563132d5f Updated copyright notices to include the year 2017.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21389
diff changeset
1 /* Copyright (c) 2004-2017 Dovecot authors, see the included COPYING file */
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "lib.h"
3612
c64473977187 Don't leak epoll fd to child processes. Memory allocations were wrong for
Timo Sirainen <tss@iki.fi>
parents: 3527
diff changeset
4 #include "array.h"
c64473977187 Don't leak epoll fd to child processes. Memory allocations were wrong for
Timo Sirainen <tss@iki.fi>
parents: 3527
diff changeset
5 #include "fd-close-on-exec.h"
13529
cf77e448295c Renamed lib/*-internal.h files to lib/*-private.h for consistency.
Timo Sirainen <tss@iki.fi>
parents: 12497
diff changeset
6 #include "ioloop-private.h"
4573
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
7 #include "ioloop-iolist.h"
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
8
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9 #ifdef IOLOOP_EPOLL
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
10
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
11 #include <sys/epoll.h>
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12 #include <unistd.h>
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
13
3483
84a4f150bd00 data -> context/ctx naming convention replaces
Timo Sirainen <tss@iki.fi>
parents: 3198
diff changeset
14 struct ioloop_handler_context {
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
15 int epfd;
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
16
4573
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
17 unsigned int deleted_count;
14920
a097ef0a9d6d Array API changed: ARRAY_DEFINE(name, type) -> ARRAY(type) name
Timo Sirainen <tss@iki.fi>
parents: 14842
diff changeset
18 ARRAY(struct io_list *) fd_index;
a097ef0a9d6d Array API changed: ARRAY_DEFINE(name, type) -> ARRAY(type) name
Timo Sirainen <tss@iki.fi>
parents: 14842
diff changeset
19 ARRAY(struct epoll_event) events;
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
20 };
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
21
8634
86c28d14ddeb Added io_loop_set_max_fd_count() to specify how many fds we expect to use.
Timo Sirainen <tss@iki.fi>
parents: 8366
diff changeset
22 void io_loop_handler_init(struct ioloop *ioloop, unsigned int initial_fd_count)
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
23 {
3483
84a4f150bd00 data -> context/ctx naming convention replaces
Timo Sirainen <tss@iki.fi>
parents: 3198
diff changeset
24 struct ioloop_handler_context *ctx;
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
25
5248
12ac5f685814 Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents: 4863
diff changeset
26 ioloop->handler_context = ctx = i_new(struct ioloop_handler_context, 1);
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
27
8634
86c28d14ddeb Added io_loop_set_max_fd_count() to specify how many fds we expect to use.
Timo Sirainen <tss@iki.fi>
parents: 8366
diff changeset
28 i_array_init(&ctx->events, initial_fd_count);
86c28d14ddeb Added io_loop_set_max_fd_count() to specify how many fds we expect to use.
Timo Sirainen <tss@iki.fi>
parents: 8366
diff changeset
29 i_array_init(&ctx->fd_index, initial_fd_count);
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
30
8634
86c28d14ddeb Added io_loop_set_max_fd_count() to specify how many fds we expect to use.
Timo Sirainen <tss@iki.fi>
parents: 8366
diff changeset
31 ctx->epfd = epoll_create(initial_fd_count);
8890
697f380acfbb If epoll_create() fails with EMFILE, suggest increasing epoll's max_user_instances.
Timo Sirainen <tss@iki.fi>
parents: 8634
diff changeset
32 if (ctx->epfd < 0) {
697f380acfbb If epoll_create() fails with EMFILE, suggest increasing epoll's max_user_instances.
Timo Sirainen <tss@iki.fi>
parents: 8634
diff changeset
33 if (errno != EMFILE)
697f380acfbb If epoll_create() fails with EMFILE, suggest increasing epoll's max_user_instances.
Timo Sirainen <tss@iki.fi>
parents: 8634
diff changeset
34 i_fatal("epoll_create(): %m");
697f380acfbb If epoll_create() fails with EMFILE, suggest increasing epoll's max_user_instances.
Timo Sirainen <tss@iki.fi>
parents: 8634
diff changeset
35 else {
697f380acfbb If epoll_create() fails with EMFILE, suggest increasing epoll's max_user_instances.
Timo Sirainen <tss@iki.fi>
parents: 8634
diff changeset
36 i_fatal("epoll_create(): %m (you may need to increase "
697f380acfbb If epoll_create() fails with EMFILE, suggest increasing epoll's max_user_instances.
Timo Sirainen <tss@iki.fi>
parents: 8634
diff changeset
37 "/proc/sys/fs/epoll/max_user_instances)");
697f380acfbb If epoll_create() fails with EMFILE, suggest increasing epoll's max_user_instances.
Timo Sirainen <tss@iki.fi>
parents: 8634
diff changeset
38 }
697f380acfbb If epoll_create() fails with EMFILE, suggest increasing epoll's max_user_instances.
Timo Sirainen <tss@iki.fi>
parents: 8634
diff changeset
39 }
3612
c64473977187 Don't leak epoll fd to child processes. Memory allocations were wrong for
Timo Sirainen <tss@iki.fi>
parents: 3527
diff changeset
40 fd_close_on_exec(ctx->epfd, TRUE);
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
41 }
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
42
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
43 void io_loop_handler_deinit(struct ioloop *ioloop)
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
44 {
3483
84a4f150bd00 data -> context/ctx naming convention replaces
Timo Sirainen <tss@iki.fi>
parents: 3198
diff changeset
45 struct ioloop_handler_context *ctx = ioloop->handler_context;
4765
7673830076ef Free all the used memory when destroying the ioloop.
Timo Sirainen <tss@iki.fi>
parents: 4666
diff changeset
46 struct io_list **list;
7673830076ef Free all the used memory when destroying the ioloop.
Timo Sirainen <tss@iki.fi>
parents: 4666
diff changeset
47 unsigned int i, count;
7673830076ef Free all the used memory when destroying the ioloop.
Timo Sirainen <tss@iki.fi>
parents: 4666
diff changeset
48
4863
d13324a8e242 s/array_get_modifyable/array_get_modifiable/
Timo Sirainen <tss@iki.fi>
parents: 4765
diff changeset
49 list = array_get_modifiable(&ctx->fd_index, &count);
4765
7673830076ef Free all the used memory when destroying the ioloop.
Timo Sirainen <tss@iki.fi>
parents: 4666
diff changeset
50 for (i = 0; i < count; i++)
5248
12ac5f685814 Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents: 4863
diff changeset
51 i_free(list[i]);
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
52
3612
c64473977187 Don't leak epoll fd to child processes. Memory allocations were wrong for
Timo Sirainen <tss@iki.fi>
parents: 3527
diff changeset
53 if (close(ctx->epfd) < 0)
c64473977187 Don't leak epoll fd to child processes. Memory allocations were wrong for
Timo Sirainen <tss@iki.fi>
parents: 3527
diff changeset
54 i_error("close(epoll) failed: %m");
c64473977187 Don't leak epoll fd to child processes. Memory allocations were wrong for
Timo Sirainen <tss@iki.fi>
parents: 3527
diff changeset
55 array_free(&ioloop->handler_context->fd_index);
4573
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
56 array_free(&ioloop->handler_context->events);
5248
12ac5f685814 Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents: 4863
diff changeset
57 i_free(ioloop->handler_context);
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
58 }
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
59
3613
c4c1b538d8d0 Added IO_ERROR condition that we can watch now.
Timo Sirainen <tss@iki.fi>
parents: 3612
diff changeset
60 #define IO_EPOLL_ERROR (EPOLLERR | EPOLLHUP)
c4c1b538d8d0 Added IO_ERROR condition that we can watch now.
Timo Sirainen <tss@iki.fi>
parents: 3612
diff changeset
61 #define IO_EPOLL_INPUT (EPOLLIN | EPOLLPRI | IO_EPOLL_ERROR)
c4c1b538d8d0 Added IO_ERROR condition that we can watch now.
Timo Sirainen <tss@iki.fi>
parents: 3612
diff changeset
62 #define IO_EPOLL_OUTPUT (EPOLLOUT | IO_EPOLL_ERROR)
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
63
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
64 static int epoll_event_mask(struct io_list *list)
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
65 {
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
66 int events = 0, i;
5248
12ac5f685814 Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents: 4863
diff changeset
67 struct io_file *io;
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
68
4573
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
69 for (i = 0; i < IOLOOP_IOLIST_IOS_PER_FD; i++) {
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
70 io = list->ios[i];
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
71
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
72 if (io == NULL)
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
73 continue;
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
74
22161
f9c89c5172a5 -Wstrict-bool warning fixes
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21406
diff changeset
75 if ((io->io.condition & IO_READ) != 0)
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
76 events |= IO_EPOLL_INPUT;
22161
f9c89c5172a5 -Wstrict-bool warning fixes
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21406
diff changeset
77 if ((io->io.condition & IO_WRITE) != 0)
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
78 events |= IO_EPOLL_OUTPUT;
22161
f9c89c5172a5 -Wstrict-bool warning fixes
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21406
diff changeset
79 if ((io->io.condition & IO_ERROR) != 0)
3613
c4c1b538d8d0 Added IO_ERROR condition that we can watch now.
Timo Sirainen <tss@iki.fi>
parents: 3612
diff changeset
80 events |= IO_EPOLL_ERROR;
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
81 }
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
82
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
83 return events;
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
84 }
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
85
8366
2c111b572eee Don't break if io_remove() or timeout_remove() are called for non-active ioloops.
Timo Sirainen <tss@iki.fi>
parents: 8100
diff changeset
86 void io_loop_handle_add(struct io_file *io)
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
87 {
8366
2c111b572eee Don't break if io_remove() or timeout_remove() are called for non-active ioloops.
Timo Sirainen <tss@iki.fi>
parents: 8100
diff changeset
88 struct ioloop_handler_context *ctx = io->io.ioloop->handler_context;
3612
c64473977187 Don't leak epoll fd to child processes. Memory allocations were wrong for
Timo Sirainen <tss@iki.fi>
parents: 3527
diff changeset
89 struct io_list **list;
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
90 struct epoll_event event;
4573
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
91 int op;
3863
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3685
diff changeset
92 bool first;
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
93
4573
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
94 list = array_idx_modifiable(&ctx->fd_index, io->fd);
3612
c64473977187 Don't leak epoll fd to child processes. Memory allocations were wrong for
Timo Sirainen <tss@iki.fi>
parents: 3527
diff changeset
95 if (*list == NULL)
5248
12ac5f685814 Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents: 4863
diff changeset
96 *list = i_new(struct io_list, 1);
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
97
4573
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
98 first = ioloop_iolist_add(*list, io);
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
99
21389
59437f8764c6 global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 20755
diff changeset
100 i_zero(&event);
3612
c64473977187 Don't leak epoll fd to child processes. Memory allocations were wrong for
Timo Sirainen <tss@iki.fi>
parents: 3527
diff changeset
101 event.data.ptr = *list;
c64473977187 Don't leak epoll fd to child processes. Memory allocations were wrong for
Timo Sirainen <tss@iki.fi>
parents: 3527
diff changeset
102 event.events = epoll_event_mask(*list);
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
103
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
104 op = first ? EPOLL_CTL_ADD : EPOLL_CTL_MOD;
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
105
4573
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
106 if (epoll_ctl(ctx->epfd, op, io->fd, &event) < 0) {
11027
60a25bda7e02 epoll: Improved error messages.
Timo Sirainen <tss@iki.fi>
parents: 10124
diff changeset
107 if (errno == EPERM && op == EPOLL_CTL_ADD) {
20185
fcfd082392ca lib: If epoll_ctl() fails, panic instead of just fatal.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
108 i_panic("epoll_ctl(add, %d) failed: %m "
12282
7a839a028dfa epoll: Suggest not-so-UUOC if epoll_ctl() fails for stdin
Timo Sirainen <tss@iki.fi>
parents: 11027
diff changeset
109 "(fd doesn't support epoll%s)", io->fd,
7a839a028dfa epoll: Suggest not-so-UUOC if epoll_ctl() fails for stdin
Timo Sirainen <tss@iki.fi>
parents: 11027
diff changeset
110 io->fd != STDIN_FILENO ? "" :
7a839a028dfa epoll: Suggest not-so-UUOC if epoll_ctl() fails for stdin
Timo Sirainen <tss@iki.fi>
parents: 11027
diff changeset
111 " - instead of '<file', try 'cat file|'");
11027
60a25bda7e02 epoll: Improved error messages.
Timo Sirainen <tss@iki.fi>
parents: 10124
diff changeset
112 }
60a25bda7e02 epoll: Improved error messages.
Timo Sirainen <tss@iki.fi>
parents: 10124
diff changeset
113 i_panic("epoll_ctl(%s, %d) failed: %m",
60a25bda7e02 epoll: Improved error messages.
Timo Sirainen <tss@iki.fi>
parents: 10124
diff changeset
114 op == EPOLL_CTL_ADD ? "add" : "mod", io->fd);
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
115 }
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
116
4573
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
117 if (first) {
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
118 /* allow epoll_wait() to return the maximum number of events
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
119 by keeping space allocated for each file descriptor */
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
120 if (ctx->deleted_count > 0)
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
121 ctx->deleted_count--;
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
122 else
14686
9ff19c1d5f69 Added array_append_zero() to write a zero-filled record to an array.
Timo Sirainen <tss@iki.fi>
parents: 13529
diff changeset
123 array_append_zero(&ctx->events);
4573
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
124 }
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
125 }
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
126
8366
2c111b572eee Don't break if io_remove() or timeout_remove() are called for non-active ioloops.
Timo Sirainen <tss@iki.fi>
parents: 8100
diff changeset
127 void io_loop_handle_remove(struct io_file *io, bool closed)
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
128 {
8366
2c111b572eee Don't break if io_remove() or timeout_remove() are called for non-active ioloops.
Timo Sirainen <tss@iki.fi>
parents: 8100
diff changeset
129 struct ioloop_handler_context *ctx = io->io.ioloop->handler_context;
3612
c64473977187 Don't leak epoll fd to child processes. Memory allocations were wrong for
Timo Sirainen <tss@iki.fi>
parents: 3527
diff changeset
130 struct io_list **list;
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
131 struct epoll_event event;
4573
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
132 int op;
3863
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3685
diff changeset
133 bool last;
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
134
4451
1a35d53c18fc Array API redesigned to work using unions. It now provides type safety
Timo Sirainen <tss@iki.fi>
parents: 4382
diff changeset
135 list = array_idx_modifiable(&ctx->fd_index, io->fd);
4573
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
136 last = ioloop_iolist_del(*list, io);
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
137
8100
83aef3a6c0a3 Added io_remove_closed().
Timo Sirainen <tss@iki.fi>
parents: 7098
diff changeset
138 if (!closed) {
21389
59437f8764c6 global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 20755
diff changeset
139 i_zero(&event);
8100
83aef3a6c0a3 Added io_remove_closed().
Timo Sirainen <tss@iki.fi>
parents: 7098
diff changeset
140 event.data.ptr = *list;
83aef3a6c0a3 Added io_remove_closed().
Timo Sirainen <tss@iki.fi>
parents: 7098
diff changeset
141 event.events = epoll_event_mask(*list);
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
142
8100
83aef3a6c0a3 Added io_remove_closed().
Timo Sirainen <tss@iki.fi>
parents: 7098
diff changeset
143 op = last ? EPOLL_CTL_DEL : EPOLL_CTL_MOD;
83aef3a6c0a3 Added io_remove_closed().
Timo Sirainen <tss@iki.fi>
parents: 7098
diff changeset
144
83aef3a6c0a3 Added io_remove_closed().
Timo Sirainen <tss@iki.fi>
parents: 7098
diff changeset
145 if (epoll_ctl(ctx->epfd, op, io->fd, &event) < 0) {
16828
86e59823d0aa Panic if io_remove() fails with EBADF.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
146 const char *errstr = t_strdup_printf(
86e59823d0aa Panic if io_remove() fails with EBADF.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
147 "epoll_ctl(%s, %d) failed: %m",
11027
60a25bda7e02 epoll: Improved error messages.
Timo Sirainen <tss@iki.fi>
parents: 10124
diff changeset
148 op == EPOLL_CTL_DEL ? "del" : "mod", io->fd);
16828
86e59823d0aa Panic if io_remove() fails with EBADF.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
149 if (errno == EBADF)
86e59823d0aa Panic if io_remove() fails with EBADF.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
150 i_panic("%s", errstr);
86e59823d0aa Panic if io_remove() fails with EBADF.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
151 else
86e59823d0aa Panic if io_remove() fails with EBADF.
Timo Sirainen <tss@iki.fi>
parents: 15715
diff changeset
152 i_error("%s", errstr);
8100
83aef3a6c0a3 Added io_remove_closed().
Timo Sirainen <tss@iki.fi>
parents: 7098
diff changeset
153 }
3685
dd71819db08e And even more log verbosity
Timo Sirainen <tss@iki.fi>
parents: 3684
diff changeset
154 }
4573
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
155 if (last) {
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
156 /* since we're not freeing memory in any case, just increase
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
157 deleted counter so next handle_add() can just decrease it
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
158 insteading of appending to the events array */
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
159 ctx->deleted_count++;
8d977716f449 Rewrote much of the kqueue code. It didn't work correctly if there were both
Timo Sirainen <tss@iki.fi>
parents: 4451
diff changeset
160 }
5248
12ac5f685814 Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents: 4863
diff changeset
161 i_free(io);
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
162 }
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
163
17187
d2a6f57e174f ioloop: Added io_set_pending()
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
164 void io_loop_handler_run_internal(struct ioloop *ioloop)
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
165 {
3483
84a4f150bd00 data -> context/ctx naming convention replaces
Timo Sirainen <tss@iki.fi>
parents: 3198
diff changeset
166 struct ioloop_handler_context *ctx = ioloop->handler_context;
4576
Timo Sirainen <tss@iki.fi>
parents: 4573
diff changeset
167 struct epoll_event *events;
Timo Sirainen <tss@iki.fi>
parents: 4573
diff changeset
168 const struct epoll_event *event;
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
169 struct io_list *list;
5248
12ac5f685814 Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents: 4863
diff changeset
170 struct io_file *io;
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
171 struct timeval tv;
12497
1bac1c09201a ioloop: Added support for per-io/timeout callback log prefix automation.
Timo Sirainen <tss@iki.fi>
parents: 12282
diff changeset
172 unsigned int events_count;
4576
Timo Sirainen <tss@iki.fi>
parents: 4573
diff changeset
173 int msecs, ret, i, j;
3863
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3685
diff changeset
174 bool call;
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
175
20755
4be088d2993b lib: Ensure handler_context is not NULL
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20185
diff changeset
176 i_assert(ctx != NULL);
4be088d2993b lib: Ensure handler_context is not NULL
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20185
diff changeset
177
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
178 /* get the time left for next timeout task */
9494
a442d3c40693 ioloop: Added callback for handling time jumping forwards/backwards.
Timo Sirainen <tss@iki.fi>
parents: 8890
diff changeset
179 msecs = io_loop_get_wait_time(ioloop, &tv);
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
180
4576
Timo Sirainen <tss@iki.fi>
parents: 4573
diff changeset
181 events = array_get_modifiable(&ctx->events, &events_count);
19034
f7c1c1dac689 ioloop-epoll: Fix fatal epoll_wait() error occurring when there are only ios with no fd.
Stephan Bosch <stephan@rename-it.nl>
parents: 18137
diff changeset
182 if (ioloop->io_files != NULL && events_count > ctx->deleted_count) {
14747
587c5579c598 ioloop-epoll: Allow running ioloop even without any I/Os (only timeouts).
Timo Sirainen <tss@iki.fi>
parents: 14686
diff changeset
183 ret = epoll_wait(ctx->epfd, events, events_count, msecs);
587c5579c598 ioloop-epoll: Allow running ioloop even without any I/Os (only timeouts).
Timo Sirainen <tss@iki.fi>
parents: 14686
diff changeset
184 if (ret < 0 && errno != EINTR)
587c5579c598 ioloop-epoll: Allow running ioloop even without any I/Os (only timeouts).
Timo Sirainen <tss@iki.fi>
parents: 14686
diff changeset
185 i_fatal("epoll_wait(): %m");
587c5579c598 ioloop-epoll: Allow running ioloop even without any I/Os (only timeouts).
Timo Sirainen <tss@iki.fi>
parents: 14686
diff changeset
186 } else {
587c5579c598 ioloop-epoll: Allow running ioloop even without any I/Os (only timeouts).
Timo Sirainen <tss@iki.fi>
parents: 14686
diff changeset
187 /* no I/Os, but we should have some timeouts.
587c5579c598 ioloop-epoll: Allow running ioloop even without any I/Os (only timeouts).
Timo Sirainen <tss@iki.fi>
parents: 14686
diff changeset
188 just wait for them. */
21406
69a699cc7149 lib: Minor panic message improvement.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
189 if (msecs < 0)
69a699cc7149 lib: Minor panic message improvement.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 21390
diff changeset
190 i_panic("BUG: No IOs or timeouts set. Not waiting for infinity.");
15401
22cfb7b347a8 liblib: Added assert-check to epoll code to make sure we don't wait infinitely with no events.
Timo Sirainen <tss@iki.fi>
parents: 15188
diff changeset
191 usleep(msecs*1000);
14842
17fb07dea309 ioloop-epoll: Fix for running with zero I/Os.
Timo Sirainen <tss@iki.fi>
parents: 14747
diff changeset
192 ret = 0;
14747
587c5579c598 ioloop-epoll: Allow running ioloop even without any I/Os (only timeouts).
Timo Sirainen <tss@iki.fi>
parents: 14686
diff changeset
193 }
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
194
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
195 /* execute timeout handlers */
7098
becdf2eacdce Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents: 5330
diff changeset
196 io_loop_handle_timeouts(ioloop);
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
197
4576
Timo Sirainen <tss@iki.fi>
parents: 4573
diff changeset
198 if (!ioloop->running)
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
199 return;
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
200
4576
Timo Sirainen <tss@iki.fi>
parents: 4573
diff changeset
201 for (i = 0; i < ret; i++) {
Timo Sirainen <tss@iki.fi>
parents: 4573
diff changeset
202 /* io_loop_handle_add() may cause events array reallocation,
Timo Sirainen <tss@iki.fi>
parents: 4573
diff changeset
203 so we have use array_idx() */
Timo Sirainen <tss@iki.fi>
parents: 4573
diff changeset
204 event = array_idx(&ctx->events, i);
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
205 list = event->data.ptr;
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
206
4576
Timo Sirainen <tss@iki.fi>
parents: 4573
diff changeset
207 for (j = 0; j < IOLOOP_IOLIST_IOS_PER_FD; j++) {
Timo Sirainen <tss@iki.fi>
parents: 4573
diff changeset
208 io = list->ios[j];
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
209 if (io == NULL)
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
210 continue;
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
211
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
212 call = FALSE;
3613
c4c1b538d8d0 Added IO_ERROR condition that we can watch now.
Timo Sirainen <tss@iki.fi>
parents: 3612
diff changeset
213 if ((event->events & (EPOLLHUP | EPOLLERR)) != 0)
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
214 call = TRUE;
5248
12ac5f685814 Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents: 4863
diff changeset
215 else if ((io->io.condition & IO_READ) != 0)
3613
c4c1b538d8d0 Added IO_ERROR condition that we can watch now.
Timo Sirainen <tss@iki.fi>
parents: 3612
diff changeset
216 call = (event->events & EPOLLIN) != 0;
5248
12ac5f685814 Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents: 4863
diff changeset
217 else if ((io->io.condition & IO_WRITE) != 0)
3613
c4c1b538d8d0 Added IO_ERROR condition that we can watch now.
Timo Sirainen <tss@iki.fi>
parents: 3612
diff changeset
218 call = (event->events & EPOLLOUT) != 0;
5248
12ac5f685814 Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents: 4863
diff changeset
219 else if ((io->io.condition & IO_ERROR) != 0)
3613
c4c1b538d8d0 Added IO_ERROR condition that we can watch now.
Timo Sirainen <tss@iki.fi>
parents: 3612
diff changeset
220 call = (event->events & IO_EPOLL_ERROR) != 0;
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
221
12497
1bac1c09201a ioloop: Added support for per-io/timeout callback log prefix automation.
Timo Sirainen <tss@iki.fi>
parents: 12282
diff changeset
222 if (call)
1bac1c09201a ioloop: Added support for per-io/timeout callback log prefix automation.
Timo Sirainen <tss@iki.fi>
parents: 12282
diff changeset
223 io_loop_call_io(&io->io);
2572
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
224 }
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
225 }
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
226 }
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
227
829e683fd894 forgot to commit
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
228 #endif /* IOLOOP_EPOLL */