rewrote curl_multi_perform_once()
This commit is contained in:
parent
2cee4b33a7
commit
2a2ac2dce2
10
src/link.c
10
src/link.c
|
@ -197,9 +197,8 @@ static void LinkTable_fill(LinkTable *linktbl)
|
||||||
Link_get_stat(this_link);
|
Link_get_stat(this_link);
|
||||||
}
|
}
|
||||||
/* Block until the LinkTable is filled up */
|
/* Block until the LinkTable is filled up */
|
||||||
while (curl_multi_perform_once()) {
|
while (curl_multi_perform_once())
|
||||||
usleep(1000);
|
;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -217,9 +216,8 @@ static void LinkTable_gap_fill(LinkTable *linktbl)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Block until the gaps are filled */
|
/* Block until the gaps are filled */
|
||||||
while (curl_multi_perform_once()) {
|
while (curl_multi_perform_once())
|
||||||
usleep(1000);
|
;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
110
src/network.c
110
src/network.c
|
@ -121,19 +121,17 @@ static void curl_process_msgs(CURLMsg *curl_msg, int n_running_curl, int n_mesgs
|
||||||
slept = 0;
|
slept = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curl_msg->data.result) {
|
if (!curl_msg->data.result) {
|
||||||
fprintf(stderr, "curl_process_msgs(): %d - %s <%s>\n",
|
|
||||||
curl_msg->data.result,
|
|
||||||
curl_easy_strerror(curl_msg->data.result),
|
|
||||||
url);
|
|
||||||
usleep(1000);
|
|
||||||
} else {
|
|
||||||
/* Transfer successful, query the file size */
|
/* Transfer successful, query the file size */
|
||||||
if (transfer->type == FILESTAT) {
|
if (transfer->type == FILESTAT) {
|
||||||
Link_set_stat(transfer->link, curl);
|
Link_set_stat(transfer->link, curl);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "curl_process_msgs(): %d - %s <%s>\n",
|
||||||
|
curl_msg->data.result,
|
||||||
|
curl_easy_strerror(curl_msg->data.result),
|
||||||
|
url);
|
||||||
}
|
}
|
||||||
|
|
||||||
curl_multi_remove_handle(curl_multi, curl);
|
curl_multi_remove_handle(curl_multi, curl);
|
||||||
/* clean up the handle, if we are querying the file size */
|
/* clean up the handle, if we are querying the file size */
|
||||||
if (transfer->type == FILESTAT) {
|
if (transfer->type == FILESTAT) {
|
||||||
|
@ -146,66 +144,61 @@ static void curl_process_msgs(CURLMsg *curl_msg, int n_running_curl, int n_mesgs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \details effectively based on
|
||||||
|
* https://curl.haxx.se/libcurl/c/multi-double.html
|
||||||
|
*/
|
||||||
int curl_multi_perform_once()
|
int curl_multi_perform_once()
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&transfer_lock);
|
pthread_mutex_lock(&transfer_lock);
|
||||||
/* Get curl multi interface to perform pending tasks */
|
/* Get curl multi interface to perform pending tasks */
|
||||||
int n_running_curl;
|
int n_running_curl;
|
||||||
curl_multi_perform(curl_multi, &n_running_curl);
|
CURLMcode mc = curl_multi_perform(curl_multi, &n_running_curl);
|
||||||
|
if(mc > 0) {
|
||||||
long timeout;
|
fprintf(stderr, "curl_multi_perform(): %s\n", curl_multi_strerror(mc));
|
||||||
if(curl_multi_timeout(curl_multi, &timeout)) {
|
|
||||||
fprintf(stderr, "curl_multi_perform_once(): curl_multi_timeout\n");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(timeout == -1) {
|
fd_set fdread;
|
||||||
/*
|
fd_set fdwrite;
|
||||||
* https://curl.haxx.se/libcurl/c/curl_multi_timeout.html
|
fd_set fdexcep;
|
||||||
* If it returns -1, there's no timeout at all set.
|
int maxfd = -1;
|
||||||
*/
|
|
||||||
timeout = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if any of the tasks encountered error */
|
long curl_timeo = -1;
|
||||||
int max_fd;
|
|
||||||
fd_set read_fd_set;
|
|
||||||
fd_set write_fd_set;
|
|
||||||
fd_set exc_fd_set;
|
|
||||||
FD_ZERO(&read_fd_set);
|
|
||||||
FD_ZERO(&write_fd_set);
|
|
||||||
FD_ZERO(&exc_fd_set);
|
|
||||||
CURLMcode res;
|
|
||||||
res = curl_multi_fdset(curl_multi, &read_fd_set, &write_fd_set, &exc_fd_set,
|
|
||||||
&max_fd);
|
|
||||||
if(res > 0) {
|
|
||||||
fprintf(stderr, "curl_multi_perform_once(): curl_multi_fdset: %d, %s\n",
|
|
||||||
res, curl_multi_strerror(res));
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(max_fd == -1) {
|
FD_ZERO(&fdread);
|
||||||
/*
|
FD_ZERO(&fdwrite);
|
||||||
* https://curl.haxx.se/libcurl/c/curl_multi_fdset.html
|
FD_ZERO(&fdexcep);
|
||||||
* The above web page suggests sleeping for 100ms, unless
|
|
||||||
* curl_multi_timeout() suggests something shorter.
|
/* set a default timeout for select() */
|
||||||
*/
|
struct timeval timeout;
|
||||||
if (timeout > 100) {
|
timeout.tv_sec = 1;
|
||||||
timeout = 100;
|
timeout.tv_usec = 0;
|
||||||
|
|
||||||
|
curl_multi_timeout(curl_multi, &curl_timeo);
|
||||||
|
/* We effectively cap timeout to 1 sec */
|
||||||
|
if (curl_timeo >= 0) {
|
||||||
|
timeout.tv_sec = curl_timeo / 1000;
|
||||||
|
if (timeout.tv_sec > 1) {
|
||||||
|
timeout.tv_sec = 1;
|
||||||
|
} else {
|
||||||
|
timeout.tv_usec = (curl_timeo % 1000) * 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* timeout is in miliseconds */
|
/* get file descriptors from the transfers */
|
||||||
struct timeval t;
|
mc = curl_multi_fdset(curl_multi, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||||
t.tv_sec = timeout/1000; /* seconds */
|
|
||||||
t.tv_usec = (timeout%1000)*1000; /* microseconds */
|
|
||||||
|
|
||||||
if(select(max_fd + 1, &read_fd_set, &write_fd_set,
|
if (mc > 0) {
|
||||||
&exc_fd_set, &t) < 0) {
|
fprintf(stderr, "curl_multi_fdset(): %s.\n", curl_multi_strerror(mc));
|
||||||
fprintf(stderr,
|
}
|
||||||
"curl_multi_perform_once(): select(%i,,,,%li): %i: %s\n",
|
|
||||||
max_fd + 1, timeout, errno, strerror(errno));
|
if (maxfd == -1) {
|
||||||
exit(EXIT_FAILURE);
|
usleep(100*1000);
|
||||||
|
} else {
|
||||||
|
if (select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout) < 0) {
|
||||||
|
fprintf(stderr, "curl_multi_perform_once(): select(): %s.\n",
|
||||||
|
strerror(errno));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process the message queue */
|
/* Process the message queue */
|
||||||
|
@ -322,18 +315,15 @@ void transfer_blocking(CURL *curl)
|
||||||
|
|
||||||
while (transfer.transferring) {
|
while (transfer.transferring) {
|
||||||
curl_multi_perform_once();
|
curl_multi_perform_once();
|
||||||
usleep(1000);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void transfer_nonblocking(CURL *curl)
|
void transfer_nonblocking(CURL *curl)
|
||||||
{
|
{
|
||||||
CURLMcode res = curl_multi_add_handle(curl_multi, curl);
|
CURLMcode res = curl_multi_add_handle(curl_multi, curl);
|
||||||
|
|
||||||
if(res > 0) {
|
if(res > 0) {
|
||||||
fprintf(stderr, "blocking_multi_transfer(): %d, %s\n",
|
fprintf(stderr, "blocking_multi_transfer(): %s\n",
|
||||||
res, curl_multi_strerror(res));
|
curl_multi_strerror(res));
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue