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