From b6eff4f490ecaf4ba0b4dabb8aab50b6a2227504 Mon Sep 17 00:00:00 2001 From: Adam Chlipala Date: Tue, 31 Dec 2013 09:34:41 -0500 Subject: Do a bit of extra userspace copying to send HTTP response with a single system call --- src/c/urweb.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'src/c/urweb.c') 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) { -- cgit v1.2.3