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