lib: Gave ioloop the ability to exit
[ashd.git] / lib / mtio-epoll.c
index 8510c5e..72468e0 100644 (file)
@@ -17,6 +17,8 @@
 */
 
 #include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
 #include <fcntl.h>
 #include <string.h>
 #include <sys/epoll.h>
@@ -41,6 +43,7 @@ struct blocker {
 };
 
 static int epfd = -1, fdln = 0;
+static int exitstatus;
 static struct blocker **fdlist;
 
 static int regfd(struct blocker *bl)
@@ -123,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)
@@ -156,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) {
@@ -183,10 +188,12 @@ 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) {
-               flog(LOG_CRIT, "ioloop: select errored out: %s", strerror(errno));
+               flog(LOG_CRIT, "ioloop: epoll_wait errored out: %s", strerror(errno));
                /* To avoid CPU hogging in case it's bad, which it
                 * probably is. */
                sleep(1);
@@ -215,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;
 }