chiark / gitweb /
a1f86a5e5f02180110cc175137de2af3bf9fce97
[mLib] / man / sel.3
1 .\" -*-nroff-*-
2 .TH sel 3 "22 May 1999" "Straylight/Edgeware" "mLib utilities library"
3 .SH NAME
4 sel \- low level interface for waiting for I/O
5 .\" @sel_init
6 .\" @sel_initfile
7 .\" @sel_addfile
8 .\" @sel_force
9 .\" @sel_rmfile
10 .\" @sel_addtimer
11 .\" @sel_rmtimer
12 .\" @sel_addhook
13 .\" @sel_rmhook
14 .\" @sel_fdmerge
15 .\" @sel_select
16 .SH SYNOPSIS
17 .nf
18 .B "#include <mLib/sel.h>"
19
20 .BI "void sel_init(sel_state *" s );
21
22 .BI "void sel_initfile(sel_state *" s ", sel_file *" f ,
23 .BI "                  int " fd ", unsigned " mode ,
24 .BI "                  void (*" func ")(int " fd ", unsigned " mode ", void *" p ),
25 .BI "                  void *" p );
26 .BI "void sel_addfile(sel_file *" f );
27 .BI "void sel_force(sel_file *" f );
28 .BI "void sel_rmfile(sel_file *" f );
29
30 .BI "void sel_addtimer(sel_state *" s ", sel_timer *" t ,
31 .BI "                  struct timeval *" tv ,
32 .BI "                  void (*" func ")(struct timeval *" tv ", void *" p ),
33 .BI "                  void *" p );
34 .BI "void sel_rmtimer(sel_timer *" t );
35
36 .BI "void sel_addhook(sel_state *" s ", sel_hook *" h ,
37 .BI "                 sel_hookfn " before ", sel_hookfn " after ,
38 .BI "                 void *" p );
39 .BI "void sel_rmhook(sel_hook *" h );
40
41 .BI "int sel_fdmerge(fd_set *" dest ", fd_set *" fd ", int " maxfd );
42
43 .BI "int sel_select(sel_state *" s );
44 .fi
45 .SH "OVERVIEW"
46 The
47 .B sel
48 subsystem provides a structured way of handling I/O in a non-blocking
49 event-driven sort of a way, for single-threaded programs.  (Although
50 there's no reason at all why multithreaded programs shouldn't use
51 .BR sel ,
52 it's much less useful.)
53 .PP
54 The
55 .B sel
56 subsystem does no memory allocation, and has no static state.  All
57 of its data is stored in structures allocated by the caller.  I'll
58 explain how this fits in nicely with typical calling sequences below.
59 .PP
60 Although all the data structures are exposed in the header file, you
61 should consider
62 .BR sel 's
63 data structures to be opaque except where described here, and not fiddle
64 around inside them.  Some things may become more sophisticated later.
65 .SH "IMPORTANT CONCEPTS"
66 The system is based around two concepts:
67 .I multiplexors
68 and
69 .IR selectors .
70 .PP
71 A
72 .I selector
73 is interested in some sort of I/O event, which might be something like
74 `my socket has become readable', or `the time is now half past three on
75 the third of June 2013'.  It has a handler function attached to it,
76 which is called when the appropriate event occurs.  Some events happen
77 once only ever; some events happen over and over again.  For example, a
78 socket might become readable many times, but it's only half-past three
79 on the third of June 2013 once.
80 .PP
81 When a selector is initialized, the caller describes the event the
82 selector is interested in, and specifies which function should handle
83 the event.  Also, it must specify an arbitrary pointer which is passed
84 to the handler function when the event occurs.  This is typically some
85 sort of pointer to instance data of some kind, providing more
86 information about the event (`it's
87 .I this
88 socket that's become readable'), or what to do about it.
89 .PP
90 A multiplexor gathers information about who's interested in what.  It
91 maintains lists of selectors.  Selectors must be added to a
92 mulitplexor before the events they're interested in are actually watched
93 for.  Selectors can be removed again when their events aren't
94 interesting any more.  Apart from adding and removing selectors, you can
95 .I select
96 on a multiplexor.  This waits for something interesting to happen and
97 then fires off all the selectors which have events waiting for them.
98 .PP
99 You can have lots of multiplexors in your program if you like.  You can
100 only ask for events from one of them at a time, though.
101 .PP
102 There are currently two types of selector understood by the low-level
103 .B sel
104 system: file selectors and timer selectors.  These two types of
105 selectors react to corresponding different types of events.  A file
106 event indicates that a file is now ready for reading or writing.  A
107 timer event indicates that a particular time has now passed (useful for
108 implementing timeouts).  More sophisticated selectors can be constructed
109 using
110 .BR sel 's
111 interface.  For examples, see
112 .BR selbuf (3)
113 and
114 .BR conn (3).
115 .SH "PROGRAMMING INTERFACE"
116 .SS "Multiplexors"
117 A multiplexor is represented using the type
118 .B sel_state
119 defined in the
120 .B <mLib/sel.h>
121 header file.  Before use, a
122 .B sel_state
123 must be initialized, by passing it to the
124 .B sel_init
125 function.  The header file talks about `state blocks' a lot \- that's
126 because it was written before I thought the word `multiplexor' was
127 nicer.
128 .PP
129 File selectors are represented by the type
130 .BR sel_file .
131 The interface provides three operations on file selectors:
132 initialization, addition to multiplexor, and removal from a
133 multiplexor.  It's convenient to separate addition and removal from
134 initialization because file selectors often get added and removed many
135 times over during their lifetimes.
136 .SS "File selectors"
137 A file selector is initialized by the
138 .B sel_initfile
139 function.  This requires a large number of arguments:
140 .TP
141 .BI "sel_state *" s
142 A pointer to the multiplexor with which the file selector will be
143 associated.  This is stored in the selector so that the multiplexor
144 argument can be omitted from later calls.
145 .TP
146 .BI "sel_file *" f
147 Pointer to the file selector object to be initialized.
148 .TP
149 .BI "int " fd
150 The file descriptor which the selector is meant to watch.
151 .TP
152 .BI "unsigned " mode
153 A constant describing which condition the selector is interested in.
154 This must be one of the
155 .B SEL_
156 constants described below.
157 .TP
158 .BI "void (*" func ")(int " fd ", unsigned " mode ", void *" p );
159 The handler function which is called when the appropriate condition
160 occurs on the file.  This function's interface is described in more
161 detail below.
162 .TP
163 .BI "void *" p
164 An arbitrary pointer argument passed to
165 .I func
166 when it's called.  Beyond this, no meaning is attached to the value of
167 the pointer.  If you don't care about it, just leave it as null.
168 .PP
169 The mode argument is one of the following constants:
170 .TP
171 .B SEL_READ
172 Raise an event when the file is ready to be read from.
173 .TP
174 .B SEL_WRITE
175 Raise an event when the file is ready to be written to.
176 .TP
177 .B SEL_EXC
178 Raise an event when the file has an `exceptional condition'.
179 .PP
180 The constant
181 .B SEL_MODES
182 contains the number of possible file modes.  This is useful internally
183 for allocating arrays of the right size.
184 .PP
185 The functions
186 .B sel_addfile
187 and
188 .B sel_rmfile
189 perform the addition and removal operations on file selectors.  They are
190 passed only the actual selector object, since the selector already knows
191 which multiplexor it's associated with.  A newly initialized file
192 selector is not added to its multiplexor: this must be done explicitly.
193 .PP
194 The handler function for a file multiplexor is passed three arguments:
195 the file descriptor for the file, a mode argument which describes the
196 file's new condition, and the pointer argument set up at initialization
197 time.
198 .PP
199 The function
200 .B sel_force
201 will sometimes be useful while a
202 .B sel_select
203 call (see below) is in progress.  It marks a file selector as being
204 ready even if it's not really.  This is most useful when dynamically
205 adding a write selector: it's likely that the write will succeed
206 immediately, so it's worth trying.  This will only work properly if
207 the write is non-blocking.
208 .PP
209 The member
210 .B fd
211 of the
212 .B sel_file
213 structure is exported.  It contains the file descriptor in which the
214 selector is interested.  You may not modify this value, but it's useful
215 to be able to read it out \- it saves having to keep a copy.
216 .SS "Timer selectors"
217 Timer selectors are simpler.  There are only two operations provided on
218 timer selectors: addition and removal.  Initialization is performed as
219 part of the addition operation.
220 .PP
221 A timer selector is represented by an object of time
222 .BR sel_timer .
223 .PP
224 The function
225 .B sel_addtimer
226 requires lots of arguments:
227 .TP
228 .BI "sel_state *" s
229 Pointer to the multiplexor to which the selector is to be added.
230 .TP
231 .BI "sel_timer *" t
232 Pointer to the timer selector object being initialized and added.
233 .TP
234 .BI "struct timeval " tv
235 When the selector should raise its event.  This is an
236 .I absolute
237 time, not a relative time as required by the traditional
238 .BR select (2)
239 and
240 .BR poll (2)
241 system calls.
242 .TP
243 .BI "void (*" func ")(struct timeval *" tv ", void *" p )
244 A handler function to be called when the event occurs.  The function is
245 passed the
246 .I current
247 time, and the arbitrary pointer passed to
248 .B sel_addtimer
249 as the
250 .I p
251 argument.
252 .TP
253 .BI "void *" p
254 A pointer passed to
255 .I func
256 when the timer event occurs.  Beyond this, the value of the pointer is
257 not inspected.
258 .PP
259 The function
260 .B sel_rmtimer
261 removes a timer selector.  It is passed only the selector object.
262 .PP
263 Note that timer events are a one-shot thing.  Once they've happened, the
264 timer selector is removed and the event can't happen again.  This is
265 normally what you want.  Removing a timer is only useful (or safe!)
266 before the timer event has been sent.
267 .SS "Performing I/O"
268 Finally, the function
269 .B sel_select
270 is passed a multiplexor object.  It waits for something interesting to
271 happen, informs the appropriate selector handlers, and returns.  If
272 everything went according to plan,
273 .B sel_select
274 returns zero.  Otherwise it returns \-1, and the global variable
275 .B errno
276 is set appropriately.
277 .SS "Hook functions"
278 In order to interface other I/O multiplexing systems to this one, it's
279 possible to register
280 .I hook
281 functions which are called before and after each
282 .BR select (2)
283 system call.
284 .PP
285 The function
286 .B sel_addhook
287 registers a pair of hook functions.  It is passed the pointer to the
288 multiplexor which is being hooked, the address of a
289 .B sel_hook
290 structure which will be used to record the hook information, the two
291 hook functions (either of which may be a null pointer, signifying no
292 action to be taken), and a pointer argument to be passed to the hook
293 functions.
294 .PP
295 The function
296 .B sel_rmhook
297 removes a pair of hooks given the address of the
298 .B sel_hook
299 structure which recorded their registration.
300 .PP
301 A
302 .I "hook function"
303 is passed three arguments:
304 .TP
305 .BI "sel_state *" s
306 A pointer to the multiplexor block.  This probably isn't very useful,
307 actually.
308 .TP
309 .BI "sel_args *" a
310 A pointer to a block containing proposed arguments for, or results from,
311 .BR select (2).
312 The format of this block is described below.
313 .TP
314 .BI "void *" p
315 A pointer argument set up in the call to
316 .B sel_addhook
317 to provide the hook function with some context.
318 .PP
319 The argument block contains the following members:
320 .TP
321 .B "int maxfd"
322 One greater than the highest-numbered file descriptor to be examined.
323 This may need to be modified if the file descriptor sets are altered.
324 .TP
325 .B "fd_set fd[SEL_MODES]"
326 A file descriptor set for each of
327 .BR SEL_READ ,
328 .B SEL_WRITE
329 and
330 .BR SEL_EXC .
331 Before the
332 .B select
333 call, these may be modified to register an interest in other file
334 descriptors.  Afterwards, they may be examined to decide which file
335 descriptors are active.
336 .TP
337 .B "struct timeval tv, *tvp"
338 Before the
339 .B select
340 call, these specify the time after which to return even if no files are
341 active.  If
342 .B tvp
343 is null, there is no timeout, and
344 .B select
345 should wait forever if necessary.  Otherwise
346 .B tvp
347 should contain the address of
348 .BR tv ,
349 and
350 .B tv
351 should contain the timeout.  After the
352 .B select
353 call, the contents of
354 .B tv
355 are undefined.
356 .TP
357 .B "struct timeval now"
358 Before the
359 .B select
360 call, contains the current time.  After the call, this will have been
361 updated to reflect the new current time only if there was a timeout
362 set before the call.
363 .PP
364 Hook functions may find the call
365 .B sel_fdmerge
366 useful.  Given two file descriptor sets
367 .I dest
368 and
369 .IR fd ,
370 and a possibly overestimated highest file descriptor in
371 .IR fd ,
372 the function sets in
373 .I dest
374 all of the descriptors set in
375 .I fd
376 and returns an accurate file descriptor count as its result.
377 .SH "OTHER NOTES"
378 Although the naming seems to suggest that this is all
379 based around the BSD-ish
380 .BR select (2)
381 system call (and indeed it is), the interface is actually a good deal
382 more general than that.  An implementation which worked off System V-ish
383 .BR poll (2)
384 instead would be possible to make, and would look just the same from the
385 outside.  Some work would be needed to make the hook functions work,
386 though.
387 .SH "SEE ALSO"
388 .BR select (2),
389 .BR poll (2),
390 .BR conn (3),
391 .BR selbuf (3),
392 .BR mLib (3).
393 .SH AUTHOR
394 Mark Wooding, <mdw@distorted.org.uk>