mirror of
https://github.com/curl/curl.git
synced 2025-02-17 14:59:45 +08:00
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
This commit is contained in:
parent
f74afa40f8
commit
675eeb1c94
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user