chiark / gitweb /
Integrated `select' handling bits from the background resolver project.
[mLib] / sel.h
1 /* -*-c-*-
2  *
3  * $Id: sel.h,v 1.1 1999/05/14 21:01:15 mdw Exp $
4  *
5  * I/O multiplexing support
6  *
7  * (c) 1999 Mark Wooding
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.1  1999/05/14 21:01:15  mdw
34  * Integrated `select' handling bits from the background resolver project.
35  *
36  */
37
38 #ifndef SEL_H
39 #define SEL_H
40
41 #ifdef __cplusplus
42   extern "C" {
43 #endif
44
45 /*----- Theory lesson -----------------------------------------------------*
46  *
47  * Things which are expecting to do I/O or go off at a certain time are
48  * called `selectors'.  There are two types of selectors: `file selectors'
49  * wait patiently for a file to become readable or writable; `timeout
50  * selectors' wait for a certain amount of time to elapse.  There is also a
51  * `multiplexor' which copes with managing all of this stuff.
52  *
53  * Multiplexors aren't actually very interesting.  You initialize them with
54  * @sel_init@, and then add and remove selectors as you go.  When you want to
55  * wait for something to happen, call @sel_select@.
56  *
57  * A file selector can *either* read *or* write.  It can't do both.  This is
58  * because you quite often want to read a socket but not write it; during
59  * those times you don't want to write, you just don't install a write
60  * selector.
61  *
62  * File selectors are called when their files are available for reading or
63  * writing as appropriate, and given their file descriptor, the state of the
64  * file, and a pointer that was registered along with the selector.
65  *
66  * File selectors are set up in two phases.  First, they're `initialized'
67  * with @sel_initfile@.  An initialized file selector doesn't do anything.
68  * It needs to be added to a multiplexor using `sel_addfile'.  It can later
69  * be removed using `sel_rmfile'.  You can carry on adding and removing as
70  * you wish.  Just don't try adding it twice in a row.
71  *
72  * Timeout selectors are called at a certain time.  (Actually, they're called
73  * *after* a certain time.)  There's no separate initialization step with
74  * timouts: you just add them and they work.  If you decide you don't want a
75  * timeout to go off, then you just remove it.  (Adding and removing the
76  * *same* timeout isn't something you do very often.  You usually use a
77  * different expiry time each time.)
78  */
79
80 /*----- Header files ------------------------------------------------------*/
81
82 #include <sys/types.h>
83 #include <sys/time.h>
84 #include <unistd.h>
85
86 /*----- Data structures ---------------------------------------------------*/
87
88 /* --- Listening for a file --- */
89
90 typedef struct sel_file {
91   struct sel_file *next;
92   struct sel_file *prev;
93   struct sel_state *s;
94   int fd;
95   unsigned mode;
96   void (*func)(int /*fd*/, unsigned /*mode*/, void */*p*/);
97   void *p;
98 } sel_file;
99
100 #define SEL_READ 0
101 #define SEL_WRITE 1
102 #define SEL_EXC 2
103 #define SEL_MODES 3
104
105 /* --- Waiting for a timeout --- */
106
107 typedef struct sel_timer {
108   struct sel_timer *next;
109   struct sel_timer *prev;
110   struct timeval tv;
111   void (*func)(struct timeval *tv, void *p);
112   void *p;
113 } sel_timer;
114
115 /* --- A multiplexer --- *
116  *
117  * The files are sorted in reverse order of file descriptor number; the
118  * timers are in normal order of occurrence.  Thus, the interesting one
119  * is always at the front of the list.
120  */
121
122 typedef struct sel_state {
123   struct sel_file *files;
124   struct sel_timer *timers;
125   fd_set fd[SEL_MODES];
126   struct timeval tv;
127 } sel_state;
128
129 /*----- Functions provided ------------------------------------------------*/
130
131 /* --- @sel_init@ --- *
132  *
133  * Arguments:   @sel_state *s@ = pointer to a state block to initialize
134  *
135  * Returns:     ---
136  *
137  * Use:         Initializes a select state block.
138  */
139
140 extern void sel_init(sel_state */*s*/);
141
142 /* --- @sel_initfile@ --- *
143  *
144  * Arguments:   @sel_state *s@ = select state to attach to
145  *              @sel_file *f@ = pointer to a file block to initialize
146  *              @int fd@ = the file descriptor to listen to
147  *              @unsigned mode@ = what to listen for
148  *              @void (*func)(int fd, unsigned mode, void *p)@ = handler
149  *              @void *p@ = argument to pass to handler
150  *
151  * Returns:     ---
152  *
153  * Use:         Initializes a file block ready for use.  The file block
154  *              isn't added to the list of things to do until a call to
155  *              @sel_addfile@.
156  */
157
158 extern void sel_initfile(sel_state */*s*/, sel_file */*f*/,
159                          int /*fd*/, unsigned /*mode*/,
160                          void (*/*func*/)(int /*fd*/,
161                                           unsigned /*mode*/,
162                                           void */*p*/),
163                          void */*p*/);
164
165 /* --- @sel_addfile@ --- *
166  *
167  * Arguments:   @sel_file *f@ = pointer to a file block
168  *
169  * Returns:     ---
170  *
171  * Use:         Adds a file block into the list of things to listen to.
172  */
173
174 extern void sel_addfile(sel_file */*f*/);
175
176 /* --- @sel_rmfile@ --- *
177  *
178  * Arguments:   @sel_file *f@ = pointer to a file block
179  *
180  * Returns:     ---
181  *
182  * Use:         Removes a file block from the list of things to listen to.
183  */
184
185 extern void sel_rmfile(sel_file */*f*/);
186
187 /* --- @sel_addtimer@ --- *
188  *
189  * Arguments:   @sel_state *s@ = pointer to a state block
190  *              @sel_timer *t@ = pointer to a timer block
191  *              @struct timeval *tv@ = pointer to time to activate
192  *              @void (*func)(struct timeval *tv, void *p)@ = handler
193  *              @void *p@ = argument for handler function
194  *
195  * Returns:     ---
196  *
197  * Use:         Registers and sets up a timer.
198  */
199
200 extern void sel_addtimer(sel_state */*s*/, sel_timer */*t*/,
201                          struct timeval */*tv*/,
202                          void (*/*func*/)(struct timeval */*tv*/,
203                                           void */*p*/),
204                          void */*p*/);
205
206 /* --- @sel_rmtimer@ --- *
207  *
208  * Arguments:   @sel_timer *t@ = pointer to timer block
209  *
210  * Returns:     ---
211  *
212  * Use:         Removes a timer from the list of timers.
213  */
214
215 extern void sel_rmtimer(sel_timer */*t*/);
216
217 /* --- @sel_select@ --- *
218  *
219  * Arguments:   @sel_state *s@ = pointer to state block
220  *
221  * Returns:     Zero if all OK, -1 on error.
222  *
223  * Use:         Does a @select@ call (or equivalent @poll@).
224  */
225
226 extern int sel_select(sel_state */*s*/);
227
228 /*----- That's all, folks -------------------------------------------------*/
229
230 #ifdef __cplusplus
231   }
232 #endif
233
234 #endif