3 * $Id: sel.h,v 1.1 1999/05/14 21:01:15 mdw Exp $
5 * I/O multiplexing support
7 * (c) 1999 Mark Wooding
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of the mLib utilities library.
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.
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.
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,
30 /*----- Revision history --------------------------------------------------*
33 * Revision 1.1 1999/05/14 21:01:15 mdw
34 * Integrated `select' handling bits from the background resolver project.
45 /*----- Theory lesson -----------------------------------------------------*
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.
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@.
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
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.
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.
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.)
80 /*----- Header files ------------------------------------------------------*/
82 #include <sys/types.h>
86 /*----- Data structures ---------------------------------------------------*/
88 /* --- Listening for a file --- */
90 typedef struct sel_file {
91 struct sel_file *next;
92 struct sel_file *prev;
96 void (*func)(int /*fd*/, unsigned /*mode*/, void */*p*/);
105 /* --- Waiting for a timeout --- */
107 typedef struct sel_timer {
108 struct sel_timer *next;
109 struct sel_timer *prev;
111 void (*func)(struct timeval *tv, void *p);
115 /* --- A multiplexer --- *
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.
122 typedef struct sel_state {
123 struct sel_file *files;
124 struct sel_timer *timers;
125 fd_set fd[SEL_MODES];
129 /*----- Functions provided ------------------------------------------------*/
131 /* --- @sel_init@ --- *
133 * Arguments: @sel_state *s@ = pointer to a state block to initialize
137 * Use: Initializes a select state block.
140 extern void sel_init(sel_state */*s*/);
142 /* --- @sel_initfile@ --- *
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
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
158 extern void sel_initfile(sel_state */*s*/, sel_file */*f*/,
159 int /*fd*/, unsigned /*mode*/,
160 void (*/*func*/)(int /*fd*/,
165 /* --- @sel_addfile@ --- *
167 * Arguments: @sel_file *f@ = pointer to a file block
171 * Use: Adds a file block into the list of things to listen to.
174 extern void sel_addfile(sel_file */*f*/);
176 /* --- @sel_rmfile@ --- *
178 * Arguments: @sel_file *f@ = pointer to a file block
182 * Use: Removes a file block from the list of things to listen to.
185 extern void sel_rmfile(sel_file */*f*/);
187 /* --- @sel_addtimer@ --- *
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
197 * Use: Registers and sets up a timer.
200 extern void sel_addtimer(sel_state */*s*/, sel_timer */*t*/,
201 struct timeval */*tv*/,
202 void (*/*func*/)(struct timeval */*tv*/,
206 /* --- @sel_rmtimer@ --- *
208 * Arguments: @sel_timer *t@ = pointer to timer block
212 * Use: Removes a timer from the list of timers.
215 extern void sel_rmtimer(sel_timer */*t*/);
217 /* --- @sel_select@ --- *
219 * Arguments: @sel_state *s@ = pointer to state block
221 * Returns: Zero if all OK, -1 on error.
223 * Use: Does a @select@ call (or equivalent @poll@).
226 extern int sel_select(sel_state */*s*/);
228 /*----- That's all, folks -------------------------------------------------*/