X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/mLib/blobdiff_plain/a3ddb7786215525dc1c17b4bbce251f1d06be083..d4efbcd93c940ad522fcf8c601ec1829d2e0b10d:/sel.h diff --git a/sel.h b/sel.h index 37b5b5f..58dab4f 100644 --- a/sel.h +++ b/sel.h @@ -1,13 +1,13 @@ /* -*-c-*- * - * $Id: sel.h,v 1.2 1999/05/15 10:33:32 mdw Exp $ + * $Id: sel.h,v 1.10 2004/04/08 01:36:13 mdw Exp $ * * I/O multiplexing support * * (c) 1999 Straylight/Edgeware */ -/*----- Licensing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of the mLib utilities library. * @@ -15,31 +15,20 @@ * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. - * + * * mLib is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. - * + * * You should have received a copy of the GNU Library General Public * License along with mLib; if not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. */ -/*----- Revision history --------------------------------------------------* - * - * $Log: sel.h,v $ - * Revision 1.2 1999/05/15 10:33:32 mdw - * Fix copyright notices. - * - * Revision 1.1 1999/05/14 21:01:15 mdw - * Integrated `select' handling bits from the background resolver project. - * - */ - -#ifndef SEL_H -#define SEL_H +#ifndef MLIB_SEL_H +#define MLIB_SEL_H #ifdef __cplusplus extern "C" { @@ -88,46 +77,76 @@ /*----- Data structures ---------------------------------------------------*/ +/* --- A multiplexor --- * + * + * The files are sorted in reverse order of file descriptor number; the + * timers are in normal order of occurrence. Thus, the interesting one + * is always at the front of the list. + */ + +enum { + SEL_READ, /* File is ready to read */ + SEL_WRITE, /* File is ready to write */ + SEL_EXC, /* Something odd has happened */ + SEL_MODES /* Number of modes available */ +}; + +typedef struct sel_state { + struct sel_file *files[SEL_MODES]; /* Lists of interesting files */ + struct sel_timer *timers; /* List of timers */ + struct sel_hook *hooks; /* List of hook functions applied */ + fd_set fd[SEL_MODES]; /* Quick reference table for files */ + struct sel_args *args; /* Pointer to arguments */ +} sel_state; + /* --- Listening for a file --- */ typedef struct sel_file { - struct sel_file *next; - struct sel_file *prev; - struct sel_state *s; - int fd; - unsigned mode; - void (*func)(int /*fd*/, unsigned /*mode*/, void */*p*/); - void *p; + struct sel_file *next; /* Next file in the list */ + struct sel_file **prev; /* Previous file in the list */ + struct sel_state *s; /* Pointer to select multiplexor */ + int fd; /* File descriptor */ + unsigned mode; /* Interesting event for file */ + void (*func)(int /*fd*/, unsigned /*mode*/, void */*p*/); /* Handler */ + void *p; /* Argument for the handler */ + struct sel_pendfile *pend; /* Pending file information */ } sel_file; -#define SEL_READ 0 -#define SEL_WRITE 1 -#define SEL_EXC 2 -#define SEL_MODES 3 - /* --- Waiting for a timeout --- */ typedef struct sel_timer { - struct sel_timer *next; - struct sel_timer *prev; - struct timeval tv; - void (*func)(struct timeval *tv, void *p); - void *p; + struct sel_timer *next; /* Next timer in the list */ + struct sel_timer **prev; /* Previous timer in the list */ + struct timeval tv; /* Real time when timer should go */ + void (*func)(struct timeval */*tv*/, void */*p*/); /* Handler function */ + void *p; /* Argument for the handler */ + struct sel_pendtimer *pend; /* Pending timer information */ } sel_timer; -/* --- A multiplexer --- * +/* --- A select argument block --- */ + +typedef struct sel_args { + int maxfd; /* Highest-numbered file */ + fd_set fd[SEL_MODES]; /* Bit flags for all the files */ + struct timeval tv, *tvp; /* Time to return */ + struct timeval now; /* Current time */ +} sel_args; + +/* --- A selector hook --- * * - * The files are sorted in reverse order of file descriptor number; the - * timers are in normal order of occurrence. Thus, the interesting one - * is always at the front of the list. + * The hooks are called (in arbitrary order) on each select. */ -typedef struct sel_state { - struct sel_file *files; - struct sel_timer *timers; - fd_set fd[SEL_MODES]; - struct timeval tv; -} sel_state; +typedef void (*sel_hookfn)(sel_state */*s*/, + sel_args */*a*/, + void */*p*/); + +typedef struct sel_hook { + struct sel_hook *next; /* Next hook in the list */ + struct sel_hook **prev; /* Previous hook in the list */ + sel_hookfn before, after; /* Hook functions */ + void *p; /* Argument for the hook functions */ +} sel_hook; /*----- Functions provided ------------------------------------------------*/ @@ -187,12 +206,25 @@ extern void sel_addfile(sel_file */*f*/); extern void sel_rmfile(sel_file */*f*/); +/* --- @sel_force@ --- * + * + * Arguments: @sel_file *f@ = pointer to file selector + * + * Returns: --- + * + * Use: Forces a file selector to be considered ready. This is only + * useful during a call to @sel_select@. Of particular use is + * forcing a write selector when there's something interesting + * ready for it. + */ + +extern void sel_force(sel_file */*f*/); + /* --- @sel_addtimer@ --- * * * Arguments: @sel_state *s@ = pointer to a state block * @sel_timer *t@ = pointer to a timer block * @struct timeval *tv@ = pointer to time to activate - * @void (*func)(struct timeval *tv, void *p)@ = handler * @void *p@ = argument for handler function * * Returns: --- @@ -217,6 +249,47 @@ extern void sel_addtimer(sel_state */*s*/, sel_timer */*t*/, extern void sel_rmtimer(sel_timer */*t*/); +/* --- @sel_addhook@ --- * + * + * Arguments: @sel_state *s@ = pointer to state block + * @sel_hook *h@ = pointer to hook block + * @sel_hookfn before, after@ = hook functions + * @void *p@ = pointer argument to pass to hook functions + * + * Returns: --- + * + * Use: Registers hook functions to be called on each select call. + */ + +extern void sel_addhook(sel_state */*s*/, sel_hook */*h*/, + sel_hookfn /*before*/, sel_hookfn /*after*/, + void */*p*/); + +/* --- @sel_rmhook@ --- * + * + * Arguments: @sel_hook *h@ = pointer to hook block + * + * Returns: --- + * + * Use: Removes hook functions. + */ + +extern void sel_rmhook(sel_hook */*h*/); + +/* --- @sel_fdmerge@ --- * + * + * Arguments: @fd_set *dest@ = destination FD set + * @fd_set *fd@ = pointer to set to merge + * @int maxfd@ = highest numbered descriptor in @fd@ + 1 + * + * Returns: Actual highest numbered descriptor. + * + * Use: Merges file descriptor sets, and returns an accurate @maxfd@ + * value. + */ + +extern int sel_fdmerge(fd_set */*dest*/, fd_set */*fd*/, int /*maxfd*/); + /* --- @sel_select@ --- * * * Arguments: @sel_state *s@ = pointer to state block