diff options
author | Daniel Stenberg <daniel@haxx.se> | 2020-09-23 09:22:02 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2020-09-23 15:14:09 +0200 |
commit | 675eeb1c941706070381faaad8ee1a5d75cff4a4 (patch) | |
tree | 180f01d716fa508c45cea533973782817d980c5c /lib | |
parent | f74afa40f8b6b87ccf74a4ca70b5514a9a87e6f1 (diff) | |
download | curl-675eeb1c941706070381faaad8ee1a5d75cff4a4.tar.gz |
pingpong: use a dynbuf for the *_pp_sendf() function
... reuses the same dynamic buffer instead of doing repeated malloc/free
cycles.
Test case 100 (FTP dir list PASV) does 7 fewer memory allocation calls
after this change in my test setup (132 => 125), curl 7.72.0 needed 140
calls for this.
Test case 103 makes 9 less allocations now (130). Down from 149 in
7.72.0.
Closes #6004
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ftp.c | 1 | ||||
-rw-r--r-- | lib/imap.c | 1 | ||||
-rw-r--r-- | lib/pingpong.c | 55 | ||||
-rw-r--r-- | lib/pingpong.h | 4 | ||||
-rw-r--r-- | lib/pop3.c | 1 | ||||
-rw-r--r-- | lib/smtp.c | 1 |
6 files changed, 32 insertions, 31 deletions
@@ -3112,6 +3112,7 @@ static CURLcode ftp_connect(struct connectdata *conn, return result; } + Curl_pp_setup(pp); /* once per transfer */ Curl_pp_init(pp); /* init the generic pingpong data */ /* When we connect, we start in the state where we await the 220 diff --git a/lib/imap.c b/lib/imap.c index b9b14d10e..02fc796e4 100644 --- a/lib/imap.c +++ b/lib/imap.c @@ -1430,6 +1430,7 @@ static CURLcode imap_connect(struct connectdata *conn, bool *done) Curl_sasl_init(&imapc->sasl, &saslimap); /* Initialise the pingpong layer */ + Curl_pp_setup(pp); Curl_pp_init(pp); /* Parse the URL options */ diff --git a/lib/pingpong.c b/lib/pingpong.c index 1cfd0286e..5a06674ad 100644 --- a/lib/pingpong.c +++ b/lib/pingpong.c @@ -146,7 +146,11 @@ void Curl_pp_init(struct pingpong *pp) pp->response = Curl_now(); /* start response time-out now! */ } - +/* setup for the coming transfer */ +void Curl_pp_setup(struct pingpong *pp) +{ + Curl_dyn_init(&pp->sendbuf, DYN_PINGPPONG_CMD); +} /*********************************************************************** * @@ -164,8 +168,6 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp, { ssize_t bytes_written = 0; size_t write_len; - char fmt_crlf[128]; - size_t fmtlen; char *s; CURLcode result; struct connectdata *conn = pp->conn; @@ -182,49 +184,42 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp, if(!conn) /* can't send without a connection! */ return CURLE_SEND_ERROR; - data = conn->data; - fmtlen = strlen(fmt); - DEBUGASSERT(fmtlen < sizeof(fmt_crlf)-3); - if(fmtlen >= sizeof(fmt_crlf)-3) - return CURLE_BAD_FUNCTION_ARGUMENT; - memcpy(fmt_crlf, fmt, fmtlen); - /* append a trailing CRLF+null to the format string */ - memcpy(&fmt_crlf[fmtlen], "\r\n", 3); - s = vaprintf(fmt_crlf, args); - if(!s) - return CURLE_OUT_OF_MEMORY; + Curl_dyn_reset(&pp->sendbuf); + result = Curl_dyn_vaddf(&pp->sendbuf, fmt, args); + if(result) + return result; - write_len = strlen(s); + /* append CRLF */ + result = Curl_dyn_addn(&pp->sendbuf, "\r\n", 2); + if(result) + return result; + write_len = Curl_dyn_len(&pp->sendbuf); + s = Curl_dyn_ptr(&pp->sendbuf); Curl_pp_init(pp); result = Curl_convert_to_network(data, s, write_len); /* Curl_convert_to_network calls failf if unsuccessful */ - if(result) { - free(s); + if(result) return result; - } #ifdef HAVE_GSSAPI conn->data_prot = PROT_CMD; #endif result = Curl_write(conn, conn->sock[FIRSTSOCKET], s, write_len, - &bytes_written); + &bytes_written); + if(result) + return result; #ifdef HAVE_GSSAPI data_sec = conn->data_prot; DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST); conn->data_prot = data_sec; #endif - if(result) { - free(s); - return result; - } - - if(conn->data->set.verbose) - Curl_debug(conn->data, CURLINFO_HEADER_OUT, s, (size_t)bytes_written); + if(data->set.verbose) + Curl_debug(data, CURLINFO_HEADER_OUT, s, (size_t)bytes_written); if(bytes_written != (ssize_t)write_len) { /* the whole chunk was not sent, keep it around and adjust sizes */ @@ -233,7 +228,6 @@ CURLcode Curl_pp_vsendf(struct pingpong *pp, pp->sendleft = write_len - bytes_written; } else { - free(s); pp->sendthis = NULL; pp->sendleft = pp->sendsize = 0; pp->response = Curl_now(); @@ -495,7 +489,6 @@ CURLcode Curl_pp_flushsend(struct pingpong *pp) pp->sendleft -= written; } else { - free(pp->sendthis); pp->sendthis = NULL; pp->sendleft = pp->sendsize = 0; pp->response = Curl_now(); @@ -505,15 +498,15 @@ CURLcode Curl_pp_flushsend(struct pingpong *pp) CURLcode Curl_pp_disconnect(struct pingpong *pp) { - free(pp->cache); - pp->cache = NULL; + Curl_dyn_free(&pp->sendbuf); + Curl_safefree(pp->cache); return CURLE_OK; } bool Curl_pp_moredata(struct pingpong *pp) { return (!pp->sendleft && pp->cache && pp->nread_resp < pp->cache_size) ? - TRUE : FALSE; + TRUE : FALSE; } #endif diff --git a/lib/pingpong.h b/lib/pingpong.h index e874799d4..855815afd 100644 --- a/lib/pingpong.h +++ b/lib/pingpong.h @@ -64,6 +64,7 @@ struct pingpong { milliseconds we await for a server response. */ struct connectdata *conn; /* points to the connectdata struct that this belongs to */ + struct dynbuf sendbuf; /* Function pointers the protocols MUST implement and provide for the pingpong layer to function */ @@ -86,6 +87,9 @@ CURLcode Curl_pp_statemach(struct pingpong *pp, bool block, /* initialize stuff to prepare for reading a fresh new response */ void Curl_pp_init(struct pingpong *pp); +/* setup for the transfer */ +void Curl_pp_setup(struct pingpong *pp); + /* Returns timeout in ms. 0 or negative number means the timeout has already triggered */ timediff_t Curl_pp_state_timeout(struct pingpong *pp, bool disconnecting); diff --git a/lib/pop3.c b/lib/pop3.c index be2748472..5a7354582 100644 --- a/lib/pop3.c +++ b/lib/pop3.c @@ -1093,6 +1093,7 @@ static CURLcode pop3_connect(struct connectdata *conn, bool *done) Curl_sasl_init(&pop3c->sasl, &saslpop3); /* Initialise the pingpong layer */ + Curl_pp_setup(pp); Curl_pp_init(pp); /* Parse the URL options */ diff --git a/lib/smtp.c b/lib/smtp.c index c2d632322..49743c036 100644 --- a/lib/smtp.c +++ b/lib/smtp.c @@ -1324,6 +1324,7 @@ static CURLcode smtp_connect(struct connectdata *conn, bool *done) Curl_sasl_init(&smtpc->sasl, &saslsmtp); /* Initialise the pingpong layer */ + Curl_pp_setup(pp); Curl_pp_init(pp); /* Parse the URL options */ |