|
@@ -584,84 +584,73 @@ bucketsForSize( int size )
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static notifier_t *notifiers;
|
|
|
|
+static int changed; /* Iterator may be invalid now. */
|
|
#ifdef HAVE_SYS_POLL_H
|
|
#ifdef HAVE_SYS_POLL_H
|
|
static struct pollfd *pollfds;
|
|
static struct pollfd *pollfds;
|
|
|
|
+static int npolls, rpolls;
|
|
#else
|
|
#else
|
|
# ifdef HAVE_SYS_SELECT_H
|
|
# ifdef HAVE_SYS_SELECT_H
|
|
# include <sys/select.h>
|
|
# include <sys/select.h>
|
|
# endif
|
|
# endif
|
|
-# define pollfds fdparms
|
|
|
|
#endif
|
|
#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
|
|
void
|
|
-add_fd( int fd, void (*cb)( int events, void *aux ), void *aux )
|
|
|
|
|
|
+init_notifier( notifier_t *sn, int fd, void (*cb)( int, void * ), void *aux )
|
|
{
|
|
{
|
|
- int n;
|
|
|
|
-
|
|
|
|
- assert( find_fd( fd ) < 0 );
|
|
|
|
- n = npolls++;
|
|
|
|
|
|
+#ifdef HAVE_SYS_POLL_H
|
|
|
|
+ int idx = npolls++;
|
|
if (rpolls < npolls) {
|
|
if (rpolls < npolls) {
|
|
rpolls = npolls;
|
|
rpolls = npolls;
|
|
-#ifdef HAVE_SYS_POLL_H
|
|
|
|
- pollfds = nfrealloc(pollfds, npolls * sizeof(*pollfds));
|
|
|
|
-#endif
|
|
|
|
- fdparms = nfrealloc(fdparms, npolls * sizeof(*fdparms));
|
|
|
|
|
|
+ pollfds = nfrealloc( pollfds, npolls * sizeof(*pollfds) );
|
|
}
|
|
}
|
|
- 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;
|
|
|
|
|
|
+ pollfds[idx].fd = fd;
|
|
|
|
+ pollfds[idx].events = 0; /* POLLERR & POLLHUP implicit */
|
|
|
|
+ sn->index = idx;
|
|
|
|
+#else
|
|
|
|
+ sn->fd = fd;
|
|
|
|
+ sn->events = 0;
|
|
|
|
+#endif
|
|
|
|
+ sn->cb = cb;
|
|
|
|
+ sn->aux = aux;
|
|
|
|
+ sn->faked = 0;
|
|
|
|
+ sn->next = notifiers;
|
|
|
|
+ notifiers = sn;
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
void
|
|
-fake_fd( int fd, int events )
|
|
|
|
|
|
+conf_notifier( notifier_t *sn, int and_events, int or_events )
|
|
{
|
|
{
|
|
- int n = find_fd( fd );
|
|
|
|
- assert( n >= 0 );
|
|
|
|
- fdparms[n].faked |= events;
|
|
|
|
|
|
+#ifdef HAVE_SYS_POLL_H
|
|
|
|
+ int idx = sn->index;
|
|
|
|
+ pollfds[idx].events = (pollfds[idx].events & and_events) | or_events;
|
|
|
|
+#else
|
|
|
|
+ sn->events = (sn->events & and_events) | or_events;
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
void
|
|
-del_fd( int fd )
|
|
|
|
|
|
+wipe_notifier( notifier_t *sn )
|
|
{
|
|
{
|
|
- int n = find_fd( fd );
|
|
|
|
- assert( n >= 0 );
|
|
|
|
- npolls--;
|
|
|
|
|
|
+ notifier_t **snp;
|
|
#ifdef HAVE_SYS_POLL_H
|
|
#ifdef HAVE_SYS_POLL_H
|
|
- memmove(pollfds + n, pollfds + n + 1, (npolls - n) * sizeof(*pollfds));
|
|
|
|
|
|
+ int idx;
|
|
#endif
|
|
#endif
|
|
- memmove(fdparms + n, fdparms + n + 1, (npolls - n) * sizeof(*fdparms));
|
|
|
|
|
|
+
|
|
|
|
+ for (snp = ¬ifiers; *snp != sn; snp = &(*snp)->next)
|
|
|
|
+ assert( *snp );
|
|
|
|
+ *snp = sn->next;
|
|
|
|
+ sn->next = 0;
|
|
changed = 1;
|
|
changed = 1;
|
|
|
|
+
|
|
|
|
+#ifdef HAVE_SYS_POLL_H
|
|
|
|
+ idx = sn->index;
|
|
|
|
+ memmove( pollfds + idx, pollfds + idx + 1, (--npolls - idx) * sizeof(*pollfds) );
|
|
|
|
+ for (sn = notifiers; sn; sn = sn->next) {
|
|
|
|
+ if (sn->index > idx)
|
|
|
|
+ sn->index--;
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
|
|
#define shifted_bit(in, from, to) \
|
|
#define shifted_bit(in, from, to) \
|
|
@@ -672,12 +661,13 @@ del_fd( int fd )
|
|
static void
|
|
static void
|
|
event_wait( void )
|
|
event_wait( void )
|
|
{
|
|
{
|
|
- int m, n;
|
|
|
|
|
|
+ notifier_t *sn;
|
|
|
|
+ int m;
|
|
|
|
|
|
#ifdef HAVE_SYS_POLL_H
|
|
#ifdef HAVE_SYS_POLL_H
|
|
int timeout = -1;
|
|
int timeout = -1;
|
|
- for (n = 0; n < npolls; n++)
|
|
|
|
- if (fdparms[n].faked) {
|
|
|
|
|
|
+ for (sn = notifiers; sn; sn = sn->next)
|
|
|
|
+ if (sn->faked) {
|
|
timeout = 0;
|
|
timeout = 0;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -685,16 +675,18 @@ event_wait( void )
|
|
perror( "poll() failed in event loop" );
|
|
perror( "poll() failed in event loop" );
|
|
abort();
|
|
abort();
|
|
}
|
|
}
|
|
- for (n = 0; n < npolls; n++)
|
|
|
|
- if ((m = pollfds[n].revents | fdparms[n].faked)) {
|
|
|
|
|
|
+ for (sn = notifiers; sn; sn = sn->next) {
|
|
|
|
+ int n = sn->index;
|
|
|
|
+ if ((m = pollfds[n].revents | sn->faked)) {
|
|
assert( !(m & POLLNVAL) );
|
|
assert( !(m & POLLNVAL) );
|
|
- fdparms[n].faked = 0;
|
|
|
|
- fdparms[n].cb( m | shifted_bit( m, POLLHUP, POLLIN ), fdparms[n].aux );
|
|
|
|
|
|
+ sn->faked = 0;
|
|
|
|
+ sn->cb( m | shifted_bit( m, POLLHUP, POLLIN ), sn->aux );
|
|
if (changed) {
|
|
if (changed) {
|
|
changed = 0;
|
|
changed = 0;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ }
|
|
#else
|
|
#else
|
|
struct timeval *timeout = 0;
|
|
struct timeval *timeout = 0;
|
|
static struct timeval null_tv;
|
|
static struct timeval null_tv;
|
|
@@ -705,13 +697,13 @@ event_wait( void )
|
|
FD_ZERO( &wfds );
|
|
FD_ZERO( &wfds );
|
|
FD_ZERO( &efds );
|
|
FD_ZERO( &efds );
|
|
m = -1;
|
|
m = -1;
|
|
- for (n = 0; n < npolls; n++) {
|
|
|
|
- if (fdparms[n].faked)
|
|
|
|
|
|
+ for (sn = notifiers; sn; sn = sn->next) {
|
|
|
|
+ if (sn->faked)
|
|
timeout = &null_tv;
|
|
timeout = &null_tv;
|
|
- fd = fdparms[n].fd;
|
|
|
|
- if (fdparms[n].events & POLLIN)
|
|
|
|
|
|
+ fd = sn->fd;
|
|
|
|
+ if (sn->events & POLLIN)
|
|
FD_SET( fd, &rfds );
|
|
FD_SET( fd, &rfds );
|
|
- if (fdparms[n].events & POLLOUT)
|
|
|
|
|
|
+ if (sn->events & POLLOUT)
|
|
FD_SET( fd, &wfds );
|
|
FD_SET( fd, &wfds );
|
|
FD_SET( fd, &efds );
|
|
FD_SET( fd, &efds );
|
|
if (fd > m)
|
|
if (fd > m)
|
|
@@ -721,9 +713,9 @@ event_wait( void )
|
|
perror( "select() failed in event loop" );
|
|
perror( "select() failed in event loop" );
|
|
abort();
|
|
abort();
|
|
}
|
|
}
|
|
- for (n = 0; n < npolls; n++) {
|
|
|
|
- fd = fdparms[n].fd;
|
|
|
|
- m = fdparms[n].faked;
|
|
|
|
|
|
+ for (sn = notifiers; sn; sn = sn->next) {
|
|
|
|
+ fd = sn->fd;
|
|
|
|
+ m = sn->faked;
|
|
if (FD_ISSET( fd, &rfds ))
|
|
if (FD_ISSET( fd, &rfds ))
|
|
m |= POLLIN;
|
|
m |= POLLIN;
|
|
if (FD_ISSET( fd, &wfds ))
|
|
if (FD_ISSET( fd, &wfds ))
|
|
@@ -731,8 +723,8 @@ event_wait( void )
|
|
if (FD_ISSET( fd, &efds ))
|
|
if (FD_ISSET( fd, &efds ))
|
|
m |= POLLERR;
|
|
m |= POLLERR;
|
|
if (m) {
|
|
if (m) {
|
|
- fdparms[n].faked = 0;
|
|
|
|
- fdparms[n].cb( m, fdparms[n].aux );
|
|
|
|
|
|
+ sn->faked = 0;
|
|
|
|
+ sn->cb( m, sn->aux );
|
|
if (changed) {
|
|
if (changed) {
|
|
changed = 0;
|
|
changed = 0;
|
|
break;
|
|
break;
|
|
@@ -745,6 +737,6 @@ event_wait( void )
|
|
void
|
|
void
|
|
main_loop( void )
|
|
main_loop( void )
|
|
{
|
|
{
|
|
- while (npolls)
|
|
|
|
|
|
+ while (notifiers)
|
|
event_wait();
|
|
event_wait();
|
|
}
|
|
}
|