Use modern libcurl poll/wait methods

This commit is contained in:
sfan5 2024-01-13 19:14:04 +01:00
parent ee727eb65e
commit 56943bef48
2 changed files with 32 additions and 49 deletions

@ -47,7 +47,7 @@ option(ENABLE_CURL "Enable cURL support for fetching media" TRUE)
set(USE_CURL FALSE)
if(ENABLE_CURL)
find_package(CURL)
find_package(CURL 7.28.0)
if (CURL_FOUND)
message(STATUS "cURL support enabled.")
set(USE_CURL TRUE)

@ -25,7 +25,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <unordered_map>
#include <cerrno>
#include <mutex>
#include "network/socket.h" // for select()
#include "threading/event.h"
#include "config.h"
#include "exceptions.h"
@ -436,6 +435,12 @@ HTTPFetchOngoing::~HTTPFetchOngoing()
}
#if LIBCURL_VERSION_NUM >= 0x074200
#define HAVE_CURL_MULTI_POLL
#else
#undef HAVE_CURL_MULTI_POLL
#endif
class CurlFetchThread : public Thread
{
protected:
@ -595,63 +600,41 @@ protected:
// Wait until some IO happens, or timeout elapses
void waitForIO(long timeout)
{
fd_set read_fd_set;
fd_set write_fd_set;
fd_set exc_fd_set;
int max_fd;
long select_timeout = -1;
struct timeval select_tv;
CURLMcode mres;
FD_ZERO(&read_fd_set);
FD_ZERO(&write_fd_set);
FD_ZERO(&exc_fd_set);
#ifdef HAVE_CURL_MULTI_POLL
mres = curl_multi_poll(m_multi, nullptr, 0, timeout, nullptr);
mres = curl_multi_fdset(m_multi, &read_fd_set,
&write_fd_set, &exc_fd_set, &max_fd);
if (mres != CURLM_OK) {
errorstream<<"curl_multi_fdset"
<<" returned error code "<<mres
<<std::endl;
select_timeout = 0;
errorstream << "curl_multi_poll returned error code "
<< mres << std::endl;
}
mres = curl_multi_timeout(m_multi, &select_timeout);
if (mres != CURLM_OK) {
errorstream<<"curl_multi_timeout"
<<" returned error code "<<mres
<<std::endl;
select_timeout = 0;
}
// Limit timeout so new requests get through
if (select_timeout < 0 || select_timeout > timeout)
select_timeout = timeout;
if (select_timeout > 0) {
// in Winsock it is forbidden to pass three empty
// fd_sets to select(), so in that case use sleep_ms
if (max_fd != -1) {
select_tv.tv_sec = select_timeout / 1000;
select_tv.tv_usec = (select_timeout % 1000) * 1000;
int retval = select(max_fd + 1, &read_fd_set,
&write_fd_set, &exc_fd_set,
&select_tv);
if (retval == -1) {
#ifdef _WIN32
errorstream<<"select returned error code "
<<WSAGetLastError()<<std::endl;
#else
errorstream<<"select returned error code "
<<errno<<std::endl;
// If there's nothing to do curl_multi_wait() will immediately return
// so we have to emulate the sleeping.
fd_set dummy;
int max_fd;
mres = curl_multi_fdset(m_multi, &dummy, &dummy, &dummy, &max_fd);
if (mres != CURLM_OK) {
errorstream << "curl_multi_fdset returned error code "
<< mres << std::endl;
max_fd = -1;
}
if (max_fd == -1) { // curl has nothing to wait for
if (timeout > 0)
sleep_ms(timeout);
} else {
mres = curl_multi_wait(m_multi, nullptr, 0, timeout, nullptr);
if (mres != CURLM_OK) {
errorstream << "curl_multi_wait returned error code "
<< mres << std::endl;
}
}
#endif
}
}
else {
sleep_ms(select_timeout);
}
}
}
void *run()
{