Procházet zdrojové kódy

add simple mainloop implementation

not used so far
Oswald Buddenhagen před 14 roky
rodič
revize
7867eb9009
4 změnil soubory, kde provedl 183 přidání a 1 odebrání
  1. 1 1
      configure.in
  2. 14 0
      src/isync.h
  3. 1 0
      src/main.c
  4. 167 0
      src/util.c

+ 1 - 1
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"])

+ 14 - 0
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];

+ 1 - 0
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;
 }
 

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