X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/mLib/blobdiff_plain/8f45ff6cb9a269fc6f8f631908f93b4c8123419c..4aee39a18184ae8595936a03ad254c27d149a0eb:/man/sel.3 diff --git a/man/sel.3 b/man/sel.3 deleted file mode 100644 index a1f86a5..0000000 --- a/man/sel.3 +++ /dev/null @@ -1,394 +0,0 @@ -.\" -*-nroff-*- -.TH sel 3 "22 May 1999" "Straylight/Edgeware" "mLib utilities library" -.SH NAME -sel \- low level interface for waiting for I/O -.\" @sel_init -.\" @sel_initfile -.\" @sel_addfile -.\" @sel_force -.\" @sel_rmfile -.\" @sel_addtimer -.\" @sel_rmtimer -.\" @sel_addhook -.\" @sel_rmhook -.\" @sel_fdmerge -.\" @sel_select -.SH SYNOPSIS -.nf -.B "#include " - -.BI "void sel_init(sel_state *" s ); - -.BI "void sel_initfile(sel_state *" s ", sel_file *" f , -.BI " int " fd ", unsigned " mode , -.BI " void (*" func ")(int " fd ", unsigned " mode ", void *" p ), -.BI " void *" p ); -.BI "void sel_addfile(sel_file *" f ); -.BI "void sel_force(sel_file *" f ); -.BI "void sel_rmfile(sel_file *" f ); - -.BI "void sel_addtimer(sel_state *" s ", sel_timer *" t , -.BI " struct timeval *" tv , -.BI " void (*" func ")(struct timeval *" tv ", void *" p ), -.BI " void *" p ); -.BI "void sel_rmtimer(sel_timer *" t ); - -.BI "void sel_addhook(sel_state *" s ", sel_hook *" h , -.BI " sel_hookfn " before ", sel_hookfn " after , -.BI " void *" p ); -.BI "void sel_rmhook(sel_hook *" h ); - -.BI "int sel_fdmerge(fd_set *" dest ", fd_set *" fd ", int " maxfd ); - -.BI "int sel_select(sel_state *" s ); -.fi -.SH "OVERVIEW" -The -.B sel -subsystem provides a structured way of handling I/O in a non-blocking -event-driven sort of a way, for single-threaded programs. (Although -there's no reason at all why multithreaded programs shouldn't use -.BR sel , -it's much less useful.) -.PP -The -.B sel -subsystem does no memory allocation, and has no static state. All -of its data is stored in structures allocated by the caller. I'll -explain how this fits in nicely with typical calling sequences below. -.PP -Although all the data structures are exposed in the header file, you -should consider -.BR sel 's -data structures to be opaque except where described here, and not fiddle -around inside them. Some things may become more sophisticated later. -.SH "IMPORTANT CONCEPTS" -The system is based around two concepts: -.I multiplexors -and -.IR selectors . -.PP -A -.I selector -is interested in some sort of I/O event, which might be something like -`my socket has become readable', or `the time is now half past three on -the third of June 2013'. It has a handler function attached to it, -which is called when the appropriate event occurs. Some events happen -once only ever; some events happen over and over again. For example, a -socket might become readable many times, but it's only half-past three -on the third of June 2013 once. -.PP -When a selector is initialized, the caller describes the event the -selector is interested in, and specifies which function should handle -the event. Also, it must specify an arbitrary pointer which is passed -to the handler function when the event occurs. This is typically some -sort of pointer to instance data of some kind, providing more -information about the event (`it's -.I this -socket that's become readable'), or what to do about it. -.PP -A multiplexor gathers information about who's interested in what. It -maintains lists of selectors. Selectors must be added to a -mulitplexor before the events they're interested in are actually watched -for. Selectors can be removed again when their events aren't -interesting any more. Apart from adding and removing selectors, you can -.I select -on a multiplexor. This waits for something interesting to happen and -then fires off all the selectors which have events waiting for them. -.PP -You can have lots of multiplexors in your program if you like. You can -only ask for events from one of them at a time, though. -.PP -There are currently two types of selector understood by the low-level -.B sel -system: file selectors and timer selectors. These two types of -selectors react to corresponding different types of events. A file -event indicates that a file is now ready for reading or writing. A -timer event indicates that a particular time has now passed (useful for -implementing timeouts). More sophisticated selectors can be constructed -using -.BR sel 's -interface. For examples, see -.BR selbuf (3) -and -.BR conn (3). -.SH "PROGRAMMING INTERFACE" -.SS "Multiplexors" -A multiplexor is represented using the type -.B sel_state -defined in the -.B -header file. Before use, a -.B sel_state -must be initialized, by passing it to the -.B sel_init -function. The header file talks about `state blocks' a lot \- that's -because it was written before I thought the word `multiplexor' was -nicer. -.PP -File selectors are represented by the type -.BR sel_file . -The interface provides three operations on file selectors: -initialization, addition to multiplexor, and removal from a -multiplexor. It's convenient to separate addition and removal from -initialization because file selectors often get added and removed many -times over during their lifetimes. -.SS "File selectors" -A file selector is initialized by the -.B sel_initfile -function. This requires a large number of arguments: -.TP -.BI "sel_state *" s -A pointer to the multiplexor with which the file selector will be -associated. This is stored in the selector so that the multiplexor -argument can be omitted from later calls. -.TP -.BI "sel_file *" f -Pointer to the file selector object to be initialized. -.TP -.BI "int " fd -The file descriptor which the selector is meant to watch. -.TP -.BI "unsigned " mode -A constant describing which condition the selector is interested in. -This must be one of the -.B SEL_ -constants described below. -.TP -.BI "void (*" func ")(int " fd ", unsigned " mode ", void *" p ); -The handler function which is called when the appropriate condition -occurs on the file. This function's interface is described in more -detail below. -.TP -.BI "void *" p -An arbitrary pointer argument passed to -.I func -when it's called. Beyond this, no meaning is attached to the value of -the pointer. If you don't care about it, just leave it as null. -.PP -The mode argument is one of the following constants: -.TP -.B SEL_READ -Raise an event when the file is ready to be read from. -.TP -.B SEL_WRITE -Raise an event when the file is ready to be written to. -.TP -.B SEL_EXC -Raise an event when the file has an `exceptional condition'. -.PP -The constant -.B SEL_MODES -contains the number of possible file modes. This is useful internally -for allocating arrays of the right size. -.PP -The functions -.B sel_addfile -and -.B sel_rmfile -perform the addition and removal operations on file selectors. They are -passed only the actual selector object, since the selector already knows -which multiplexor it's associated with. A newly initialized file -selector is not added to its multiplexor: this must be done explicitly. -.PP -The handler function for a file multiplexor is passed three arguments: -the file descriptor for the file, a mode argument which describes the -file's new condition, and the pointer argument set up at initialization -time. -.PP -The function -.B sel_force -will sometimes be useful while a -.B sel_select -call (see below) is in progress. It marks a file selector as being -ready even if it's not really. This is most useful when dynamically -adding a write selector: it's likely that the write will succeed -immediately, so it's worth trying. This will only work properly if -the write is non-blocking. -.PP -The member -.B fd -of the -.B sel_file -structure is exported. It contains the file descriptor in which the -selector is interested. You may not modify this value, but it's useful -to be able to read it out \- it saves having to keep a copy. -.SS "Timer selectors" -Timer selectors are simpler. There are only two operations provided on -timer selectors: addition and removal. Initialization is performed as -part of the addition operation. -.PP -A timer selector is represented by an object of time -.BR sel_timer . -.PP -The function -.B sel_addtimer -requires lots of arguments: -.TP -.BI "sel_state *" s -Pointer to the multiplexor to which the selector is to be added. -.TP -.BI "sel_timer *" t -Pointer to the timer selector object being initialized and added. -.TP -.BI "struct timeval " tv -When the selector should raise its event. This is an -.I absolute -time, not a relative time as required by the traditional -.BR select (2) -and -.BR poll (2) -system calls. -.TP -.BI "void (*" func ")(struct timeval *" tv ", void *" p ) -A handler function to be called when the event occurs. The function is -passed the -.I current -time, and the arbitrary pointer passed to -.B sel_addtimer -as the -.I p -argument. -.TP -.BI "void *" p -A pointer passed to -.I func -when the timer event occurs. Beyond this, the value of the pointer is -not inspected. -.PP -The function -.B sel_rmtimer -removes a timer selector. It is passed only the selector object. -.PP -Note that timer events are a one-shot thing. Once they've happened, the -timer selector is removed and the event can't happen again. This is -normally what you want. Removing a timer is only useful (or safe!) -before the timer event has been sent. -.SS "Performing I/O" -Finally, the function -.B sel_select -is passed a multiplexor object. It waits for something interesting to -happen, informs the appropriate selector handlers, and returns. If -everything went according to plan, -.B sel_select -returns zero. Otherwise it returns \-1, and the global variable -.B errno -is set appropriately. -.SS "Hook functions" -In order to interface other I/O multiplexing systems to this one, it's -possible to register -.I hook -functions which are called before and after each -.BR select (2) -system call. -.PP -The function -.B sel_addhook -registers a pair of hook functions. It is passed the pointer to the -multiplexor which is being hooked, the address of a -.B sel_hook -structure which will be used to record the hook information, the two -hook functions (either of which may be a null pointer, signifying no -action to be taken), and a pointer argument to be passed to the hook -functions. -.PP -The function -.B sel_rmhook -removes a pair of hooks given the address of the -.B sel_hook -structure which recorded their registration. -.PP -A -.I "hook function" -is passed three arguments: -.TP -.BI "sel_state *" s -A pointer to the multiplexor block. This probably isn't very useful, -actually. -.TP -.BI "sel_args *" a -A pointer to a block containing proposed arguments for, or results from, -.BR select (2). -The format of this block is described below. -.TP -.BI "void *" p -A pointer argument set up in the call to -.B sel_addhook -to provide the hook function with some context. -.PP -The argument block contains the following members: -.TP -.B "int maxfd" -One greater than the highest-numbered file descriptor to be examined. -This may need to be modified if the file descriptor sets are altered. -.TP -.B "fd_set fd[SEL_MODES]" -A file descriptor set for each of -.BR SEL_READ , -.B SEL_WRITE -and -.BR SEL_EXC . -Before the -.B select -call, these may be modified to register an interest in other file -descriptors. Afterwards, they may be examined to decide which file -descriptors are active. -.TP -.B "struct timeval tv, *tvp" -Before the -.B select -call, these specify the time after which to return even if no files are -active. If -.B tvp -is null, there is no timeout, and -.B select -should wait forever if necessary. Otherwise -.B tvp -should contain the address of -.BR tv , -and -.B tv -should contain the timeout. After the -.B select -call, the contents of -.B tv -are undefined. -.TP -.B "struct timeval now" -Before the -.B select -call, contains the current time. After the call, this will have been -updated to reflect the new current time only if there was a timeout -set before the call. -.PP -Hook functions may find the call -.B sel_fdmerge -useful. Given two file descriptor sets -.I dest -and -.IR fd , -and a possibly overestimated highest file descriptor in -.IR fd , -the function sets in -.I dest -all of the descriptors set in -.I fd -and returns an accurate file descriptor count as its result. -.SH "OTHER NOTES" -Although the naming seems to suggest that this is all -based around the BSD-ish -.BR select (2) -system call (and indeed it is), the interface is actually a good deal -more general than that. An implementation which worked off System V-ish -.BR poll (2) -instead would be possible to make, and would look just the same from the -outside. Some work would be needed to make the hook functions work, -though. -.SH "SEE ALSO" -.BR select (2), -.BR poll (2), -.BR conn (3), -.BR selbuf (3), -.BR mLib (3). -.SH AUTHOR -Mark Wooding,