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