diff options
author | Adam Chlipala <adam@chlipala.net> | 2011-04-09 14:36:47 -0400 |
---|---|---|
committer | Adam Chlipala <adam@chlipala.net> | 2011-04-09 14:36:47 -0400 |
commit | 51b2033057b25f4cecd3d5e73dc49b60b532834e (patch) | |
tree | 129120a683d01c00c6deb50349c48d8975dfd573 | |
parent | 039b577f61a2bdf98abe10c5f10c8e3539a59d19 (diff) |
Each context gets its own non-repeating sequence of source numbers
-rw-r--r-- | include/request.h | 2 | ||||
-rw-r--r-- | include/types.h | 5 | ||||
-rw-r--r-- | include/urweb.h | 9 | ||||
-rw-r--r-- | lib/js/urweb.js | 8 | ||||
-rw-r--r-- | src/c/cgi.c | 2 | ||||
-rw-r--r-- | src/c/fastcgi.c | 2 | ||||
-rw-r--r-- | src/c/http.c | 2 | ||||
-rw-r--r-- | src/c/request.c | 15 | ||||
-rw-r--r-- | src/c/urweb.c | 61 | ||||
-rw-r--r-- | src/cjr_print.sml | 6 | ||||
-rw-r--r-- | src/cjrize.sml | 2 | ||||
-rw-r--r-- | src/jscomp.sml | 3 | ||||
-rw-r--r-- | src/mono_opt.sml | 3 | ||||
-rw-r--r-- | tests/rs.ur | 15 | ||||
-rw-r--r-- | tests/rs.urs | 1 |
15 files changed, 102 insertions, 34 deletions
diff --git a/include/request.h b/include/request.h index d2385af7..dd0359c9 100644 --- a/include/request.h +++ b/include/request.h @@ -22,7 +22,7 @@ request_result uw_request(uw_request_context, uw_context, int (*send)(int sockfd, const void *buf, ssize_t len), int (*close)(int fd)); -uw_context uw_request_new_context(uw_app*, void *logger_data, uw_logger log_error, uw_logger log_debug); +uw_context uw_request_new_context(int id, uw_app*, void *logger_data, uw_logger log_error, uw_logger log_debug); typedef struct { uw_app *app; diff --git a/include/types.h b/include/types.h index 28658862..1e479398 100644 --- a/include/types.h +++ b/include/types.h @@ -35,6 +35,11 @@ typedef struct { unsigned cli, chn; } uw_Basis_channel; +typedef struct { + int context; + unsigned long long source; +} uw_Basis_source; + typedef struct uw_Basis_file { uw_Basis_string name, type; uw_Basis_blob data; diff --git a/include/urweb.h b/include/urweb.h index 30db875b..15ef33e5 100644 --- a/include/urweb.h +++ b/include/urweb.h @@ -20,7 +20,7 @@ void uw_client_connect(unsigned id, int pass, int sock, void uw_prune_clients(uw_context); failure_kind uw_initialize(uw_context); -uw_context uw_init(void *logger_data, uw_logger log_debug); +uw_context uw_init(int id, void *logger_data, uw_logger log_debug); void uw_close(uw_context); int uw_set_app(uw_context, uw_app*); uw_app *uw_get_app(uw_context); @@ -71,12 +71,13 @@ int uw_next_entry(uw_context); void uw_write(uw_context, const char*); -uw_Basis_int uw_Basis_new_client_source(uw_context, uw_Basis_string); -uw_unit uw_Basis_set_client_source(uw_context, uw_Basis_int, uw_Basis_string); +uw_Basis_source uw_Basis_new_client_source(uw_context, uw_Basis_string); +uw_unit uw_Basis_set_client_source(uw_context, uw_Basis_source, uw_Basis_string); void uw_set_script_header(uw_context, const char*); const char *uw_Basis_get_settings(uw_context, uw_unit); const char *uw_Basis_get_script(uw_context, uw_unit); +const char *uw_get_real_script(uw_context); uw_Basis_string uw_Basis_maybe_onload(uw_context, uw_Basis_string); uw_Basis_string uw_Basis_maybe_onunload(uw_context, uw_Basis_string); @@ -90,6 +91,7 @@ char *uw_Basis_htmlifyString(uw_context, uw_Basis_string); char *uw_Basis_htmlifyBool(uw_context, uw_Basis_bool); char *uw_Basis_htmlifyTime(uw_context, uw_Basis_time); char *uw_Basis_htmlifySpecialChar(uw_context, unsigned char); +char *uw_Basis_htmlifySource(uw_context, uw_Basis_source); uw_unit uw_Basis_htmlifyInt_w(uw_context, uw_Basis_int); uw_unit uw_Basis_htmlifyFloat_w(uw_context, uw_Basis_float); @@ -97,6 +99,7 @@ uw_unit uw_Basis_htmlifyString_w(uw_context, uw_Basis_string); uw_unit uw_Basis_htmlifyBool_w(uw_context, uw_Basis_bool); uw_unit uw_Basis_htmlifyTime_w(uw_context, uw_Basis_time); uw_unit uw_Basis_htmlifySpecialChar_w(uw_context, unsigned char); +uw_unit uw_Basis_htmlifySource_w(uw_context, uw_Basis_source); char *uw_Basis_attrifyInt(uw_context, uw_Basis_int); char *uw_Basis_attrifyFloat(uw_context, uw_Basis_float); diff --git a/lib/js/urweb.js b/lib/js/urweb.js index 3cb667d6..f5764896 100644 --- a/lib/js/urweb.js +++ b/lib/js/urweb.js @@ -734,8 +734,14 @@ function rc(prefix, uri, parse, k, needsSig) { } catch (e) { } if (isok) { + var lines = xhr.responseText.split("\n"); + if (lines.length != 2) + whine("Bad RPC response lines"); + + eval(lines[0]); + try { - k(parse(xhr.responseText)); + k(parse(lines[1])); } catch (v) { doExn(v); } diff --git a/src/c/cgi.c b/src/c/cgi.c index 50d64f58..52d122ca 100644 --- a/src/c/cgi.c +++ b/src/c/cgi.c @@ -56,7 +56,7 @@ static void log_debug(void *data, const char *fmt, ...) { } int main(int argc, char *argv[]) { - uw_context ctx = uw_request_new_context(&uw_application, NULL, log_error, log_debug); + uw_context ctx = uw_request_new_context(0, &uw_application, NULL, log_error, log_debug); uw_request_context rc = uw_new_request_context(); request_result rr; char *method = getenv("REQUEST_METHOD"), diff --git a/src/c/fastcgi.c b/src/c/fastcgi.c index ec1afb8e..161cb834 100644 --- a/src/c/fastcgi.c +++ b/src/c/fastcgi.c @@ -322,7 +322,7 @@ int fastcgi_send_normal(int sock, const void *buf, ssize_t len) { static void *worker(void *data) { FCGI_Input *in = fastcgi_input(); FCGI_Output *out = fastcgi_output(); - uw_context ctx = uw_request_new_context(&uw_application, out, log_error, log_debug); + uw_context ctx = uw_request_new_context(*(int *)data, &uw_application, out, log_error, log_debug); uw_request_context rc = uw_new_request_context(); headers hs; size_t body_size = 0; diff --git a/src/c/http.c b/src/c/http.c index 7ba06871..579c874e 100644 --- a/src/c/http.c +++ b/src/c/http.c @@ -63,7 +63,7 @@ static void log_debug(void *data, const char *fmt, ...) { static void *worker(void *data) { int me = *(int *)data; - uw_context ctx = uw_request_new_context(&uw_application, NULL, log_error, log_debug); + uw_context ctx = uw_request_new_context(me, &uw_application, NULL, log_error, log_debug); size_t buf_size = 2; char *buf = malloc(buf_size); uw_request_context rc = uw_new_request_context(); diff --git a/src/c/request.c b/src/c/request.c index 2d0d0dc7..3fd12ff6 100644 --- a/src/c/request.c +++ b/src/c/request.c @@ -32,8 +32,8 @@ static int try_rollback(uw_context ctx, int will_retry, void *logger_data, uw_lo return r; } -uw_context uw_request_new_context(uw_app *app, void *logger_data, uw_logger log_error, uw_logger log_debug) { - uw_context ctx = uw_init(logger_data, log_debug); +uw_context uw_request_new_context(int id, uw_app *app, void *logger_data, uw_logger log_error, uw_logger log_debug) { + uw_context ctx = uw_init(id, logger_data, log_debug); int retries_left = MAX_RETRIES; uw_set_app(ctx, app); @@ -84,13 +84,14 @@ typedef struct { } loggers; typedef struct { + int id; loggers *ls; uw_periodic pdic; } periodic; static void *periodic_loop(void *data) { periodic *p = (periodic *)data; - uw_context ctx = uw_request_new_context(p->ls->app, p->ls->logger_data, p->ls->log_error, p->ls->log_debug); + uw_context ctx = uw_request_new_context(p->id, p->ls->app, p->ls->logger_data, p->ls->log_error, p->ls->log_debug); if (!ctx) exit(1); @@ -127,6 +128,7 @@ void uw_request_init(uw_app *app, void *logger_data, uw_logger log_error, uw_log failure_kind fk; uw_periodic *ps; loggers *ls = malloc(sizeof(loggers)); + int id; ls->app = app; ls->logger_data = logger_data; @@ -145,7 +147,7 @@ void uw_request_init(uw_app *app, void *logger_data, uw_logger log_error, uw_log } } - ctx = uw_request_new_context(app, logger_data, log_error, log_debug); + ctx = uw_request_new_context(0, app, logger_data, log_error, log_debug); if (!ctx) exit(1); @@ -164,9 +166,11 @@ void uw_request_init(uw_app *app, void *logger_data, uw_logger log_error, uw_log uw_free(ctx); + id = 1; for (ps = app->periodics; ps->callback; ++ps) { pthread_t thread; periodic *arg = malloc(sizeof(periodic)); + arg->id = id++; arg->ls = ls; arg->pdic = *ps; @@ -218,6 +222,7 @@ request_result uw_request(uw_request_context rc, uw_context ctx, char errmsg[ERROR_BUF_LEN]; uw_reset(ctx); + rc->queryString[0] = 0; for (s = path; *s; ++s) { @@ -546,7 +551,7 @@ request_result uw_request(uw_request_context rc, uw_context ctx, void *client_pruner(void *data) { loggers *ls = (loggers *)data; - uw_context ctx = uw_request_new_context(ls->app, ls->logger_data, ls->log_error, ls->log_debug); + uw_context ctx = uw_request_new_context(0, ls->app, ls->logger_data, ls->log_error, ls->log_debug); if (!ctx) exit(1); diff --git a/src/c/urweb.c b/src/c/urweb.c index 27dfd909..582aaf29 100644 --- a/src/c/urweb.c +++ b/src/c/urweb.c @@ -399,6 +399,7 @@ typedef struct { struct uw_context { uw_app *app; + int id; char *(*get_header)(void *, const char *); void *get_header_data; @@ -408,7 +409,7 @@ struct uw_context { input *inputs, *subinputs, *cur_container; size_t sz_inputs, n_subinputs, used_subinputs; - int source_count; + unsigned long long source_count; void *db; @@ -454,10 +455,11 @@ size_t uw_page_max = SIZE_MAX; size_t uw_heap_max = SIZE_MAX; size_t uw_script_max = SIZE_MAX; -uw_context uw_init(void *logger_data, uw_logger log_debug) { +uw_context uw_init(int id, void *logger_data, uw_logger log_debug) { uw_context ctx = malloc(sizeof(struct uw_context)); ctx->app = NULL; + ctx->id = id; ctx->get_header = NULL; ctx->get_header_data = NULL; @@ -584,7 +586,6 @@ void uw_reset_keep_error_message(uw_context ctx) { uw_buffer_reset(&ctx->heap); ctx->regions = NULL; ctx->cleanup_front = ctx->cleanup; - ctx->source_count = 0; ctx->used_deltas = 0; ctx->client = NULL; ctx->cur_container = NULL; @@ -621,6 +622,10 @@ void uw_close(uw_context ctx) { ctx->app->db_close(ctx); } +uw_Basis_string uw_Basis_requestHeader(uw_context ctx, uw_Basis_string h) { + return ctx->get_header(ctx->get_header_data, h); +} + void uw_set_headers(uw_context ctx, char *(*get_header)(void *, const char *), void *get_header_data) { ctx->get_header = get_header; ctx->get_header_data = get_header_data; @@ -680,10 +685,6 @@ void uw_push_cleanup(uw_context ctx, void (*func)(void *), void *arg) { ++ctx->cleanup_front; } -uw_Basis_string uw_Basis_requestHeader(uw_context ctx, uw_Basis_string h) { - return ctx->get_header(ctx->get_header_data, h); -} - char *uw_Basis_htmlifyString(uw_context, const char *); void uw_login(uw_context ctx) { @@ -1296,6 +1297,10 @@ const char *uw_Basis_get_script(uw_context ctx, uw_unit u) { return "<sc>"; } +const char *uw_get_real_script(uw_context ctx) { + return ctx->script.start; +} + uw_Basis_string uw_Basis_maybe_onload(uw_context ctx, uw_Basis_string s) { if (s[0] == 0) return ""; @@ -1345,7 +1350,7 @@ const char *uw_Basis_get_settings(uw_context ctx, uw_unit u) { uw_Basis_string uw_Basis_jsifyString(uw_context ctx, uw_Basis_string s) { char *r, *s2; - uw_check_heap(ctx, strlen(s) * 4 + 2); + uw_check_heap(ctx, strlen(s) * 4 + 3); r = s2 = ctx->heap.front; *s2++ = '"'; @@ -1385,7 +1390,7 @@ uw_Basis_string uw_Basis_jsifyChar(uw_context ctx, uw_Basis_char c1) { unsigned char c = c1; char *r, *s2; - uw_check_heap(ctx, 6); + uw_check_heap(ctx, 7); r = s2 = ctx->heap.front; *s2++ = '"'; @@ -1420,7 +1425,7 @@ uw_Basis_string uw_Basis_jsifyChar(uw_context ctx, uw_Basis_char c1) { uw_Basis_string uw_Basis_jsifyString_ws(uw_context ctx, uw_Basis_string s) { char *r, *s2; - uw_check_script(ctx, strlen(s) * 4 + 2); + uw_check_script(ctx, strlen(s) * 4 + 3); r = s2 = ctx->script.front; *s2++ = '"'; @@ -1467,27 +1472,28 @@ char *uw_Basis_jsifyChannel(uw_context ctx, uw_Basis_channel chn) { } } -uw_Basis_int uw_Basis_new_client_source(uw_context ctx, uw_Basis_string s) { +uw_Basis_source uw_Basis_new_client_source(uw_context ctx, uw_Basis_string s) { int len; size_t s_len = strlen(s); - uw_check_script(ctx, 18 + INTS_MAX + s_len); - sprintf(ctx->script.front, "var s%d=sc(exec(%n", ctx->source_count, &len); + uw_check_script(ctx, 15 + 2 * INTS_MAX + s_len); + sprintf(ctx->script.front, "s%d_%llu=sc(exec(%n", ctx->id, ctx->source_count, &len); ctx->script.front += len; strcpy(ctx->script.front, s); ctx->script.front += s_len; strcpy(ctx->script.front, "));"); ctx->script.front += 3; - return ctx->source_count++; + uw_Basis_source r = {ctx->id, ctx->source_count++}; + return r; } -uw_unit uw_Basis_set_client_source(uw_context ctx, uw_Basis_int n, uw_Basis_string s) { +uw_unit uw_Basis_set_client_source(uw_context ctx, uw_Basis_source src, uw_Basis_string s) { int len; size_t s_len = strlen(s); - uw_check_script(ctx, 12 + INTS_MAX + s_len); - sprintf(ctx->script.front, "sv(s%d,exec(%n", (int)n, &len); + uw_check_script(ctx, 15 + 2 * INTS_MAX + s_len); + sprintf(ctx->script.front, "sv(s%d_%llu,exec(%n", src.context, src.source, &len); ctx->script.front += len; strcpy(ctx->script.front, s); ctx->script.front += s_len; @@ -2128,6 +2134,27 @@ uw_unit uw_Basis_htmlifyTime_w(uw_context ctx, uw_Basis_time t) { return uw_unit_v; } +char *uw_Basis_htmlifySource(uw_context ctx, uw_Basis_source src) { + int len; + char *r; + + uw_check_heap(ctx, 2 * INTS_MAX + 2); + r = ctx->heap.front; + sprintf(r, "s%d_%llu%n", src.context, src.source, &len); + ctx->heap.front += len+1; + return r; +} + +uw_unit uw_Basis_htmlifySource_w(uw_context ctx, uw_Basis_source src) { + int len; + + uw_check(ctx, 2 * INTS_MAX + 1); + sprintf(ctx->page.front, "s%d_%llu%n", src.context, src.source, &len); + ctx->page.front += len; + + return uw_unit_v; +} + uw_Basis_char uw_Basis_strsub(uw_context ctx, uw_Basis_string s, uw_Basis_int n) { while (n >= 0) { if (*s == 0) diff --git a/src/cjr_print.sml b/src/cjr_print.sml index d6c0db98..3988a921 100644 --- a/src/cjr_print.sml +++ b/src/cjr_print.sml @@ -2723,7 +2723,11 @@ fun p_file env (ds, ps) = string ", 0);", newline, box (case ek of - Core.Rpc _ => [urlify env ran] + Core.Rpc _ => [string "uw_write(ctx, uw_get_real_script(ctx));", + newline, + string "uw_write(ctx, \"\\n\");", + newline, + urlify env ran] | _ => [string "uw_write(ctx, \"</html>\");", newline]), string "return;", diff --git a/src/cjrize.sml b/src/cjrize.sml index 2c13e494..b48a4ebd 100644 --- a/src/cjrize.sml +++ b/src/cjrize.sml @@ -161,7 +161,7 @@ fun cifyTyp x = in ((L'.TList (t', si), loc), sm) end - | L.TSource => ((L'.TFfi ("Basis", "int"), loc), sm) + | L.TSource => ((L'.TFfi ("Basis", "source"), loc), sm) | L.TSignal _ => raise Fail "Cjrize: TSignal remains" in cify IM.empty x diff --git a/src/jscomp.sml b/src/jscomp.sml index ce64c11b..d8b2d661 100644 --- a/src/jscomp.sml +++ b/src/jscomp.sml @@ -91,8 +91,7 @@ fun process file = fun quoteExp loc (t : typ) (e, st) = case #1 t of - TSource => (strcat loc [str loc "s", - (EFfiApp ("Basis", "htmlifyInt", [e]), loc)], st) + TSource => ((EFfiApp ("Basis", "htmlifySource", [e]), loc), st) | TRecord [] => (str loc "null", st) | TRecord [(x, t)] => diff --git a/src/mono_opt.sml b/src/mono_opt.sml index 12a811cb..34c13e82 100644 --- a/src/mono_opt.sml +++ b/src/mono_opt.sml @@ -249,6 +249,9 @@ fun exp e = | EFfiApp ("Basis", "htmlifyString_w", [(EPrim (Prim.String s), loc)]) => EWrite (EPrim (Prim.String (htmlifyString s)), loc) + | EWrite (EFfiApp ("Basis", "htmlifySource", [e]), _) => + EFfiApp ("Basis", "htmlifySource_w", [e]) + | EFfiApp ("Basis", "attrifyInt", [(EPrim (Prim.Int n), _)]) => EPrim (Prim.String (attrifyInt n)) | EWrite (EFfiApp ("Basis", "attrifyInt", [(EPrim (Prim.Int n), _)]), loc) => diff --git a/tests/rs.ur b/tests/rs.ur new file mode 100644 index 00000000..ae5ff85f --- /dev/null +++ b/tests/rs.ur @@ -0,0 +1,15 @@ +fun bobo () = + n1 <- source 0; + n2 <- source 1; + return <xml> + <dyn signal={n1 <- signal n1; n2 <- signal n2; return <xml>{[n1 + n2]}</xml>}/> + <button value="Increment1" onclick={v <- get n1; set n1 (v + 1)}/> + <button value="Increment2" onclick={v <- get n2; set n2 (v + 1)}/> + </xml> + +fun main () = + x <- source <xml/>; + return <xml><body> + <dyn signal={signal x}/> + <button value="Grab" onclick={y <- rpc (bobo ()); set x y}/> + </body></xml> diff --git a/tests/rs.urs b/tests/rs.urs new file mode 100644 index 00000000..6ac44e0b --- /dev/null +++ b/tests/rs.urs @@ -0,0 +1 @@ +val main : unit -> transaction page |