From d13d8a046838ce3d0e2643bb5b49f2ff77d679ca Mon Sep 17 00:00:00 2001 From: Marc Horowitz Date: Wed, 1 Nov 1989 20:02:01 +0000 Subject: Initial revision --- zwgc/mux.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 zwgc/mux.c (limited to 'zwgc/mux.c') diff --git a/zwgc/mux.c b/zwgc/mux.c new file mode 100644 index 0000000..e19067c --- /dev/null +++ b/zwgc/mux.c @@ -0,0 +1,138 @@ +/****************************************************************************/ +/* */ +/* Module containing code to wait on multiple file descriptors: */ +/* */ +/****************************************************************************/ + +#include +#include +#include +#include +#include "mux.h" +#include "error.h" +#include "zwgc.h" + +/* + * mux_end_loop_p - Setting this to true during a mux_loop causes the mux_loop + * to be exited. + */ + +int mux_end_loop_p; + +/* + * max_source - the maximum file descriptor that a handler was ever + * registered for: + */ + +static int max_source = -1; + +/* + * Which file descriptors we're waiting on for input & the accompanying + * input handlers & their arguments: + */ + +static fd_set input_sources; +static void (*input_handler[MAX_SOURCES])(); +static void *input_handler_arg[MAX_SOURCES]; + +/* + * void mux_init() + * Requires: mux_init has never been called before + * Effects: Initializes the mux module. Must be called before + * any other mux call. + */ + +void mux_init() +{ + int i; + + FD_ZERO(&input_sources); + + for (i=0; i= MAX_SOURCES) + abort(); /* <<<>>> */ +#endif + + input_handler[descriptor] = handler; + input_handler_arg[descriptor] = arg; + FD_SET(descriptor, &input_sources); + if(descriptor > max_source) + max_source = descriptor; +} + +/* + * void mux_loop() + * Requires: mux_init has been called. + * Effects: Loops until mux_end_loop_p becomes true. (Sets + * mux_end_loop_p false to start). Whenever input is + * available on an input source which has a registered + * handler (see mux_add_input_source), that handler is + * called with its argument. It is guarenteed that if + * input is available on a source, its respective input + * handler, if any, will eventually be called. No other + * ordering guarentees are made. When some signal handler + * or input handler eventually sets mux_end_loop_p to + * true, we return. + */ + +void mux_loop() +{ + int i; + fd_set input_sources_copy; + + mux_end_loop_p = 0; + + for (;;) { + /* + * Exit if mux_end_loop_p has been set to true by a handler: + */ + if (mux_end_loop_p) + break; + + /* + * Do a select on all the file descriptors we care about to + * wait until at least one of them has input available: + */ + input_sources_copy = input_sources; + if ( select(max_source+1, &input_sources_copy, (fd_set *)NULL, + (fd_set *)NULL, (struct timeval *)NULL) == -1 ) + if (errno == EINTR) + continue; /* on a signal restart checking mux_loop_end_p */ + else + FATAL_TRAP( errno, "while selecting" ); + + /* + * Call all input handlers whose corresponding file descriptors have + * input: + */ + for(i=0; i<=max_source; i++) + if (FD_ISSET(i, &input_sources_copy) && input_handler[i]) { +#ifdef DEBUG + if (zwgc_debug) + fprintf(stderr, + "mux_loop...activity on fd %d, calling %x(%x)\n", + i,input_handler[i],input_handler_arg[i]); +#endif + input_handler[i](input_handler_arg[i]); + } + } +} -- cgit v1.2.3