diff options
Diffstat (limited to 'src/blogc-make')
-rw-r--r-- | src/blogc-make/ctx.c | 11 | ||||
-rw-r--r-- | src/blogc-make/ctx.h | 2 | ||||
-rw-r--r-- | src/blogc-make/reloader.c | 93 | ||||
-rw-r--r-- | src/blogc-make/reloader.h | 25 | ||||
-rw-r--r-- | src/blogc-make/rules.c | 74 |
5 files changed, 131 insertions, 74 deletions
diff --git a/src/blogc-make/ctx.c b/src/blogc-make/ctx.c index 62b40b8..ff825e1 100644 --- a/src/blogc-make/ctx.c +++ b/src/blogc-make/ctx.c @@ -215,11 +215,11 @@ bm_ctx_new(bm_ctx_t *base, const char *settings_file, const char *argv0, } -void +bool bm_ctx_reload(bm_ctx_t *ctx) { if (ctx == NULL || ctx->settings_fctx == NULL) - return; + return false; if (bm_filectx_changed(ctx->settings_fctx, NULL)) { // reload everything! we could just reload settings_fctx, as this @@ -231,11 +231,12 @@ bm_ctx_reload(bm_ctx_t *ctx) bc_error_t *err = NULL; ctx = bm_ctx_new(ctx, tmp, NULL, &err); free(tmp); - if (err != NULL) { // failed to reload, keep old ctx + if (err != NULL) { bc_error_print(err, "blogc-make"); bc_error_free(err); + return false; } - return; + return true; } bm_filectx_reload(ctx->main_template_fctx); @@ -249,6 +250,8 @@ bm_ctx_reload(bm_ctx_t *ctx) for (bc_slist_t *tmp = ctx->copy_fctx; tmp != NULL; tmp = tmp->next) bm_filectx_reload((bm_filectx_t*) tmp->data); + + return true; } diff --git a/src/blogc-make/ctx.h b/src/blogc-make/ctx.h index 77e8088..8d87163 100644 --- a/src/blogc-make/ctx.h +++ b/src/blogc-make/ctx.h @@ -53,7 +53,7 @@ void bm_filectx_reload(bm_filectx_t *ctx); void bm_filectx_free(bm_filectx_t *fctx); bm_ctx_t* bm_ctx_new(bm_ctx_t *base, const char *settings_file, const char *argv0, bc_error_t **err); -void bm_ctx_reload(bm_ctx_t *ctx); +bool bm_ctx_reload(bm_ctx_t *ctx); void bm_ctx_free_internal(bm_ctx_t *ctx); void bm_ctx_free(bm_ctx_t *ctx); diff --git a/src/blogc-make/reloader.c b/src/blogc-make/reloader.c new file mode 100644 index 0000000..1b55253 --- /dev/null +++ b/src/blogc-make/reloader.c @@ -0,0 +1,93 @@ +/* + * blogc: A blog compiler. + * Copyright (C) 2014-2017 Rafael G. Martins <rafael@rafaelmartins.eng.br> + * + * This program can be distributed under the terms of the BSD License. + * See the file LICENSE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <pthread.h> +#include "../common/error.h" +#include "ctx.h" +#include "rules.h" +#include "reloader.h" + +// we are not going to unit-test these functions, then printing errors +// directly is not a big issue + + +static void* +bm_reloader_thread(void *arg) +{ + bm_reloader_t *reloader = arg; + while (reloader->running) { + if (!bm_ctx_reload(reloader->ctx)) { + fprintf(stderr, "blogc-make: error: failed to reload context. " + "reloader disabled!\n"); + break; + } + if (0 != reloader->rule_exec(reloader->ctx, NULL, NULL)) { + fprintf(stderr, "blogc-make: error: failed to rebuild website. " + "reloader disabled!\n"); + break; + } + sleep(1); + } + + free(reloader); + return NULL; +} + + +bm_reloader_t* +bm_reloader_new(bm_ctx_t *ctx, bm_rule_exec_func_t rule_exec) +{ + // first rule_exec call is syncronous, to do a 'sanity check' + if (0 != rule_exec(ctx, NULL, NULL)) + return NULL; + + int err; + + pthread_attr_t attr; + if (0 != (err = pthread_attr_init(&attr))) { + fprintf(stderr, "blogc-make: error: failed to initialize reloader " + "thread attributes: %s\n", strerror(err)); + return NULL; + } + + // we run the thread detached, because we don't want to wait it to join + // before exiting. the OS can clean it properly + if (0 != (err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED))) { + fprintf(stderr, "blogc-make: error: failed to mark reloader thread as " + "detached: %s\n", strerror(err)); + return NULL; + } + + bm_reloader_t *rv = bc_malloc(sizeof(bm_reloader_t)); + rv->ctx = ctx; + rv->rule_exec = rule_exec; + rv->running = true; + + pthread_t thread; + if (0 != (err = pthread_create(&thread, &attr, bm_reloader_thread, rv))) { + fprintf(stderr, "blogc-make: error: failed to create reloader " + "thread: %s\n", strerror(err)); + free(rv); + return NULL; + } + + return rv; +} + + +void +bm_reloader_stop(bm_reloader_t *reloader) +{ + if (reloader == NULL) + return; + reloader->running = false; +} diff --git a/src/blogc-make/reloader.h b/src/blogc-make/reloader.h new file mode 100644 index 0000000..70464a8 --- /dev/null +++ b/src/blogc-make/reloader.h @@ -0,0 +1,25 @@ +/* + * blogc: A blog compiler. + * Copyright (C) 2014-2017 Rafael G. Martins <rafael@rafaelmartins.eng.br> + * + * This program can be distributed under the terms of the BSD License. + * See the file LICENSE. + */ + +#ifndef _MAKE_RELOADER_H +#define _MAKE_RELOADER_H + +#include <stdbool.h> +#include "ctx.h" +#include "rules.h" + +typedef struct { + bm_ctx_t *ctx; + bm_rule_exec_func_t rule_exec; + bool running; +} bm_reloader_t; + +bm_reloader_t* bm_reloader_new(bm_ctx_t *ctx, bm_rule_exec_func_t rule_exec); +void bm_reloader_stop(bm_reloader_t *reloader); + +#endif /* _MAKE_RELOADER_H */ diff --git a/src/blogc-make/rules.c b/src/blogc-make/rules.c index 631d0ee..1f4a121 100644 --- a/src/blogc-make/rules.c +++ b/src/blogc-make/rules.c @@ -12,15 +12,13 @@ #include <stdlib.h> #include <time.h> #include <math.h> -#include <unistd.h> -#include <pthread.h> -#include <signal.h> #include "../common/utils.h" #include "ctx.h" #include "exec.h" #include "exec-native.h" -#include "rules.h" +#include "reloader.h" #include "settings.h" +#include "rules.h" // INDEX RULE @@ -552,77 +550,15 @@ static int all_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args); // RUNSERVER RULE -typedef struct { - bm_ctx_t *ctx; - bool running; -} runserver_args_t; - -static void* -runserver_thread(void *arg) -{ - runserver_args_t *args = arg; - while (args->running) { - bm_ctx_reload(args->ctx); - if (args->ctx == NULL) { - fprintf(stderr, "blogc-make: error: failed to reload context. " - "reloader disabled!\n"); - goto runserver_cleanup; - } - if (0 != all_exec(args->ctx, NULL, NULL)) { - fprintf(stderr, "blogc-make: error: failed to rebuild website. " - "reloader disabled!\n"); - goto runserver_cleanup; - } - sleep(1); - } - -runserver_cleanup: - free(args); - return NULL; -} - static int runserver_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args) { - // first 'all' call is syncronous, to do a 'sanity check' - int rv = all_exec(ctx, NULL, NULL); - if (rv != 0) - return rv; - - runserver_args_t *r_args = bc_malloc(sizeof(runserver_args_t)); - r_args->ctx = ctx; - r_args->running = true; - - int err; - pthread_attr_t attr; + bm_reloader_t *reloader = bm_reloader_new(ctx, all_exec); - if (0 != (err = pthread_attr_init(&attr))) { - fprintf(stderr, "blogc-make: error: failed to initialize reloader " - "thread attributes: %s\n", strerror(err)); - return 3; - } - - // we run the thread detached, because we don't want to wait it to join - // before exiting. the OS can clean it properly - if (0 != (err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED))) { - fprintf(stderr, "blogc-make: error: failed to mark reloader thread as " - "detached: %s\n", strerror(err)); - return 3; - } - - pthread_t thread; - - if (0 != (err = pthread_create(&thread, &attr, runserver_thread, r_args))) { - fprintf(stderr, "blogc-make: error: failed to create reloader " - "thread: %s\n", strerror(err)); - return 3; - } - - rv = bm_exec_blogc_runserver(ctx, bc_trie_lookup(args, "host"), + int rv = bm_exec_blogc_runserver(ctx, bc_trie_lookup(args, "host"), bc_trie_lookup(args, "port"), bc_trie_lookup(args, "threads")); - r_args->running = false; - + bm_reloader_stop(reloader); return rv; } |