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:
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();
+}