Mercurial > urweb
comparison src/c/urweb.c @ 1936:6745eafff617
Start SQL transactions as read-only when possible, based on conservative program analysis
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Thu, 12 Dec 2013 17:42:48 -0500 |
parents | 420d129c4174 |
children | d02c1a0d8082 |
comparison
equal
deleted
inserted
replaced
1935:fda9d5af69e7 | 1936:6745eafff617 |
---|---|
439 | 439 |
440 cleanup *cleanup, *cleanup_front, *cleanup_back; | 440 cleanup *cleanup, *cleanup_front, *cleanup_back; |
441 | 441 |
442 const char *script_header; | 442 const char *script_header; |
443 | 443 |
444 int needs_push, needs_sig; | 444 int needs_push, needs_sig, could_write_db; |
445 | 445 |
446 size_t n_deltas, used_deltas; | 446 size_t n_deltas, used_deltas; |
447 delta *deltas; | 447 delta *deltas; |
448 | 448 |
449 client *client; | 449 client *client; |
515 ctx->cleanup_front = ctx->cleanup_back = ctx->cleanup = malloc(0); | 515 ctx->cleanup_front = ctx->cleanup_back = ctx->cleanup = malloc(0); |
516 | 516 |
517 ctx->script_header = ""; | 517 ctx->script_header = ""; |
518 ctx->needs_push = 0; | 518 ctx->needs_push = 0; |
519 ctx->needs_sig = 0; | 519 ctx->needs_sig = 0; |
520 ctx->could_write_db = 1; | |
520 | 521 |
521 ctx->source_count = 0; | 522 ctx->source_count = 0; |
522 | 523 |
523 ctx->n_deltas = ctx->used_deltas = 0; | 524 ctx->n_deltas = ctx->used_deltas = 0; |
524 ctx->deltas = malloc(0); | 525 ctx->deltas = malloc(0); |
775 return r; | 776 return r; |
776 } | 777 } |
777 | 778 |
778 void uw_ensure_transaction(uw_context ctx) { | 779 void uw_ensure_transaction(uw_context ctx) { |
779 if (!ctx->transaction_started) { | 780 if (!ctx->transaction_started) { |
780 if (ctx->app->db_begin(ctx)) | 781 if (ctx->app->db_begin(ctx, ctx->could_write_db)) |
781 uw_error(ctx, BOUNDED_RETRY, "Error running SQL BEGIN"); | 782 uw_error(ctx, BOUNDED_RETRY, "Error running SQL BEGIN"); |
782 ctx->transaction_started = 1; | 783 ctx->transaction_started = 1; |
783 } | 784 } |
784 } | 785 } |
785 | 786 |
1187 ctx->needs_push = n; | 1188 ctx->needs_push = n; |
1188 } | 1189 } |
1189 | 1190 |
1190 void uw_set_needs_sig(uw_context ctx, int n) { | 1191 void uw_set_needs_sig(uw_context ctx, int n) { |
1191 ctx->needs_sig = n; | 1192 ctx->needs_sig = n; |
1193 } | |
1194 | |
1195 void uw_set_could_write_db(uw_context ctx, int n) { | |
1196 ctx->could_write_db = n; | |
1192 } | 1197 } |
1193 | 1198 |
1194 | 1199 |
1195 static void uw_buffer_check_ctx(uw_context ctx, const char *kind, uw_buffer *b, size_t extra, const char *desc) { | 1200 static void uw_buffer_check_ctx(uw_context ctx, const char *kind, uw_buffer *b, size_t extra, const char *desc) { |
1196 if (b->back - b->front < extra) { | 1201 if (b->back - b->front < extra) { |
3464 | 3469 |
3465 failure_kind uw_initialize(uw_context ctx) { | 3470 failure_kind uw_initialize(uw_context ctx) { |
3466 int r = setjmp(ctx->jmp_buf); | 3471 int r = setjmp(ctx->jmp_buf); |
3467 | 3472 |
3468 if (r == 0) { | 3473 if (r == 0) { |
3469 if (ctx->app->db_begin(ctx)) | 3474 uw_ensure_transaction(ctx); |
3470 uw_error(ctx, FATAL, "Error running SQL BEGIN"); | |
3471 ctx->transaction_started = 1; | |
3472 ctx->app->initializer(ctx); | 3475 ctx->app->initializer(ctx); |
3473 if (ctx->app->db_commit(ctx)) | 3476 if (ctx->app->db_commit(ctx)) |
3474 uw_error(ctx, FATAL, "Error running SQL COMMIT"); | 3477 uw_error(ctx, FATAL, "Error running SQL COMMIT"); |
3475 } | 3478 } |
3476 | 3479 |
4083 | 4086 |
4084 failure_kind uw_runCallback(uw_context ctx, void (*callback)(uw_context)) { | 4087 failure_kind uw_runCallback(uw_context ctx, void (*callback)(uw_context)) { |
4085 int r = setjmp(ctx->jmp_buf); | 4088 int r = setjmp(ctx->jmp_buf); |
4086 | 4089 |
4087 if (r == 0) { | 4090 if (r == 0) { |
4088 if (ctx->app->db_begin(ctx)) | 4091 uw_ensure_transaction(ctx); |
4089 uw_error(ctx, BOUNDED_RETRY, "Error running SQL BEGIN"); | |
4090 ctx->transaction_started = 1; | |
4091 | 4092 |
4092 callback(ctx); | 4093 callback(ctx); |
4093 } | 4094 } |
4094 | 4095 |
4095 return r; | 4096 return r; |
4132 failure_kind uw_begin_onError(uw_context ctx, char *msg) { | 4133 failure_kind uw_begin_onError(uw_context ctx, char *msg) { |
4133 int r = setjmp(ctx->jmp_buf); | 4134 int r = setjmp(ctx->jmp_buf); |
4134 | 4135 |
4135 if (ctx->app->on_error) { | 4136 if (ctx->app->on_error) { |
4136 if (r == 0) { | 4137 if (r == 0) { |
4137 if (ctx->app->db_begin(ctx)) | 4138 uw_ensure_transaction(ctx); |
4138 uw_error(ctx, BOUNDED_RETRY, "Error running SQL BEGIN"); | |
4139 ctx->transaction_started = 1; | |
4140 | 4139 |
4141 uw_buffer_reset(&ctx->outHeaders); | 4140 uw_buffer_reset(&ctx->outHeaders); |
4142 if (on_success[0]) | 4141 if (on_success[0]) |
4143 uw_write_header(ctx, "HTTP/1.1 "); | 4142 uw_write_header(ctx, "HTTP/1.1 "); |
4144 else | 4143 else |