From: rcombs Date: Thu, 25 Aug 2022 13:55:36 +0000 (-0500) Subject: multi: use a pipe instead of a socketpair on apple platforms X-Git-Tag: curl-7_85_0~26 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=07f80f968df365cbfb5bfcea149baf9eb20cb60f;p=thirdparty%2Fcurl.git 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 --- diff --git a/docs/KNOWN_BUGS b/docs/KNOWN_BUGS index 20cf43f4dc..976cf325e4 100644 --- a/docs/KNOWN_BUGS +++ b/docs/KNOWN_BUGS @@ -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 diff --git a/lib/multi.c b/lib/multi.c index 2527de3a6d..b20bd9ad3f 100644 --- a/lib/multi.c +++ b/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 @@ -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);