aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/blogc-make/httpd.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/src/blogc-make/httpd.c b/src/blogc-make/httpd.c
index adf9a9b..3855c44 100644
--- a/src/blogc-make/httpd.c
+++ b/src/blogc-make/httpd.c
@@ -26,15 +26,26 @@ typedef struct {
bc_trie_t *args;
} bm_httpd_t;
+static pthread_mutex_t mutex_httpd_starting = PTHREAD_MUTEX_INITIALIZER;
+static bool httpd_starting = false;
+
static void*
httpd_thread(void *arg)
{
bm_httpd_t *httpd = arg;
+ pthread_mutex_lock(&mutex_httpd_starting);
+ httpd_starting = true;
+ pthread_mutex_unlock(&mutex_httpd_starting);
+
int rv = bm_exec_blogc_runserver(httpd->ctx, bc_trie_lookup(httpd->args, "host"),
bc_trie_lookup(httpd->args, "port"), bc_trie_lookup(httpd->args, "threads"));
+ pthread_mutex_lock(&mutex_httpd_starting);
+ httpd_starting = false;
+ pthread_mutex_unlock(&mutex_httpd_starting);
+
free(httpd);
// stop the reloader
@@ -48,15 +59,13 @@ int
bm_httpd_run(bm_ctx_t **ctx, bm_rule_exec_func_t rule_exec, bc_slist_t *outputs,
bc_trie_t *args)
{
- // this is here to avoid that the httpd starts running in the middle of the
- // first build, as the reloader and the httpd are started in parallel.
- // we run the task synchronously for the first time, and start the httpd
- // thread afterwards.
- bool wait_before_reloader = false;
- if (0 != rule_exec(*ctx, outputs, args)) {
- fprintf(stderr, "blogc-make: warning: failed to rebuild website. "
- "retrying in 5 seconds ...\n\n");
- wait_before_reloader = true;
+ pthread_mutex_lock(&mutex_httpd_starting);
+ bool starting = httpd_starting;
+ pthread_mutex_unlock(&mutex_httpd_starting);
+
+ if (starting) {
+ fprintf(stderr, "blogc-make: error: httpd already running\n");
+ return 1;
}
int err;
@@ -88,9 +97,25 @@ bm_httpd_run(bm_ctx_t **ctx, bm_rule_exec_func_t rule_exec, bc_slist_t *outputs,
return 1;
}
- // run the reloader
- if (wait_before_reloader) {
- sleep(5);
+ // we could use some pthread_*_timedwait() apis here, but I decided to
+ // just use simple mutexes for the sake of portability.
+ size_t count = 0;
+ while (true) {
+ pthread_mutex_lock(&mutex_httpd_starting);
+ starting = httpd_starting;
+ pthread_mutex_unlock(&mutex_httpd_starting);
+
+ if (starting)
+ break;
+
+ if (++count > 100) {
+ fprintf(stderr, "blogc-make: error: failed to start httpd thread: "
+ "too many retries\n");
+ // rv will leak, but it is not safe to free here
+ return 1;
+ }
+ usleep(100000);
}
+
return bm_reloader_run(ctx, rule_exec, outputs, args);
}