Mercurial > urweb
comparison src/c/urweb.c @ 1131:94e83c5533d2
Handling errors during commit
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Tue, 26 Jan 2010 14:59:19 -0500 |
parents | e1cf925e2074 |
children | b08b73591d2c |
comparison
equal
deleted
inserted
replaced
1130:67d875c8ac71 | 1131:94e83c5533d2 |
---|---|
609 static void uw_set_error(uw_context ctx, const char *fmt, ...) { | 609 static void uw_set_error(uw_context ctx, const char *fmt, ...) { |
610 va_list ap; | 610 va_list ap; |
611 va_start(ap, fmt); | 611 va_start(ap, fmt); |
612 | 612 |
613 vsnprintf(ctx->error_message, ERROR_BUF_LEN, fmt, ap); | 613 vsnprintf(ctx->error_message, ERROR_BUF_LEN, fmt, ap); |
614 } | |
615 | |
616 int uw_has_error(uw_context ctx) { | |
617 return ctx->error_message[0] != 0; | |
614 } | 618 } |
615 | 619 |
616 __attribute__((noreturn)) void uw_error(uw_context ctx, failure_kind fk, const char *fmt, ...) { | 620 __attribute__((noreturn)) void uw_error(uw_context ctx, failure_kind fk, const char *fmt, ...) { |
617 cleanup *cl; | 621 cleanup *cl; |
618 | 622 |
2886 ctx_buf_append(ctx, "messages", &d->msgs, "\n", 1); | 2890 ctx_buf_append(ctx, "messages", &d->msgs, "\n", 1); |
2887 | 2891 |
2888 return uw_unit_v; | 2892 return uw_unit_v; |
2889 } | 2893 } |
2890 | 2894 |
2895 int uw_rollback(uw_context ctx) { | |
2896 int i; | |
2897 cleanup *cl; | |
2898 | |
2899 if (ctx->client) | |
2900 release_client(ctx->client); | |
2901 | |
2902 for (cl = ctx->cleanup; cl < ctx->cleanup_front; ++cl) | |
2903 cl->func(cl->arg); | |
2904 | |
2905 ctx->cleanup_front = ctx->cleanup; | |
2906 | |
2907 for (i = ctx->used_transactionals-1; i >= 0; --i) | |
2908 if (ctx->transactionals[i].rollback != NULL) | |
2909 ctx->transactionals[i].rollback(ctx->transactionals[i].data); | |
2910 | |
2911 for (i = ctx->used_transactionals-1; i >= 0; --i) | |
2912 if (ctx->transactionals[i].free) | |
2913 ctx->transactionals[i].free(ctx->transactionals[i].data); | |
2914 | |
2915 return ctx->app->db_rollback(ctx); | |
2916 } | |
2917 | |
2891 void uw_commit(uw_context ctx) { | 2918 void uw_commit(uw_context ctx) { |
2892 int i; | 2919 int i; |
2893 | 2920 |
2921 if (uw_has_error(ctx)) { | |
2922 uw_rollback(ctx); | |
2923 return; | |
2924 } | |
2925 | |
2894 for (i = ctx->used_transactionals-1; i >= 0; --i) | 2926 for (i = ctx->used_transactionals-1; i >= 0; --i) |
2895 if (ctx->transactionals[i].rollback != NULL) | 2927 if (ctx->transactionals[i].rollback != NULL) |
2896 if (ctx->transactionals[i].commit) | 2928 if (ctx->transactionals[i].commit) { |
2897 ctx->transactionals[i].commit(ctx->transactionals[i].data); | 2929 ctx->transactionals[i].commit(ctx->transactionals[i].data); |
2930 if (uw_has_error(ctx)) { | |
2931 uw_rollback(ctx); | |
2932 return; | |
2933 } | |
2934 } | |
2898 | 2935 |
2899 for (i = ctx->used_transactionals-1; i >= 0; --i) | 2936 for (i = ctx->used_transactionals-1; i >= 0; --i) |
2900 if (ctx->transactionals[i].rollback == NULL) | 2937 if (ctx->transactionals[i].rollback == NULL) |
2901 if (ctx->transactionals[i].commit) | 2938 if (ctx->transactionals[i].commit) { |
2902 ctx->transactionals[i].commit(ctx->transactionals[i].data); | 2939 ctx->transactionals[i].commit(ctx->transactionals[i].data); |
2903 | 2940 if (uw_has_error(ctx)) { |
2904 if (ctx->app->db_commit(ctx)) | 2941 uw_rollback(ctx); |
2905 uw_error(ctx, FATAL, "Error running SQL COMMIT"); | 2942 return; |
2943 } | |
2944 } | |
2945 | |
2946 if (ctx->app->db_commit(ctx)) { | |
2947 uw_set_error_message(ctx, "Error running SQL COMMIT"); | |
2948 return; | |
2949 } | |
2906 | 2950 |
2907 for (i = 0; i < ctx->used_deltas; ++i) { | 2951 for (i = 0; i < ctx->used_deltas; ++i) { |
2908 delta *d = &ctx->deltas[i]; | 2952 delta *d = &ctx->deltas[i]; |
2909 client *c = find_client(d->client); | 2953 client *c = find_client(d->client); |
2910 | 2954 |
2952 memcpy(start + lenH + 31 + len, "</script>", 9); | 2996 memcpy(start + lenH + 31 + len, "</script>", 9); |
2953 } | 2997 } |
2954 } | 2998 } |
2955 } | 2999 } |
2956 | 3000 |
2957 int uw_rollback(uw_context ctx) { | |
2958 int i; | |
2959 cleanup *cl; | |
2960 | |
2961 if (ctx->client) | |
2962 release_client(ctx->client); | |
2963 | |
2964 for (cl = ctx->cleanup; cl < ctx->cleanup_front; ++cl) | |
2965 cl->func(cl->arg); | |
2966 | |
2967 ctx->cleanup_front = ctx->cleanup; | |
2968 | |
2969 for (i = ctx->used_transactionals-1; i >= 0; --i) | |
2970 if (ctx->transactionals[i].rollback != NULL) | |
2971 ctx->transactionals[i].rollback(ctx->transactionals[i].data); | |
2972 | |
2973 for (i = ctx->used_transactionals-1; i >= 0; --i) | |
2974 if (ctx->transactionals[i].free) | |
2975 ctx->transactionals[i].free(ctx->transactionals[i].data); | |
2976 | |
2977 return ctx->app->db_rollback(ctx); | |
2978 } | |
2979 | 3001 |
2980 size_t uw_transactionals_max = SIZE_MAX; | 3002 size_t uw_transactionals_max = SIZE_MAX; |
2981 | 3003 |
2982 void uw_register_transactional(uw_context ctx, void *data, uw_callback commit, uw_callback rollback, | 3004 void uw_register_transactional(uw_context ctx, void *data, uw_callback commit, uw_callback rollback, |
2983 uw_callback free) { | 3005 uw_callback free) { |