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