diff options
author | Adam Chlipala <adam@chlipala.net> | 2013-12-31 09:34:41 -0500 |
---|---|---|
committer | Adam Chlipala <adam@chlipala.net> | 2013-12-31 09:34:41 -0500 |
commit | be71c276ef94fa0a37216aa05466fa03f1de55ad (patch) | |
tree | 7ac6772c131992640def65b9826c65413be0fea5 | |
parent | 62aacecd7de0dc53ff4617aed905058a19b2a012 (diff) |
Do a bit of extra userspace copying to send HTTP response with a single system call
-rw-r--r-- | src/c/urweb.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/src/c/urweb.c b/src/c/urweb.c index 0a385cae..3a5933c5 100644 --- a/src/c/urweb.c +++ b/src/c/urweb.c @@ -474,6 +474,9 @@ struct uw_context { char error_message[ERROR_BUF_LEN]; int usedSig, needsResig; + + char *output_buffer; + size_t output_buffer_size; }; size_t uw_headers_max = SIZE_MAX; @@ -554,6 +557,9 @@ uw_context uw_init(int id, void *logger_data, uw_logger log_debug) { ctx->usedSig = 0; ctx->needsResig = 0; + ctx->output_buffer = malloc(1); + ctx->output_buffer_size = 1; + return ctx; } @@ -612,6 +618,8 @@ void uw_free(uw_context ctx) { ctx->globals[i].free(ctx->globals[i].data); free(ctx->globals); + free(ctx->output_buffer); + free(ctx); } @@ -1297,17 +1305,20 @@ int uw_pagelen(uw_context ctx) { } int uw_send(uw_context ctx, int sock) { - int n = uw_really_send(sock, ctx->outHeaders.start, ctx->outHeaders.front - ctx->outHeaders.start); + size_t target_length = (ctx->outHeaders.front - ctx->outHeaders.start) + 2 + (ctx->page.front - ctx->page.start); - if (n < 0) - return n; - - n = uw_really_send(sock, "\r\n", 2); + if (ctx->output_buffer_size < target_length) { + do { + ctx->output_buffer_size *= 2; + } while (ctx->output_buffer_size < target_length); + ctx->output_buffer = realloc(ctx->output_buffer, ctx->output_buffer_size); + } - if (n < 0) - return n; + memcpy(ctx->output_buffer, ctx->outHeaders.start, ctx->outHeaders.front - ctx->outHeaders.start); + memcpy(ctx->output_buffer + (ctx->outHeaders.front - ctx->outHeaders.start), "\r\n", 2); + memcpy(ctx->output_buffer + (ctx->outHeaders.front - ctx->outHeaders.start) + 2, ctx->page.start, ctx->page.front - ctx->page.start); - return uw_really_send(sock, ctx->page.start, ctx->page.front - ctx->page.start); + return uw_really_send(sock, ctx->output_buffer, target_length); } int uw_print(uw_context ctx, int fd) { |