]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
multi: use a pipe instead of a socketpair on apple platforms
authorrcombs <rcombs@rcombs.me>
Thu, 25 Aug 2022 13:55:36 +0000 (08:55 -0500)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 25 Aug 2022 15:43:08 +0000 (17:43 +0200)
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

docs/KNOWN_BUGS
lib/multi.c

index 20cf43f4dc11a7da2032fb3bcfdb3b8d0ede9d07..976cf325e492a33353a91d73808069e6226518ef 100644 (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
index 2527de3a6d58790932e42276eab28f2729c1fa7b..b20bd9ad3f8ac4e1e060b306cba69fa363903028 100644 (file)
 #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);