--- thttpd.orig.c	Sun Mar  9 18:46:11 2003
+++ thttpd.c	Sun Mar  9 18:42:00 2003
@@ -562,6 +562,13 @@
     (void) gettimeofday( &tv, (struct timezone*) 0 );
     while ( ( ! terminate ) || numconnects > 0 )
 	{
+        if ( hs != (httpd_server*) 0 )
+        {
+            if (hs->listen4_fd != -1)
+                fdwatch_reset_fd(hs->listen4_fd);
+            if (hs->listen6_fd != -1)
+                fdwatch_reset_fd(hs->listen6_fd);
+        }
         /* Do the fd watch. */
         num_ready = fdwatch( tmr_mstimeout( &tv ) );
         if ( num_ready < 0 )
--- fdwatch.orig.c	Sun Mar  9 18:46:33 2003
+++ fdwatch.c	Sun Mar  9 18:42:29 2003
@@ -49,6 +49,10 @@
 #include <sys/event.h>
 #endif /* HAVE_SYS_EVENT_H */
 
+#ifdef HAVE_EPOLL
+#include <sys/epoll.h>
+#endif /* HAVE_EPOLL */
+
 #include "fdwatch.h"
 
 #ifdef HAVE_SELECT
@@ -91,6 +95,15 @@
 static int select_check_fd( int fd );
 static int select_get_fd( int ridx );
 static int select_get_maxfd( void );
+#else /* HAVE_SELECT */
+#   ifdef HAVE_EPOLL
+static int epoll_init( int nfiles );
+static void epoll_add_fd( int fd, int rw );
+static void epoll_del_fd( int fd );
+static int epoll_watch( long timeout_msecs );
+static int epoll_check_fd( int fd );
+static int epoll_get_fd( int ridx );
+#   endif /* HAVE_EPOLL */
 #  endif /* HAVE_SELECT */
 # endif /* HAVE_POLL */
 #endif /* HAVE_KQUEUE */
@@ -146,6 +159,11 @@
 #  ifdef HAVE_SELECT
     if ( select_init( nfiles ) == -1 )
         return -1;
+# else /* HAVE_SELECT */
+#  ifdef HAVE_EPOLL
+    if ( epoll_init( nfiles ) == -1 )
+        return -1;
+#   endif /* HAVE_EPOLL */
 #  endif /* HAVE_SELECT */
 # endif /* HAVE_POLL */
 #endif /* HAVE_KQUEUE */
@@ -172,6 +190,10 @@
 # else /* HAVE_POLL */
 #  ifdef HAVE_SELECT
     select_add_fd( fd, rw );
+#else /* HAVE_SELECT */
+#   ifdef HAVE_EPOLL
+    epoll_add_fd( fd, rw );
+#   endif /* HAVE_EPOLL */
 #  endif /* HAVE_SELECT */
 # endif /* HAVE_POLL */
 #endif /* HAVE_KQUEUE */
@@ -199,6 +221,10 @@
 # else /* HAVE_POLL */
 #  ifdef HAVE_SELECT
     select_del_fd( fd );
+#else /* HAVE_SELECT */
+#   ifdef HAVE_EPOLL
+    epoll_del_fd( fd );
+#   endif /* HAVE_EPOLL */
 #  endif /* HAVE_SELECT */
 # endif /* HAVE_POLL */
 #endif /* HAVE_KQUEUE */
@@ -222,8 +248,12 @@
 # else /* HAVE_POLL */
 #  ifdef HAVE_SELECT
     return select_watch( timeout_msecs );
-#  else /* HAVE_SELECT */
+#else /* HAVE_SELECT */
+#   ifdef HAVE_EPOLL
+    return epoll_watch( timeout_msecs );
+#   else /* HAVE_EPOLL */
     return -1;
+#   endif /* HAVE_EPOLL */
 #  endif /* HAVE_SELECT */
 # endif /* HAVE_POLL */
 #endif /* HAVE_KQUEUE */
@@ -248,8 +278,12 @@
 # else /* HAVE_POLL */
 #  ifdef HAVE_SELECT
     return select_check_fd( fd );
+#else
+# ifdef HAVE_EPOLL
+    return epoll_check_fd( fd );
 #  else /* HAVE_SELECT */
     return 0;
+#  endif /* HAVE_EPOLL */
 #  endif /* HAVE_SELECT */
 # endif /* HAVE_POLL */
 #endif /* HAVE_KQUEUE */
@@ -270,7 +304,11 @@
 #  ifdef HAVE_SELECT
     fd = select_get_fd( ridx );
 #  else /* HAVE_SELECT */
+# ifdef HAVE_EPOLL
+    fd = epoll_get_fd( ridx );
+# else /* HAVE_EPOLL */
     fd = -1;
+#  endif /* HAVE_EPOLL */
 #  endif /* HAVE_SELECT */
 # endif /* HAVE_POLL */
 #endif /* HAVE_KQUEUE */
@@ -296,7 +334,11 @@
 #  ifdef HAVE_SELECT
     which = "select";
 #  else /* HAVE_SELECT */
+# ifdef HAVE_EPOLL
+    which = "epoll";
+# else /* HAVE_EPOLL */
     which = "UNKNOWN";
+#  endif /* HAVE_EPOLL */
 #  endif /* HAVE_SELECT */
 # endif /* HAVE_POLL */
 #endif /* HAVE_KQUEUE */
@@ -309,6 +351,29 @@
 }
 
 
+void
+fdwatch_reset_fd( int fd )
+{
+#ifdef HAVE_KQUEUE
+    return kqueue_reset_fd( fd );
+#else
+# ifdef HAVE_POLL
+    return poll_reset_fd( fd );
+# else /* HAVE_POLL */
+#  ifdef HAVE_SELECT
+    return select_reset_fd( fd );
+#else
+# ifdef HAVE_EPOLL
+    return epoll_reset_fd( fd );
+#  else /* HAVE_SELECT */
+    return 0;
+#  endif /* HAVE_EPOLL */
+#  endif /* HAVE_SELECT */
+# endif /* HAVE_POLL */
+#endif /* HAVE_KQUEUE */
+}
+
+
 #ifdef HAVE_KQUEUE
 
 static struct kevent* kqevents;
@@ -423,6 +488,14 @@
     return kqrevents[ridx].ident;
 }
 
+
+void
+kqueue_reset_fd( int fd )
+{
+
+}
+
+
 #else /* HAVE_KQUEUE */
 
 
@@ -529,6 +602,14 @@
     return poll_rfdidx[ridx];
 }
 
+
+void
+poll_reset_fd( int fd )
+{
+
+}
+
+
 # else /* HAVE_POLL */
 
 
@@ -675,8 +756,141 @@
     return maxfd;
 }
 
+
+void
+select_reset_fd( int fd )
+{
+
+}
+
+
+# else /* HAVE_SELECT */
+
+# ifdef HAVE_EPOLL
+
+static int ep_fd;
+static struct epoll_event *ep_events;
+static int ep_readyfds;
+static int* epoll_rs2idx;
+static int* epoll_idx2rs;
+
+
+static int
+epoll_init( int nfiles )
+{
+    ep_readyfds = 0;
+    ep_fd = epoll_create(nfiles + 1);
+    ep_events = (struct epoll_event*) malloc( sizeof(struct epoll_event) * nfiles );
+    epoll_rs2idx = (int*) malloc( sizeof(int) * nfiles );
+    epoll_idx2rs = (int*) malloc( sizeof(int) * nfiles );
+    if ( ep_fd < 0 || ep_events == (struct epoll_event*) 0 || epoll_rs2idx == (int*) 0 ||
+         epoll_idx2rs == (int*) 0)
+        return -1;
+    return 0;
+}
+
+
+static void
+epoll_add_fd( int fd, int rw )
+{
+    struct epoll_event ev;
+
+    ev.data.fd = fd;
+    switch ( rw )
+    {
+    case FDW_READ: ev.events = EPOLLIN; break;
+    case FDW_WRITE: ev.events = EPOLLOUT; break;
+    default:
+        ev.events = 0;
+        break;
+    }
+    if (epoll_ctl(ep_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
+    {
+        perror("epoll_ctl( EPOLL_CTL_ADD)");
+        exit(1);
+    }
+}
+
+
+static void
+epoll_del_fd( int fd )
+{
+    struct epoll_event ev;
+
+    if (epoll_ctl(ep_fd, EPOLL_CTL_DEL, fd, &ev) < 0)
+    {
+        perror("epoll_ctl( EPOLL_CTL_DEL)");
+        exit(1);
+    }
+}
+
+
+static int
+epoll_watch( long timeout_msecs )
+{
+    int i, ridx;
+
+    ep_readyfds = epoll_wait(ep_fd, ep_events, nfiles, timeout_msecs);
+
+    for ( i = 0, ridx = 0; i < ep_readyfds; ++i )
+        if ( ep_events[i].events &
+             ( EPOLLIN | EPOLLOUT | EPOLLERR | EPOLLHUP ) )
+        {
+            epoll_idx2rs[ep_events[i].data.fd] = i;
+            epoll_rs2idx[ridx] = i;
+            ridx++;
+        }
+
+    return ridx;
+}
+
+
+static int
+epoll_check_fd( int fd )
+{
+    int fdidx = epoll_idx2rs[fd];
+
+    if ( fdidx < -1 || fdidx >= nfiles)
+    {
+        syslog( LOG_ERR, "bad fdidx (%d) in epoll_check_fd!", fdidx);
+        return 0;
+    }
+    if ( fdidx == -1 || ep_events[fdidx].data.fd != fd || ep_events[fdidx].events & EPOLLERR )
+        return 0;
+    switch ( fd_rw[fd] )
+    {
+    case FDW_READ: return ep_events[fdidx].events & ( EPOLLIN | EPOLLERR | EPOLLHUP );
+    case FDW_WRITE: return ep_events[fdidx].events & ( EPOLLOUT | EPOLLERR | EPOLLHUP );
+    default: return 0;
+    }
+}
+
+
+static int
+epoll_get_fd( int ridx )
+{
+    if ( ridx < 0 || ridx >= ep_readyfds )
+    {
+        syslog( LOG_ERR, "bad ridx (%d) in epoll_get_fd!", ridx );
+        return -1;
+    }
+
+    return ep_events[epoll_rs2idx[ridx]].data.fd;
+}
+
+
+void
+epoll_reset_fd( int fd )
+{
+    epoll_idx2rs[fd] = -1;
+}
+
+
+#   endif /* HAVE_EPOLL */
+
 #  endif /* HAVE_SELECT */
 
 # endif /* HAVE_POLL */
 
 #endif /* HAVE_KQUEUE */
+
--- fdwatch.orig.h	Sun Mar  9 18:46:21 2003
+++ fdwatch.h	Sun Mar  9 18:36:27 2003
@@ -86,4 +86,7 @@
 /* Generate debugging statistics syslog message. */
 extern void fdwatch_logstats( long secs );
 
+/* Inavlidates fd event set */
+extern void fdwatch_reset_fd( int fd );
+
 #endif /* _FDWATCH_H_ */
