chiark / gitweb /
New dynamic array implementation replaces `dynarray.h'.
[mLib] / sel.h
CommitLineData
97f65b00 1/* -*-c-*-
2 *
1101f87a 3 * $Id: sel.h,v 1.6 1999/08/31 17:42:22 mdw Exp $
97f65b00 4 *
5 * I/O multiplexing support
6 *
a3ddb778 7 * (c) 1999 Straylight/Edgeware
97f65b00 8 */
9
10/*----- Licensing notice --------------------------------------------------*
11 *
12 * This file is part of the mLib utilities library.
13 *
14 * mLib is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * mLib is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
23 *
24 * You should have received a copy of the GNU Library General Public
25 * License along with mLib; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27 * MA 02111-1307, USA.
28 */
29
30/*----- Revision history --------------------------------------------------*
31 *
32 * $Log: sel.h,v $
1101f87a 33 * Revision 1.6 1999/08/31 17:42:22 mdw
34 * New function `sel_force' to force a descriptor to be `selected'.
35 *
1226c514 36 * Revision 1.5 1999/08/19 18:30:26 mdw
37 * Implement hooks for foreign select-using systems (currently not well
38 * tested).
39 *
d6232a7a 40 * Revision 1.4 1999/05/22 13:39:15 mdw
41 * Change spelling of `multiplexor'. ;-)
42 *
e32dabae 43 * Revision 1.3 1999/05/17 20:36:36 mdw
44 * Make the selector type symbols an enumeration rather than a bunch of
45 * #defines.
46 *
a3ddb778 47 * Revision 1.2 1999/05/15 10:33:32 mdw
48 * Fix copyright notices.
49 *
97f65b00 50 * Revision 1.1 1999/05/14 21:01:15 mdw
51 * Integrated `select' handling bits from the background resolver project.
52 *
53 */
54
55#ifndef SEL_H
56#define SEL_H
57
58#ifdef __cplusplus
59 extern "C" {
60#endif
61
62/*----- Theory lesson -----------------------------------------------------*
63 *
64 * Things which are expecting to do I/O or go off at a certain time are
65 * called `selectors'. There are two types of selectors: `file selectors'
66 * wait patiently for a file to become readable or writable; `timeout
67 * selectors' wait for a certain amount of time to elapse. There is also a
68 * `multiplexor' which copes with managing all of this stuff.
69 *
70 * Multiplexors aren't actually very interesting. You initialize them with
71 * @sel_init@, and then add and remove selectors as you go. When you want to
72 * wait for something to happen, call @sel_select@.
73 *
74 * A file selector can *either* read *or* write. It can't do both. This is
75 * because you quite often want to read a socket but not write it; during
76 * those times you don't want to write, you just don't install a write
77 * selector.
78 *
79 * File selectors are called when their files are available for reading or
80 * writing as appropriate, and given their file descriptor, the state of the
81 * file, and a pointer that was registered along with the selector.
82 *
83 * File selectors are set up in two phases. First, they're `initialized'
84 * with @sel_initfile@. An initialized file selector doesn't do anything.
85 * It needs to be added to a multiplexor using `sel_addfile'. It can later
86 * be removed using `sel_rmfile'. You can carry on adding and removing as
87 * you wish. Just don't try adding it twice in a row.
88 *
89 * Timeout selectors are called at a certain time. (Actually, they're called
90 * *after* a certain time.) There's no separate initialization step with
91 * timouts: you just add them and they work. If you decide you don't want a
92 * timeout to go off, then you just remove it. (Adding and removing the
93 * *same* timeout isn't something you do very often. You usually use a
94 * different expiry time each time.)
95 */
96
97/*----- Header files ------------------------------------------------------*/
98
99#include <sys/types.h>
100#include <sys/time.h>
101#include <unistd.h>
102
103/*----- Data structures ---------------------------------------------------*/
104
1226c514 105/* --- A multiplexor --- *
106 *
107 * The files are sorted in reverse order of file descriptor number; the
108 * timers are in normal order of occurrence. Thus, the interesting one
109 * is always at the front of the list.
110 */
111
112enum {
1101f87a 113 SEL_READ, /* File is ready to read */
114 SEL_WRITE, /* File is ready to write */
115 SEL_EXC, /* Something odd has happened */
116 SEL_MODES /* Number of modes available */
1226c514 117};
118
119typedef struct sel_state {
1101f87a 120 struct sel_file *files[SEL_MODES]; /* Lists of interesting files */
121 struct sel_timer *timers; /* List of timers */
122 struct sel_hook *hooks; /* List of hook functions applied */
123 fd_set fd[SEL_MODES]; /* Quick reference table for files */
124 struct sel_args *args; /* Pointer to arguments */
1226c514 125} sel_state;
126
97f65b00 127/* --- Listening for a file --- */
128
129typedef struct sel_file {
1101f87a 130 struct sel_file *next; /* Next file in the list */
131 struct sel_file *prev; /* Previous file in the list */
132 struct sel_state *s; /* Pointer to select multiplexor */
133 int fd; /* File descriptor */
134 unsigned mode; /* Interesting event for file */
135 void (*func)(int /*fd*/, unsigned /*mode*/, void */*p*/); /* Handler */
136 void *p; /* Argument for the handler */
97f65b00 137} sel_file;
138
97f65b00 139/* --- Waiting for a timeout --- */
140
141typedef struct sel_timer {
1101f87a 142 struct sel_timer *next; /* Next timer in the list */
143 struct sel_timer *prev; /* Previous timer in the list */
144 struct timeval tv; /* Real time when timer should go */
145 void (*func)(struct timeval */*tv*/, void */*p*/); /* Handler function */
146 void *p; /* Argument for the handler */
97f65b00 147} sel_timer;
148
1226c514 149/* --- A select argument block --- */
150
151typedef struct sel_args {
1101f87a 152 int maxfd; /* Highest-numbered file */
153 fd_set fd[SEL_MODES]; /* Bit flags for all the files */
154 struct timeval tv, *tvp; /* Time to return */
155 struct timeval now; /* Current time */
1226c514 156} sel_args;
157
158/* --- A selector hook --- *
97f65b00 159 *
1226c514 160 * The hooks are called (in arbitrary order) on each select.
97f65b00 161 */
162
1226c514 163typedef void (*sel_hookfn)(sel_state */*s*/,
164 sel_args */*a*/,
165 void */*p*/);
166
167typedef struct sel_hook {
1101f87a 168 struct sel_hook *next; /* Next hook in the list */
169 struct sel_hook *prev; /* Previous hook in the list */
170 sel_hookfn before, after; /* Hook functions */
171 void *p; /* Argument for the hook functions */
1226c514 172} sel_hook;
97f65b00 173
174/*----- Functions provided ------------------------------------------------*/
175
176/* --- @sel_init@ --- *
177 *
178 * Arguments: @sel_state *s@ = pointer to a state block to initialize
179 *
180 * Returns: ---
181 *
182 * Use: Initializes a select state block.
183 */
184
185extern void sel_init(sel_state */*s*/);
186
187/* --- @sel_initfile@ --- *
188 *
189 * Arguments: @sel_state *s@ = select state to attach to
190 * @sel_file *f@ = pointer to a file block to initialize
191 * @int fd@ = the file descriptor to listen to
192 * @unsigned mode@ = what to listen for
193 * @void (*func)(int fd, unsigned mode, void *p)@ = handler
194 * @void *p@ = argument to pass to handler
195 *
196 * Returns: ---
197 *
198 * Use: Initializes a file block ready for use. The file block
199 * isn't added to the list of things to do until a call to
200 * @sel_addfile@.
201 */
202
203extern void sel_initfile(sel_state */*s*/, sel_file */*f*/,
204 int /*fd*/, unsigned /*mode*/,
205 void (*/*func*/)(int /*fd*/,
206 unsigned /*mode*/,
207 void */*p*/),
208 void */*p*/);
209
210/* --- @sel_addfile@ --- *
211 *
212 * Arguments: @sel_file *f@ = pointer to a file block
213 *
214 * Returns: ---
215 *
216 * Use: Adds a file block into the list of things to listen to.
217 */
218
219extern void sel_addfile(sel_file */*f*/);
220
221/* --- @sel_rmfile@ --- *
222 *
223 * Arguments: @sel_file *f@ = pointer to a file block
224 *
225 * Returns: ---
226 *
227 * Use: Removes a file block from the list of things to listen to.
228 */
229
230extern void sel_rmfile(sel_file */*f*/);
231
1101f87a 232/* --- @sel_force@ --- *
233 *
234 * Arguments: @sel_file *f@ = pointer to file selector
235 *
236 * Returns: ---
237 *
238 * Use: Forces a file selector to be considered ready. This is only
239 * useful during a call to @sel_select@. Of particular use is
240 * forcing a write selector when there's something interesting
241 * ready for it.
242 */
243
244extern void sel_force(sel_file */*f*/);
245
97f65b00 246/* --- @sel_addtimer@ --- *
247 *
248 * Arguments: @sel_state *s@ = pointer to a state block
249 * @sel_timer *t@ = pointer to a timer block
250 * @struct timeval *tv@ = pointer to time to activate
97f65b00 251 * @void *p@ = argument for handler function
252 *
253 * Returns: ---
254 *
255 * Use: Registers and sets up a timer.
256 */
257
258extern void sel_addtimer(sel_state */*s*/, sel_timer */*t*/,
259 struct timeval */*tv*/,
260 void (*/*func*/)(struct timeval */*tv*/,
261 void */*p*/),
262 void */*p*/);
263
264/* --- @sel_rmtimer@ --- *
265 *
266 * Arguments: @sel_timer *t@ = pointer to timer block
267 *
268 * Returns: ---
269 *
270 * Use: Removes a timer from the list of timers.
271 */
272
273extern void sel_rmtimer(sel_timer */*t*/);
274
1226c514 275/* --- @sel_addhook@ --- *
276 *
277 * Arguments: @sel_state *s@ = pointer to state block
278 * @sel_hook *h@ = pointer to hook block
279 * @sel_hookfn before, after@ = hook functions
280 * @void *p@ = pointer argument to pass to hook functions
281 *
282 * Returns: ---
283 *
284 * Use: Registers hook functions to be called on each select call.
285 */
286
287extern void sel_addhook(sel_state */*s*/, sel_hook */*h*/,
288 sel_hookfn /*before*/, sel_hookfn /*after*/,
289 void */*p*/);
290
291/* --- @sel_rmhook@ --- *
292 *
293 * Arguments: @sel_hook *h@ = pointer to hook block
294 *
295 * Returns: ---
296 *
297 * Use: Removes hook functions.
298 */
299
300extern void sel_rmhook(sel_hook */*h*/);
301
302/* --- @sel_fdmerge@ --- *
303 *
304 * Arguments: @fd_set *dest@ = destination FD set
305 * @fd_set *fd@ = pointer to set to merge
306 * @int maxfd@ = highest numbered descriptor in @fd@ + 1
307 *
308 * Returns: Actual highest numbered descriptor.
309 *
310 * Use: Merges file descriptor sets, and returns an accurate @maxfd@
311 * value.
312 */
313
314extern int sel_fdmerge(fd_set */*dest*/, fd_set */*fd*/, int /*maxfd*/);
315
97f65b00 316/* --- @sel_select@ --- *
317 *
318 * Arguments: @sel_state *s@ = pointer to state block
319 *
320 * Returns: Zero if all OK, -1 on error.
321 *
322 * Use: Does a @select@ call (or equivalent @poll@).
323 */
324
325extern int sel_select(sel_state */*s*/);
326
327/*----- That's all, folks -------------------------------------------------*/
328
329#ifdef __cplusplus
330 }
331#endif
332
333#endif