add simple mainloop implementation

not used so far
This commit is contained in:
Oswald Buddenhagen 2011-03-13 14:29:12 +01:00
parent a55354516b
commit 7867eb9009
4 changed files with 183 additions and 1 deletions

View File

@ -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"])

View File

@ -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];

View File

@ -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;
}

View File

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