From: Fredrik Tolf Date: Fri, 28 Dec 2012 05:55:12 +0000 (+0100) Subject: lib: Gave ioloop the ability to exit X-Git-Tag: 0.12~20 X-Git-Url: http://www.dolda2000.com/gitweb/?p=ashd.git;a=commitdiff_plain;h=9d32586e59d7053a53e54860cbcfbb9c23f59e8a lib: Gave ioloop the ability to exit There are race issues with signaling, however. It should be possible to call an ioloop variant that uses pselect or similar. --- diff --git a/lib/mtio-epoll.c b/lib/mtio-epoll.c index 85ee4a1..72468e0 100644 --- a/lib/mtio-epoll.c +++ b/lib/mtio-epoll.c @@ -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; } diff --git a/lib/mtio-select.c b/lib/mtio-select.c index 6536c95..26e6785 100644 --- a/lib/mtio-select.c +++ b/lib/mtio-select.c @@ -32,6 +32,7 @@ #include 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; } diff --git a/lib/mtio.h b/lib/mtio.h index 874eec6..2ea0eb5 100644 --- a/lib/mtio.h +++ b/lib/mtio.h @@ -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