Commit | Line | Data |
---|---|---|
460b9539 | 1 | /* |
2 | * This file is part of DisOrder. | |
e8c92ba7 | 3 | * Copyright (C) 2004, 2007 Richard Kettlewell |
460b9539 | 4 | * |
e7eb3a27 | 5 | * This program is free software: you can redistribute it and/or modify |
460b9539 | 6 | * it under the terms of the GNU General Public License as published by |
e7eb3a27 | 7 | * the Free Software Foundation, either version 3 of the License, or |
460b9539 | 8 | * (at your option) any later version. |
e7eb3a27 RK |
9 | * |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
460b9539 | 15 | * You should have received a copy of the GNU General Public License |
e7eb3a27 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
460b9539 | 17 | */ |
132a5a4a RK |
18 | /** @file lib/event.h |
19 | * @brief DisOrder event loop | |
20 | */ | |
460b9539 | 21 | #ifndef EVENT_H |
22 | #define EVENT_H | |
23 | ||
fdca70ee RK |
24 | #include <sys/socket.h> |
25 | ||
460b9539 | 26 | typedef struct ev_source ev_source; |
27 | ||
28 | struct rusage; | |
29 | struct sink; | |
30 | ||
31 | ev_source *ev_new(void); | |
32 | /* create a new event loop */ | |
33 | ||
34 | int ev_run(ev_source *ev); | |
35 | /* run an event loop. If any callback returns nonzero then that value | |
36 | * is returned. If an error occurs then -1 is returned and @error@ is | |
37 | * called. */ | |
38 | ||
39 | /* file descriptors ***********************************************************/ | |
40 | ||
41 | typedef enum { | |
42 | ev_read, | |
43 | ev_write, | |
44 | ev_except, | |
45 | ||
46 | ev_nmodes | |
47 | } ev_fdmode; | |
48 | ||
49 | typedef int ev_fd_callback(ev_source *ev, int fd, void *u); | |
50 | /* signature for fd callback functions */ | |
51 | ||
52 | int ev_fd(ev_source *ev, | |
53 | ev_fdmode mode, | |
54 | int fd, | |
55 | ev_fd_callback *callback, | |
e8c92ba7 RK |
56 | void *u, |
57 | const char *what); | |
460b9539 | 58 | /* register a callback on a file descriptor */ |
59 | ||
60 | int ev_fd_cancel(ev_source *ev, | |
61 | ev_fdmode mode, | |
62 | int fd); | |
63 | /* cancel a callback on a file descriptor */ | |
64 | ||
65 | int ev_fd_disable(ev_source *ev, | |
66 | ev_fdmode mode, | |
67 | int fd); | |
68 | /* temporarily disable callbacks on a file descriptor */ | |
69 | ||
70 | int ev_fd_enable(ev_source *ev, | |
71 | ev_fdmode mode, | |
72 | int fd); | |
73 | /* re-enable callbacks on a file descriptor */ | |
74 | ||
768d7355 RK |
75 | void ev_report(ev_source *ev); |
76 | ||
460b9539 | 77 | /* timeouts *******************************************************************/ |
78 | ||
79 | typedef int ev_timeout_callback(ev_source *ev, | |
80 | const struct timeval *now, | |
81 | void *u); | |
82 | /* signature for timeout callback functions */ | |
83 | ||
84 | typedef void *ev_timeout_handle; | |
85 | ||
86 | int ev_timeout(ev_source *ev, | |
87 | ev_timeout_handle *handlep, | |
88 | const struct timeval *when, | |
89 | ev_timeout_callback *callback, | |
90 | void *u); | |
91 | /* register a timeout callback. If @handlep@ is not a null pointer then a | |
92 | * handle suitable for ev_timeout_cancel() below is returned through it. */ | |
93 | ||
94 | int ev_timeout_cancel(ev_source *ev, | |
95 | ev_timeout_handle handle); | |
96 | /* cancel a timeout callback */ | |
97 | ||
98 | /* signals ********************************************************************/ | |
99 | ||
100 | typedef int ev_signal_callback(ev_source *ev, | |
101 | int sig, | |
102 | void *u); | |
103 | /* signature for signal callback functions */ | |
104 | ||
105 | int ev_signal(ev_source *ev, | |
106 | int sig, | |
107 | ev_signal_callback *callback, | |
108 | void *u); | |
109 | /* register a signal callback */ | |
110 | ||
111 | int ev_signal_cancel(ev_source *ev, | |
112 | int sig); | |
113 | /* cancel a signal callback */ | |
114 | ||
115 | void ev_signal_atfork(ev_source *ev); | |
116 | /* unhandle and unblock handled signals - call after calling fork and | |
117 | * then setting @exitfn@ */ | |
118 | ||
119 | /* child processes ************************************************************/ | |
120 | ||
121 | typedef int ev_child_callback(ev_source *ev, | |
122 | pid_t pid, | |
123 | int status, | |
124 | const struct rusage *rusage, | |
125 | void *u); | |
126 | /* signature for child wait callbacks */ | |
127 | ||
128 | int ev_child_setup(ev_source *ev); | |
129 | /* must be called exactly once before @ev_child@ */ | |
130 | ||
131 | int ev_child(ev_source *ev, | |
132 | pid_t pid, | |
133 | int options, | |
134 | ev_child_callback *callback, | |
135 | void *u); | |
136 | /* register a child callback. @options@ must be 0 or WUNTRACED. */ | |
137 | ||
138 | int ev_child_cancel(ev_source *ev, | |
139 | pid_t pid); | |
140 | /* cancel a child callback. */ | |
141 | ||
142 | /* socket listeners ***********************************************************/ | |
143 | ||
144 | typedef int ev_listen_callback(ev_source *ev, | |
145 | int newfd, | |
146 | const struct sockaddr *remote, | |
147 | socklen_t rlen, | |
148 | void *u); | |
149 | /* callback when a connection arrives. */ | |
150 | ||
151 | int ev_listen(ev_source *ev, | |
152 | int fd, | |
153 | ev_listen_callback *callback, | |
e8c92ba7 RK |
154 | void *u, |
155 | const char *what); | |
460b9539 | 156 | /* register a socket listener callback. @bind@ and @listen@ should |
157 | * already have been called. */ | |
158 | ||
159 | int ev_listen_cancel(ev_source *ev, | |
160 | int fd); | |
161 | /* cancel a socket listener callback */ | |
162 | ||
163 | /* buffered writer ************************************************************/ | |
164 | ||
165 | typedef struct ev_writer ev_writer; | |
166 | ||
75d64210 RK |
167 | /** @brief Error callback for @ref ev_reader and @ref ev_writer |
168 | * @param ev Event loop | |
169 | * @param errno_value Errno value (might be 0) | |
170 | * @param u As passed to ev_writer_new() or ev_reader_new() | |
171 | * @return 0 on success, non-0 on error | |
172 | * | |
173 | * This is called for a writer in the following situations: | |
174 | * - on error, with @p errno_value != 0 | |
175 | * - when all buffered data has been written, with @p errno_value = 0 | |
176 | * - after called ev_writer_cancel(), with @p errno_value = 0 | |
177 | * | |
178 | * It is called for a reader only on error, with @p errno_value != 0. | |
179 | */ | |
460b9539 | 180 | typedef int ev_error_callback(ev_source *ev, |
460b9539 | 181 | int errno_value, |
182 | void *u); | |
460b9539 | 183 | |
184 | ev_writer *ev_writer_new(ev_source *ev, | |
185 | int fd, | |
186 | ev_error_callback *callback, | |
e8c92ba7 RK |
187 | void *u, |
188 | const char *what); | |
460b9539 | 189 | /* create a new buffered writer, writing to @fd@. Calls @error@ if an |
190 | * error occurs. */ | |
191 | ||
cb9a695c RK |
192 | int ev_writer_time_bound(ev_writer *ev, |
193 | int new_time_bound); | |
194 | int ev_writer_space_bound(ev_writer *ev, | |
195 | int new_space_bound); | |
196 | ||
460b9539 | 197 | int ev_writer_close(ev_writer *w); |
198 | /* close a writer (i.e. promise not to write to it any more) */ | |
199 | ||
200 | int ev_writer_cancel(ev_writer *w); | |
201 | /* cancel a writer */ | |
202 | ||
203 | int ev_writer_flush(ev_writer *w); | |
204 | /* attempt to flush the buffer */ | |
205 | ||
206 | struct sink *ev_writer_sink(ev_writer *w) attribute((const)); | |
207 | /* return a sink for the writer - use this to actually write to it */ | |
208 | ||
209 | /* buffered reader ************************************************************/ | |
210 | ||
211 | typedef struct ev_reader ev_reader; | |
212 | ||
75d64210 RK |
213 | /** @brief Called when data is available to read |
214 | * @param ev Event loop | |
215 | * @param reader Reader | |
216 | * @param fd File descriptor we read from | |
217 | * @param ptr Pointer to first byte | |
218 | * @param bytes Number of bytes available | |
219 | * @param eof True if EOF has been detected | |
220 | * @param u As passed to ev_reader_new() | |
221 | * @return 0 on succes, non-0 on error | |
222 | * | |
223 | * This callback should call ev_reader_consume() to indicate how many bytes you | |
224 | * actually used. If you do not call it then it is assumed no bytes were | |
225 | * consumed. | |
226 | * | |
227 | * If having consumed some number of bytes it is not possible to do any further | |
228 | * processing until more data is available then the callback can just return. | |
229 | * Note that this is not allowed if @p eof was set. | |
230 | * | |
231 | * If on the other hand it would be possible to do more processing immediately | |
232 | * with the bytes available, but this is undesirable for some other reason, | |
233 | * then ev_reader_incomplete() should be called. This will arrange a further | |
234 | * callback in the very near future even if no more bytes are read. | |
235 | */ | |
460b9539 | 236 | typedef int ev_reader_callback(ev_source *ev, |
237 | ev_reader *reader, | |
460b9539 | 238 | void *ptr, |
239 | size_t bytes, | |
240 | int eof, | |
241 | void *u); | |
460b9539 | 242 | |
243 | ev_reader *ev_reader_new(ev_source *ev, | |
244 | int fd, | |
245 | ev_reader_callback *callback, | |
246 | ev_error_callback *error_callback, | |
e8c92ba7 RK |
247 | void *u, |
248 | const char *what); | |
460b9539 | 249 | /* register a new reader. @callback@ will be called whenever data is |
250 | * available. */ | |
251 | ||
252 | void ev_reader_buffer(ev_reader *r, size_t nbytes); | |
75d64210 | 253 | /* specify a buffer size */ |
460b9539 | 254 | |
75d64210 RK |
255 | void ev_reader_consume(ev_reader *r |
256 | , size_t nbytes); | |
460b9539 | 257 | /* consume @nbytes@ bytes. */ |
258 | ||
259 | int ev_reader_cancel(ev_reader *r); | |
260 | /* cancel a reader */ | |
261 | ||
262 | int ev_reader_disable(ev_reader *r); | |
263 | /* disable reading */ | |
264 | ||
265 | int ev_reader_incomplete(ev_reader *r); | |
266 | /* callback didn't fully process buffer, but would like another | |
267 | * callback (used where processing more would block too long) */ | |
268 | ||
269 | int ev_reader_enable(ev_reader *r); | |
270 | /* enable reading. If there is unconsumed data then you get a | |
271 | * callback next time round the event loop even if nothing new has | |
272 | * been read. | |
273 | * | |
274 | * The idea is in your read callback you come across a line (or | |
275 | * whatever) that can't be processed immediately. So you set up | |
276 | * processing and disable reading. Later when you finish processing | |
277 | * you re-enable. You'll automatically get another callback pretty | |
278 | * much direct from the event loop (not from inside ev_reader_enable) | |
279 | * so you can handle the next line (or whatever) if the whole thing | |
280 | * has in fact already arrived. | |
281 | */ | |
282 | ||
75d64210 RK |
283 | int ev_tie(ev_reader *r, ev_writer *w); |
284 | ||
460b9539 | 285 | #endif /* EVENT_H */ |
286 | ||
287 | /* | |
288 | Local Variables: | |
289 | c-basic-offset:2 | |
290 | comment-column:40 | |
291 | fill-column:79 | |
292 | End: | |
293 | */ |