chore: backport EPROTOTYPE fixes from libuv (#32856)
This commit backports three commits from libuv's 1.x branch to fix issues with CPU going to 100% on macOS when EPROTOTYPE is returned. See:abb109f30f
See:3a7b95593a
See:de24da8c11
This commit is contained in:
parent
34129b83a4
commit
fe43296f7f
4 changed files with 137 additions and 0 deletions
|
@ -28,3 +28,6 @@ fix_crash_caused_by_gethostnamew_on_windows_7.patch
|
|||
fix_suppress_clang_-wdeprecated-declarations_in_libuv.patch
|
||||
fix_don_t_create_console_window_when_creating_process.patch
|
||||
fix_serdes_test.patch
|
||||
darwin_remove_eprototype_error_workaround_3405.patch
|
||||
darwin_translate_eprototype_to_econnreset_3413.patch
|
||||
darwin_bump_minimum_supported_version_to_10_15_3406.patch
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Noordhuis <info@bnoordhuis.nl>
|
||||
Date: Tue, 8 Feb 2022 14:18:29 +0100
|
||||
Subject: darwin: bump minimum supported version to 10.15 (#3406)
|
||||
|
||||
We can't realistically claim to support 10.7 or any version that Apple
|
||||
no longer supports so let's bump the baseline to something more
|
||||
realistic.
|
||||
|
||||
Refs: https://github.com/libuv/libuv/pull/482
|
||||
Refs: https://github.com/libuv/libuv/pull/3405
|
||||
|
||||
diff --git a/deps/uv/SUPPORTED_PLATFORMS.md b/deps/uv/SUPPORTED_PLATFORMS.md
|
||||
index 30e0ea617a6fcaa5b4b7c7c5b117652e61f367d3..dc57dfb12dc7ddf8d29308ac44f46084a933d5ca 100644
|
||||
--- a/deps/uv/SUPPORTED_PLATFORMS.md
|
||||
+++ b/deps/uv/SUPPORTED_PLATFORMS.md
|
||||
@@ -3,7 +3,7 @@
|
||||
| System | Support type | Supported versions | Notes |
|
||||
|---|---|---|---|
|
||||
| GNU/Linux | Tier 1 | Linux >= 2.6.32 with glibc >= 2.12 | |
|
||||
-| macOS | Tier 1 | macOS >= 10.7 | |
|
||||
+| macOS | Tier 1 | macOS >= 10.15 | Current and previous macOS release |
|
||||
| Windows | Tier 1 | >= Windows 8 | VS 2015 and later are supported |
|
||||
| FreeBSD | Tier 1 | >= 10 | |
|
||||
| AIX | Tier 2 | >= 6 | Maintainers: @libuv/aix |
|
|
@ -0,0 +1,65 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Noordhuis <info@bnoordhuis.nl>
|
||||
Date: Sun, 9 Jan 2022 12:20:15 +0100
|
||||
Subject: darwin: remove EPROTOTYPE error workaround (#3405)
|
||||
|
||||
It's been reported in the past that OS X 10.10, because of a race
|
||||
condition in the XNU kernel, sometimes returns a transient EPROTOTYPE
|
||||
error when trying to write to a socket. Libuv handles that by retrying
|
||||
the operation until it succeeds or fails with a different error.
|
||||
|
||||
Recently it's been reported that current versions of the operating
|
||||
system formerly known as OS X fail permanently with EPROTOTYPE under
|
||||
certain conditions, resulting in an infinite loop.
|
||||
|
||||
Because Apple isn't exactly forthcoming with bug fixes or even details,
|
||||
I'm opting to simply remove the workaround and have the error bubble up.
|
||||
|
||||
Refs: https://github.com/libuv/libuv/pull/482
|
||||
|
||||
diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c
|
||||
index bc64fe8f44b26d9f4c0d4d0d282b65cdf11a531b..1af448e7691392c3f7794eed1905d9132394e207 100644
|
||||
--- a/deps/uv/src/unix/stream.c
|
||||
+++ b/deps/uv/src/unix/stream.c
|
||||
@@ -58,20 +58,6 @@ struct uv__stream_select_s {
|
||||
fd_set* swrite;
|
||||
size_t swrite_sz;
|
||||
};
|
||||
-
|
||||
-/* Due to a possible kernel bug at least in OS X 10.10 "Yosemite",
|
||||
- * EPROTOTYPE can be returned while trying to write to a socket that is
|
||||
- * shutting down. If we retry the write, we should get the expected EPIPE
|
||||
- * instead.
|
||||
- */
|
||||
-# define RETRY_ON_WRITE_ERROR(errno) (errno == EINTR || errno == EPROTOTYPE)
|
||||
-# define IS_TRANSIENT_WRITE_ERROR(errno, send_handle) \
|
||||
- (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || \
|
||||
- (errno == EMSGSIZE && send_handle != NULL))
|
||||
-#else
|
||||
-# define RETRY_ON_WRITE_ERROR(errno) (errno == EINTR)
|
||||
-# define IS_TRANSIENT_WRITE_ERROR(errno, send_handle) \
|
||||
- (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
|
||||
#endif /* defined(__APPLE__) */
|
||||
|
||||
static void uv__stream_connect(uv_stream_t*);
|
||||
@@ -866,17 +852,17 @@ static int uv__try_write(uv_stream_t* stream,
|
||||
|
||||
do
|
||||
n = sendmsg(uv__stream_fd(stream), &msg, 0);
|
||||
- while (n == -1 && RETRY_ON_WRITE_ERROR(errno));
|
||||
+ while (n == -1 && errno == EINTR);
|
||||
} else {
|
||||
do
|
||||
n = uv__writev(uv__stream_fd(stream), iov, iovcnt);
|
||||
- while (n == -1 && RETRY_ON_WRITE_ERROR(errno));
|
||||
+ while (n == -1 && errno == EINTR);
|
||||
}
|
||||
|
||||
if (n >= 0)
|
||||
return n;
|
||||
|
||||
- if (IS_TRANSIENT_WRITE_ERROR(errno, send_handle))
|
||||
+ if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
|
||||
return UV_EAGAIN;
|
||||
|
||||
return UV__ERR(errno);
|
|
@ -0,0 +1,44 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Noordhuis <info@bnoordhuis.nl>
|
||||
Date: Wed, 12 Jan 2022 16:11:43 +0100
|
||||
Subject: darwin: translate EPROTOTYPE to ECONNRESET (#3413)
|
||||
|
||||
macOS versions 10.10 and 10.15 - and presumbaly 10.11 to 10.14, too -
|
||||
have a bug where a race condition causes the kernel to return EPROTOTYPE
|
||||
because the socket isn't fully constructed.
|
||||
|
||||
It's probably the result of the peer closing the connection and that is
|
||||
why libuv translates it to ECONNRESET.
|
||||
|
||||
Previously, libuv retried until the EPROTOTYPE error went away but some
|
||||
VPN software causes the same behavior except the error is permanent, not
|
||||
transient, turning the retry mechanism into an infinite loop.
|
||||
|
||||
Refs: https://github.com/libuv/libuv/pull/482
|
||||
Refs: https://github.com/libuv/libuv/pull/3405
|
||||
|
||||
diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c
|
||||
index 1af448e7691392c3f7794eed1905d9132394e207..9d22debf2bf5bd5912ade152e55a85ad652e3819 100644
|
||||
--- a/deps/uv/src/unix/stream.c
|
||||
+++ b/deps/uv/src/unix/stream.c
|
||||
@@ -865,6 +865,20 @@ static int uv__try_write(uv_stream_t* stream,
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
|
||||
return UV_EAGAIN;
|
||||
|
||||
+#ifdef __APPLE__
|
||||
+ /* macOS versions 10.10 and 10.15 - and presumbaly 10.11 to 10.14, too -
|
||||
+ * have a bug where a race condition causes the kernel to return EPROTOTYPE
|
||||
+ * because the socket isn't fully constructed. It's probably the result of
|
||||
+ * the peer closing the connection and that is why libuv translates it to
|
||||
+ * ECONNRESET. Previously, libuv retried until the EPROTOTYPE error went
|
||||
+ * away but some VPN software causes the same behavior except the error is
|
||||
+ * permanent, not transient, turning the retry mechanism into an infinite
|
||||
+ * loop. See https://github.com/libuv/libuv/pull/482.
|
||||
+ */
|
||||
+ if (errno == EPROTOTYPE)
|
||||
+ return UV_ECONNRESET;
|
||||
+#endif /* __APPLE__ */
|
||||
+
|
||||
return UV__ERR(errno);
|
||||
}
|
||||
|
Loading…
Reference in a new issue