kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

commit ed4ef22f1b242b0ffc508da577a9a84133bed204
parent f958d86616ee7c43121f06422bcb6cfd17b7ffeb
Author: Joris Vink <joris@coders.se>
Date:   Thu, 31 Aug 2017 16:26:36 +0200

automatically resolve existing symbols upon reload.

doing this allows us to get rid of the validator reload
and handler reload as well as fixing websocket runtime
callbacks which were never being resolved upon module reloads.

Diffstat:
includes/kore.h | 4+++-
src/kore.c | 4+++-
src/module.c | 16+---------------
src/runtime.c | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
src/validator.c | 16----------------
src/worker.c | 2++
6 files changed, 62 insertions(+), 33 deletions(-)

diff --git a/includes/kore.h b/includes/kore.h @@ -625,6 +625,9 @@ int kore_module_handler_new(const char *, const char *, const char *, const char *, int); void kore_module_handler_free(struct kore_module_handle *); +void kore_runtime_init(void); +void kore_runtime_reload(void); +void kore_runtime_cleanup(void); struct kore_runtime_call *kore_runtime_getcall(const char *); void kore_runtime_execute(struct kore_runtime_call *); @@ -648,7 +651,6 @@ struct kore_module_handle *kore_module_handler_find(const char *, #if !defined(KORE_NO_HTTP) void kore_validator_init(void); -void kore_validator_reload(void); int kore_validator_add(const char *, u_int8_t, const char *); int kore_validator_run(struct http_request *, const char *, char *); int kore_validator_check(struct http_request *, diff --git a/src/kore.c b/src/kore.c @@ -166,9 +166,10 @@ main(int argc, char *argv[]) argv += optind; kore_mem_init(); + kore_runtime_init(); if (argc > 0) - fatal("did you mean to run `kodevĀ“ instead?"); + fatal("did you mean to run `kodev` instead?"); kore_pid = getpid(); nlisteners = 0; @@ -235,6 +236,7 @@ main(int argc, char *argv[]) kore_python_cleanup(); #endif + kore_runtime_cleanup(); kore_mem_cleanup(); return (0); diff --git a/src/module.c b/src/module.c @@ -134,8 +134,6 @@ kore_module_reload(int cbs) { struct stat st; int ret; - struct kore_domain *dom; - struct kore_module_handle *hdlr; struct kore_module *module; TAILQ_FOREACH(module, &modules, list) { @@ -182,19 +180,7 @@ kore_module_reload(int cbs) kore_log(LOG_NOTICE, "reloaded '%s' module", module->path); } - TAILQ_FOREACH(dom, &domains, list) { - TAILQ_FOREACH(hdlr, &(dom->handlers), list) { - kore_free(hdlr->rcall); - hdlr->rcall = kore_runtime_getcall(hdlr->func); - if (hdlr->rcall == NULL) - fatal("no function '%s' found", hdlr->func); - hdlr->errors = 0; - } - } - -#if !defined(KORE_NO_HTTP) - kore_validator_reload(); -#endif + kore_runtime_reload(); } int diff --git a/src/runtime.c b/src/runtime.c @@ -51,13 +51,61 @@ struct kore_runtime kore_native_runtime = { .execute = native_runtime_execute }; +struct symbol { + char *name; + struct kore_runtime_call *rcall; + TAILQ_ENTRY(symbol) list; +}; + +static TAILQ_HEAD(, symbol) resolved_symbols; + +void +kore_runtime_init(void) +{ + TAILQ_INIT(&resolved_symbols); +} + +void +kore_runtime_cleanup(void) +{ + struct symbol *sym; + + while ((sym = TAILQ_FIRST(&resolved_symbols)) != NULL) { + TAILQ_REMOVE(&resolved_symbols, sym, list); + kore_free(sym->name); + kore_free(sym); + } +} + +void +kore_runtime_reload(void) +{ + void *ptr; + struct symbol *sym; + struct kore_runtime *runtime; + + TAILQ_FOREACH(sym, &resolved_symbols, list) { + ptr = kore_module_getsym(sym->name, &runtime); + if (ptr == NULL) + fatal("required symbol '%s' not found", sym->name); + sym->rcall->runtime = runtime; + sym->rcall->addr = ptr; + } +} + struct kore_runtime_call * kore_runtime_getcall(const char *symbol) { void *ptr; + struct symbol *sym; struct kore_runtime_call *rcall; struct kore_runtime *runtime; + TAILQ_FOREACH(sym, &resolved_symbols, list) { + if (!strcmp(sym->name, symbol)) + return (sym->rcall); + } + ptr = kore_module_getsym(symbol, &runtime); if (ptr == NULL) return (NULL); @@ -66,6 +114,11 @@ kore_runtime_getcall(const char *symbol) rcall->addr = ptr; rcall->runtime = runtime; + sym = kore_malloc(sizeof(*sym)); + sym->name = kore_strdup(symbol); + sym->rcall = rcall; + TAILQ_INSERT_TAIL(&resolved_symbols, sym, list); + return (rcall); } diff --git a/src/validator.c b/src/validator.c @@ -104,22 +104,6 @@ kore_validator_check(struct http_request *req, struct kore_validator *val, return (r); } -void -kore_validator_reload(void) -{ - struct kore_validator *val; - - TAILQ_FOREACH(val, &validators, list) { - if (val->type != KORE_VALIDATOR_TYPE_FUNCTION) - continue; - - kore_free(val->rcall); - val->rcall = kore_runtime_getcall(val->arg); - if (val->rcall == NULL) - fatal("no function for validator %s found", val->arg); - } -} - struct kore_validator * kore_validator_lookup(const char *name) { diff --git a/src/worker.c b/src/worker.c @@ -446,7 +446,9 @@ kore_worker_entry(struct kore_worker *kw) kore_debug("worker %d shutting down", kw->id); + kore_runtime_cleanup(); kore_mem_cleanup(); + exit(0); }