diff options
Diffstat (limited to 'src')
| -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;  } | 
