Mercurial > dovecot > core-2.2
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 |
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 | 2 |
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 | 8 |
9 #ifdef IOLOOP_EPOLL | |
10 | |
11 #include <sys/epoll.h> | |
12 #include <unistd.h> | |
13 | |
3483
84a4f150bd00
data -> context/ctx naming convention replaces
Timo Sirainen <tss@iki.fi>
parents:
3198
diff
changeset
|
14 struct ioloop_handler_context { |
2572 | 15 int epfd; |
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 | 20 }; |
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 | 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 | 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 | 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 | 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 | 41 } |
42 | |
43 void io_loop_handler_deinit(struct ioloop *ioloop) | |
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 | 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 | 58 } |
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 | 63 |
64 static int epoll_event_mask(struct io_list *list) | |
65 { | |
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 | 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 | 70 io = list->ios[i]; |
71 | |
72 if (io == NULL) | |
73 continue; | |
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 | 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 | 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 | 81 } |
82 | |
83 return events; | |
84 } | |
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 | 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 | 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 | 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 | 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 | 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 | 103 |
104 op = first ? EPOLL_CTL_ADD : EPOLL_CTL_MOD; | |
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 | 115 } |
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 | 125 } |
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 | 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 | 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 | 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 | 137 |
8100 | 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 | 140 event.data.ptr = *list; |
141 event.events = epoll_event_mask(*list); | |
2572 | 142 |
8100 | 143 op = last ? EPOLL_CTL_DEL : EPOLL_CTL_MOD; |
144 | |
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 | 153 } |
3685 | 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 | 162 } |
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 | 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 | 167 struct epoll_event *events; |
168 const struct epoll_event *event; | |
2572 | 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 | 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 | 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 | 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 | 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 | 180 |
4576 | 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 | 194 |
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 | 197 |
4576 | 198 if (!ioloop->running) |
2572 | 199 return; |
200 | |
4576 | 201 for (i = 0; i < ret; i++) { |
202 /* io_loop_handle_add() may cause events array reallocation, | |
203 so we have use array_idx() */ | |
204 event = array_idx(&ctx->events, i); | |
2572 | 205 list = event->data.ptr; |
206 | |
4576 | 207 for (j = 0; j < IOLOOP_IOLIST_IOS_PER_FD; j++) { |
208 io = list->ios[j]; | |
2572 | 209 if (io == NULL) |
210 continue; | |
211 | |
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 | 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 | 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 | 224 } |
225 } | |
226 } | |
227 | |
228 #endif /* IOLOOP_EPOLL */ |