# HG changeset patch # User Adam Chlipala # Date 1386791874 18000 # Node ID 1a04b1edded2f93bb672a3d3b002d7aeda3179d8 # Parent 5a7ae5acdcea737b4a85e24609c1e46e8b694399 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 diff -r 5a7ae5acdcea -r 1a04b1edded2 include/urweb/urweb_cpp.h --- a/include/urweb/urweb_cpp.h Wed Dec 11 11:06:08 2013 -0500 +++ b/include/urweb/urweb_cpp.h Wed Dec 11 14:57:54 2013 -0500 @@ -37,6 +37,7 @@ void uw_set_headers(struct uw_context *, char *(*get_header)(void *, const char *), void *get_header_data); void uw_set_env(struct uw_context *, char *(*get_env)(void *, const char *), void *get_env_data); failure_kind uw_begin(struct uw_context *, char *path); +void uw_ensure_transaction(struct uw_context *); failure_kind uw_begin_onError(struct uw_context *, char *msg); void uw_login(struct uw_context *); void uw_commit(struct uw_context *); diff -r 5a7ae5acdcea -r 1a04b1edded2 src/c/http.c --- a/src/c/http.c Wed Dec 11 11:06:08 2013 -0500 +++ b/src/c/http.c Wed Dec 11 14:57:54 2013 -0500 @@ -260,7 +260,9 @@ close(sock); sock = 0; } - } else if (rr != KEEP_OPEN) + } else if (rr == KEEP_OPEN) + sock = 0; + else fprintf(stderr, "Illegal uw_request return code: %d\n", rr); break; diff -r 5a7ae5acdcea -r 1a04b1edded2 src/c/urweb.c --- a/src/c/urweb.c Wed Dec 11 11:06:08 2013 -0500 +++ b/src/c/urweb.c Wed Dec 11 14:57:54 2013 -0500 @@ -431,6 +431,7 @@ unsigned long long source_count; void *db; + int transaction_started; jmp_buf jmp_buf; @@ -507,6 +508,7 @@ ctx->sz_inputs = ctx->n_subinputs = ctx->used_subinputs = 0; ctx->db = NULL; + ctx->transaction_started = 0; ctx->regions = NULL; @@ -631,6 +633,7 @@ ctx->amInitializing = 0; ctx->usedSig = 0; ctx->needsResig = 0; + ctx->transaction_started = 0; } void uw_reset_keep_request(uw_context ctx) { @@ -766,14 +769,18 @@ failure_kind uw_begin(uw_context ctx, char *path) { int r = setjmp(ctx->jmp_buf); - if (r == 0) { + if (r == 0) + ctx->app->handle(ctx, path); + + return r; +} + +void uw_ensure_transaction(uw_context ctx) { + if (!ctx->transaction_started) { if (ctx->app->db_begin(ctx)) uw_error(ctx, BOUNDED_RETRY, "Error running SQL BEGIN"); - - ctx->app->handle(ctx, path); + ctx->transaction_started = 1; } - - return r; } uw_Basis_client uw_Basis_self(uw_context ctx) { @@ -3205,7 +3212,7 @@ if (ctx->transactionals[i].free) ctx->transactionals[i].free(ctx->transactionals[i].data, will_retry); - return ctx->app ? ctx->app->db_rollback(ctx) : 0; + return (ctx->app && ctx->transaction_started) ? ctx->app->db_rollback(ctx) : 0; } static const char begin_xhtml[] = "\n\n"; @@ -3262,7 +3269,7 @@ } } - if (ctx->app->db_commit(ctx)) { + if (ctx->transaction_started && ctx->app->db_commit(ctx)) { uw_set_error_message(ctx, "Error running SQL COMMIT"); return; } @@ -3453,6 +3460,7 @@ if (r == 0) { if (ctx->app->db_begin(ctx)) uw_error(ctx, FATAL, "Error running SQL BEGIN"); + ctx->transaction_started = 1; ctx->app->initializer(ctx); if (ctx->app->db_commit(ctx)) uw_error(ctx, FATAL, "Error running SQL COMMIT"); @@ -4037,6 +4045,7 @@ if (r == 0) { if (ctx->app->db_begin(ctx)) uw_error(ctx, BOUNDED_RETRY, "Error running SQL BEGIN"); + ctx->transaction_started = 1; callback(ctx); } @@ -4085,6 +4094,7 @@ if (r == 0) { if (ctx->app->db_begin(ctx)) uw_error(ctx, BOUNDED_RETRY, "Error running SQL BEGIN"); + ctx->transaction_started = 1; uw_buffer_reset(&ctx->outHeaders); if (on_success[0]) diff -r 5a7ae5acdcea -r 1a04b1edded2 src/cjr_print.sml --- a/src/cjr_print.sml Wed Dec 11 11:06:08 2013 -0500 +++ b/src/cjr_print.sml Wed Dec 11 14:57:54 2013 -0500 @@ -2079,6 +2079,8 @@ newline, string "int dummy = (uw_begin_region(ctx), 0);", newline, + string "uw_ensure_transaction(ctx);", + newline, case prepared of NONE => @@ -2140,6 +2142,8 @@ p_exp' false false env dml, string ";", newline, + string "uw_ensure_transaction(ctx);", + newline, newline, #dml (Settings.currentDbms ()) (loc, mode)] | SOME {id, dml = dml'} => @@ -2159,8 +2163,10 @@ string ";"]) inputs, newline, + string "uw_ensure_transaction(ctx);", newline, - + newline, + #dmlPrepared (Settings.currentDbms ()) {loc = loc, id = id, dml = dml', @@ -2184,6 +2190,8 @@ newline, string "uw_Basis_int n;", newline, + string "uw_ensure_transaction(ctx);", + newline, case prepared of NONE => #nextval (Settings.currentDbms ()) {loc = loc, @@ -2204,6 +2212,8 @@ | ESetval {seq, count} => box [string "({", newline, + string "uw_ensure_transaction(ctx);", + newline, #setval (Settings.currentDbms ()) {loc = loc, seqE = p_exp' false false env seq,