commit d6ab1d74450cbe17ea0e7b12d05d6bb827c6a783
parent cf028f20b6b9c526ad792a08b21b04e3eac8c254
Author: Joris Vink <joris@coders.se>
Date: Mon, 6 Apr 2015 18:54:35 +0200
Add rudimentary timers to Kore.
Timers are in ms resolution and are added using
kore_timer_add(cb, interval, flags).
Both oneshot timers and continious timers are supported.
Diffstat:
5 files changed, 113 insertions(+), 6 deletions(-)
diff --git a/Makefile b/Makefile
@@ -8,8 +8,8 @@ INCLUDE_DIR=$(PREFIX)/include/kore
S_SRC= src/kore.c src/accesslog.c src/auth.c src/buf.c src/cli.c src/config.c \
src/connection.c src/domain.c src/http.c src/mem.c src/module.c \
- src/net.c src/pool.c src/spdy.c src/validator.c src/utils.c \
- src/websocket.c src/worker.c src/zlib_dict.c
+ src/net.c src/pool.c src/spdy.c src/timer.c src/validator.c \
+ src/utils.c src/websocket.c src/worker.c src/zlib_dict.c
S_OBJS= $(S_SRC:.c=.o)
CFLAGS+=-Wall -Wstrict-prototypes -Wmissing-prototypes
diff --git a/includes/kore.h b/includes/kore.h
@@ -164,6 +164,8 @@ LIST_HEAD(listener_head, listener);
#define WEBSOCKET_BROADCAST_LOCAL 1
#define WEBSOCKET_BROADCAST_GLOBAL 2
+#define KORE_TIMER_ONESHOT 0x01
+
struct connection {
u_int8_t type;
int fd;
@@ -407,6 +409,11 @@ void kore_auth_init(void);
int kore_auth_new(const char *);
struct kore_auth *kore_auth_lookup(const char *);
+void kore_timer_init(void);
+u_int64_t kore_timer_run(u_int64_t);
+void kore_timer_add(void (*cb)(u_int64_t, u_int64_t),
+ u_int64_t, int);
+
int kore_ssl_sni_cb(SSL *, int *, void *);
int kore_server_bind(const char *, const char *);
int kore_ssl_npn_cb(SSL *, const u_char **, unsigned int *, void *);
diff --git a/src/bsd.c b/src/bsd.c
@@ -102,8 +102,8 @@ kore_platform_event_wait(u_int64_t timer)
struct timespec timeo;
int n, i;
- timeo.tv_sec = 0;
- timeo.tv_nsec = timer * 1000000;
+ timeo.tv_sec = timer / 1000;
+ timeo.tv_nsec = (timer % 1000) * 1000000;
n = kevent(kfd, changelist, nchanges, events, event_count, &timeo);
if (n == -1) {
if (errno == EINTR)
diff --git a/src/timer.c b/src/timer.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2015 Joris Vink <joris@coders.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+
+#include "kore.h"
+
+struct timer {
+ u_int64_t nextrun;
+ u_int64_t interval;
+ int flags;
+ void (*cb)(u_int64_t, u_int64_t);
+ TAILQ_ENTRY(timer) list;
+};
+
+TAILQ_HEAD(timerlist, timer) kore_timers;
+
+void
+kore_timer_init(void)
+{
+ TAILQ_INIT(&kore_timers);
+}
+
+void
+kore_timer_add(void (*cb)(u_int64_t, u_int64_t), u_int64_t interval, int flags)
+{
+ struct timer *timer, *t;
+
+ timer = kore_malloc(sizeof(*timer));
+
+ timer->cb = cb;
+ timer->flags = flags;
+ timer->interval = interval;
+ timer->nextrun = kore_time_ms() + timer->interval;
+
+ TAILQ_FOREACH(t, &kore_timers, list) {
+ if (t->nextrun > timer->nextrun) {
+ TAILQ_INSERT_BEFORE(t, timer, list);
+ return;
+ }
+ }
+
+ TAILQ_INSERT_TAIL(&kore_timers, timer, list);
+}
+
+u_int64_t
+kore_timer_run(u_int64_t now)
+{
+ struct timer *timer, *t;
+ u_int64_t next_timer, delta;
+
+ next_timer = 100;
+
+ while ((timer = TAILQ_FIRST(&kore_timers)) != NULL) {
+ if (timer->nextrun > now) {
+ next_timer = timer->nextrun - now;
+ break;
+ }
+
+ TAILQ_REMOVE(&kore_timers, timer, list);
+ delta = now - timer->nextrun;
+ timer->cb(now, delta);
+
+ if (timer->flags & KORE_TIMER_ONESHOT) {
+ kore_mem_free(timer);
+ } else {
+ timer->nextrun += timer->interval - delta;
+ TAILQ_FOREACH(t, &kore_timers, list) {
+ if (t->nextrun > timer->nextrun) {
+ TAILQ_INSERT_BEFORE(t, timer, list);
+ break;
+ }
+ }
+
+ if (t == NULL)
+ TAILQ_INSERT_TAIL(&kore_timers, timer, list);
+ }
+ }
+
+ if (next_timer > 1)
+ next_timer -= 1;
+
+ return (next_timer);
+}
diff --git a/src/worker.c b/src/worker.c
@@ -186,7 +186,7 @@ kore_worker_entry(struct kore_worker *kw)
char buf[16];
struct connection *c, *cnext;
int quit, had_lock, r;
- u_int64_t now, idle_check, next_lock;
+ u_int64_t now, idle_check, next_lock, netwait;
worker = kw;
@@ -234,6 +234,7 @@ kore_worker_entry(struct kore_worker *kw)
net_init();
http_init();
+ kore_timer_init();
kore_connection_init();
kore_domain_load_crl();
TAILQ_INIT(&disconnected);
@@ -273,6 +274,7 @@ kore_worker_entry(struct kore_worker *kw)
}
now = kore_time_ms();
+ netwait = kore_timer_run(now);
if (now > next_lock) {
if (kore_worker_acceptlock_obtain()) {
@@ -290,7 +292,7 @@ kore_worker_entry(struct kore_worker *kw)
}
}
- r = kore_platform_event_wait(100);
+ r = kore_platform_event_wait(netwait);
if (worker->has_lock && r > 0) {
kore_worker_acceptlock_release();
next_lock = now + WORKER_LOCK_TIMEOUT;