Mercurial > urweb
changeset 1327:1cc67fdac4d3
New argument to transactional free functions, to specify whether we are about to retry
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Sat, 04 Dec 2010 11:15:20 -0500 |
parents | d91f84599693 |
children | c5799b1e4c58 |
files | include/types.h include/urweb.h src/c/request.c src/c/urweb.c tests/transact.ur tests/transact.urp tests/transact.urs tests/transactional.c tests/transactional.h tests/transactional.urp tests/transactional.urs |
diffstat | 11 files changed, 59 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/include/types.h Thu Dec 02 14:11:18 2010 -0500 +++ b/include/types.h Sat Dec 04 11:15:20 2010 -0500 @@ -51,6 +51,7 @@ #define TIMES_MAX 100 typedef void (*uw_callback)(void *); +typedef void (*uw_callback_with_retry)(void *, int will_retry); typedef void (*uw_logger)(void*, const char *fmt, ...); typedef struct {
--- a/include/urweb.h Thu Dec 02 14:11:18 2010 -0500 +++ b/include/urweb.h Sat Dec 04 11:15:20 2010 -0500 @@ -39,7 +39,7 @@ failure_kind uw_begin_onError(uw_context, char *msg); void uw_login(uw_context); void uw_commit(uw_context); -int uw_rollback(uw_context); +int uw_rollback(uw_context, int will_retry); __attribute__((noreturn)) void uw_error(uw_context, failure_kind, const char *fmt, ...); char *uw_error_message(uw_context); @@ -228,7 +228,7 @@ uw_Basis_time uw_Basis_minusSeconds(uw_context, uw_Basis_time, uw_Basis_int); extern const uw_Basis_time uw_Basis_minTime; -void uw_register_transactional(uw_context, void *data, uw_callback commit, uw_callback rollback, uw_callback free); +void uw_register_transactional(uw_context, void *data, uw_callback commit, uw_callback rollback, uw_callback_with_retry free); void uw_check_heap(uw_context, size_t extra); char *uw_heap_front(uw_context);
--- a/src/c/request.c Thu Dec 02 14:11:18 2010 -0500 +++ b/src/c/request.c Sat Dec 04 11:15:20 2010 -0500 @@ -19,8 +19,8 @@ void *memmem(const void *b1, size_t len1, const void *b2, size_t len2); -static int try_rollback(uw_context ctx, void *logger_data, uw_logger log_error) { - int r = uw_rollback(ctx); +static int try_rollback(uw_context ctx, int will_retry, void *logger_data, uw_logger log_error) { + int r = uw_rollback(ctx, will_retry); if (r) { log_error(logger_data, "Error running SQL ROLLBACK\n"); @@ -102,13 +102,13 @@ for (fk = uw_initialize(ctx); fk == UNLIMITED_RETRY; fk = uw_initialize(ctx)) { log_debug(logger_data, "Unlimited retry during init: %s\n", uw_error_message(ctx)); - uw_rollback(ctx); + uw_rollback(ctx, 1); uw_reset(ctx); } if (fk != SUCCESS) { log_error(logger_data, "Failed to initialize database! %s\n", uw_error_message(ctx)); - uw_rollback(ctx); + uw_rollback(ctx, 0); exit(1); } @@ -403,7 +403,7 @@ else { log_error(logger_data, "Fatal error (out of retries): %s\n", uw_error_message(ctx)); - try_rollback(ctx, logger_data, log_error); + try_rollback(ctx, 0, logger_data, log_error); if (!had_error && uw_get_app(ctx)->on_error) { had_error = 1; @@ -424,7 +424,7 @@ else if (fk == FATAL) { log_error(logger_data, "Fatal error: %s\n", uw_error_message(ctx)); - try_rollback(ctx, logger_data, log_error); + try_rollback(ctx, 0, logger_data, log_error); if (uw_get_app(ctx)->on_error && !had_error) { had_error = 1; @@ -443,7 +443,7 @@ } else { log_error(logger_data, "Unknown uw_handle return code!\n"); - try_rollback(ctx, logger_data, log_error); + try_rollback(ctx, 0, logger_data, log_error); if (uw_get_app(ctx)->on_error && !had_error) { had_error = 1; @@ -458,7 +458,7 @@ } } - if (try_rollback(ctx, logger_data, log_error)) + if (try_rollback(ctx, 1, logger_data, log_error)) return FAILED; uw_reset_keep_request(ctx);
--- a/src/c/urweb.c Thu Dec 02 14:11:18 2010 -0500 +++ b/src/c/urweb.c Sat Dec 04 11:15:20 2010 -0500 @@ -390,7 +390,8 @@ typedef struct { void *data; - uw_callback commit, rollback, free; + uw_callback commit, rollback; + uw_callback_with_retry free; } transactional; typedef struct { @@ -2902,7 +2903,7 @@ return uw_unit_v; } -int uw_rollback(uw_context ctx) { +int uw_rollback(uw_context ctx, int will_retry) { int i; cleanup *cl; @@ -2920,7 +2921,7 @@ for (i = ctx->used_transactionals-1; i >= 0; --i) if (ctx->transactionals[i].free) - ctx->transactionals[i].free(ctx->transactionals[i].data); + ctx->transactionals[i].free(ctx->transactionals[i].data, will_retry); return ctx->app ? ctx->app->db_rollback(ctx) : 0; } @@ -2929,7 +2930,7 @@ int i; if (uw_has_error(ctx)) { - uw_rollback(ctx); + uw_rollback(ctx, 0); return; } @@ -2938,7 +2939,7 @@ if (ctx->transactionals[i].commit) { ctx->transactionals[i].commit(ctx->transactionals[i].data); if (uw_has_error(ctx)) { - uw_rollback(ctx); + uw_rollback(ctx, 0); return; } } @@ -2948,7 +2949,7 @@ if (ctx->transactionals[i].commit) { ctx->transactionals[i].commit(ctx->transactionals[i].data); if (uw_has_error(ctx)) { - uw_rollback(ctx); + uw_rollback(ctx, 0); return; } } @@ -2972,7 +2973,7 @@ for (i = ctx->used_transactionals-1; i >= 0; --i) if (ctx->transactionals[i].free) - ctx->transactionals[i].free(ctx->transactionals[i].data); + ctx->transactionals[i].free(ctx->transactionals[i].data, 0); // Splice script data into appropriate part of page if (ctx->returning_indirectly || ctx->script_header[0] == 0) { @@ -3012,7 +3013,7 @@ size_t uw_transactionals_max = SIZE_MAX; void uw_register_transactional(uw_context ctx, void *data, uw_callback commit, uw_callback rollback, - uw_callback free) { + uw_callback_with_retry free) { if (ctx->used_transactionals >= ctx->n_transactionals) { if (ctx->used_transactionals+1 > uw_transactionals_max) uw_error(ctx, FATAL, "Exceeded limit on number of transactionals");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/transact.ur Sat Dec 04 11:15:20 2010 -0500 @@ -0,0 +1,13 @@ +fun listHell n = + if n <= 0 then + [] + else + n :: List.append (listHell (n-1)) (listHell (n-1)) + +fun doit r = + Transactional.foo; + return <xml>{[listHell (readError r.N)]}</xml> + +fun main () = return <xml><body> + <form> <textbox{#N}/> <submit action={doit}/> </form> +</body></xml>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/transact.urp Sat Dec 04 11:15:20 2010 -0500 @@ -0,0 +1,5 @@ +library transactional +rewrite all Transact/* + +$/list +transact
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/transact.urs Sat Dec 04 11:15:20 2010 -0500 @@ -0,0 +1,1 @@ +val main : unit -> transaction page
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/transactional.c Sat Dec 04 11:15:20 2010 -0500 @@ -0,0 +1,12 @@ +#include <stdio.h> + +#include "/usr/local/include/urweb/urweb.h" + +static void do_free(void *data, int will_retry) { + printf("will_retry = %d\n", will_retry); +} + +uw_unit uw_Transactional_foo(uw_context ctx) { + printf("Registering....\n"); + uw_register_transactional(ctx, NULL, NULL, NULL, do_free); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/transactional.h Sat Dec 04 11:15:20 2010 -0500 @@ -0,0 +1,3 @@ +#include "/usr/local/include/urweb/types.h" + +uw_unit uw_Transactional_foo(uw_context);