mirror of
https://github.com/transmission/transmission
synced 2024-12-26 09:37:56 +00:00
Lift 1024 open files limit (switch to curl polling API) (#893)
* Switch to new libcurl's polling interface * Drop unused includes * Use NOFILE limit value defined by operating system * Avoid tight loops, ensure blocking for a small timeout When there are no file descriptors to wait for, select() would work the same as sleep(). But curl_multi_wait() returns immediately in this case, so we need to add explicit wait to avoid tight loops. Documentation: https://curl.haxx.se/libcurl/c/curl_multi_timeout.html Discussion: https://curl.haxx.se/mail/lib-2018-03/0074.html * Bump libcurl minimum version to 7.28.0
This commit is contained in:
parent
9da4abb003
commit
2da97b25fa
4 changed files with 20 additions and 83 deletions
|
@ -97,7 +97,7 @@ string(SUBSTRING "${TR_VCS_REVISION}" 0 10 TR_VCS_REVISION)
|
|||
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
set(CURL_MINIMUM 7.15.4)
|
||||
set(CURL_MINIMUM 7.28.0)
|
||||
set(EVENT2_MINIMUM 2.0.10)
|
||||
set(OPENSSL_MINIMUM 0.9.7)
|
||||
set(CYASSL_MINIMUM 3.0)
|
||||
|
|
|
@ -39,7 +39,7 @@ AM_CONDITIONAL(HAVE_REVISION_FILE, test -f REVISION)
|
|||
##
|
||||
##
|
||||
|
||||
CURL_MINIMUM=7.15.4
|
||||
CURL_MINIMUM=7.28.0
|
||||
AC_SUBST(CURL_MINIMUM)
|
||||
LIBEVENT_MINIMUM=2.0.10
|
||||
AC_SUBST(LIBEVENT_MINIMUM)
|
||||
|
|
|
@ -10,11 +10,6 @@
|
|||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/time.h> /* getrlimit */
|
||||
#include <sys/resource.h> /* getrlimit */
|
||||
#endif
|
||||
|
||||
#include "transmission.h"
|
||||
#include "error.h"
|
||||
#include "error-types.h"
|
||||
|
@ -389,27 +384,6 @@ static void ensureSessionFdInfoExists(tr_session* session)
|
|||
i = tr_new0(struct tr_fdInfo, 1);
|
||||
fileset_construct(&i->fileset, FILE_CACHE_SIZE);
|
||||
session->fdInfo = i;
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
/* set the open-file limit to the largest safe size wrt FD_SETSIZE */
|
||||
struct rlimit limit;
|
||||
|
||||
if (getrlimit(RLIMIT_NOFILE, &limit) == 0)
|
||||
{
|
||||
int const old_limit = (int)limit.rlim_cur;
|
||||
int const new_limit = MIN(limit.rlim_max, FD_SETSIZE);
|
||||
|
||||
if (new_limit != old_limit)
|
||||
{
|
||||
limit.rlim_cur = new_limit;
|
||||
setrlimit(RLIMIT_NOFILE, &limit);
|
||||
getrlimit(RLIMIT_NOFILE, &limit);
|
||||
tr_logAddInfo("Changed open file limit from %d to %d", old_limit, (int)limit.rlim_cur);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,9 +11,6 @@
|
|||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
@ -391,41 +388,6 @@ struct tr_web_task* tr_webRunWebseed(tr_torrent* tor, char const* url, char cons
|
|||
return tr_webRunImpl(tor->session, tr_torrentId(tor), url, range, NULL, done_func, done_func_user_data, buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Portability wrapper for select().
|
||||
*
|
||||
* http://msdn.microsoft.com/en-us/library/ms740141%28VS.85%29.aspx
|
||||
* On win32, any two of the parameters, readfds, writefds, or exceptfds,
|
||||
* can be given as null. At least one must be non-null, and any non-null
|
||||
* descriptor set must contain at least one handle to a socket.
|
||||
*/
|
||||
static void tr_select(int nfds, fd_set* r_fd_set, fd_set* w_fd_set, fd_set* c_fd_set, struct timeval* t)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
||||
(void)nfds;
|
||||
|
||||
if (r_fd_set->fd_count == 0 && w_fd_set->fd_count == 0 && c_fd_set->fd_count == 0)
|
||||
{
|
||||
long int const msec = t->tv_sec * 1000 + t->tv_usec / 1000;
|
||||
tr_wait_msec(msec);
|
||||
}
|
||||
else if (select(0, r_fd_set->fd_count != 0 ? r_fd_set : NULL, w_fd_set->fd_count != 0 ? w_fd_set : NULL,
|
||||
c_fd_set->fd_count != 0 ? c_fd_set : NULL, t) == -1)
|
||||
{
|
||||
char errstr[512];
|
||||
int const e = EVUTIL_SOCKET_ERROR();
|
||||
tr_net_strerror(errstr, sizeof(errstr), e);
|
||||
dbgmsg("Error: select (%d) %s", e, errstr);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
select(nfds, r_fd_set, w_fd_set, c_fd_set, t);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static void tr_webThreadFunc(void* vsession)
|
||||
{
|
||||
char* str;
|
||||
|
@ -434,6 +396,7 @@ static void tr_webThreadFunc(void* vsession)
|
|||
int taskCount = 0;
|
||||
struct tr_web_task* task;
|
||||
tr_session* session = vsession;
|
||||
uint32_t repeats = 0;
|
||||
|
||||
/* try to enable ssl for https support; but if that fails,
|
||||
* try a plain vanilla init */
|
||||
|
@ -473,6 +436,7 @@ static void tr_webThreadFunc(void* vsession)
|
|||
for (;;)
|
||||
{
|
||||
long msec;
|
||||
int numfds;
|
||||
int unused;
|
||||
CURLMsg* msg;
|
||||
CURLMcode mcode;
|
||||
|
@ -538,28 +502,27 @@ static void tr_webThreadFunc(void* vsession)
|
|||
|
||||
if (msec > 0)
|
||||
{
|
||||
int usec;
|
||||
int max_fd;
|
||||
struct timeval t;
|
||||
fd_set r_fd_set;
|
||||
fd_set w_fd_set;
|
||||
fd_set c_fd_set;
|
||||
|
||||
max_fd = 0;
|
||||
FD_ZERO(&r_fd_set);
|
||||
FD_ZERO(&w_fd_set);
|
||||
FD_ZERO(&c_fd_set);
|
||||
curl_multi_fdset(multi, &r_fd_set, &w_fd_set, &c_fd_set, &max_fd);
|
||||
|
||||
if (msec > THREADFUNC_MAX_SLEEP_MSEC)
|
||||
{
|
||||
msec = THREADFUNC_MAX_SLEEP_MSEC;
|
||||
}
|
||||
|
||||
usec = msec * 1000;
|
||||
t.tv_sec = usec / 1000000;
|
||||
t.tv_usec = usec % 1000000;
|
||||
tr_select(max_fd + 1, &r_fd_set, &w_fd_set, &c_fd_set, &t);
|
||||
curl_multi_wait(multi, NULL, 0, msec, &numfds);
|
||||
if (!numfds)
|
||||
{
|
||||
repeats++;
|
||||
if (repeats > 1)
|
||||
{
|
||||
/* curl_multi_wait() returns immediately if there are
|
||||
* no fds to wait for, so we need an explicit wait here
|
||||
* to emulate select() behavior */
|
||||
tr_wait_msec(MIN(msec, THREADFUNC_MAX_SLEEP_MSEC / 2));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
repeats = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* call curl_multi_perform() */
|
||||
|
|
Loading…
Reference in a new issue