diff options
author | Adam Chlipala <adam@chlipala.net> | 2010-12-18 15:17:09 -0500 |
---|---|---|
committer | Adam Chlipala <adam@chlipala.net> | 2010-12-18 15:17:09 -0500 |
commit | 541a15124e163ce8aff94bf37f24c54085c19884 (patch) | |
tree | 3f41e8cb1cc8bb5b84384840ebdf5b296e0c1732 /src/c | |
parent | 39cd3aba26129807a15ccc29bb9f71e2537c4551 (diff) |
Periodic tasks
Diffstat (limited to 'src/c')
-rw-r--r-- | src/c/request.c | 53 | ||||
-rw-r--r-- | src/c/urweb.c | 16 |
2 files changed, 63 insertions, 6 deletions
diff --git a/src/c/request.c b/src/c/request.c index e51f95ae..b49a524e 100644 --- a/src/c/request.c +++ b/src/c/request.c @@ -79,9 +79,44 @@ static void *ticker(void *data) { return NULL; } +typedef struct { + uw_app *app; + void *logger_data; + uw_logger log_error, log_debug; +} loggers; + +typedef struct { + loggers *ls; + uw_periodic pdic; +} periodic; + +static void *periodic_loop(void *data) { + periodic *p = (periodic *)data; + uw_context ctx = uw_request_new_context(p->ls->app, p->ls->logger_data, p->ls->log_error, p->ls->log_debug); + + if (!ctx) + exit(1); + + while (1) { + failure_kind r; + do { + r = uw_runCallback(ctx, p->pdic.callback); + } while (r == UNLIMITED_RETRY); + + sleep(p->pdic.period); + }; +} + void uw_request_init(uw_app *app, void *logger_data, uw_logger log_error, uw_logger log_debug) { uw_context ctx; failure_kind fk; + uw_periodic *ps; + loggers *ls = malloc(sizeof(loggers)); + + ls->app = app; + ls->logger_data = logger_data; + ls->log_error = log_error; + ls->log_debug = log_debug; uw_global_init(); uw_app_init(app); @@ -113,6 +148,18 @@ void uw_request_init(uw_app *app, void *logger_data, uw_logger log_error, uw_log } uw_free(ctx); + + for (ps = app->periodics; ps->callback; ++ps) { + pthread_t thread; + periodic *arg = malloc(sizeof(periodic)); + arg->ls = ls; + arg->pdic = *ps; + + if (pthread_create(&thread, NULL, periodic_loop, arg)) { + fprintf(stderr, "Error creating periodic thread\n"); + exit(1); + } + } } @@ -468,12 +515,6 @@ request_result uw_request(uw_request_context rc, uw_context ctx, } } -typedef struct { - uw_app *app; - void *logger_data; - uw_logger log_error, log_debug; -} loggers; - void *client_pruner(void *data) { loggers *ls = (loggers *)data; uw_context ctx = uw_request_new_context(ls->app, ls->logger_data, ls->log_error, ls->log_debug); diff --git a/src/c/urweb.c b/src/c/urweb.c index 2b54e87c..0356e0fa 100644 --- a/src/c/urweb.c +++ b/src/c/urweb.c @@ -3492,3 +3492,19 @@ uw_Basis_postBody uw_getPostBody(uw_context ctx) { else uw_error(ctx, FATAL, "Asked for POST body when none exists"); } + +failure_kind uw_runCallback(uw_context ctx, void (*callback)(uw_context)) { + int r = setjmp(ctx->jmp_buf); + + if (ctx->app->db_begin(ctx)) + uw_error(ctx, BOUNDED_RETRY, "Error running SQL BEGIN"); + + if (r == 0) { + callback(ctx); + uw_commit(ctx); + } + else + uw_rollback(ctx, 0); + + return r; +} |