changeset 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 5a7ae5acdcea
children 98895243b5b6
files include/urweb/urweb_cpp.h src/c/http.c src/c/urweb.c src/cjr_print.sml
diffstat 4 files changed, 32 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- 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 *);
--- 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;
--- 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[] = "<?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\">";
@@ -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])
--- 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,