comparison src/c/urweb.c @ 1931:1a04b1edded2

Fix regression in http.c for long-polling connections; add lazy initialization of database connections, to avoid the overhead in handlers that don't use SQL
author Adam Chlipala <adam@chlipala.net>
date Wed, 11 Dec 2013 14:57:54 -0500
parents 2f33d9a51765
children 98895243b5b6
comparison
equal deleted inserted replaced
1930:5a7ae5acdcea 1931:1a04b1edded2
429 size_t sz_inputs, n_subinputs, used_subinputs; 429 size_t sz_inputs, n_subinputs, used_subinputs;
430 430
431 unsigned long long source_count; 431 unsigned long long source_count;
432 432
433 void *db; 433 void *db;
434 int transaction_started;
434 435
435 jmp_buf jmp_buf; 436 jmp_buf jmp_buf;
436 437
437 regions *regions; 438 regions *regions;
438 439
505 ctx->cur_container = NULL; 506 ctx->cur_container = NULL;
506 ctx->subinputs = malloc(0); 507 ctx->subinputs = malloc(0);
507 ctx->sz_inputs = ctx->n_subinputs = ctx->used_subinputs = 0; 508 ctx->sz_inputs = ctx->n_subinputs = ctx->used_subinputs = 0;
508 509
509 ctx->db = NULL; 510 ctx->db = NULL;
511 ctx->transaction_started = 0;
510 512
511 ctx->regions = NULL; 513 ctx->regions = NULL;
512 514
513 ctx->cleanup_front = ctx->cleanup_back = ctx->cleanup = malloc(0); 515 ctx->cleanup_front = ctx->cleanup_back = ctx->cleanup = malloc(0);
514 516
629 ctx->queryString = NULL; 631 ctx->queryString = NULL;
630 ctx->nextId = 0; 632 ctx->nextId = 0;
631 ctx->amInitializing = 0; 633 ctx->amInitializing = 0;
632 ctx->usedSig = 0; 634 ctx->usedSig = 0;
633 ctx->needsResig = 0; 635 ctx->needsResig = 0;
636 ctx->transaction_started = 0;
634 } 637 }
635 638
636 void uw_reset_keep_request(uw_context ctx) { 639 void uw_reset_keep_request(uw_context ctx) {
637 uw_reset_keep_error_message(ctx); 640 uw_reset_keep_error_message(ctx);
638 ctx->error_message[0] = 0; 641 ctx->error_message[0] = 0;
764 } 767 }
765 768
766 failure_kind uw_begin(uw_context ctx, char *path) { 769 failure_kind uw_begin(uw_context ctx, char *path) {
767 int r = setjmp(ctx->jmp_buf); 770 int r = setjmp(ctx->jmp_buf);
768 771
769 if (r == 0) { 772 if (r == 0)
773 ctx->app->handle(ctx, path);
774
775 return r;
776 }
777
778 void uw_ensure_transaction(uw_context ctx) {
779 if (!ctx->transaction_started) {
770 if (ctx->app->db_begin(ctx)) 780 if (ctx->app->db_begin(ctx))
771 uw_error(ctx, BOUNDED_RETRY, "Error running SQL BEGIN"); 781 uw_error(ctx, BOUNDED_RETRY, "Error running SQL BEGIN");
772 782 ctx->transaction_started = 1;
773 ctx->app->handle(ctx, path); 783 }
774 }
775
776 return r;
777 } 784 }
778 785
779 uw_Basis_client uw_Basis_self(uw_context ctx) { 786 uw_Basis_client uw_Basis_self(uw_context ctx) {
780 if (ctx->client == NULL) 787 if (ctx->client == NULL)
781 uw_error(ctx, FATAL, "Call to Basis.self() from page that has only server-side code"); 788 uw_error(ctx, FATAL, "Call to Basis.self() from page that has only server-side code");
3203 3210
3204 for (i = ctx->used_transactionals-1; i >= 0; --i) 3211 for (i = ctx->used_transactionals-1; i >= 0; --i)
3205 if (ctx->transactionals[i].free) 3212 if (ctx->transactionals[i].free)
3206 ctx->transactionals[i].free(ctx->transactionals[i].data, will_retry); 3213 ctx->transactionals[i].free(ctx->transactionals[i].data, will_retry);
3207 3214
3208 return ctx->app ? ctx->app->db_rollback(ctx) : 0; 3215 return (ctx->app && ctx->transaction_started) ? ctx->app->db_rollback(ctx) : 0;
3209 } 3216 }
3210 3217
3211 static const char begin_xhtml[] = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">"; 3218 static const char begin_xhtml[] = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">";
3212 3219
3213 extern int uw_hash_blocksize; 3220 extern int uw_hash_blocksize;
3260 uw_rollback(ctx, 0); 3267 uw_rollback(ctx, 0);
3261 return; 3268 return;
3262 } 3269 }
3263 } 3270 }
3264 3271
3265 if (ctx->app->db_commit(ctx)) { 3272 if (ctx->transaction_started && ctx->app->db_commit(ctx)) {
3266 uw_set_error_message(ctx, "Error running SQL COMMIT"); 3273 uw_set_error_message(ctx, "Error running SQL COMMIT");
3267 return; 3274 return;
3268 } 3275 }
3269 3276
3270 for (i = 0; i < ctx->used_deltas; ++i) { 3277 for (i = 0; i < ctx->used_deltas; ++i) {
3451 int r = setjmp(ctx->jmp_buf); 3458 int r = setjmp(ctx->jmp_buf);
3452 3459
3453 if (r == 0) { 3460 if (r == 0) {
3454 if (ctx->app->db_begin(ctx)) 3461 if (ctx->app->db_begin(ctx))
3455 uw_error(ctx, FATAL, "Error running SQL BEGIN"); 3462 uw_error(ctx, FATAL, "Error running SQL BEGIN");
3463 ctx->transaction_started = 1;
3456 ctx->app->initializer(ctx); 3464 ctx->app->initializer(ctx);
3457 if (ctx->app->db_commit(ctx)) 3465 if (ctx->app->db_commit(ctx))
3458 uw_error(ctx, FATAL, "Error running SQL COMMIT"); 3466 uw_error(ctx, FATAL, "Error running SQL COMMIT");
3459 } 3467 }
3460 3468
4035 int r = setjmp(ctx->jmp_buf); 4043 int r = setjmp(ctx->jmp_buf);
4036 4044
4037 if (r == 0) { 4045 if (r == 0) {
4038 if (ctx->app->db_begin(ctx)) 4046 if (ctx->app->db_begin(ctx))
4039 uw_error(ctx, BOUNDED_RETRY, "Error running SQL BEGIN"); 4047 uw_error(ctx, BOUNDED_RETRY, "Error running SQL BEGIN");
4048 ctx->transaction_started = 1;
4040 4049
4041 callback(ctx); 4050 callback(ctx);
4042 } 4051 }
4043 4052
4044 return r; 4053 return r;
4083 4092
4084 if (ctx->app->on_error) { 4093 if (ctx->app->on_error) {
4085 if (r == 0) { 4094 if (r == 0) {
4086 if (ctx->app->db_begin(ctx)) 4095 if (ctx->app->db_begin(ctx))
4087 uw_error(ctx, BOUNDED_RETRY, "Error running SQL BEGIN"); 4096 uw_error(ctx, BOUNDED_RETRY, "Error running SQL BEGIN");
4097 ctx->transaction_started = 1;
4088 4098
4089 uw_buffer_reset(&ctx->outHeaders); 4099 uw_buffer_reset(&ctx->outHeaders);
4090 if (on_success[0]) 4100 if (on_success[0])
4091 uw_write_header(ctx, "HTTP/1.1 "); 4101 uw_write_header(ctx, "HTTP/1.1 ");
4092 else 4102 else