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