summaryrefslogtreecommitdiff
path: root/src/c
diff options
context:
space:
mode:
authorGravatar Adam Chlipala <adam@chlipala.net>2010-12-18 15:17:09 -0500
committerGravatar Adam Chlipala <adam@chlipala.net>2010-12-18 15:17:09 -0500
commit541a15124e163ce8aff94bf37f24c54085c19884 (patch)
tree3f41e8cb1cc8bb5b84384840ebdf5b296e0c1732 /src/c
parent39cd3aba26129807a15ccc29bb9f71e2537c4551 (diff)
Periodic tasks
Diffstat (limited to 'src/c')
-rw-r--r--src/c/request.c53
-rw-r--r--src/c/urweb.c16
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;
+}