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