Mercurial > urweb
changeset 1446:36f7d1debb37
Each context gets its own non-repeating sequence of source numbers
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Sat, 09 Apr 2011 14:36:47 -0400 |
parents | 6e6f1643c4e9 |
children | 17393c5e2b90 |
files | include/request.h include/types.h include/urweb.h lib/js/urweb.js src/c/cgi.c src/c/fastcgi.c src/c/http.c src/c/request.c src/c/urweb.c src/cjr_print.sml src/cjrize.sml src/jscomp.sml src/mono_opt.sml tests/rs.ur tests/rs.urs |
diffstat | 15 files changed, 104 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/include/request.h Mon Mar 28 10:37:49 2011 -0400 +++ b/include/request.h Sat Apr 09 14:36:47 2011 -0400 @@ -22,7 +22,7 @@ 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;
--- a/include/types.h Mon Mar 28 10:37:49 2011 -0400 +++ b/include/types.h Sat Apr 09 14:36:47 2011 -0400 @@ -35,6 +35,11 @@ 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;
--- a/include/urweb.h Mon Mar 28 10:37:49 2011 -0400 +++ b/include/urweb.h Sat Apr 09 14:36:47 2011 -0400 @@ -20,7 +20,7 @@ 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 @@ 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_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_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);
--- a/lib/js/urweb.js Mon Mar 28 10:37:49 2011 -0400 +++ b/lib/js/urweb.js Sat Apr 09 14:36:47 2011 -0400 @@ -734,8 +734,14 @@ } 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); }
--- a/src/c/cgi.c Mon Mar 28 10:37:49 2011 -0400 +++ b/src/c/cgi.c Sat Apr 09 14:36:47 2011 -0400 @@ -56,7 +56,7 @@ } 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"),
--- a/src/c/fastcgi.c Mon Mar 28 10:37:49 2011 -0400 +++ b/src/c/fastcgi.c Sat Apr 09 14:36:47 2011 -0400 @@ -322,7 +322,7 @@ 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;
--- a/src/c/http.c Mon Mar 28 10:37:49 2011 -0400 +++ b/src/c/http.c Sat Apr 09 14:36:47 2011 -0400 @@ -63,7 +63,7 @@ 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();
--- a/src/c/request.c Mon Mar 28 10:37:49 2011 -0400 +++ b/src/c/request.c Sat Apr 09 14:36:47 2011 -0400 @@ -32,8 +32,8 @@ 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 @@ } 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 @@ 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 @@ } } - 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 @@ 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 @@ char errmsg[ERROR_BUF_LEN]; uw_reset(ctx); + rc->queryString[0] = 0; for (s = path; *s; ++s) { @@ -546,7 +551,7 @@ 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);
--- a/src/c/urweb.c Mon Mar 28 10:37:49 2011 -0400 +++ b/src/c/urweb.c Sat Apr 09 14:36:47 2011 -0400 @@ -399,6 +399,7 @@ struct uw_context { uw_app *app; + int id; char *(*get_header)(void *, const char *); void *get_header_data; @@ -408,7 +409,7 @@ 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_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 @@ 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 @@ 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 @@ ++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 @@ 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 @@ 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 @@ 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_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 @@ } } -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_unit uw_Basis_set_client_source(uw_context ctx, uw_Basis_int n, uw_Basis_string s) { + uw_Basis_source r = {ctx->id, ctx->source_count++}; + return r; +} + +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 @@ 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)
--- a/src/cjr_print.sml Mon Mar 28 10:37:49 2011 -0400 +++ b/src/cjr_print.sml Sat Apr 09 14:36:47 2011 -0400 @@ -2723,7 +2723,11 @@ 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;",
--- a/src/cjrize.sml Mon Mar 28 10:37:49 2011 -0400 +++ b/src/cjrize.sml Sat Apr 09 14:36:47 2011 -0400 @@ -161,7 +161,7 @@ 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
--- a/src/jscomp.sml Mon Mar 28 10:37:49 2011 -0400 +++ b/src/jscomp.sml Sat Apr 09 14:36:47 2011 -0400 @@ -91,8 +91,7 @@ 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)] =>
--- a/src/mono_opt.sml Mon Mar 28 10:37:49 2011 -0400 +++ b/src/mono_opt.sml Sat Apr 09 14:36:47 2011 -0400 @@ -249,6 +249,9 @@ | 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) =>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/rs.ur Sat Apr 09 14:36:47 2011 -0400 @@ -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>