Add config option to specify amount of parallel download streams

It includes pacman.conf new 'ParallelDownloads' option that
specifies how many concurrent downloads cURL starts in parallel.

Add alpm_option_set_parallel_downloads() ALPM function that
allows to set this config option programmatically.

Signed-off-by: Anatol Pomozov <anatol.pomozov@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
This commit is contained in:
Anatol Pomozov 2020-03-08 13:33:32 -07:00 committed by Allan McRae
parent cffda331ad
commit fe8e13341b
7 changed files with 89 additions and 0 deletions

View file

@ -209,6 +209,11 @@ Options
Disable defaults for low speed limit and timeout on downloads. Use this Disable defaults for low speed limit and timeout on downloads. Use this
if you have issues downloading files with proxy and/or security gateway. if you have issues downloading files with proxy and/or security gateway.
*ParallelDownloads*::
Specifies number of concurrent download streams. The value needs to be a
positive integer. If this config option is not set then only one download
stream is used (i.e. downloads happen sequentially).
Repository Sections Repository Sections
------------------- -------------------

View file

@ -35,6 +35,7 @@ Architecture = auto
#TotalDownload #TotalDownload
CheckSpace CheckSpace
#VerbosePkgLists #VerbosePkgLists
ParallelDownloads = 5
# PGP signature checking # PGP signature checking
#SigLevel = Optional #SigLevel = Optional

View file

@ -903,6 +903,15 @@ int alpm_option_set_remote_file_siglevel(alpm_handle_t *handle, int level);
int alpm_option_set_disable_dl_timeout(alpm_handle_t *handle, unsigned short disable_dl_timeout); int alpm_option_set_disable_dl_timeout(alpm_handle_t *handle, unsigned short disable_dl_timeout);
/** Sets number of parallel streams to download database and package files.
* If the function is not called then the default value of '1' stream
* (i.e. sequential download) is used.
* @param handle the context handle
* @param num_streams number of parallel download streams
* @return 0 on success, -1 on error
*/
int alpm_option_set_parallel_downloads(alpm_handle_t *handle, unsigned int num_streams);
/** @} */ /** @} */
/** @addtogroup alpm_api_databases Database Functions /** @addtogroup alpm_api_databases Database Functions

View file

@ -856,3 +856,18 @@ int SYMEXPORT alpm_option_set_disable_dl_timeout(alpm_handle_t *handle,
#endif #endif
return 0; return 0;
} }
int SYMEXPORT alpm_option_set_parallel_downloads(alpm_handle_t *handle,
unsigned int num_streams)
{
CHECK_HANDLE(handle, return -1);
#ifdef HAVE_LIBCURL
if(num_streams < 1) {
return -1;
}
handle->parallel_downloads = num_streams;
#else
(void)num_streams; /* silence unused variable warnings */
#endif
return 0;
}

View file

@ -61,6 +61,7 @@ struct __alpm_handle_t {
/* libcurl handle */ /* libcurl handle */
CURL *curl; /* reusable curl_easy handle */ CURL *curl; /* reusable curl_easy handle */
unsigned short disable_dl_timeout; unsigned short disable_dl_timeout;
unsigned int parallel_downloads; /* number of download streams */
#endif #endif
#ifdef HAVE_LIBGPGME #ifdef HAVE_LIBGPGME

View file

@ -114,6 +114,8 @@ config_t *config_new(void)
newconfig->remotefilesiglevel = ALPM_SIG_USE_DEFAULT; newconfig->remotefilesiglevel = ALPM_SIG_USE_DEFAULT;
} }
/* by default use 1 download stream */
newconfig->parallel_downloads = 1;
newconfig->colstr.colon = ":: "; newconfig->colstr.colon = ":: ";
newconfig->colstr.title = ""; newconfig->colstr.title = "";
newconfig->colstr.repo = ""; newconfig->colstr.repo = "";
@ -404,6 +406,32 @@ int config_set_arch(const char *arch)
return 0; return 0;
} }
/**
* Parse a string into long number. The input string has to be non-empty
* and represent a number that fits long type.
* @param value the string to parse
* @param result pointer to long where the final result will be stored.
* This result is modified if the input string parsed successfully.
* @return 0 in case if value parsed successfully, 1 otherwise.
*/
static int parse_number(char *value, long *result) {
char *endptr;
long val;
int invalid;
errno = 0; /* To distinguish success/failure after call */
val = strtol(value, &endptr, 10);
invalid = (errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
|| (*endptr != '\0')
|| (endptr == value);
if(!invalid) {
*result = val;
}
return invalid;
}
/** /**
* Parse a signature verification level line. * Parse a signature verification level line.
* @param values the list of parsed option values * @param values the list of parsed option values
@ -683,6 +711,33 @@ static int _parse_options(const char *key, char *value,
return 1; return 1;
} }
FREELIST(values); FREELIST(values);
} else if(strcmp(key, "ParallelDownloads") == 0) {
long number;
int err;
err = parse_number(value, &number);
if(err) {
pm_printf(ALPM_LOG_WARNING,
_("config file %s, line %d: invalid value for '%s' : '%s'\n"),
file, linenum, "ParallelDownloads", value);
return 1;
}
if(number < 1) {
pm_printf(ALPM_LOG_WARNING,
_("config file %s, line %d: value for '%s' has to be positive : '%s'\n"),
file, linenum, "ParallelDownloads", value);
return 1;
}
if(number > INT_MAX) {
pm_printf(ALPM_LOG_WARNING,
_("config file %s, line %d: value for '%s' is too large : '%s'\n"),
file, linenum, "ParallelDownloads", value);
return 1;
}
config->parallel_downloads = number;
} else { } else {
pm_printf(ALPM_LOG_WARNING, pm_printf(ALPM_LOG_WARNING,
_("config file %s, line %d: directive '%s' in section '%s' not recognized.\n"), _("config file %s, line %d: directive '%s' in section '%s' not recognized.\n"),
@ -851,6 +906,7 @@ static int setup_libalpm(void)
alpm_option_set_noextracts(handle, config->noextract); alpm_option_set_noextracts(handle, config->noextract);
alpm_option_set_disable_dl_timeout(handle, config->disable_dl_timeout); alpm_option_set_disable_dl_timeout(handle, config->disable_dl_timeout);
alpm_option_set_parallel_downloads(handle, config->parallel_downloads);
for(i = config->assumeinstalled; i; i = i->next) { for(i = config->assumeinstalled; i; i = i->next) {
char *entry = i->data; char *entry = i->data;

View file

@ -116,6 +116,8 @@ typedef struct __config_t {
/* When downloading, display the amount downloaded, rate, ETA, and percent /* When downloading, display the amount downloaded, rate, ETA, and percent
* downloaded of the total download list */ * downloaded of the total download list */
unsigned short totaldownload; unsigned short totaldownload;
/* number of parallel download streams */
unsigned int parallel_downloads;
/* select -Sc behavior */ /* select -Sc behavior */
unsigned short cleanmethod; unsigned short cleanmethod;
alpm_list_t *holdpkg; alpm_list_t *holdpkg;