summaryrefslogtreecommitdiffstats
path: root/contrib/libs/curl/lib/multi.c
diff options
context:
space:
mode:
authorrobot-contrib <[email protected]>2022-09-21 14:47:18 +0300
committerrobot-contrib <[email protected]>2022-09-21 14:47:18 +0300
commitf904cb56d9b1584ffcc28e53dec706fe1dc15d6f (patch)
treefe2764cc64c10b674559b367741a172323b52bcd /contrib/libs/curl/lib/multi.c
parent37a16126ac62d0af47b33d50c786b9adc009f6f3 (diff)
Update contrib/libs/curl to 7.85.0
Diffstat (limited to 'contrib/libs/curl/lib/multi.c')
-rw-r--r--contrib/libs/curl/lib/multi.c80
1 files changed, 62 insertions, 18 deletions
diff --git a/contrib/libs/curl/lib/multi.c b/contrib/libs/curl/lib/multi.c
index dc1c1267468..f78ff72c42e 100644
--- a/contrib/libs/curl/lib/multi.c
+++ b/contrib/libs/curl/lib/multi.c
@@ -55,6 +55,22 @@
#include "curl_memory.h"
#include "memdebug.h"
+#ifdef __APPLE__
+
+#define wakeup_write write
+#define wakeup_read read
+#define wakeup_close close
+#define wakeup_create pipe
+
+#else /* __APPLE__ */
+
+#define wakeup_write swrite
+#define wakeup_read sread
+#define wakeup_close sclose
+#define wakeup_create(p) Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, p)
+
+#endif /* __APPLE__ */
+
/*
CURL_SOCKET_HASH_TABLE_SIZE should be a prime number. Increasing it from 97
to 911 takes on a 32-bit machine 4 x 804 = 3211 more bytes. Still, every
@@ -68,6 +84,10 @@
#define CURL_CONNECTION_HASH_SIZE 97
#endif
+#ifndef CURL_DNS_HASH_SIZE
+#define CURL_DNS_HASH_SIZE 71
+#endif
+
#define CURL_MULTI_HANDLE 0x000bab1e
#define GOOD_MULTI_HANDLE(x) \
@@ -372,7 +392,8 @@ static CURLMcode multi_addmsg(struct Curl_multi *multi,
}
struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
- int chashsize) /* connection hash */
+ int chashsize, /* connection hash */
+ int dnssize) /* dns hash */
{
struct Curl_multi *multi = calloc(1, sizeof(struct Curl_multi));
@@ -381,7 +402,7 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
multi->magic = CURL_MULTI_HANDLE;
- Curl_init_dnscache(&multi->hostcache);
+ Curl_init_dnscache(&multi->hostcache, dnssize);
sh_init(&multi->sockhash, hashsize);
@@ -404,14 +425,14 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
goto error;
#else
#ifdef ENABLE_WAKEUP
- if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, multi->wakeup_pair) < 0) {
+ if(wakeup_create(multi->wakeup_pair) < 0) {
multi->wakeup_pair[0] = CURL_SOCKET_BAD;
multi->wakeup_pair[1] = CURL_SOCKET_BAD;
}
else if(curlx_nonblock(multi->wakeup_pair[0], TRUE) < 0 ||
curlx_nonblock(multi->wakeup_pair[1], TRUE) < 0) {
- sclose(multi->wakeup_pair[0]);
- sclose(multi->wakeup_pair[1]);
+ wakeup_close(multi->wakeup_pair[0]);
+ wakeup_close(multi->wakeup_pair[1]);
multi->wakeup_pair[0] = CURL_SOCKET_BAD;
multi->wakeup_pair[1] = CURL_SOCKET_BAD;
}
@@ -435,7 +456,8 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
struct Curl_multi *curl_multi_init(void)
{
return Curl_multi_handle(CURL_SOCKET_HASH_TABLE_SIZE,
- CURL_CONNECTION_HASH_SIZE);
+ CURL_CONNECTION_HASH_SIZE,
+ CURL_DNS_HASH_SIZE);
}
CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
@@ -631,7 +653,7 @@ static CURLcode multi_done(struct Curl_easy *data,
if(CURLE_ABORTED_BY_CALLBACK != result) {
/* avoid this if we already aborted by callback to avoid this calling
another callback */
- CURLcode rc = Curl_pgrsDone(data);
+ int rc = Curl_pgrsDone(data);
if(!result && rc)
result = CURLE_ABORTED_BY_CALLBACK;
}
@@ -830,6 +852,24 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
/* Remove the association between the connection and the handle */
Curl_detach_connection(data);
+ if(data->set.connect_only && !data->multi_easy) {
+ /* This removes a handle that was part the multi inteface that used
+ CONNECT_ONLY, that connection is now left alive but since this handle
+ has bits.close set nothing can use that transfer anymore and it is
+ forbidden from reuse. And this easy handle cannot find the connection
+ anymore once removed from the multi handle
+
+ Better close the connection here, at once.
+ */
+ struct connectdata *c;
+ curl_socket_t s;
+ s = Curl_getconnectinfo(data, &c);
+ if((s != CURL_SOCKET_BAD) && c) {
+ Curl_conncache_remove_conn(data, c, TRUE);
+ Curl_disconnect(data, c, TRUE);
+ }
+ }
+
if(data->state.lastconnect_id != -1) {
/* Mark any connect-only connection for closure */
Curl_conncache_foreach(data, data->state.conn_cache,
@@ -1311,8 +1351,6 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
pollrc = Curl_poll(ufds, nfds, 0); /* just pre-check with WinSock */
else
pollrc = 0;
- if(pollrc <= 0) /* now wait... if not ready during the pre-check above */
- WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, timeout_ms, FALSE);
#else
pollrc = Curl_poll(ufds, nfds, timeout_ms); /* wait... */
#endif
@@ -1323,6 +1361,9 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
retcode = pollrc;
#ifdef USE_WINSOCK
}
+ else { /* now wait... if not ready during the pre-check (pollrc == 0) */
+ WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, timeout_ms, FALSE);
+ }
/* With WinSock, we have to run the following section unconditionally
to call WSAEventSelect(fd, event, 0) on all the sockets */
{
@@ -1334,20 +1375,23 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
unsigned r = ufds[curlfds + i].revents;
unsigned short mask = 0;
#ifdef USE_WINSOCK
+ curl_socket_t s = extra_fds[i].fd;
wsa_events.lNetworkEvents = 0;
- if(WSAEnumNetworkEvents(extra_fds[i].fd, NULL, &wsa_events) == 0) {
+ if(WSAEnumNetworkEvents(s, NULL, &wsa_events) == 0) {
if(wsa_events.lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE))
mask |= CURL_WAIT_POLLIN;
if(wsa_events.lNetworkEvents & (FD_WRITE|FD_CONNECT|FD_CLOSE))
mask |= CURL_WAIT_POLLOUT;
if(wsa_events.lNetworkEvents & FD_OOB)
mask |= CURL_WAIT_POLLPRI;
- if(ret && pollrc <= 0 && wsa_events.lNetworkEvents)
+ if(ret && !pollrc && wsa_events.lNetworkEvents)
retcode++;
}
- WSAEventSelect(extra_fds[i].fd, multi->wsa_event, 0);
- if(pollrc <= 0)
+ WSAEventSelect(s, multi->wsa_event, 0);
+ if(!pollrc) {
+ extra_fds[i].revents = mask;
continue;
+ }
#endif
if(r & POLLIN)
mask |= CURL_WAIT_POLLIN;
@@ -1370,7 +1414,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
if(bitmap & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i))) {
wsa_events.lNetworkEvents = 0;
if(WSAEnumNetworkEvents(sockbunch[i], NULL, &wsa_events) == 0) {
- if(ret && pollrc <= 0 && wsa_events.lNetworkEvents)
+ if(ret && !pollrc && wsa_events.lNetworkEvents)
retcode++;
}
WSAEventSelect(sockbunch[i], multi->wsa_event, 0);
@@ -1397,7 +1441,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi,
data from it until it receives an error (except EINTR).
In normal cases it will get EAGAIN or EWOULDBLOCK
when there is no more data, breaking the loop. */
- nread = sread(multi->wakeup_pair[0], buf, sizeof(buf));
+ nread = wakeup_read(multi->wakeup_pair[0], buf, sizeof(buf));
if(nread <= 0) {
if(nread < 0 && EINTR == SOCKERRNO)
continue;
@@ -1490,7 +1534,7 @@ CURLMcode curl_multi_wakeup(struct Curl_multi *multi)
that will call curl_multi_wait(). If swrite() returns that it
would block, it's considered successful because it means that
previous calls to this function will wake up the poll(). */
- if(swrite(multi->wakeup_pair[1], buf, sizeof(buf)) < 0) {
+ if(wakeup_write(multi->wakeup_pair[1], buf, sizeof(buf)) < 0) {
int err = SOCKERRNO;
int return_success;
#ifdef USE_WINSOCK
@@ -2726,8 +2770,8 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
WSACloseEvent(multi->wsa_event);
#else
#ifdef ENABLE_WAKEUP
- sclose(multi->wakeup_pair[0]);
- sclose(multi->wakeup_pair[1]);
+ wakeup_close(multi->wakeup_pair[0]);
+ wakeup_close(multi->wakeup_pair[1]);
#endif
#endif
free(multi);