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