chiark / gitweb /
Implement hooks for foreign select-using systems (currently not well
[mLib] / sel.h
1 /* -*-c-*-
2  *
3  * $Id: sel.h,v 1.5 1999/08/19 18:30:26 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.5  1999/08/19 18:30:26  mdw
34  * Implement hooks for foreign select-using systems (currently not well
35  * tested).
36  *
37  * Revision 1.4  1999/05/22 13:39:15  mdw
38  * Change spelling of `multiplexor'. ;-)
39  *
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  *
44  * Revision 1.2  1999/05/15 10:33:32  mdw
45  * Fix copyright notices.
46  *
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
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
109 enum {
110   SEL_READ,
111   SEL_WRITE,
112   SEL_EXC,
113   SEL_MODES
114 };
115
116 typedef 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
124 /* --- Listening for a file --- */
125
126 typedef 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
136 /* --- Waiting for a timeout --- */
137
138 typedef struct sel_timer {
139   struct sel_timer *next;
140   struct sel_timer *prev;
141   struct timeval tv;
142   void (*func)(struct timeval */*tv*/, void */*p*/);
143   void *p;
144 } sel_timer;
145
146 /* --- A select argument block --- */
147
148 typedef 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 --- *
156  *
157  * The hooks are called (in arbitrary order) on each select.
158  */
159
160 typedef void (*sel_hookfn)(sel_state */*s*/,
161                            sel_args */*a*/,
162                            void */*p*/);
163
164 typedef struct sel_hook {
165   struct sel_hook *next;
166   struct sel_hook *prev;
167   sel_hookfn before, after;
168   void *p;
169 } sel_hook;
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
182 extern 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
200 extern 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
216 extern 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
227 extern 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
234  *              @void *p@ = argument for handler function
235  *
236  * Returns:     ---
237  *
238  * Use:         Registers and sets up a timer.
239  */
240
241 extern 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
256 extern void sel_rmtimer(sel_timer */*t*/);
257
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
270 extern 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
283 extern 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
297 extern int sel_fdmerge(fd_set */*dest*/, fd_set */*fd*/, int /*maxfd*/);
298
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
308 extern int sel_select(sel_state */*s*/);
309
310 /*----- That's all, folks -------------------------------------------------*/
311
312 #ifdef __cplusplus
313   }
314 #endif
315
316 #endif