multi: use a pipe instead of a socketpair on apple platforms

Sockets may be shut down by the kernel when the app is moved to the
background, but pipes are not.

Removed from KNOWN_BUGS

Fixes #6132
Closes #9368
This commit is contained in:
rcombs 2022-08-25 08:55:36 -05:00 committed by Daniel Stenberg
parent 89d204036a
commit 07f80f968d
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
2 changed files with 23 additions and 20 deletions

View File

@ -120,7 +120,6 @@ problems may have been fixed or changed somewhat since this was written.
11.10 Blocking socket operations in non-blocking API
11.11 A shared connection cache is not thread-safe
11.12 'no_proxy' string-matches IPv6 numerical addresses
11.13 wakeup socket disconnect causes havoc
11.14 Multi perform hangs waiting for threaded resolver
11.15 CURLOPT_OPENSOCKETPAIRFUNCTION is missing
11.16 libcurl uses renames instead of locking for atomic operations
@ -939,18 +938,6 @@ problems may have been fixed or changed somewhat since this was written.
See https://github.com/curl/curl/issues/5745
11.13 wakeup socket disconnect causes havoc
waking an iPad breaks the wakeup socket pair, triggering a POLLIN event and
resulting in SOCKERRNO being set to ENOTCONN.
This condition, and other possible error conditions on the wakeup socket, are
not handled, so the condition remains on the FD and curl_multi_poll will
never block again.
See https://github.com/curl/curl/issues/6132 and
https://github.com/curl/curl/pull/6133
11.14 Multi perform hangs waiting for threaded resolver
If a threaded resolver takes a long time to complete, libcurl can be blocked

View File

@ -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
@ -404,14 +420,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;
}
@ -1413,7 +1429,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;
@ -1506,7 +1522,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
@ -2742,8 +2758,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);