X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/mLib/blobdiff_plain/e32dabae3480363e6eb93153f5242ed8c9f2b590..d320826dff9b92551d8530fafeb2e54510973dfa:/sel.h diff --git a/sel.h b/sel.h index 1fc0148..9749a7a 100644 --- a/sel.h +++ b/sel.h @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: sel.h,v 1.3 1999/05/17 20:36:36 mdw Exp $ + * $Id: sel.h,v 1.7 1999/12/10 23:42:04 mdw Exp $ * * I/O multiplexing support * @@ -30,6 +30,19 @@ /*----- Revision history --------------------------------------------------* * * $Log: sel.h,v $ + * Revision 1.7 1999/12/10 23:42:04 mdw + * Change header file guard names. + * + * Revision 1.6 1999/08/31 17:42:22 mdw + * New function `sel_force' to force a descriptor to be `selected'. + * + * Revision 1.5 1999/08/19 18:30:26 mdw + * Implement hooks for foreign select-using systems (currently not well + * tested). + * + * Revision 1.4 1999/05/22 13:39:15 mdw + * Change spelling of `multiplexor'. ;-) + * * Revision 1.3 1999/05/17 20:36:36 mdw * Make the selector type symbols an enumeration rather than a bunch of * #defines. @@ -42,8 +55,8 @@ * */ -#ifndef SEL_H -#define SEL_H +#ifndef MLIB_SEL_H +#define MLIB_SEL_H #ifdef __cplusplus extern "C" { @@ -92,48 +105,74 @@ /*----- 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 */ } sel_file; -enum { - SEL_READ, - SEL_WRITE, - SEL_EXC, - SEL_MODES -}; - /* --- 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 */ } 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 ------------------------------------------------*/ @@ -193,12 +232,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: --- @@ -223,6 +275,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