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