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