Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib/ioloop.c @ 9451:9fff30644260 HEAD
istream-concat: Fixed a lot of bugs.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 26 Oct 2009 17:06:57 -0400 |
parents | f834d95f173a |
children | 00cd9aacd03c |
rev | line source |
---|---|
8590
b9faf4db2a9f
Updated copyright notices to include year 2009.
Timo Sirainen <tss@iki.fi>
parents:
8504
diff
changeset
|
1 /* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */ |
0 | 2 |
3 #include "lib.h" | |
9310
f834d95f173a
Moved all struct timeval comparing/calculation code to lib/time-util.
Timo Sirainen <tss@iki.fi>
parents:
8634
diff
changeset
|
4 #include "time-util.h" |
0 | 5 #include "ioloop-internal.h" |
6 | |
5222
685a2d213438
If time moves backwards only max. 5 seconds, sleep instead of killing
Timo Sirainen <tss@iki.fi>
parents:
5204
diff
changeset
|
7 #include <unistd.h> |
685a2d213438
If time moves backwards only max. 5 seconds, sleep instead of killing
Timo Sirainen <tss@iki.fi>
parents:
5204
diff
changeset
|
8 |
685a2d213438
If time moves backwards only max. 5 seconds, sleep instead of killing
Timo Sirainen <tss@iki.fi>
parents:
5204
diff
changeset
|
9 /* If time moves backwards more than this, kill ourself instead of sleeping. */ |
685a2d213438
If time moves backwards only max. 5 seconds, sleep instead of killing
Timo Sirainen <tss@iki.fi>
parents:
5204
diff
changeset
|
10 #define IOLOOP_MAX_TIME_BACKWARDS_SLEEP 5 |
685a2d213438
If time moves backwards only max. 5 seconds, sleep instead of killing
Timo Sirainen <tss@iki.fi>
parents:
5204
diff
changeset
|
11 |
4102
99b17f13cc1e
Timers weren't called always properly when they should have.
Timo Sirainen <tss@iki.fi>
parents:
3987
diff
changeset
|
12 #define timer_is_larger(tvp, uvp) \ |
0 | 13 ((tvp)->tv_sec > (uvp)->tv_sec || \ |
14 ((tvp)->tv_sec == (uvp)->tv_sec && \ | |
15 (tvp)->tv_usec > (uvp)->tv_usec)) | |
16 | |
404
f25e575bf1ca
Created datastack_mempool which is used by at least a few temporary
Timo Sirainen <tss@iki.fi>
parents:
389
diff
changeset
|
17 time_t ioloop_time = 0; |
0 | 18 struct timeval ioloop_timeval; |
492
efa46e28a0d7
Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents:
404
diff
changeset
|
19 struct timezone ioloop_timezone; |
0 | 20 |
3798
be1bac1dd005
Export current_ioloop globally.
Timo Sirainen <tss@iki.fi>
parents:
3534
diff
changeset
|
21 struct ioloop *current_ioloop = NULL; |
0 | 22 |
8634
86c28d14ddeb
Added io_loop_set_max_fd_count() to specify how many fds we expect to use.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
23 static void io_loop_initialize_handler(struct ioloop *ioloop) |
86c28d14ddeb
Added io_loop_set_max_fd_count() to specify how many fds we expect to use.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
24 { |
86c28d14ddeb
Added io_loop_set_max_fd_count() to specify how many fds we expect to use.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
25 unsigned int 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:
8590
diff
changeset
|
26 |
86c28d14ddeb
Added io_loop_set_max_fd_count() to specify how many fds we expect to use.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
27 initial_fd_count = ioloop->max_fd_count > 0 && |
86c28d14ddeb
Added io_loop_set_max_fd_count() to specify how many fds we expect to use.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
28 ioloop->max_fd_count < IOLOOP_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:
8590
diff
changeset
|
29 ioloop->max_fd_count : IOLOOP_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:
8590
diff
changeset
|
30 io_loop_handler_init(ioloop, 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:
8590
diff
changeset
|
31 } |
86c28d14ddeb
Added io_loop_set_max_fd_count() to specify how many fds we expect to use.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
32 |
4903
204d7edc7cdc
Added context parameter type safety checks for most callback APIs.
Timo Sirainen <tss@iki.fi>
parents:
4582
diff
changeset
|
33 #undef io_add |
1729
5bf22d6bb65e
Added IO_DIR_NOTIFY and IO_FILE_NOTIFY conditions to io_add(). IO_DIR_NOTIFY
Timo Sirainen <tss@iki.fi>
parents:
1502
diff
changeset
|
34 struct io *io_add(int fd, enum io_condition condition, |
5bf22d6bb65e
Added IO_DIR_NOTIFY and IO_FILE_NOTIFY conditions to io_add(). IO_DIR_NOTIFY
Timo Sirainen <tss@iki.fi>
parents:
1502
diff
changeset
|
35 io_callback_t *callback, void *context) |
0 | 36 { |
5248
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
37 struct io_file *io; |
0 | 38 |
39 i_assert(fd >= 0); | |
953
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
40 i_assert(callback != NULL); |
3534
a9be1824403b
New inotify code and notify API change. Patch by Johannes Berg
Timo Sirainen <tss@iki.fi>
parents:
3527
diff
changeset
|
41 i_assert((condition & IO_NOTIFY) == 0); |
1729
5bf22d6bb65e
Added IO_DIR_NOTIFY and IO_FILE_NOTIFY conditions to io_add(). IO_DIR_NOTIFY
Timo Sirainen <tss@iki.fi>
parents:
1502
diff
changeset
|
42 |
5248
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
43 io = i_new(struct io_file, 1); |
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
44 io->io.condition = condition; |
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
45 io->io.callback = callback; |
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
46 io->io.context = context; |
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
|
47 io->io.ioloop = current_ioloop; |
4579
40b353def38c
OK, so the original kqueue code wasn't actually broken, but it could have
Timo Sirainen <tss@iki.fi>
parents:
4102
diff
changeset
|
48 io->refcount = 1; |
0 | 49 io->fd = fd; |
50 | |
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
|
51 if (io->io.ioloop->handler_context == NULL) |
8634
86c28d14ddeb
Added io_loop_set_max_fd_count() to specify how many fds we expect to use.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
52 io_loop_initialize_handler(io->io.ioloop); |
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
|
53 io_loop_handle_add(io); |
0 | 54 |
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
|
55 if (io->io.ioloop->io_files != NULL) { |
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
|
56 io->io.ioloop->io_files->prev = io; |
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
|
57 io->next = io->io.ioloop->io_files; |
5248
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
58 } |
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
|
59 io->io.ioloop->io_files = io; |
5248
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
60 return &io->io; |
0 | 61 } |
62 | |
5248
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
63 static void io_file_unlink(struct io_file *io) |
3534
a9be1824403b
New inotify code and notify API change. Patch by Johannes Berg
Timo Sirainen <tss@iki.fi>
parents:
3527
diff
changeset
|
64 { |
5248
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
65 if (io->prev != NULL) |
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
66 io->prev->next = io->next; |
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
67 else |
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
|
68 io->io.ioloop->io_files = io->next; |
3959
ef5595d6ddec
Cleanups: Make io_remove() do the linked list updating also for notify
Timo Sirainen <tss@iki.fi>
parents:
3958
diff
changeset
|
69 |
ef5595d6ddec
Cleanups: Make io_remove() do the linked list updating also for notify
Timo Sirainen <tss@iki.fi>
parents:
3958
diff
changeset
|
70 if (io->next != NULL) |
5248
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
71 io->next->prev = io->prev; |
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
72 |
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
73 /* if we got here from an I/O handler callback, make sure we |
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
74 don't try to handle this one next. */ |
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
|
75 if (io->io.ioloop->next_io_file == io) |
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
|
76 io->io.ioloop->next_io_file = io->next; |
3534
a9be1824403b
New inotify code and notify API change. Patch by Johannes Berg
Timo Sirainen <tss@iki.fi>
parents:
3527
diff
changeset
|
77 } |
a9be1824403b
New inotify code and notify API change. Patch by Johannes Berg
Timo Sirainen <tss@iki.fi>
parents:
3527
diff
changeset
|
78 |
8100 | 79 static void io_remove_full(struct io **_io, bool closed) |
0 | 80 { |
3879
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
81 struct io *io = *_io; |
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
82 |
6587 | 83 i_assert(io->callback != NULL); |
84 | |
3879
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
85 *_io = NULL; |
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
86 |
5248
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
87 /* make sure the callback doesn't get called anymore. |
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
88 kqueue code relies on this. */ |
4579
40b353def38c
OK, so the original kqueue code wasn't actually broken, but it could have
Timo Sirainen <tss@iki.fi>
parents:
4102
diff
changeset
|
89 io->callback = NULL; |
40b353def38c
OK, so the original kqueue code wasn't actually broken, but it could have
Timo Sirainen <tss@iki.fi>
parents:
4102
diff
changeset
|
90 |
5248
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
91 if ((io->condition & IO_NOTIFY) != 0) |
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
|
92 io_loop_notify_remove(io); |
5248
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
93 else { |
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
94 struct io_file *io_file = (struct io_file *)io; |
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
95 |
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
96 io_file_unlink(io_file); |
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
|
97 io_loop_handle_remove(io_file, closed); |
5248
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
98 } |
0 | 99 } |
100 | |
8100 | 101 void io_remove(struct io **io) |
102 { | |
103 io_remove_full(io, FALSE); | |
104 } | |
105 | |
106 void io_remove_closed(struct io **io) | |
107 { | |
108 i_assert(((*io)->condition & IO_NOTIFY) == 0); | |
109 | |
110 io_remove_full(io, TRUE); | |
111 } | |
112 | |
1171
6a22587f069a
Don't inline timeout_update_next(). gcc 3.2.2 with -O2 seems to break it.
Timo Sirainen <tss@iki.fi>
parents:
1036
diff
changeset
|
113 static void timeout_update_next(struct timeout *timeout, struct timeval *tv_now) |
0 | 114 { |
1203 | 115 if (tv_now == NULL) { |
116 if (gettimeofday(&timeout->next_run, NULL) < 0) | |
117 i_fatal("gettimeofday(): %m"); | |
118 } else { | |
0 | 119 timeout->next_run.tv_sec = tv_now->tv_sec; |
120 timeout->next_run.tv_usec = tv_now->tv_usec; | |
121 } | |
122 | |
123 /* we don't want microsecond accuracy or this function will be | |
124 called all the time - millisecond is more than enough */ | |
1171
6a22587f069a
Don't inline timeout_update_next(). gcc 3.2.2 with -O2 seems to break it.
Timo Sirainen <tss@iki.fi>
parents:
1036
diff
changeset
|
125 timeout->next_run.tv_usec -= timeout->next_run.tv_usec % 1000; |
0 | 126 |
127 timeout->next_run.tv_sec += timeout->msecs/1000; | |
128 timeout->next_run.tv_usec += (timeout->msecs%1000)*1000; | |
129 | |
130 if (timeout->next_run.tv_usec > 1000000) { | |
131 timeout->next_run.tv_sec++; | |
132 timeout->next_run.tv_usec -= 1000000; | |
133 } | |
134 } | |
135 | |
4903
204d7edc7cdc
Added context parameter type safety checks for most callback APIs.
Timo Sirainen <tss@iki.fi>
parents:
4582
diff
changeset
|
136 #undef timeout_add |
1499
e850252cdc7e
Removed I/O priorities. They were pretty much useless and were just getting
Timo Sirainen <tss@iki.fi>
parents:
1475
diff
changeset
|
137 struct timeout *timeout_add(unsigned int msecs, timeout_callback_t *callback, |
953
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
138 void *context) |
0 | 139 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
899
diff
changeset
|
140 struct timeout *timeout; |
0 | 141 |
5248
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
142 timeout = i_new(struct timeout, 1); |
0 | 143 timeout->msecs = msecs; |
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
|
144 timeout->ioloop = current_ioloop; |
0 | 145 |
953
411006be3c66
Naming change for function typedefs.
Timo Sirainen <tss@iki.fi>
parents:
903
diff
changeset
|
146 timeout->callback = callback; |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
147 timeout->context = context; |
0 | 148 |
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
|
149 timeout_update_next(timeout, timeout->ioloop->running ? |
404
f25e575bf1ca
Created datastack_mempool which is used by at least a few temporary
Timo Sirainen <tss@iki.fi>
parents:
389
diff
changeset
|
150 NULL : &ioloop_timeval); |
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
|
151 priorityq_add(timeout->ioloop->timeouts, &timeout->item); |
0 | 152 return timeout; |
153 } | |
154 | |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
155 void timeout_remove(struct timeout **_timeout) |
0 | 156 { |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
157 struct timeout *timeout = *_timeout; |
0 | 158 |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
159 *_timeout = NULL; |
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
|
160 priorityq_remove(timeout->ioloop->timeouts, &timeout->item); |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
161 i_free(timeout); |
0 | 162 } |
163 | |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
164 static void |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
165 timeout_reset_timeval(struct timeout *timeout, struct timeval *tv_now) |
0 | 166 { |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
167 timeout_update_next(timeout, tv_now); |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
168 if (timeout->msecs == 0) { |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
169 /* if we came here from io_loop_handle_timeouts(), |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
170 next_run must be larger than tv_now or we could go to |
8504
2297a352dfd3
ioloop: 0 ms timeouts could still have caused infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
8503
diff
changeset
|
171 infinite loop. +1000 to get 1 ms further, another +1000 to |
2297a352dfd3
ioloop: 0 ms timeouts could still have caused infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
8503
diff
changeset
|
172 account for timeout_update_next()'s truncation. */ |
2297a352dfd3
ioloop: 0 ms timeouts could still have caused infinite looping.
Timo Sirainen <tss@iki.fi>
parents:
8503
diff
changeset
|
173 timeout->next_run.tv_usec += 2000; |
7537
d432ef4835e3
timeout_add(0, ..) was looping in timeout handling code.
Timo Sirainen <tss@iki.fi>
parents:
7226
diff
changeset
|
174 if (timeout->next_run.tv_usec >= 1000000) { |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
175 timeout->next_run.tv_sec++; |
7537
d432ef4835e3
timeout_add(0, ..) was looping in timeout handling code.
Timo Sirainen <tss@iki.fi>
parents:
7226
diff
changeset
|
176 timeout->next_run.tv_usec -= 1000000; |
d432ef4835e3
timeout_add(0, ..) was looping in timeout handling code.
Timo Sirainen <tss@iki.fi>
parents:
7226
diff
changeset
|
177 } |
1475
474e4b205af7
If there were no timeouts, struct timeval wasn't initialized and select()
Timo Sirainen <tss@iki.fi>
parents:
1351
diff
changeset
|
178 } |
7537
d432ef4835e3
timeout_add(0, ..) was looping in timeout handling code.
Timo Sirainen <tss@iki.fi>
parents:
7226
diff
changeset
|
179 i_assert(tv_now == NULL || |
d432ef4835e3
timeout_add(0, ..) was looping in timeout handling code.
Timo Sirainen <tss@iki.fi>
parents:
7226
diff
changeset
|
180 timeout->next_run.tv_sec > tv_now->tv_sec || |
d432ef4835e3
timeout_add(0, ..) was looping in timeout handling code.
Timo Sirainen <tss@iki.fi>
parents:
7226
diff
changeset
|
181 (timeout->next_run.tv_sec == tv_now->tv_sec && |
d432ef4835e3
timeout_add(0, ..) was looping in timeout handling code.
Timo Sirainen <tss@iki.fi>
parents:
7226
diff
changeset
|
182 timeout->next_run.tv_usec > tv_now->tv_usec)); |
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
|
183 priorityq_remove(timeout->ioloop->timeouts, &timeout->item); |
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
|
184 priorityq_add(timeout->ioloop->timeouts, &timeout->item); |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
185 } |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
186 |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
187 void timeout_reset(struct timeout *timeout) |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
188 { |
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
|
189 timeout_reset_timeval(timeout, timeout->ioloop->running ? NULL : |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
190 &ioloop_timeval); |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
191 } |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
192 |
7152
3e506d46655f
timeout_get_wait_time() may have returned negative seconds in timeval. Also
Timo Sirainen <tss@iki.fi>
parents:
7098
diff
changeset
|
193 static int timeout_get_wait_time(struct timeout *timeout, struct timeval *tv_r, |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
194 struct timeval *tv_now) |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
195 { |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
196 int ret; |
0 | 197 |
1203 | 198 if (tv_now == NULL) { |
7152
3e506d46655f
timeout_get_wait_time() may have returned negative seconds in timeval. Also
Timo Sirainen <tss@iki.fi>
parents:
7098
diff
changeset
|
199 if (gettimeofday(tv_r, NULL) < 0) |
1203 | 200 i_fatal("gettimeofday(): %m"); |
201 } else { | |
7152
3e506d46655f
timeout_get_wait_time() may have returned negative seconds in timeval. Also
Timo Sirainen <tss@iki.fi>
parents:
7098
diff
changeset
|
202 tv_r->tv_sec = tv_now->tv_sec; |
3e506d46655f
timeout_get_wait_time() may have returned negative seconds in timeval. Also
Timo Sirainen <tss@iki.fi>
parents:
7098
diff
changeset
|
203 tv_r->tv_usec = tv_now->tv_usec; |
0 | 204 } |
8503
16ca1b36e6c3
Avoid integer overflows when calculating with very large timeout values.
Timo Sirainen <tss@iki.fi>
parents:
8366
diff
changeset
|
205 i_assert(tv_r->tv_sec > 0); |
16ca1b36e6c3
Avoid integer overflows when calculating with very large timeout values.
Timo Sirainen <tss@iki.fi>
parents:
8366
diff
changeset
|
206 i_assert(timeout->next_run.tv_sec > 0); |
0 | 207 |
7152
3e506d46655f
timeout_get_wait_time() may have returned negative seconds in timeval. Also
Timo Sirainen <tss@iki.fi>
parents:
7098
diff
changeset
|
208 tv_r->tv_sec = timeout->next_run.tv_sec - tv_r->tv_sec; |
3e506d46655f
timeout_get_wait_time() may have returned negative seconds in timeval. Also
Timo Sirainen <tss@iki.fi>
parents:
7098
diff
changeset
|
209 tv_r->tv_usec = timeout->next_run.tv_usec - tv_r->tv_usec; |
3e506d46655f
timeout_get_wait_time() may have returned negative seconds in timeval. Also
Timo Sirainen <tss@iki.fi>
parents:
7098
diff
changeset
|
210 if (tv_r->tv_usec < 0) { |
3e506d46655f
timeout_get_wait_time() may have returned negative seconds in timeval. Also
Timo Sirainen <tss@iki.fi>
parents:
7098
diff
changeset
|
211 tv_r->tv_sec--; |
3e506d46655f
timeout_get_wait_time() may have returned negative seconds in timeval. Also
Timo Sirainen <tss@iki.fi>
parents:
7098
diff
changeset
|
212 tv_r->tv_usec += 1000000; |
0 | 213 } |
214 | |
8503
16ca1b36e6c3
Avoid integer overflows when calculating with very large timeout values.
Timo Sirainen <tss@iki.fi>
parents:
8366
diff
changeset
|
215 if (tv_r->tv_sec < 0 || (tv_r->tv_sec == 0 && tv_r->tv_usec < 1000)) { |
7152
3e506d46655f
timeout_get_wait_time() may have returned negative seconds in timeval. Also
Timo Sirainen <tss@iki.fi>
parents:
7098
diff
changeset
|
216 tv_r->tv_sec = 0; |
3e506d46655f
timeout_get_wait_time() may have returned negative seconds in timeval. Also
Timo Sirainen <tss@iki.fi>
parents:
7098
diff
changeset
|
217 tv_r->tv_usec = 0; |
3e506d46655f
timeout_get_wait_time() may have returned negative seconds in timeval. Also
Timo Sirainen <tss@iki.fi>
parents:
7098
diff
changeset
|
218 return 0; |
3e506d46655f
timeout_get_wait_time() may have returned negative seconds in timeval. Also
Timo Sirainen <tss@iki.fi>
parents:
7098
diff
changeset
|
219 } |
8503
16ca1b36e6c3
Avoid integer overflows when calculating with very large timeout values.
Timo Sirainen <tss@iki.fi>
parents:
8366
diff
changeset
|
220 if (tv_r->tv_sec > INT_MAX/1000-1) |
16ca1b36e6c3
Avoid integer overflows when calculating with very large timeout values.
Timo Sirainen <tss@iki.fi>
parents:
8366
diff
changeset
|
221 tv_r->tv_sec = INT_MAX/1000-1; |
16ca1b36e6c3
Avoid integer overflows when calculating with very large timeout values.
Timo Sirainen <tss@iki.fi>
parents:
8366
diff
changeset
|
222 |
16ca1b36e6c3
Avoid integer overflows when calculating with very large timeout values.
Timo Sirainen <tss@iki.fi>
parents:
8366
diff
changeset
|
223 /* round wait times up to next millisecond */ |
16ca1b36e6c3
Avoid integer overflows when calculating with very large timeout values.
Timo Sirainen <tss@iki.fi>
parents:
8366
diff
changeset
|
224 ret = tv_r->tv_sec * 1000 + (tv_r->tv_usec + 999) / 1000; |
16ca1b36e6c3
Avoid integer overflows when calculating with very large timeout values.
Timo Sirainen <tss@iki.fi>
parents:
8366
diff
changeset
|
225 i_assert(ret > 0 && tv_r->tv_sec >= 0 && tv_r->tv_usec >= 0); |
7152
3e506d46655f
timeout_get_wait_time() may have returned negative seconds in timeval. Also
Timo Sirainen <tss@iki.fi>
parents:
7098
diff
changeset
|
226 return ret; |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
227 } |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
228 |
7152
3e506d46655f
timeout_get_wait_time() may have returned negative seconds in timeval. Also
Timo Sirainen <tss@iki.fi>
parents:
7098
diff
changeset
|
229 int io_loop_get_wait_time(struct ioloop *ioloop, struct timeval *tv_r, |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
230 struct timeval *tv_now) |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
231 { |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
232 struct priorityq_item *item; |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
233 struct timeout *timeout; |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
234 |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
235 item = priorityq_peek(ioloop->timeouts); |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
236 timeout = (struct timeout *)item; |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
237 if (timeout == NULL) { |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
238 /* no timeouts. give it INT_MAX msecs. */ |
7152
3e506d46655f
timeout_get_wait_time() may have returned negative seconds in timeval. Also
Timo Sirainen <tss@iki.fi>
parents:
7098
diff
changeset
|
239 tv_r->tv_sec = INT_MAX / 1000; |
3e506d46655f
timeout_get_wait_time() may have returned negative seconds in timeval. Also
Timo Sirainen <tss@iki.fi>
parents:
7098
diff
changeset
|
240 tv_r->tv_usec = 0; |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
241 return INT_MAX; |
5328
239ccb49852c
If timeout wait time was less than 1 millisecond, we wasted CPU calling
Timo Sirainen <tss@iki.fi>
parents:
5248
diff
changeset
|
242 } |
0 | 243 |
7152
3e506d46655f
timeout_get_wait_time() may have returned negative seconds in timeval. Also
Timo Sirainen <tss@iki.fi>
parents:
7098
diff
changeset
|
244 return timeout_get_wait_time(timeout, tv_r, tv_now); |
0 | 245 } |
246 | |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
247 static int timeout_cmp(const void *p1, const void *p2) |
0 | 248 { |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
249 const struct timeout *to1 = p1, *to2 = p2; |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
250 |
9310
f834d95f173a
Moved all struct timeval comparing/calculation code to lib/time-util.
Timo Sirainen <tss@iki.fi>
parents:
8634
diff
changeset
|
251 return timeval_cmp(&to1->next_run, &to2->next_run); |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
252 } |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
253 |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
254 static void io_loop_handle_timeouts_real(struct ioloop *ioloop) |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
255 { |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
256 struct priorityq_item *item; |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
257 struct timeval tv, tv_call; |
536
37893ed97492
changed t_push() and t_pop() to return unsigned int. added global
Timo Sirainen <tss@iki.fi>
parents:
492
diff
changeset
|
258 unsigned int t_id; |
0 | 259 |
1203 | 260 if (gettimeofday(&ioloop_timeval, &ioloop_timezone) < 0) |
261 i_fatal("gettimeofday(): %m"); | |
5204
c0d7aeedea81
If time moves backwards, kill ourself.
Timo Sirainen <tss@iki.fi>
parents:
5139
diff
changeset
|
262 |
5222
685a2d213438
If time moves backwards only max. 5 seconds, sleep instead of killing
Timo Sirainen <tss@iki.fi>
parents:
5204
diff
changeset
|
263 /* Don't bother comparing usecs. */ |
5204
c0d7aeedea81
If time moves backwards, kill ourself.
Timo Sirainen <tss@iki.fi>
parents:
5139
diff
changeset
|
264 if (ioloop_time > ioloop_timeval.tv_sec) { |
5222
685a2d213438
If time moves backwards only max. 5 seconds, sleep instead of killing
Timo Sirainen <tss@iki.fi>
parents:
5204
diff
changeset
|
265 time_t diff = ioloop_time - ioloop_timeval.tv_sec; |
685a2d213438
If time moves backwards only max. 5 seconds, sleep instead of killing
Timo Sirainen <tss@iki.fi>
parents:
5204
diff
changeset
|
266 |
5242
8bdbb0b17ae2
Added a comment about the time moving backwards code.
Timo Sirainen <tss@iki.fi>
parents:
5237
diff
changeset
|
267 /* Note that this code is here only because this is the easiest |
8bdbb0b17ae2
Added a comment about the time moving backwards code.
Timo Sirainen <tss@iki.fi>
parents:
5237
diff
changeset
|
268 place to check for this. The I/O loop code itself could be |
8bdbb0b17ae2
Added a comment about the time moving backwards code.
Timo Sirainen <tss@iki.fi>
parents:
5237
diff
changeset
|
269 easily fixed to work with time moving backwards, but there's |
8bdbb0b17ae2
Added a comment about the time moving backwards code.
Timo Sirainen <tss@iki.fi>
parents:
5237
diff
changeset
|
270 really no point because there are a lot of other places |
8bdbb0b17ae2
Added a comment about the time moving backwards code.
Timo Sirainen <tss@iki.fi>
parents:
5237
diff
changeset
|
271 which may break in more or less bad ways, such as files' |
8bdbb0b17ae2
Added a comment about the time moving backwards code.
Timo Sirainen <tss@iki.fi>
parents:
5237
diff
changeset
|
272 timestamps moving backwards. */ |
5222
685a2d213438
If time moves backwards only max. 5 seconds, sleep instead of killing
Timo Sirainen <tss@iki.fi>
parents:
5204
diff
changeset
|
273 if (diff > IOLOOP_MAX_TIME_BACKWARDS_SLEEP) { |
685a2d213438
If time moves backwards only max. 5 seconds, sleep instead of killing
Timo Sirainen <tss@iki.fi>
parents:
5204
diff
changeset
|
274 i_fatal("Time just moved backwards by %ld seconds. " |
685a2d213438
If time moves backwards only max. 5 seconds, sleep instead of killing
Timo Sirainen <tss@iki.fi>
parents:
5204
diff
changeset
|
275 "This might cause a lot of problems, " |
5636
d5212abd8d61
Added wiki link to "time moved backwards" error.
Timo Sirainen <tss@iki.fi>
parents:
5418
diff
changeset
|
276 "so I'll just kill myself now. " |
d5212abd8d61
Added wiki link to "time moved backwards" error.
Timo Sirainen <tss@iki.fi>
parents:
5418
diff
changeset
|
277 "http://wiki.dovecot.org/TimeMovedBackwards", |
d5212abd8d61
Added wiki link to "time moved backwards" error.
Timo Sirainen <tss@iki.fi>
parents:
5418
diff
changeset
|
278 (long)diff); |
5222
685a2d213438
If time moves backwards only max. 5 seconds, sleep instead of killing
Timo Sirainen <tss@iki.fi>
parents:
5204
diff
changeset
|
279 } else { |
685a2d213438
If time moves backwards only max. 5 seconds, sleep instead of killing
Timo Sirainen <tss@iki.fi>
parents:
5204
diff
changeset
|
280 i_error("Time just moved backwards by %ld seconds. " |
5636
d5212abd8d61
Added wiki link to "time moved backwards" error.
Timo Sirainen <tss@iki.fi>
parents:
5418
diff
changeset
|
281 "I'll sleep now until we're back in present. " |
d5212abd8d61
Added wiki link to "time moved backwards" error.
Timo Sirainen <tss@iki.fi>
parents:
5418
diff
changeset
|
282 "http://wiki.dovecot.org/TimeMovedBackwards", |
5222
685a2d213438
If time moves backwards only max. 5 seconds, sleep instead of killing
Timo Sirainen <tss@iki.fi>
parents:
5204
diff
changeset
|
283 (long)diff); |
685a2d213438
If time moves backwards only max. 5 seconds, sleep instead of killing
Timo Sirainen <tss@iki.fi>
parents:
5204
diff
changeset
|
284 /* Sleep extra second to make sure usecs also grows. */ |
5237
78553445a036
Don't die if "time moved backwards" sleep is interrupted.
Timo Sirainen <tss@iki.fi>
parents:
5222
diff
changeset
|
285 diff++; |
78553445a036
Don't die if "time moved backwards" sleep is interrupted.
Timo Sirainen <tss@iki.fi>
parents:
5222
diff
changeset
|
286 |
78553445a036
Don't die if "time moved backwards" sleep is interrupted.
Timo Sirainen <tss@iki.fi>
parents:
5222
diff
changeset
|
287 while (diff > 0 && sleep(diff) != 0) { |
78553445a036
Don't die if "time moved backwards" sleep is interrupted.
Timo Sirainen <tss@iki.fi>
parents:
5222
diff
changeset
|
288 /* don't use sleep()'s return value, because |
78553445a036
Don't die if "time moved backwards" sleep is interrupted.
Timo Sirainen <tss@iki.fi>
parents:
5222
diff
changeset
|
289 it could get us to a long loop in case |
78553445a036
Don't die if "time moved backwards" sleep is interrupted.
Timo Sirainen <tss@iki.fi>
parents:
5222
diff
changeset
|
290 interrupts just keep coming */ |
78553445a036
Don't die if "time moved backwards" sleep is interrupted.
Timo Sirainen <tss@iki.fi>
parents:
5222
diff
changeset
|
291 diff = ioloop_time - time(NULL) + 1; |
78553445a036
Don't die if "time moved backwards" sleep is interrupted.
Timo Sirainen <tss@iki.fi>
parents:
5222
diff
changeset
|
292 } |
5222
685a2d213438
If time moves backwards only max. 5 seconds, sleep instead of killing
Timo Sirainen <tss@iki.fi>
parents:
5204
diff
changeset
|
293 |
685a2d213438
If time moves backwards only max. 5 seconds, sleep instead of killing
Timo Sirainen <tss@iki.fi>
parents:
5204
diff
changeset
|
294 /* Try again. */ |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
295 io_loop_handle_timeouts(ioloop); |
5222
685a2d213438
If time moves backwards only max. 5 seconds, sleep instead of killing
Timo Sirainen <tss@iki.fi>
parents:
5204
diff
changeset
|
296 } |
5204
c0d7aeedea81
If time moves backwards, kill ourself.
Timo Sirainen <tss@iki.fi>
parents:
5139
diff
changeset
|
297 } |
0 | 298 ioloop_time = ioloop_timeval.tv_sec; |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
299 tv_call = ioloop_timeval; |
0 | 300 |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
301 while ((item = priorityq_peek(ioloop->timeouts)) != NULL) { |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
302 struct timeout *timeout = (struct timeout *)item; |
4102
99b17f13cc1e
Timers weren't called always properly when they should have.
Timo Sirainen <tss@iki.fi>
parents:
3987
diff
changeset
|
303 |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
304 /* use tv_call to make sure we don't get to infinite loop in |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
305 case callbacks update ioloop_timeval. */ |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
306 if (timeout_get_wait_time(timeout, &tv, &tv_call) > 0) |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
307 break; |
0 | 308 |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
309 /* update timeout's next_run and reposition it in the queue */ |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
310 timeout_reset_timeval(timeout, &tv_call); |
0 | 311 |
312 t_id = t_push(); | |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
313 timeout->callback(timeout->context); |
3527
56df153e9f65
If we leaked a t_pop() call, tell where it happened
Timo Sirainen <tss@iki.fi>
parents:
3482
diff
changeset
|
314 if (t_pop() != t_id) { |
56df153e9f65
If we leaked a t_pop() call, tell where it happened
Timo Sirainen <tss@iki.fi>
parents:
3482
diff
changeset
|
315 i_panic("Leaked a t_pop() call in timeout handler %p", |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
316 (void *)timeout->callback); |
3527
56df153e9f65
If we leaked a t_pop() call, tell where it happened
Timo Sirainen <tss@iki.fi>
parents:
3482
diff
changeset
|
317 } |
0 | 318 } |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
319 } |
4102
99b17f13cc1e
Timers weren't called always properly when they should have.
Timo Sirainen <tss@iki.fi>
parents:
3987
diff
changeset
|
320 |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
321 void io_loop_handle_timeouts(struct ioloop *ioloop) |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
322 { |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7154
diff
changeset
|
323 T_BEGIN { |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
324 io_loop_handle_timeouts_real(ioloop); |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7154
diff
changeset
|
325 } T_END; |
0 | 326 } |
327 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
899
diff
changeset
|
328 void io_loop_run(struct ioloop *ioloop) |
0 | 329 { |
5939
8f1d94246a8f
Delay initializing ioloop backend until it's needed.
Timo Sirainen <tss@iki.fi>
parents:
5636
diff
changeset
|
330 if (ioloop->handler_context == NULL) |
8634
86c28d14ddeb
Added io_loop_set_max_fd_count() to specify how many fds we expect to use.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
331 io_loop_initialize_handler(ioloop); |
5939
8f1d94246a8f
Delay initializing ioloop backend until it's needed.
Timo Sirainen <tss@iki.fi>
parents:
5636
diff
changeset
|
332 |
8f1d94246a8f
Delay initializing ioloop backend until it's needed.
Timo Sirainen <tss@iki.fi>
parents:
5636
diff
changeset
|
333 ioloop->running = TRUE; |
0 | 334 while (ioloop->running) |
335 io_loop_handler_run(ioloop); | |
336 } | |
337 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
899
diff
changeset
|
338 void io_loop_stop(struct ioloop *ioloop) |
0 | 339 { |
340 ioloop->running = FALSE; | |
341 } | |
342 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
899
diff
changeset
|
343 void io_loop_set_running(struct ioloop *ioloop) |
0 | 344 { |
345 ioloop->running = TRUE; | |
346 } | |
347 | |
8634
86c28d14ddeb
Added io_loop_set_max_fd_count() to specify how many fds we expect to use.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
348 void io_loop_set_max_fd_count(struct ioloop *ioloop, unsigned int max_fds) |
86c28d14ddeb
Added io_loop_set_max_fd_count() to specify how many fds we expect to use.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
349 { |
86c28d14ddeb
Added io_loop_set_max_fd_count() to specify how many fds we expect to use.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
350 ioloop->max_fd_count = max_fds; |
86c28d14ddeb
Added io_loop_set_max_fd_count() to specify how many fds we expect to use.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
351 } |
86c28d14ddeb
Added io_loop_set_max_fd_count() to specify how many fds we expect to use.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
352 |
3863
55df57c028d4
Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents:
3798
diff
changeset
|
353 bool io_loop_is_running(struct ioloop *ioloop) |
1033 | 354 { |
355 return ioloop->running; | |
356 } | |
357 | |
5248
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
358 struct ioloop *io_loop_create(void) |
0 | 359 { |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
899
diff
changeset
|
360 struct ioloop *ioloop; |
0 | 361 |
362 /* initialize time */ | |
1203 | 363 if (gettimeofday(&ioloop_timeval, &ioloop_timezone) < 0) |
364 i_fatal("gettimeofday(): %m"); | |
0 | 365 ioloop_time = ioloop_timeval.tv_sec; |
366 | |
5248
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
367 ioloop = i_new(struct ioloop, 1); |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
368 ioloop->timeouts = priorityq_init(timeout_cmp, 32); |
0 | 369 |
370 ioloop->prev = current_ioloop; | |
371 current_ioloop = ioloop; | |
372 | |
373 return ioloop; | |
374 } | |
375 | |
3879
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
376 void io_loop_destroy(struct ioloop **_ioloop) |
0 | 377 { |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
378 struct ioloop *ioloop = *_ioloop; |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
379 struct priorityq_item *item; |
1351
6709d9330885
minor memory leak/cleanup fixes
Timo Sirainen <tss@iki.fi>
parents:
1203
diff
changeset
|
380 |
3879
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
381 *_ioloop = NULL; |
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
382 |
5139
2d1f02635ccf
Delay initializing I/O notify backend until the first notify is added.
Timo Sirainen <tss@iki.fi>
parents:
4903
diff
changeset
|
383 if (ioloop->notify_handler_context != NULL) |
2d1f02635ccf
Delay initializing I/O notify backend until the first notify is added.
Timo Sirainen <tss@iki.fi>
parents:
4903
diff
changeset
|
384 io_loop_notify_handler_deinit(ioloop); |
3958
3e9b43d0cd80
kqueue updates. Patch by Vaclav Haisman
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
385 |
5248
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
386 while (ioloop->io_files != NULL) { |
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
387 struct io_file *io = ioloop->io_files; |
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
388 struct io *_io = &io->io; |
0 | 389 |
5248
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
390 i_warning("I/O leak: %p (%d)", (void *)io->io.callback, io->fd); |
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
391 io_remove(&_io); |
0 | 392 } |
393 | |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
394 while ((item = priorityq_pop(ioloop->timeouts)) != NULL) { |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
395 struct timeout *to = (struct timeout *)item; |
0 | 396 |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
397 i_warning("Timeout leak: %p", (void *)to->callback); |
5248
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
398 i_free(to); |
0 | 399 } |
7098
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
400 priorityq_deinit(&ioloop->timeouts); |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
401 |
becdf2eacdce
Use priority queue to implement timeout handling. Added timeout_reset().
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
402 if (ioloop->handler_context != NULL) |
5939
8f1d94246a8f
Delay initializing ioloop backend until it's needed.
Timo Sirainen <tss@iki.fi>
parents:
5636
diff
changeset
|
403 io_loop_handler_deinit(ioloop); |
0 | 404 |
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
|
405 /* ->prev won't work unless loops are destroyed in create order */ |
0 | 406 i_assert(ioloop == current_ioloop); |
407 current_ioloop = current_ioloop->prev; | |
408 | |
5248
12ac5f685814
Various cleanups to ioloop code.
Timo Sirainen <tss@iki.fi>
parents:
5242
diff
changeset
|
409 i_free(ioloop); |
0 | 410 } |
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
|
411 |
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
|
412 void io_loop_set_current(struct ioloop *ioloop) |
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
|
413 { |
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
|
414 current_ioloop = ioloop; |
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
|
415 } |