summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Adam Chlipala <adamc@hcoop.net>2008-09-11 12:40:40 -0400
committerGravatar Adam Chlipala <adamc@hcoop.net>2008-09-11 12:40:40 -0400
commitfe9025e471578cbdef8ee21e0f9dc51f0f2107ce (patch)
tree69868d711618839352bda0d8d00aa7505c27892a
parent549b3c11b75bb08eb6b686d2d1a04bc0ec7647a9 (diff)
Region memory allocation for query parameters
-rw-r--r--include/urweb.h3
-rw-r--r--src/c/urweb.c31
-rw-r--r--src/cjr_print.sml6
3 files changed, 38 insertions, 2 deletions
diff --git a/include/urweb.h b/include/urweb.h
index c05b49d5..2d201125 100644
--- a/include/urweb.h
+++ b/include/urweb.h
@@ -21,6 +21,9 @@ __attribute__((noreturn)) void uw_error(uw_context, failure_kind, const char *fm
char *uw_error_message(uw_context);
void *uw_malloc(uw_context, size_t);
+void uw_begin_region(uw_context);
+void uw_end_region(uw_context);
+
int uw_send(uw_context, int sock);
void uw_set_input(uw_context, char *name, char *value);
diff --git a/src/c/urweb.c b/src/c/urweb.c
index d8d1ab18..7c7b057f 100644
--- a/src/c/urweb.c
+++ b/src/c/urweb.c
@@ -11,6 +11,10 @@ uw_unit uw_unit_v = {};
#define ERROR_BUF_LEN 1024
+typedef struct regions {
+ struct regions *next;
+} regions;
+
struct uw_context {
char *page, *page_front, *page_back;
char *heap, *heap_front, *heap_back;
@@ -20,6 +24,8 @@ struct uw_context {
jmp_buf jmp_buf;
+ regions *regions;
+
char error_message[ERROR_BUF_LEN];
};
@@ -38,6 +44,8 @@ uw_context uw_init(size_t page_len, size_t heap_len) {
ctx->db = NULL;
+ ctx->regions = NULL;
+
ctx->error_message[0] = 0;
return ctx;
@@ -61,6 +69,7 @@ void uw_free(uw_context ctx) {
void uw_reset_keep_request(uw_context ctx) {
ctx->page_front = ctx->page;
ctx->heap_front = ctx->heap;
+ ctx->regions = NULL;
ctx->error_message[0] = 0;
}
@@ -68,6 +77,7 @@ void uw_reset_keep_request(uw_context ctx) {
void uw_reset_keep_error_message(uw_context ctx) {
ctx->page_front = ctx->page;
ctx->heap_front = ctx->heap;
+ ctx->regions = NULL;
}
void uw_reset(uw_context ctx) {
@@ -176,6 +186,27 @@ void *uw_malloc(uw_context ctx, size_t len) {
return result;
}
+void uw_begin_region(uw_context ctx) {
+ regions *r = (regions *) ctx->heap_front;
+
+ uw_check_heap(ctx, sizeof(regions));
+
+ ctx->heap_front += sizeof(regions);
+
+ r->next = ctx->regions;
+ ctx->regions = r;
+}
+
+void uw_end_region(uw_context ctx) {
+ regions *r = ctx->regions;
+
+ if (r == NULL)
+ uw_error(ctx, FATAL, "Region stack underflow");
+
+ ctx->heap_front = (char *) r;
+ ctx->regions = r->next;
+}
+
int uw_really_send(int sock, const void *buf, ssize_t len) {
while (len > 0) {
ssize_t n = send(sock, buf, len, 0);
diff --git a/src/cjr_print.sml b/src/cjr_print.sml
index 73a4f0fc..8bdb1ba5 100644
--- a/src/cjr_print.sml
+++ b/src/cjr_print.sml
@@ -712,7 +712,7 @@ fun p_exp' par env (e, loc) =
val outputs = exps @ tables
in
- box [string "({",
+ box [string "(uw_begin_region(ctx), ({",
newline,
string "PGconn *conn = uw_get_db(ctx);",
newline,
@@ -791,6 +791,8 @@ fun p_exp' par env (e, loc) =
newline,
newline,
+ string "uw_end_region(ctx);",
+ newline,
string "n = PQntuples(res);",
newline,
string "for (i = 0; i < n; ++i) {",
@@ -851,7 +853,7 @@ fun p_exp' par env (e, loc) =
newline,
string "acc;",
newline,
- string "})"]
+ string "}))"]
end
| EDml {dml, prepared} =>