From 83723896cdbe2fb064748e45611e9b9c829c1d72 Mon Sep 17 00:00:00 2001 From: Fredrik Tolf Date: Wed, 17 Dec 2008 06:42:26 +0100 Subject: [PATCH] Moved htparser's ioloop to the library. --- lib/Makefile.am | 2 +- lib/mtio.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/mtio.h | 10 +++++ src/htparser.c | 99 +------------------------------------------- 4 files changed, 137 insertions(+), 98 deletions(-) create mode 100644 lib/mtio.c create mode 100644 lib/mtio.h diff --git a/lib/Makefile.am b/lib/Makefile.am index 30c1dee..b5cc5f6 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,4 +1,4 @@ noinst_LIBRARIES = libht.a -libht_a_SOURCES = utils.c mt.c log.c req.c proc.c +libht_a_SOURCES = utils.c mt.c log.c req.c proc.c mtio.c libht_a_CFLAGS = -fPIC diff --git a/lib/mtio.c b/lib/mtio.c new file mode 100644 index 0000000..2a46369 --- /dev/null +++ b/lib/mtio.c @@ -0,0 +1,124 @@ +/* + ashd - A Sane HTTP Daemon + Copyright (C) 2008 Fredrik Tolf + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include + +struct blocker { + struct blocker *n, *p; + int fd; + int ev; + time_t to; + struct muth *th; +}; + +static struct blocker *blockers; + +int block(int fd, int ev, time_t to) +{ + struct blocker *bl; + int rv; + + omalloc(bl); + bl->fd = fd; + bl->ev = ev; + if(to > 0) + bl->to = time(NULL) + to; + bl->th = current; + bl->n = blockers; + if(blockers) + blockers->p = bl; + blockers = bl; + rv = yield(); + if(bl->n) + bl->n->p = bl->p; + if(bl->p) + bl->p->n = bl->n; + if(bl == blockers) + blockers = bl->n; + return(rv); +} + +void ioloop(void) +{ + int ret; + fd_set rfds, wfds, efds; + struct blocker *bl, *nbl; + struct timeval toval; + time_t now, timeout; + int maxfd; + int ev; + + while(blockers != NULL) { + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&efds); + maxfd = 0; + now = time(NULL); + timeout = 0; + for(bl = blockers; bl; bl = bl->n) { + if(bl->ev & EV_READ) + FD_SET(bl->fd, &rfds); + if(bl->ev & EV_WRITE) + FD_SET(bl->fd, &wfds); + FD_SET(bl->fd, &efds); + if(bl->fd > maxfd) + maxfd = bl->fd; + if((bl->to != 0) && ((timeout == 0) || (timeout > bl->to))) + timeout = bl->to; + } + toval.tv_sec = timeout - now; + toval.tv_usec = 0; + ret = select(maxfd + 1, &rfds, &wfds, &efds, timeout?(&toval):NULL); + if(ret < 0) { + if(errno != EINTR) { + flog(LOG_CRIT, "ioloop: select errored out: %s", strerror(errno)); + /* To avoid CPU hogging in case it's bad, which it + * 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) + resume(bl->th, ev); + else if((bl->to != 0) && (bl->to <= now)) + resume(bl->th, 0); + } + } +} diff --git a/lib/mtio.h b/lib/mtio.h new file mode 100644 index 0000000..32bb0ad --- /dev/null +++ b/lib/mtio.h @@ -0,0 +1,10 @@ +#ifndef _LIB_MTIO_H +#define _LIB_MTIO_H + +#define EV_READ 1 +#define EV_WRITE 2 + +int block(int fd, int ev, time_t to); +void ioloop(void); + +#endif diff --git a/src/htparser.c b/src/htparser.c index a96b7b4..6382bf2 100644 --- a/src/htparser.c +++ b/src/htparser.c @@ -20,60 +20,22 @@ #include #include #include -#include #include #include #include #include -#include #ifdef HAVE_CONFIG_H #include #endif #include #include +#include #include #include #include -#define EV_READ 1 -#define EV_WRITE 2 - -struct blocker { - struct blocker *n, *p; - int fd; - int ev; - time_t to; - struct muth *th; -}; - -static struct blocker *blockers; -int plex; - -static int block(int fd, int ev, time_t to) -{ - struct blocker *bl; - int rv; - - omalloc(bl); - bl->fd = fd; - bl->ev = ev; - if(to > 0) - bl->to = time(NULL) + to; - bl->th = current; - bl->n = blockers; - if(blockers) - blockers->p = bl; - blockers = bl; - rv = yield(); - if(bl->n) - bl->n->p = bl->p; - if(bl->p) - bl->p->n = bl->n; - if(bl == blockers) - blockers = bl->n; - return(rv); -} +static int plex; static int listensock4(int port) { @@ -481,63 +443,6 @@ out: close(ss); } -static void ioloop(void) -{ - int ret; - fd_set rfds, wfds, efds; - struct blocker *bl, *nbl; - struct timeval toval; - time_t now, timeout; - int maxfd; - int ev; - - while(blockers != NULL) { - FD_ZERO(&rfds); - FD_ZERO(&wfds); - FD_ZERO(&efds); - maxfd = 0; - now = time(NULL); - timeout = 0; - for(bl = blockers; bl; bl = bl->n) { - if(bl->ev & EV_READ) - FD_SET(bl->fd, &rfds); - if(bl->ev & EV_WRITE) - FD_SET(bl->fd, &wfds); - FD_SET(bl->fd, &efds); - if(bl->fd > maxfd) - maxfd = bl->fd; - if((bl->to != 0) && ((timeout == 0) || (timeout > bl->to))) - timeout = bl->to; - } - toval.tv_sec = timeout - now; - toval.tv_usec = 0; - ret = select(maxfd + 1, &rfds, &wfds, &efds, timeout?(&toval):NULL); - if(ret < 0) { - if(errno != EINTR) { - flog(LOG_CRIT, "ioloop: select errored out: %s", strerror(errno)); - /* To avoid CPU hogging in case it's bad, which it - * 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) - resume(bl->th, ev); - else if((bl->to != 0) && (bl->to <= now)) - resume(bl->th, 0); - } - } -} - int main(int argc, char **argv) { int fd; -- 2.11.0