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