comparison src/c/urweb.c @ 1949:d7bec4e63415

Do a bit of extra userspace copying to send HTTP response with a single system call
author Adam Chlipala <adam@chlipala.net>
date Tue, 31 Dec 2013 09:34:41 -0500
parents 3ecd0b6360eb
children ac1be85e91ad
comparison
equal deleted inserted replaced
1948:6b80900ddc66 1949:d7bec4e63415
472 int amInitializing; 472 int amInitializing;
473 473
474 char error_message[ERROR_BUF_LEN]; 474 char error_message[ERROR_BUF_LEN];
475 475
476 int usedSig, needsResig; 476 int usedSig, needsResig;
477
478 char *output_buffer;
479 size_t output_buffer_size;
477 }; 480 };
478 481
479 size_t uw_headers_max = SIZE_MAX; 482 size_t uw_headers_max = SIZE_MAX;
480 size_t uw_page_max = SIZE_MAX; 483 size_t uw_page_max = SIZE_MAX;
481 size_t uw_heap_max = SIZE_MAX; 484 size_t uw_heap_max = SIZE_MAX;
551 554
552 ctx->amInitializing = 0; 555 ctx->amInitializing = 0;
553 556
554 ctx->usedSig = 0; 557 ctx->usedSig = 0;
555 ctx->needsResig = 0; 558 ctx->needsResig = 0;
559
560 ctx->output_buffer = malloc(1);
561 ctx->output_buffer_size = 1;
556 562
557 return ctx; 563 return ctx;
558 } 564 }
559 565
560 size_t uw_inputs_max = SIZE_MAX; 566 size_t uw_inputs_max = SIZE_MAX;
609 615
610 for (i = 0; i < ctx->n_globals; ++i) 616 for (i = 0; i < ctx->n_globals; ++i)
611 if (ctx->globals[i].free) 617 if (ctx->globals[i].free)
612 ctx->globals[i].free(ctx->globals[i].data); 618 ctx->globals[i].free(ctx->globals[i].data);
613 free(ctx->globals); 619 free(ctx->globals);
620
621 free(ctx->output_buffer);
614 622
615 free(ctx); 623 free(ctx);
616 } 624 }
617 625
618 void uw_reset_keep_error_message(uw_context ctx) { 626 void uw_reset_keep_error_message(uw_context ctx) {
1295 int uw_pagelen(uw_context ctx) { 1303 int uw_pagelen(uw_context ctx) {
1296 return ctx->page.front - ctx->page.start; 1304 return ctx->page.front - ctx->page.start;
1297 } 1305 }
1298 1306
1299 int uw_send(uw_context ctx, int sock) { 1307 int uw_send(uw_context ctx, int sock) {
1300 int n = uw_really_send(sock, ctx->outHeaders.start, ctx->outHeaders.front - ctx->outHeaders.start); 1308 size_t target_length = (ctx->outHeaders.front - ctx->outHeaders.start) + 2 + (ctx->page.front - ctx->page.start);
1301 1309
1302 if (n < 0) 1310 if (ctx->output_buffer_size < target_length) {
1303 return n; 1311 do {
1304 1312 ctx->output_buffer_size *= 2;
1305 n = uw_really_send(sock, "\r\n", 2); 1313 } while (ctx->output_buffer_size < target_length);
1306 1314 ctx->output_buffer = realloc(ctx->output_buffer, ctx->output_buffer_size);
1307 if (n < 0) 1315 }
1308 return n; 1316
1309 1317 memcpy(ctx->output_buffer, ctx->outHeaders.start, ctx->outHeaders.front - ctx->outHeaders.start);
1310 return uw_really_send(sock, ctx->page.start, ctx->page.front - ctx->page.start); 1318 memcpy(ctx->output_buffer + (ctx->outHeaders.front - ctx->outHeaders.start), "\r\n", 2);
1319 memcpy(ctx->output_buffer + (ctx->outHeaders.front - ctx->outHeaders.start) + 2, ctx->page.start, ctx->page.front - ctx->page.start);
1320
1321 return uw_really_send(sock, ctx->output_buffer, target_length);
1311 } 1322 }
1312 1323
1313 int uw_print(uw_context ctx, int fd) { 1324 int uw_print(uw_context ctx, int fd) {
1314 int n = uw_really_write(fd, ctx->outHeaders.start, ctx->outHeaders.front - ctx->outHeaders.start); 1325 int n = uw_really_write(fd, ctx->outHeaders.start, ctx->outHeaders.front - ctx->outHeaders.start);
1315 1326