isync

mailbox synchronization program
git clone https://git.code.sf.net/p/isync/isync
Log | Files | Refs | README | LICENSE

commit 7867eb9009791b670e085655bcc1b6be924299c4
parent a55354516b08efa98be7b4973691d4eb671d79bb
Author: Oswald Buddenhagen <ossi@users.sf.net>
Date:   Sun, 13 Mar 2011 14:29:12 +0100

add simple mainloop implementation

not used so far

Diffstat:
Mconfigure.in | 2+-
Msrc/isync.h | 14++++++++++++++
Msrc/main.c | 1+
Msrc/util.c | 167+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 183 insertions(+), 1 deletion(-)

diff --git a/configure.in b/configure.in @@ -9,7 +9,7 @@ if test "$GCC" = yes; then CFLAGS="$CFLAGS -pipe -W -Wall -Wshadow -Wstrict-prototypes" fi -AC_CHECK_HEADERS([sys/filio.h]) +AC_CHECK_HEADERS(sys/filio.h sys/poll.h sys/select.h) AC_CHECK_FUNCS(vasprintf) AC_CHECK_LIB(socket, socket, [SOCK_LIBS="-lsocket"]) diff --git a/src/isync.h b/src/isync.h @@ -397,6 +397,20 @@ void sort_ints( int *arr, int len ); void arc4_init( void ); unsigned char arc4_getbyte( void ); +#ifdef HAVE_SYS_POLL_H +# include <sys/poll.h> +#else +# define POLLIN 1 +# define POLLOUT 4 +# define POLLERR 8 +#endif + +void add_fd( int fd, void (*cb)( int events, void *aux ), void *aux ); +void conf_fd( int fd, int and_events, int or_events ); +void fake_fd( int fd, int events ); +void del_fd( int fd ); +void main_loop( void ); + /* sync.c */ extern const char *str_ms[2], *str_hl[2]; diff --git a/src/main.c b/src/main.c @@ -485,6 +485,7 @@ main( int argc, char **argv ) mvars->argv = argv; mvars->cben = 1; sync_chans( mvars, E_START ); + main_loop(); return mvars->ret; } diff --git a/src/util.c b/src/util.c @@ -23,6 +23,7 @@ #include "isync.h" +#include <assert.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> @@ -411,3 +412,169 @@ arc4_getbyte( void ) rs.s[rs.j] = si; return rs.s[(si + sj) & 0xff]; } + + +#ifdef HAVE_SYS_POLL_H +static struct pollfd *pollfds; +#else +# ifdef HAVE_SYS_SELECT_H +# include <sys/select.h> +# endif +# define pollfds fdparms +#endif +static struct { + void (*cb)( int what, void *aux ); + void *aux; +#ifndef HAVE_SYS_POLL_H + int fd, events; +#endif + int faked; +} *fdparms; +static int npolls, rpolls, changed; + +static int +find_fd( int fd ) +{ + int n; + + for (n = 0; n < npolls; n++) + if (pollfds[n].fd == fd) + return n; + return -1; +} + +void +add_fd( int fd, void (*cb)( int events, void *aux ), void *aux ) +{ + int n; + + assert( find_fd( fd ) < 0 ); + n = npolls++; + if (rpolls < npolls) { + rpolls = npolls; +#ifdef HAVE_SYS_POLL_H + pollfds = nfrealloc(pollfds, npolls * sizeof(*pollfds)); +#endif + fdparms = nfrealloc(fdparms, npolls * sizeof(*fdparms)); + } + pollfds[n].fd = fd; + pollfds[n].events = 0; /* POLLERR & POLLHUP implicit */ + fdparms[n].faked = 0; + fdparms[n].cb = cb; + fdparms[n].aux = aux; + changed = 1; +} + +void +conf_fd( int fd, int and_events, int or_events ) +{ + int n = find_fd( fd ); + assert( n >= 0 ); + pollfds[n].events = (pollfds[n].events & and_events) | or_events; +} + +void +fake_fd( int fd, int events ) +{ + int n = find_fd( fd ); + assert( n >= 0 ); + fdparms[n].faked |= events; +} + +void +del_fd( int fd ) +{ + int n = find_fd( fd ); + assert( n >= 0 ); + npolls--; +#ifdef HAVE_SYS_POLL_H + memmove(pollfds + n, pollfds + n + 1, (npolls - n) * sizeof(*pollfds)); +#endif + memmove(fdparms + n, fdparms + n + 1, (npolls - n) * sizeof(*fdparms)); + changed = 1; +} + +#define shifted_bit(in, from, to) \ + (((unsigned)(in) & from) \ + / (from > to ? from / to : 1) \ + * (to > from ? to / from : 1)) + +static void +event_wait( void ) +{ + int m, n; + +#ifdef HAVE_SYS_POLL_H + int timeout = -1; + for (n = 0; n < npolls; n++) + if (fdparms[n].faked) { + timeout = 0; + break; + } + if (poll( pollfds, npolls, timeout ) < 0) { + perror( "poll() failed in event loop" ); + abort(); + } + for (n = 0; n < npolls; n++) + if ((m = pollfds[n].revents | fdparms[n].faked)) { + assert( !(m & POLLNVAL) ); + fdparms[n].faked = 0; + fdparms[n].cb( m | shifted_bit( m, POLLHUP, POLLIN ), fdparms[n].aux ); + if (changed) { + changed = 0; + break; + } + } +#else + struct timeval *timeout = 0; + static struct timeval null_tv; + fd_set rfds, wfds, efds; + int fd; + + FD_ZERO( &rfds ); + FD_ZERO( &wfds ); + FD_ZERO( &efds ); + m = -1; + for (n = 0; n < npolls; n++) { + if (fdparms[n].faked) + timeout = &null_tv; + fd = fdparms[n].fd; + if (fdparms[n].events & POLLIN) + FD_SET( fd, &rfds ); + if (fdparms[n].events & POLLOUT) + FD_SET( fd, &wfds ); + FD_SET( fd, &efds ); + if (fd > m) + m = fd; + } + if (select( m + 1, &rfds, &wfds, &efds, timeout ) < 0) { + perror( "select() failed in event loop" ); + abort(); + } + for (n = 0; n < npolls; n++) { + fd = fdparms[n].fd; + m = fdparms[n].faked; + if (FD_ISSET( fd, &rfds )) + m |= POLLIN; + if (FD_ISSET( fd, &wfds )) + m |= POLLOUT; + if (FD_ISSET( fd, &efds )) + m |= POLLERR; + if (m) { + fdparms[n].faked = 0; + fdparms[n].cb( m, fdparms[n].aux ); + if (changed) { + changed = 0; + break; + } + } + } +#endif +} + +void +main_loop( void ) +{ + while (npolls) + event_wait(); +}