lib: Gave ioloop the ability to exit
authorFredrik Tolf <fredrik@dolda2000.com>
Fri, 28 Dec 2012 05:55:12 +0000 (06:55 +0100)
committerFredrik Tolf <fredrik@dolda2000.com>
Fri, 28 Dec 2012 05:55:12 +0000 (06:55 +0100)
There are race issues with signaling, however. It should be possible to
call an ioloop variant that uses pselect or similar.

lib/mtio-epoll.c
lib/mtio-select.c
lib/mtio.h

index 85ee4a1..72468e0 100644 (file)
@@ -43,6 +43,7 @@ struct blocker {
 };
 
 static int epfd = -1, fdln = 0;
+static int exitstatus;
 static struct blocker **fdlist;
 
 static int regfd(struct blocker *bl)
@@ -125,6 +126,7 @@ static void remfd(struct blocker *bl)
            flog(LOG_ERR, "epoll_mod on fd %i: %s", bl->fd, strerror(errno));
        }
     }
+    bl->reg = 0;
 }
 
 int block(int fd, int ev, time_t to)
@@ -158,13 +160,14 @@ int block(int fd, int ev, time_t to)
     return(rv);
 }
 
-void ioloop(void)
+int ioloop(void)
 {
     struct blocker *bl, *nbl;
     struct epoll_event evr[16];
     int i, fd, nev, ev, toval;
     time_t now, timeout;
     
+    exitstatus = 0;
     epfd = epoll_create(128);
     fcntl(epfd, F_SETFD, FD_CLOEXEC);
     for(bl = blockers; bl; bl = nbl) {
@@ -185,6 +188,8 @@ void ioloop(void)
            toval = (timeout - now) * 1000;
        else
            toval = 1000;
+       if(exitstatus)
+           break;
        nev = epoll_wait(epfd, evr, sizeof(evr) / sizeof(*evr), toval);
        if(nev < 0) {
            if(errno != EINTR) {
@@ -217,6 +222,14 @@ void ioloop(void)
                resume(bl->th, 0);
        }
     }
+    for(bl = blockers; bl; bl = bl->n)
+       remfd(bl);
     close(epfd);
     epfd = -1;
+    return(exitstatus);
+}
+
+void exitioloop(int status)
+{
+    exitstatus = status;
 }
index 6536c95..26e6785 100644 (file)
@@ -32,6 +32,7 @@
 #include <mtio.h>
 
 static struct blocker *blockers;
+static int exitstatus;
 
 struct blocker {
     struct blocker *n, *p;
@@ -72,7 +73,7 @@ int block(int fd, int ev, time_t to)
     return(rv);
 }
 
-void ioloop(void)
+int ioloop(void)
 {
     int ret;
     fd_set rfds, wfds, efds;
@@ -82,6 +83,7 @@ void ioloop(void)
     int maxfd;
     int ev;
     
+    exitstatus = 0;
     while(blockers != NULL) {
        FD_ZERO(&rfds);
        FD_ZERO(&wfds);
@@ -100,6 +102,8 @@ void ioloop(void)
            if((bl->to != 0) && ((timeout == 0) || (timeout > bl->to)))
                timeout = bl->to;
        }
+       if(exitstatus)
+           return(exitstatus);
        toval.tv_sec = timeout - now;
        toval.tv_usec = 0;
        ret = select(maxfd + 1, &rfds, &wfds, &efds, timeout?(&toval):NULL);
@@ -110,21 +114,28 @@ void ioloop(void)
                 * probably is. */
                sleep(1);
            }
-       }
-       now = time(NULL);
-       for(bl = blockers; bl; bl = nbl) {
-           nbl = bl->n;
-           ev = 0;
-           if(FD_ISSET(bl->fd, &rfds))
-               ev |= EV_READ;
-           if(FD_ISSET(bl->fd, &wfds))
-               ev |= EV_WRITE;
-           if(FD_ISSET(bl->fd, &efds))
-               ev = -1;
-           if((ev < 0) || (ev & bl->ev))
-               resume(bl->th, ev);
-           else if((bl->to != 0) && (bl->to <= now))
-               resume(bl->th, 0);
+       } else {
+           now = time(NULL);
+           for(bl = blockers; bl; bl = nbl) {
+               nbl = bl->n;
+               ev = 0;
+               if(FD_ISSET(bl->fd, &rfds))
+                   ev |= EV_READ;
+               if(FD_ISSET(bl->fd, &wfds))
+                   ev |= EV_WRITE;
+               if(FD_ISSET(bl->fd, &efds))
+                   ev = -1;
+               if((ev < 0) || (ev & bl->ev))
+                   resume(bl->th, ev);
+               else if((bl->to != 0) && (bl->to <= now))
+                   resume(bl->th, 0);
+           }
        }
     }
+    return(0);
+}
+
+void exitioloop(int status)
+{
+    exitstatus = status;
 }
index 874eec6..2ea0eb5 100644 (file)
@@ -7,7 +7,8 @@
 #define EV_WRITE 2
 
 int block(int fd, int ev, time_t to);
-void ioloop(void);
+int ioloop(void);
+void exitioloop(int status);
 FILE *mtstdopen(int fd, int issock, int timeout, char *mode);
 
 #endif