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