diff --git a/daemon/main.c b/daemon/main.c index 55b8097d0..bbf913da1 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -413,14 +413,24 @@ void create_everything(struct main_context *ctx) { if (redis_restore(ctx->m, mc.redis)) die("Refusing to continue without working Redis database\n"); } +} - thread_create_detach(sighandler, NULL); +static void timer_loop(void *d) { + struct poller *p = d; + + while (!global_shutdown) + poller_timers_wait_run(p, 100); } +static void poller_loop(void *d) { + struct poller *p = d; + + while (!global_shutdown) + poller_poll(p, 100); +} int main(int argc, char **argv) { struct main_context ctx; - int ret; init_everything(); options(&argc, &argv); @@ -428,10 +438,12 @@ int main(int argc, char **argv) { mylog(LOG_INFO, "Startup complete, version %s", MEDIAPROXY_VERSION); + thread_create_detach(sighandler, NULL); + thread_create_detach(timer_loop, ctx.p); + thread_create_detach(poller_loop, ctx.p); + while (!global_shutdown) { - ret = poller_poll(ctx.p, 100); - if (ret == -1) - break; + usleep(100000); threads_join_all(); } diff --git a/daemon/poller.c b/daemon/poller.c index 9bdd0cd2a..d0cca9472 100644 --- a/daemon/poller.c +++ b/daemon/poller.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "poller.h" #include "aux.h" @@ -290,7 +291,6 @@ static void poller_timers_run(struct poller *p) { int poller_poll(struct poller *p, int timeout) { int ret, i; struct poller_item_int *it; - time_t last; struct epoll_event evs[128], *ev, e; if (!p) @@ -302,15 +302,6 @@ int poller_poll(struct poller *p, int timeout) { if (!p->items || !p->items_size) goto out; - last = poller_now; - poller_now = time(NULL); - if (last != poller_now) { - mutex_unlock(&p->lock); - poller_timers_run(p); - ret = p->items_size; - goto out_lock; - } - mutex_unlock(&p->lock); errno = 0; ret = epoll_wait(p->fd, evs, sizeof(evs) / sizeof(*evs), timeout); @@ -318,9 +309,13 @@ int poller_poll(struct poller *p, int timeout) { if (errno == EINTR) ret = 0; - if (ret < 0) + if (ret == 0) + ret = 0; + if (ret <= 0) goto out; + poller_now = time(NULL); + for (i = 0; i < ret; i++) { ev = &evs[i]; @@ -369,7 +364,6 @@ next: out: mutex_unlock(&p->lock); -out_lock: return ret; } @@ -482,3 +476,30 @@ int poller_del_timer(struct poller *p, void (*f)(void *), struct obj *o) { int poller_add_timer(struct poller *p, void (*f)(void *), struct obj *o) { return poller_timer_link(p, &p->timers_add, f, o); } + +/* run in thread separate from poller_poll() */ +void poller_timers_wait_run(struct poller *p, int max) { + struct timeval tv; + int wt; + int i = 0; + + max *= 1000; + +retry: + gettimeofday(&tv, NULL); + if (tv.tv_sec != poller_now) + goto now; + if (i) + return; + + wt = 1000000 - tv.tv_usec; + if (max >= 0 && max < wt) + wt = max; + usleep(wt); + i = 1; + goto retry; + +now: + poller_now = tv.tv_sec; + poller_timers_run(p); +} diff --git a/daemon/poller.h b/daemon/poller.h index b04abf2f7..a536df261 100644 --- a/daemon/poller.h +++ b/daemon/poller.h @@ -35,11 +35,13 @@ struct poller *poller_new(void); int poller_add_item(struct poller *, struct poller_item *); int poller_update_item(struct poller *, struct poller_item *); int poller_del_item(struct poller *, int); -int poller_poll(struct poller *, int); void poller_blocked(struct poller *, int); int poller_isblocked(struct poller *, int); void poller_error(struct poller *, int); +int poller_poll(struct poller *, int); +void poller_timers_wait_run(struct poller *, int max); + int poller_add_timer(struct poller *, void (*)(void *), struct obj *); int poller_del_timer(struct poller *, void (*)(void *), struct obj *);