mirror of
https://github.com/curl/curl.git
synced 2026-08-25 04:23:36 +03:00
curl: support parallel transfers
This is done by making sure each individual transfer is first added to a linked list as then they can be performed serially, or at will, in parallel. Closes #3804
This commit is contained in:
parent
14a385b3ae
commit
b889408500
34 changed files with 1517 additions and 800 deletions
|
|
@ -40,6 +40,7 @@
|
|||
#include "tool_msgs.h"
|
||||
#include "tool_paramhlp.h"
|
||||
#include "tool_parsecfg.h"
|
||||
#include "tool_main.h"
|
||||
|
||||
#include "memdebug.h" /* keep this as LAST include */
|
||||
|
||||
|
|
@ -316,6 +317,8 @@ static const struct LongShort aliases[]= {
|
|||
{"Y", "speed-limit", ARG_STRING},
|
||||
{"y", "speed-time", ARG_STRING},
|
||||
{"z", "time-cond", ARG_STRING},
|
||||
{"Z", "parallel", ARG_BOOL},
|
||||
{"Zb", "parallel-max", ARG_STRING},
|
||||
{"#", "progress-bar", ARG_BOOL},
|
||||
{":", "next", ARG_NONE},
|
||||
};
|
||||
|
|
@ -1104,7 +1107,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
|
|||
break;
|
||||
case 'L': /* --test-event */
|
||||
#ifdef CURLDEBUG
|
||||
config->test_event_based = toggle;
|
||||
global->test_event_based = toggle;
|
||||
#else
|
||||
warnf(global, "--test-event is ignored unless a debug build!\n");
|
||||
#endif
|
||||
|
|
@ -1356,7 +1359,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
|
|||
size = 0;
|
||||
}
|
||||
else {
|
||||
char *enc = curl_easy_escape(config->easy, postdata, (int)size);
|
||||
char *enc = curl_easy_escape(NULL, postdata, (int)size);
|
||||
Curl_safefree(postdata); /* no matter if it worked or not */
|
||||
if(enc) {
|
||||
/* now make a string with the name from above and append the
|
||||
|
|
@ -2127,6 +2130,21 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
|
|||
if(!config->low_speed_time)
|
||||
config->low_speed_time = 30;
|
||||
break;
|
||||
case 'Z':
|
||||
switch(subletter) {
|
||||
case '\0': /* --parallel */
|
||||
global->parallel = toggle;
|
||||
break;
|
||||
case 'b': /* --parallel-max */
|
||||
err = str2unum(&global->parallel_max, nextarg);
|
||||
if(err)
|
||||
return err;
|
||||
if((global->parallel_max > MAX_PARALLEL) ||
|
||||
(global->parallel_max < 1))
|
||||
global->parallel_max = PARALLEL_DEFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'z': /* time condition coming up */
|
||||
switch(*nextarg) {
|
||||
case '+':
|
||||
|
|
@ -2176,14 +2194,14 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
|
|||
return PARAM_OK;
|
||||
}
|
||||
|
||||
ParameterError parse_args(struct GlobalConfig *config, int argc,
|
||||
ParameterError parse_args(struct GlobalConfig *global, int argc,
|
||||
argv_item_t argv[])
|
||||
{
|
||||
int i;
|
||||
bool stillflags;
|
||||
char *orig_opt = NULL;
|
||||
ParameterError result = PARAM_OK;
|
||||
struct OperationConfig *operation = config->first;
|
||||
struct OperationConfig *config = global->first;
|
||||
|
||||
for(i = 1, stillflags = TRUE; i < argc && !result; i++) {
|
||||
orig_opt = argv[i];
|
||||
|
|
@ -2199,31 +2217,28 @@ ParameterError parse_args(struct GlobalConfig *config, int argc,
|
|||
else {
|
||||
char *nextarg = (i < (argc - 1)) ? argv[i + 1] : NULL;
|
||||
|
||||
result = getparameter(flag, nextarg, &passarg, config, operation);
|
||||
result = getparameter(flag, nextarg, &passarg, global, config);
|
||||
if(result == PARAM_NEXT_OPERATION) {
|
||||
/* Reset result as PARAM_NEXT_OPERATION is only used here and not
|
||||
returned from this function */
|
||||
result = PARAM_OK;
|
||||
|
||||
if(operation->url_list && operation->url_list->url) {
|
||||
if(config->url_list && config->url_list->url) {
|
||||
/* Allocate the next config */
|
||||
operation->next = malloc(sizeof(struct OperationConfig));
|
||||
if(operation->next) {
|
||||
config->next = malloc(sizeof(struct OperationConfig));
|
||||
if(config->next) {
|
||||
/* Initialise the newly created config */
|
||||
config_init(operation->next);
|
||||
|
||||
/* Copy the easy handle */
|
||||
operation->next->easy = config->easy;
|
||||
config_init(config->next);
|
||||
|
||||
/* Set the global config pointer */
|
||||
operation->next->global = config;
|
||||
config->next->global = global;
|
||||
|
||||
/* Update the last operation pointer */
|
||||
config->last = operation->next;
|
||||
/* Update the last config pointer */
|
||||
global->last = config->next;
|
||||
|
||||
/* Move onto the new config */
|
||||
operation->next->prev = operation;
|
||||
operation = operation->next;
|
||||
config->next->prev = config;
|
||||
config = config->next;
|
||||
}
|
||||
else
|
||||
result = PARAM_NO_MEM;
|
||||
|
|
@ -2237,8 +2252,8 @@ ParameterError parse_args(struct GlobalConfig *config, int argc,
|
|||
bool used;
|
||||
|
||||
/* Just add the URL please */
|
||||
result = getparameter((char *)"--url", argv[i], &used, config,
|
||||
operation);
|
||||
result = getparameter((char *)"--url", argv[i], &used, global,
|
||||
config);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2249,9 +2264,9 @@ ParameterError parse_args(struct GlobalConfig *config, int argc,
|
|||
const char *reason = param2text(result);
|
||||
|
||||
if(orig_opt && strcmp(":", orig_opt))
|
||||
helpf(config->errors, "option %s: %s\n", orig_opt, reason);
|
||||
helpf(global->errors, "option %s: %s\n", orig_opt, reason);
|
||||
else
|
||||
helpf(config->errors, "%s\n", reason);
|
||||
helpf(global->errors, "%s\n", reason);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue