chiark / gitweb /
c3e81ae2b6ac238c74426fd1c380b2e461b35c91
[mLib] / man / sel.3
1 .\" -*-nroff-*-
2 .TH sel 3mLib "22 May 1999" mLib
3 .SH NAME
4 sel \- low level interface for waiting for I/O
5 .SH SYNOPSIS
6 .nf
7 .B "#include <mLib/sel.h>"
8
9 .BI "void sel_init(sel_state *" s );
10
11 .BI "void sel_initfile(sel_state *" s ", sel_file *" f ,
12 .BI "                  int " fd ", unsigned " mode ,
13 .BI "                  void (*" func ")(int " fd ", unsigned " mode ", void *" p ),
14 .BI "                  void *" p );
15 .BI "void sel_addfile(sel_file *" f );
16 .BI "void sel_rmfile(sel_file *" f );
17
18 .BI "void sel_addtimer(sel_state *" s ", sel_timer *" t ,
19 .BI "                  struct timeval *" tv ,
20 .BI "                  void (*" func ")(struct timeval *" tv ", void *" p ),
21 .BI "void sel_rmtimer(sel_timer *" t );
22
23 .BI "int sel_select(sel_state *" s );
24 .fi
25 .SH "OVERVIEW"
26 The
27 .B sel
28 subsystem provides a structured way of handling I/O in a non-blocking
29 event-driven sort of a way, for single-threaded programs.  (Although
30 there's no reason at all why multithreaded programs shouldn't use 
31 .BR sel ,
32 it's much less useful.)
33 .PP
34 The
35 .B sel
36 subsystem does no memory allocation, and has no static state.  All
37 of its data is stored in structures allocated by the caller.  I'll
38 explain how this fits in nicely with typical calling sequences below.
39 .PP
40 Although all the data structures are exposed in the header file, you
41 should consider
42 .BR sel 's
43 data structures to be opaque except where described here, and not fiddle
44 around inside them.  Some things may become more sophisticated later.
45 .SH "IMPORTANT CONCEPTS"
46 The system is based around two concepts:
47 .I multiplexors
48 and
49 .IR selectors .
50 .PP
51 A
52 .I selector
53 is interested in some sort of I/O event, which might be something like
54 `my socket has become readable', or `the time is now half past three on
55 the third of June 2013'.  It has a handler function attached to it,
56 which is called when the appropriate event occurs.  Some events happen
57 once only ever; some events happen over and over again.  For example, a
58 socket might become readable many times, but it's only half-past three
59 on the third of June 2013 once.
60 .PP
61 When a selector is initialized, the caller describes the event the
62 selector is interested in, and specifies which function should handle
63 the event.  Also, it must specify an arbitrary pointer which is passed
64 to the handler function when the event occurs.  This is typically some
65 sort of pointer to instance data of some kind, providing more
66 information about the event (`it's
67 .I this
68 socket that's become readable'), or what to do about it.
69 .PP
70 A multiplexor gathers information about who's interested in what.  It
71 maintains lists of selectors.  Selectors must be added to a
72 mulitplexor before the events they're interested in are actually watched
73 for.  Selectors can be removed again when their events aren't
74 interesting any more.  Apart from adding and removing selectors, you can
75 .I select
76 on a multiplexor.  This waits for something interesting to happen and
77 then fires off all the selectors which have events waiting for them.
78 .PP
79 You can have lots of multiplexors in your program if you like.  You can
80 only ask for events from one of them at a time, though.
81 .PP
82 There are currently two types of selector understood by the low-level
83 .B sel
84 system: file selectors and timer selectors.  These two types of
85 selectors react to corresponding different types of events.  A file
86 event indicates that a file is now ready for reading or writing.  A
87 timer event indicates that a particular time has now passed (useful for
88 implementing timeouts).  More sophisticated selectors can be constructed
89 using
90 .BR sel 's
91 interface.  For examples, see
92 .BR selbuf (3mLib)
93 and
94 .BR conn (3mLib).
95 .SH "PROGRAMMING INTERFACE"
96 A multiplexor is represented using the type
97 .B sel_state
98 defined in the
99 .B <mLib/sel.h>
100 header file.  Before use, a
101 .B sel_state
102 must be initialized, by passing it to the
103 .B sel_init
104 function.  The header file talks about `state blocks' a lot \- that's
105 because it was written before I thought the word `multiplexor' was
106 nicer.
107 .PP
108 File selectors are represented by the type
109 .BR sel_file .
110 The interface provides three operations on file selectors:
111 initialization, addition to multiplexor, and removal from a
112 multiplexor.  It's convenient to separate addition and removal from
113 initialization because file selectors often get added and removed many
114 times over during their lifetimes.
115 .PP
116 A file selector is initialized by the
117 .B sel_initfile
118 function.  This requires a large number of arguments:
119 .TP
120 .I s
121 A pointer to the multiplexor with which the file selector will be
122 associated.  This is stored in the selector so that the multiplexor
123 argument can be omitted from later calls.
124 .TP
125 .I f
126 Pointer to the file selector object to be initialized.
127 .TP
128 .I fd
129 The file descriptor which the selector is meant to watch.
130 .TP
131 .I mode
132 A constant describing which condition the selector is interested in.
133 This must be one of the
134 .B SEL_
135 constants described below.
136 .TP
137 .I func
138 The handler function which is called when the appropriate condition
139 occurs on the file.  This function's interface is described in more
140 detail below.
141 .TP
142 .I p
143 An arbitrary pointer argument passed to
144 .I func
145 when it's called.  Beyond this, no meaning is attached to the value of
146 the pointer.  If you don't care about it, just leave it as null.
147 .PP
148 The mode argument is one of the following constants:
149 .TP
150 .B SEL_READ
151 Raise an event when the file is ready to be read from.
152 .TP
153 .B SEL_WRITE
154 Raise an event when the file is ready to be written to.
155 .TP
156 .B SEL_EXC
157 Raise an event when the file has an `exceptional condition'.
158 .PP
159 The constant
160 .B SEL_MODES
161 contains the number of possible file modes.  This is useful internally
162 for allocating arrays of the right size.
163 .PP
164 The functions
165 .B sel_addfile
166 and
167 .B sel_rmfile
168 perform the addition and removal operations on file selectors.  They are
169 passed only the actual selector object, since the selector already knows
170 which multiplexor it's associated with.  A newly initialized file
171 selector is not added to its multiplexor: this must be done explicitly.
172 .PP
173 The handler function for a file multiplexor is passed three arguments:
174 the file descriptor for the file, a mode argument which descibes the
175 file's new condition, and the pointer argument set up at initialization
176 time.
177 .PP
178 The member
179 .B fd
180 of the
181 .B sel_file
182 structure is exported.  It contains the file descriptor in which the
183 selector is interested.  You may not modify this value, but it's useful
184 to be able to read it out \- it saves having to keep a copy.
185 .PP
186 Timer selectors are simpler.  There are only two operations provided on
187 timer selectors: addition and removal.  Initialization is performed as
188 part of the addition operation.
189 .PP
190 A timer selector is represented by an object of time
191 .BR sel_timer .
192 .PP
193 The function
194 .B sel_addtimer
195 requires lots of arguments:
196 .TP
197 .I s
198 Pointer to the multiplexor to which the selector is to be added.
199 .TP
200 .I t
201 Pointer to the timer selector object being initialized and added.
202 .TP
203 .I tv
204 A
205 .B "struct timeval"
206 object describing when the selector should raise its event.  This is an
207 .I absolute
208 time, not a relative time as required by the traditional
209 .BR select (2)
210 and
211 .BR poll (2)
212 system calls.
213 .TP
214 .I func
215 A handler function to be called when the event occurs.  The function is
216 passed the
217 .I current
218 time, and the arbitrary pointer passed to
219 .B sel_addtimer
220 as the
221 .I p
222 argument.
223 .TP
224 .I p
225 A pointer passed to
226 .I func
227 when the timer event occurs.  Beyond this, the value of the pointer is
228 not inspected.
229 .PP
230 The function
231 .B sel_rmtimer
232 removes a timer selector.  It is passed only the selector object.
233 .PP
234 Note that timer events are a one-shot thing.  Once they've happened, the
235 timer selector is removed and the event can't happen again.  This is
236 normally what you want.  Removing a timer is only useful (or safe!)
237 before the timer event has been sent.
238 .PP
239 Finally, the function
240 .B sel_select
241 is passed a multiplexor object.  It waits for something interesting to
242 happen, informs the appropriate selector handlers, and returns.  If
243 everything went according to plan,
244 .B sel_select
245 returns zero.  Otherwise it returns -1, and the global variable
246 .B errno
247 is set appropriately.
248 .SH "OTHER NOTES"
249 Although the naming seems to suggest that this is all
250 based around the BSD-ish
251 .BR select (2)
252 system call (and indeed it is), the interface is actually a good deal
253 more general than that.  An implementation which worked off System V-ish
254 .BR poll (2)
255 instead would be fairly trivial to make, and would look just the same
256 from the outside.
257 .SH AUTHOR
258 Mark Wooding, <mdw@nsict.org>