-static struct blocker *blockers;
-
-#ifdef HAVE_EPOLL
-
-/*
- * Support for epoll. Optimally, different I/O loops should be split
- * into different files for greater clarity, but I'll save that fun
- * for another day.
- *
- * Scroll down to #else for the normal select loop.
- */
-
-#include <sys/epoll.h>
-
-struct blocker {
- struct blocker *n, *p, *n2, *p2;
- int fd, reg;
- int ev;
- time_t to;
- struct muth *th;
-};
-
-static int epfd = -1, fdln = 0;
-static struct blocker **fdlist;
-
-static int regfd(struct blocker *bl)
-{
- struct blocker *o;
- struct epoll_event evd;
-
- evd.events = 0;
- if(bl->ev & EV_READ)
- evd.events |= EPOLLIN;
- if(bl->ev & EV_WRITE)
- evd.events |= EPOLLOUT;
- evd.data.fd = bl->fd;
- if(bl->fd >= fdln) {
- if(fdlist) {
- fdlist = srealloc(fdlist, sizeof(*fdlist) * (bl->fd + 1));
- memset(fdlist + fdln, 0, sizeof(*fdlist) * (bl->fd + 1 - fdln));
- fdln = bl->fd + 1;
- } else {
- fdlist = szmalloc(sizeof(*fdlist) * (fdln = (bl->fd + 1)));
- }
- }
- if(fdlist[bl->fd] == NULL) {
- if(epoll_ctl(epfd, EPOLL_CTL_ADD, bl->fd, &evd)) {
- /* XXX?! Whatever to do, really? */
- flog(LOG_ERR, "epoll_add on fd %i: %s", bl->fd, strerror(errno));
- return(-1);
- }
- } else {
- for(o = fdlist[bl->fd]; o; o = o->n2) {
- if(o->ev & EV_READ)
- evd.events |= EPOLLIN;
- if(o->ev & EV_WRITE)
- evd.events |= EPOLLOUT;
- }
- if(epoll_ctl(epfd, EPOLL_CTL_MOD, bl->fd, &evd)) {
- /* XXX?! Whatever to do, really? */
- flog(LOG_ERR, "epoll_mod on fd %i: %s", bl->fd, strerror(errno));
- return(-1);
- }
- }
- bl->n2 = fdlist[bl->fd];
- bl->p2 = NULL;
- if(fdlist[bl->fd] != NULL)
- fdlist[bl->fd]->p2 = bl;
- fdlist[bl->fd] = bl;
- bl->reg = 1;
- return(0);
-}
-
-static void remfd(struct blocker *bl)
-{
- struct blocker *o;
- struct epoll_event evd;
-
- if(!bl->reg)
- return;
- if(bl->n2)
- bl->n2->p2 = bl->p2;
- if(bl->p2)
- bl->p2->n2 = bl->n2;
- if(bl == fdlist[bl->fd])
- fdlist[bl->fd] = bl->n2;
- if(fdlist[bl->fd] == NULL) {
- if(epoll_ctl(epfd, EPOLL_CTL_DEL, bl->fd, NULL))
- flog(LOG_ERR, "epoll_del on fd %i: %s", bl->fd, strerror(errno));
- } else {
- evd.events = 0;
- evd.data.fd = bl->fd;
- for(o = fdlist[bl->fd]; o; o = o->n2) {
- if(o->ev & EV_READ)
- evd.events |= EPOLLIN;
- if(o->ev & EV_WRITE)
- evd.events |= EPOLLOUT;
- }
- if(epoll_ctl(epfd, EPOLL_CTL_MOD, bl->fd, &evd)) {
- /* XXX?! Whatever to do, really? */
- flog(LOG_ERR, "epoll_mod on fd %i: %s", bl->fd, strerror(errno));
- }
- }
-}
-
-int block(int fd, int ev, time_t to)