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.
This commit is contained in:
Joris Vink 2015-04-06 18:54:35 +02:00
parent cf028f20b6
commit d6ab1d7445
5 changed files with 113 additions and 6 deletions

View File

@ -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

View File

@ -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 *);

View File

@ -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)

98
src/timer.c Normal file
View File

@ -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);
}

View File

@ -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;