cURL / Mailing Lists / curl-library / Single Mail

curl-library

[PATCH] - master_buffer alloc only on pipelining set on

From: Robert Iakobashvili <coroberti_at_gmail.com>
Date: Fri, 20 Apr 2007 14:32:49 +0200

Not sure, that mainline needs it, but it may be good for the
people, using libcurl at low memory (some embedded) systems.

It safes 16K per client from the total ~60K.

The patch is against 7.16.2 inlined as well as attached.
---------------------------------------------------------------------------------
diff -Naru curl-7.16.2/lib/multi.c curl-7.16.2-mod/lib/multi.c
--- curl-7.16.2/lib/multi.c 2007-04-20 14:26:51.000000000 +0300
+++ curl-7.16.2-mod/lib/multi.c 2007-04-20 13:57:17.000000000 +0300
@@ -1765,6 +1765,8 @@
                             CURLMoption option, ...)
 {
   struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
+ struct Curl_one_easy *easy;
+ bool pipelining_alloc_failed = false;
   CURLMcode res = CURLM_OK;
   va_list param;

@@ -1781,7 +1783,35 @@
     multi->socket_userp = va_arg(param, void *);
     break;
   case CURLMOPT_PIPELINING:
- multi->pipelining_enabled = (bool)(0 != va_arg(param, long));
+ /* Traverse all easy handles and allocate master_buffer for pipelining */
+ easy=multi->easy.next;
+ while(easy != &multi->easy) {
+ if (easy->easy_conn->master_buffer == NULL) {
+ if (!(easy->easy_conn->master_buffer =
+ calloc (BUFSIZE, sizeof (char)))) {
+ pipelining_alloc_failed = true;
+ break;
+ }
+ }
+ easy = easy->next; /* check next handle */
+ }
+
+ if (pipelining_alloc_failed) {
+ /* Traverse all easy handles and release master_buffer, where exists */
+ easy=multi->easy.next;
+ while(easy != &multi->easy) {
+ if (easy->easy_conn->master_buffer) {
+ free (easy->easy_conn->master_buffer);
+ easy->easy_conn->master_buffer = NULL;
+ }
+ easy = easy->next; /* check next handle */
+ }
+ res = CURLM_OUT_OF_MEMORY;
+ }
+
+ if (!pipelining_alloc_failed) {
+ multi->pipelining_enabled = (bool)(0 != va_arg(param, long));
+ }
     break;
   case CURLMOPT_TIMERFUNCTION:
     multi->timer_cb = va_arg(param, curl_multi_timer_callback);
diff -Naru curl-7.16.2/lib/sendf.c curl-7.16.2-mod/lib/sendf.c
--- curl-7.16.2/lib/sendf.c 2007-04-20 14:27:15.000000000 +0300
+++ curl-7.16.2-mod/lib/sendf.c 2007-04-20 14:13:37.000000000 +0300
@@ -496,7 +496,7 @@
     }
     /* If we come here, it means that there is no data to read from the buffer,
      * so we read from the socket */
- bytesfromsocket = MIN(sizerequested, sizeof(conn->master_buffer));
+ bytesfromsocket = MIN(sizerequested, BUFSIZE * sizeof (char));
     buffertofill = conn->master_buffer;
   }
   else {
diff -Naru curl-7.16.2/lib/transfer.c curl-7.16.2-mod/lib/transfer.c
--- curl-7.16.2/lib/transfer.c 2007-04-20 14:26:51.000000000 +0300
+++ curl-7.16.2-mod/lib/transfer.c 2007-04-20 14:19:28.000000000 +0300
@@ -289,8 +289,13 @@
     size_t show;

     show = MIN(conn->buf_len - conn->read_pos, sizeof(buf)-1);
- memcpy(buf, conn->master_buffer + conn->read_pos, show);
- buf[show] = '\0';
+ if (conn->master_buffer) {
+ memcpy(buf, conn->master_buffer + conn->read_pos, show);
+ buf[show] = '\0';
+ }
+ else {
+ buf[0] = '\0';
+ }

     DEBUGF(infof(conn->data,
                  "Buffer after stream rewind (read_pos = %d): [%s]",
diff -Naru curl-7.16.2/lib/url.c curl-7.16.2-mod/lib/url.c
--- curl-7.16.2/lib/url.c 2007-04-10 23:46:40.000000000 +0300
+++ curl-7.16.2-mod/lib/url.c 2007-04-20 14:50:51.000000000 +0300
@@ -1805,6 +1805,8 @@

   Curl_free_ssl_config(&conn->ssl_config);

+ Curl_safefree(conn->master_buffer);
+
   free(conn); /* free all the connection oriented data */
 }

diff -Naru curl-7.16.2/lib/urldata.h curl-7.16.2-mod/lib/urldata.h
--- curl-7.16.2/lib/urldata.h 2007-04-20 14:26:51.000000000 +0300
+++ curl-7.16.2-mod/lib/urldata.h 2007-04-20 13:46:56.000000000 +0300
@@ -868,7 +868,8 @@
   struct curl_llist *recv_pipe; /* List of handles waiting to read
                                    their responses on this pipeline */

- char master_buffer[BUFSIZE]; /* The master buffer for this connection. */
+ char* master_buffer; /* The master buffer allocated on-demand;
+ used for pipelining. */
   size_t read_pos; /* Current read position in the master buffer */
   size_t buf_len; /* Length of the buffer?? */

------------------------------------------------------------------------------------------------------------------

-- 
Sincerely,
Robert Iakobashvili,
coroberti %x40 gmail %x2e com
...................................................................
Navigare necesse est, vivere non est necesse
...................................................................
http://curl-loader.sourceforge.net
An open-source HTTP/S, FTP/S traffic
generating, and web testing tool.

Received on 2007-04-20