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