mirror of
https://github.com/curl/curl.git
synced 2025-02-23 15:10:03 +08:00
tool_operate: reduce errorbuffer allocs
- parallel transfers: only alloc and keep errorbuffers in memory for actual "live" transfers and not for the ones in the pending queue - serial transfers: reuse the same fixed buffer for all transfers, not allocated at all. Closes #9394
This commit is contained in:
parent
c9061f242b
commit
7be53774c4
@ -347,6 +347,9 @@ static void AmigaSetComment(struct per_transfer *per,
|
|||||||
#define AmigaSetComment(x,y) Curl_nop_stmt
|
#define AmigaSetComment(x,y) Curl_nop_stmt
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* When doing serial transfers, we use a single fixed error area */
|
||||||
|
static char global_errorbuffer[CURL_ERROR_SIZE];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call this after a transfer has completed.
|
* Call this after a transfer has completed.
|
||||||
*/
|
*/
|
||||||
@ -378,9 +381,9 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if(!config->synthetic_error && result && global->showerror) {
|
if(!config->synthetic_error && result && global->showerror) {
|
||||||
|
const char *msg = per->errorbuffer;
|
||||||
fprintf(global->errors, "curl: (%d) %s\n", result,
|
fprintf(global->errors, "curl: (%d) %s\n", result,
|
||||||
(per->errorbuffer[0]) ? per->errorbuffer :
|
(msg && msg[0]) ? msg : curl_easy_strerror(result));
|
||||||
curl_easy_strerror(result));
|
|
||||||
if(result == CURLE_PEER_FAILED_VERIFICATION)
|
if(result == CURLE_PEER_FAILED_VERIFICATION)
|
||||||
fputs(CURL_CA_CERT_ERRORMSG, global->errors);
|
fputs(CURL_CA_CERT_ERRORMSG, global->errors);
|
||||||
}
|
}
|
||||||
@ -656,6 +659,8 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
|
|||||||
free(per->this_url);
|
free(per->this_url);
|
||||||
free(per->outfile);
|
free(per->outfile);
|
||||||
free(per->uploadfile);
|
free(per->uploadfile);
|
||||||
|
if(global->parallel)
|
||||||
|
free(per->errorbuffer);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -706,7 +711,6 @@ static long url_proto(char *url)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* create the next (singular) transfer */
|
/* create the next (singular) transfer */
|
||||||
|
|
||||||
static CURLcode single_transfer(struct GlobalConfig *global,
|
static CURLcode single_transfer(struct GlobalConfig *global,
|
||||||
struct OperationConfig *config,
|
struct OperationConfig *config,
|
||||||
CURLSH *share,
|
CURLSH *share,
|
||||||
@ -1364,7 +1368,10 @@ static CURLcode single_transfer(struct GlobalConfig *global,
|
|||||||
my_setopt_str(curl, CURLOPT_LOGIN_OPTIONS, config->login_options);
|
my_setopt_str(curl, CURLOPT_LOGIN_OPTIONS, config->login_options);
|
||||||
my_setopt_str(curl, CURLOPT_USERPWD, config->userpwd);
|
my_setopt_str(curl, CURLOPT_USERPWD, config->userpwd);
|
||||||
my_setopt_str(curl, CURLOPT_RANGE, config->range);
|
my_setopt_str(curl, CURLOPT_RANGE, config->range);
|
||||||
my_setopt(curl, CURLOPT_ERRORBUFFER, per->errorbuffer);
|
if(!global->parallel) {
|
||||||
|
per->errorbuffer = global_errorbuffer;
|
||||||
|
my_setopt(curl, CURLOPT_ERRORBUFFER, global_errorbuffer);
|
||||||
|
}
|
||||||
my_setopt(curl, CURLOPT_TIMEOUT_MS, (long)(config->timeout * 1000));
|
my_setopt(curl, CURLOPT_TIMEOUT_MS, (long)(config->timeout * 1000));
|
||||||
|
|
||||||
switch(config->httpreq) {
|
switch(config->httpreq) {
|
||||||
@ -2196,6 +2203,7 @@ static CURLcode add_parallel_transfers(struct GlobalConfig *global,
|
|||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
CURLMcode mcode;
|
CURLMcode mcode;
|
||||||
bool sleeping = FALSE;
|
bool sleeping = FALSE;
|
||||||
|
char *errorbuf;
|
||||||
*addedp = FALSE;
|
*addedp = FALSE;
|
||||||
*morep = FALSE;
|
*morep = FALSE;
|
||||||
if(all_pers < (global->parallel_max*2)) {
|
if(all_pers < (global->parallel_max*2)) {
|
||||||
@ -2219,6 +2227,13 @@ static CURLcode add_parallel_transfers(struct GlobalConfig *global,
|
|||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
errorbuf = per->errorbuffer;
|
||||||
|
if(!errorbuf) {
|
||||||
|
errorbuf = malloc(CURL_ERROR_SIZE);
|
||||||
|
if(!errorbuf)
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
/* parallel connect means that we don't set PIPEWAIT since pipewait
|
/* parallel connect means that we don't set PIPEWAIT since pipewait
|
||||||
will make libcurl prefer multiplexing */
|
will make libcurl prefer multiplexing */
|
||||||
(void)curl_easy_setopt(per->curl, CURLOPT_PIPEWAIT,
|
(void)curl_easy_setopt(per->curl, CURLOPT_PIPEWAIT,
|
||||||
@ -2227,14 +2242,20 @@ static CURLcode add_parallel_transfers(struct GlobalConfig *global,
|
|||||||
(void)curl_easy_setopt(per->curl, CURLOPT_XFERINFOFUNCTION, xferinfo_cb);
|
(void)curl_easy_setopt(per->curl, CURLOPT_XFERINFOFUNCTION, xferinfo_cb);
|
||||||
(void)curl_easy_setopt(per->curl, CURLOPT_XFERINFODATA, per);
|
(void)curl_easy_setopt(per->curl, CURLOPT_XFERINFODATA, per);
|
||||||
(void)curl_easy_setopt(per->curl, CURLOPT_NOPROGRESS, 0L);
|
(void)curl_easy_setopt(per->curl, CURLOPT_NOPROGRESS, 0L);
|
||||||
|
(void)curl_easy_setopt(per->curl, CURLOPT_ERRORBUFFER, errorbuf);
|
||||||
|
|
||||||
mcode = curl_multi_add_handle(multi, per->curl);
|
mcode = curl_multi_add_handle(multi, per->curl);
|
||||||
if(mcode)
|
if(mcode) {
|
||||||
|
free(errorbuf);
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
result = create_transfer(global, share, &getadded);
|
result = create_transfer(global, share, &getadded);
|
||||||
if(result)
|
if(result) {
|
||||||
|
free(errorbuf);
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
|
per->errorbuffer = errorbuf;
|
||||||
per->added = TRUE;
|
per->added = TRUE;
|
||||||
all_added++;
|
all_added++;
|
||||||
*addedp = TRUE;
|
*addedp = TRUE;
|
||||||
|
@ -52,7 +52,6 @@ struct per_transfer {
|
|||||||
struct HdrCbData hdrcbdata;
|
struct HdrCbData hdrcbdata;
|
||||||
long num_headers;
|
long num_headers;
|
||||||
bool was_last_header_empty;
|
bool was_last_header_empty;
|
||||||
char errorbuffer[CURL_ERROR_SIZE];
|
|
||||||
|
|
||||||
bool added; /* set TRUE when added to the multi handle */
|
bool added; /* set TRUE when added to the multi handle */
|
||||||
time_t startat; /* when doing parallel transfers, this is a retry transfer
|
time_t startat; /* when doing parallel transfers, this is a retry transfer
|
||||||
@ -72,6 +71,8 @@ struct per_transfer {
|
|||||||
|
|
||||||
/* NULL or malloced */
|
/* NULL or malloced */
|
||||||
char *uploadfile;
|
char *uploadfile;
|
||||||
|
char *errorbuffer; /* alloced and assigned while this is used for a
|
||||||
|
transfer */
|
||||||
};
|
};
|
||||||
|
|
||||||
CURLcode operate(struct GlobalConfig *config, int argc, argv_item_t argv[]);
|
CURLcode operate(struct GlobalConfig *config, int argc, argv_item_t argv[]);
|
||||||
|
@ -195,8 +195,8 @@ static int writeString(FILE *stream, const struct writeoutvar *wovar,
|
|||||||
switch(wovar->id) {
|
switch(wovar->id) {
|
||||||
case VAR_ERRORMSG:
|
case VAR_ERRORMSG:
|
||||||
if(per_result) {
|
if(per_result) {
|
||||||
strinfo = per->errorbuffer[0] ? per->errorbuffer :
|
strinfo = (per->errorbuffer && per->errorbuffer[0]) ?
|
||||||
curl_easy_strerror(per_result);
|
per->errorbuffer : curl_easy_strerror(per_result);
|
||||||
valid = true;
|
valid = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user