Mercurial > urweb
comparison src/c/urweb.c @ 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 | 714e8b84221b |
children | 452b14d88a10 |
comparison
equal
deleted
inserted
replaced
1326:d91f84599693 | 1327:1cc67fdac4d3 |
---|---|
388 } data; | 388 } data; |
389 } input; | 389 } input; |
390 | 390 |
391 typedef struct { | 391 typedef struct { |
392 void *data; | 392 void *data; |
393 uw_callback commit, rollback, free; | 393 uw_callback commit, rollback; |
394 uw_callback_with_retry free; | |
394 } transactional; | 395 } transactional; |
395 | 396 |
396 typedef struct { | 397 typedef struct { |
397 char *name; | 398 char *name; |
398 void *data; | 399 void *data; |
2900 ctx_buf_append(ctx, "messages", &d->msgs, "\n", 1); | 2901 ctx_buf_append(ctx, "messages", &d->msgs, "\n", 1); |
2901 | 2902 |
2902 return uw_unit_v; | 2903 return uw_unit_v; |
2903 } | 2904 } |
2904 | 2905 |
2905 int uw_rollback(uw_context ctx) { | 2906 int uw_rollback(uw_context ctx, int will_retry) { |
2906 int i; | 2907 int i; |
2907 cleanup *cl; | 2908 cleanup *cl; |
2908 | 2909 |
2909 if (ctx->client) | 2910 if (ctx->client) |
2910 release_client(ctx->client); | 2911 release_client(ctx->client); |
2918 if (ctx->transactionals[i].rollback != NULL) | 2919 if (ctx->transactionals[i].rollback != NULL) |
2919 ctx->transactionals[i].rollback(ctx->transactionals[i].data); | 2920 ctx->transactionals[i].rollback(ctx->transactionals[i].data); |
2920 | 2921 |
2921 for (i = ctx->used_transactionals-1; i >= 0; --i) | 2922 for (i = ctx->used_transactionals-1; i >= 0; --i) |
2922 if (ctx->transactionals[i].free) | 2923 if (ctx->transactionals[i].free) |
2923 ctx->transactionals[i].free(ctx->transactionals[i].data); | 2924 ctx->transactionals[i].free(ctx->transactionals[i].data, will_retry); |
2924 | 2925 |
2925 return ctx->app ? ctx->app->db_rollback(ctx) : 0; | 2926 return ctx->app ? ctx->app->db_rollback(ctx) : 0; |
2926 } | 2927 } |
2927 | 2928 |
2928 void uw_commit(uw_context ctx) { | 2929 void uw_commit(uw_context ctx) { |
2929 int i; | 2930 int i; |
2930 | 2931 |
2931 if (uw_has_error(ctx)) { | 2932 if (uw_has_error(ctx)) { |
2932 uw_rollback(ctx); | 2933 uw_rollback(ctx, 0); |
2933 return; | 2934 return; |
2934 } | 2935 } |
2935 | 2936 |
2936 for (i = ctx->used_transactionals-1; i >= 0; --i) | 2937 for (i = ctx->used_transactionals-1; i >= 0; --i) |
2937 if (ctx->transactionals[i].rollback != NULL) | 2938 if (ctx->transactionals[i].rollback != NULL) |
2938 if (ctx->transactionals[i].commit) { | 2939 if (ctx->transactionals[i].commit) { |
2939 ctx->transactionals[i].commit(ctx->transactionals[i].data); | 2940 ctx->transactionals[i].commit(ctx->transactionals[i].data); |
2940 if (uw_has_error(ctx)) { | 2941 if (uw_has_error(ctx)) { |
2941 uw_rollback(ctx); | 2942 uw_rollback(ctx, 0); |
2942 return; | 2943 return; |
2943 } | 2944 } |
2944 } | 2945 } |
2945 | 2946 |
2946 for (i = ctx->used_transactionals-1; i >= 0; --i) | 2947 for (i = ctx->used_transactionals-1; i >= 0; --i) |
2947 if (ctx->transactionals[i].rollback == NULL) | 2948 if (ctx->transactionals[i].rollback == NULL) |
2948 if (ctx->transactionals[i].commit) { | 2949 if (ctx->transactionals[i].commit) { |
2949 ctx->transactionals[i].commit(ctx->transactionals[i].data); | 2950 ctx->transactionals[i].commit(ctx->transactionals[i].data); |
2950 if (uw_has_error(ctx)) { | 2951 if (uw_has_error(ctx)) { |
2951 uw_rollback(ctx); | 2952 uw_rollback(ctx, 0); |
2952 return; | 2953 return; |
2953 } | 2954 } |
2954 } | 2955 } |
2955 | 2956 |
2956 if (ctx->app->db_commit(ctx)) { | 2957 if (ctx->app->db_commit(ctx)) { |
2970 if (ctx->client) | 2971 if (ctx->client) |
2971 release_client(ctx->client); | 2972 release_client(ctx->client); |
2972 | 2973 |
2973 for (i = ctx->used_transactionals-1; i >= 0; --i) | 2974 for (i = ctx->used_transactionals-1; i >= 0; --i) |
2974 if (ctx->transactionals[i].free) | 2975 if (ctx->transactionals[i].free) |
2975 ctx->transactionals[i].free(ctx->transactionals[i].data); | 2976 ctx->transactionals[i].free(ctx->transactionals[i].data, 0); |
2976 | 2977 |
2977 // Splice script data into appropriate part of page | 2978 // Splice script data into appropriate part of page |
2978 if (ctx->returning_indirectly || ctx->script_header[0] == 0) { | 2979 if (ctx->returning_indirectly || ctx->script_header[0] == 0) { |
2979 char *start = strstr(ctx->page.start, "<sc>"); | 2980 char *start = strstr(ctx->page.start, "<sc>"); |
2980 if (start) { | 2981 if (start) { |
3010 | 3011 |
3011 | 3012 |
3012 size_t uw_transactionals_max = SIZE_MAX; | 3013 size_t uw_transactionals_max = SIZE_MAX; |
3013 | 3014 |
3014 void uw_register_transactional(uw_context ctx, void *data, uw_callback commit, uw_callback rollback, | 3015 void uw_register_transactional(uw_context ctx, void *data, uw_callback commit, uw_callback rollback, |
3015 uw_callback free) { | 3016 uw_callback_with_retry free) { |
3016 if (ctx->used_transactionals >= ctx->n_transactionals) { | 3017 if (ctx->used_transactionals >= ctx->n_transactionals) { |
3017 if (ctx->used_transactionals+1 > uw_transactionals_max) | 3018 if (ctx->used_transactionals+1 > uw_transactionals_max) |
3018 uw_error(ctx, FATAL, "Exceeded limit on number of transactionals"); | 3019 uw_error(ctx, FATAL, "Exceeded limit on number of transactionals"); |
3019 ctx->transactionals = realloc(ctx->transactionals, sizeof(transactional) * (ctx->used_transactionals+1)); | 3020 ctx->transactionals = realloc(ctx->transactionals, sizeof(transactional) * (ctx->used_transactionals+1)); |
3020 ++ctx->n_transactionals; | 3021 ++ctx->n_transactionals; |