io_uring support was default-disabled because of numerous kernel bugs
but those are all in the sqpoll (file i/o) parts of io_uring.
Batching of epoll_ctl calls through io_uring works fine, is a nice
optimization, and is therefore unconditionally enabled again.
The UV_USE_IO_URING environment variable now only affects sqpoll, and
only when the UV_LOOP_ENABLE_IO_URING_SQPOLL event loop flag is set.
Fixes: https://github.com/libuv/libuv/issues/4616
Libuv looks for "Processor" in /proc/cpuinfo but it's been reported
that on at least some Raspberry Pi models, it's called "model name".
Look for both.
Fixes: https://github.com/nodejs/node/issues/56105
`uv_thread_setname()` sets the name of the current thread. Different
platforms define different limits on the max number of characters
a thread name can be: Linux, IBMi (16), macOS (64), Windows (32767),
and NetBSD (32), etc. `uv_thread_setname()` will truncate it in case
`name` is larger than the limit of the platform.
`uv_thread_getname()` gets the name of the thread specified by `tid`.
The thread name is copied into the buffer pointed to by `name`. The
`size` parameter specifies the size of the buffer pointed to by `name`.
The buffer should be large enough to hold the name of the thread plus
the trailing NUL, or it will be truncated to fit.
This commit introduces the `uv_thread_detach` for thread detaching,
allowing threads to be detached state on both UNIX and Windows platforms.
Signed-off-by: Juan José Arboleda <soyjuanarbol@gmail.com>
For any API that takes a buffer and size pointer, check both pointers
and the pointed-to size and return UV_EINVAL in case of error.
Example:
```
int uv_foo(char* buffer, size_t* size) {
if (buffer == NULL || size == NULL || *size == 0)
return UV_EINVAL;
...
}
```
In order to "peek" the necessary size for dynamic allocation, the
following pattern can be used:
```
char *buf;
char scratch[1];
size_t len = sizeof(scratch);
int r;
r = uv_foo(scratch, &len);
assert(r == UV_ENOBUFS);
buf = malloc(len);
r = uv_foo(buf, &len);
...
```
The compile-time detection check from commit 7b75935 ("kqueue: use
EVFILT_USER for async if available") was not being used, breaking
numerous operating systems. This commit hopefully unbreaks them.
Fixes; https://github.com/libuv/libuv/issues/4608
Signed-off-by: Jeffrey H. Johnson <trnsz@pobox.com>
uv_wtf8_length_as_utf16() checks if codepoints are > 0xFFFF (to see if
it should be encoded as a surrogate pair), therefore uv_wtf8_to_utf16()
should too. Instead it checked > 0x1000. Harmonize the checks.
Fixes: https://github.com/nodejs/node/issues/55914
Establishes a user event for kqueue to eliminate the overhead
of the pipe and the system call read(2) per wakeup event.
Relands commit 27134547ff using VSCode merge, since it shows the
conflict is just on the order of #ifdef calls.
Co-authored-by: Andy Pan <panjf2000@gmail.com>
It seemed incorrect to map a segfault to EACCES, since posix would typically
map this to EFAULT. The ERROR_BUFFER_OVERFLOW is literally "the filename is too
long", and is not typically an invalid parameter in posix.
Test originally added in #1060 to test the API, not the value.
This reverts commit e5cb1d3d3d.
Reason: bisecting says it breaks dnstap.
Also revert commit 27134547ff ("kqueue: use EVFILT_USER for async if
available") because otherwise the first commit doesn't revert cleanly,
with enough conflicts in src/unix/async.c that I'm not comfortable
fixing those up manually.
Fixes: https://github.com/libuv/libuv/issues/4584
Make sure `UV__SOLARIS_11_4` is not set for `smartOS`/`illumOS`. In our
codebase is used only twice:
- Detect correct implementation of `SO_REUSEPORT`, which is not even
implemented on `illumOS`.
- Detect the time unit used for the TCP keepalive options. If set to
`0`, which was the case for `illumOS`, it chose milliseconds, which is
not correct for `illumOS` either as it uses seconds.
The implementation of IPC pipe in libuv on Windows does not properly support
async reading. This means we cannot set the more parameter without likely
causing hangs. Sorry this is yet another followup to #4511.
Fixes#4548
After commit 18266a6969, it changed to return `ENOTDIR`, which makes it
consistent with other platforms but it also can be considered a breaking
change.
Route ftruncate() system calls through io_uring instead of the thread
pool when the kernel is new enough to support it (linux >= 6.9).
This commit harmonizes how libuv checks if the kernel is new enough.
Some ops were checking against `uv__kernel_version()` directly while
others stored the result of the version check as a feature flag.
Because the kernel version is cached, and because it is more direct
than a feature flag, I opted for the former approach.
Introduced in Linux 6.6, it tells the kernel to omit the sqarray from
the ring buffer.
Libuv initalizes the array once to an identity mapping and then forgets
about it, so not only does it save a little memory (ca. 1 KiB per ring)
but it also makes things more efficient kernel-side because it removes
a level of indirection.
Libuv stores the `struct termios` for use inside uv_tty_reset_mode().
Node.js uses said function to restore the tty to its original mode
on SIGINT or SIGTERM, when there is no opportunity to shut down the
process normally.
Track uv_tty_t handle closing, otherwise we might be trying to use a
stale termios.
The current solution is not ideal because there can be multiple handles
that refer to the same tty/pty and, for various reasons, we can't really
determine when we close the last handle. The last handle may not even be
inside the current process.
Still, all things considered, it's probably (hopefully!) an improvement
over the status quo.
Refs: https://github.com/libuv/libuv/issues/4398
Yet another followup to #4511. The functional/legacy/increment_spec.lua
test failed most of the time without this, and passes consistently with
it. It seemed unexpected this code path gets reached (perhaps imply
that the user wrote zero bytes?), but good to fix of course.
Fixes commit 58dfb6c89b from a few days ago. DWORD_PTR is 32 bits on
x86 Windows. Use the right bit count when checking the population count.
Interestingly enough, it manifested itself as double counting online
processors, presumably because the compiler emits a ROR instead of SHR.
Fixes: https://github.com/libuv/libuv/issues/4524
Use GetProcessAffinityMask() to estimate the available parallelism.
Before this commit, it simply used the number of available CPUs.
Fixes: https://github.com/libuv/libuv/issues/4520
In #4470, I accidentally copied the bug from unix, where calling
uv_stream_set_blocking can cause the whole process to hang on a read.
However, unlike unix, where libuv attempts to set the O_NONBLOCK flag in
uv_pipe_open (as long as the handle never gets passed to uv_spawn), the
NT kernel is not capable of enabling OVERLAPPED operation later (but
fortunately, it also cannot disable it later too).
This implementation might be good to copy to unix (using FIONREAD) to
address the same bug that happens there if the user has called uv_spawn
or uv_stream_set_non_blocking on this handle in the past.
Establishes a user event for kqueue to eliminate the overhead
of the pipe and the system call read(2) per wakeup event.
---------
Signed-off-by: Andy Pan <i@andypan.me>
Co-authored-by: Jameson Nash <vtjnash@gmail.com>
Autobinding is a feature that lets the kernel pick a name for the
abstract socket, instead of userspace having to provide one.
Two bugs that this change exposed are also fixed:
1. strlen(sa.sun_path) can read past the end if the file path is exactly
sizeof(sa.sun_path) long (use memchr instead), and
2. don't return UV_ENOBUFS for abstract sockets when the buffer is
exactly large enough to hold the result; per commit e5f4b79809,
abstract socket names are not zero-terminated
Refactor / cleanup arithmetic for unix -> win filetime conversion
in order to avoid multiplication overflow.
Fixes:
```
src/win/fs.c:106:48: runtime error: signed integer overflow: 1702781567 * 10 cannot be represented in type 'long'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/win/fs.c:106:48 in
```
Co-authored-by: Jameson Nash <vtjnash@gmail.com>
The SQPOLL io_uring instance wasn't providing consistent behaviour to
users depending on kernel versions, load shape, ... creating issues
difficult to track and fix. Don't use this ring by default but allow
enabling it by calling `uv_loop_configure()` with
`UV_LOOP_ENABLE_IO_URING_SQPOLL`.
MSVC does not actually support ubsan. There is a long-standing ticket
requesting this:
https://developercommunity.visualstudio.com/t/add-support-for-ubsan/840750
There are no known compilers that currently accept the
`/fsanitize=undefined` spelling. clang-cl accepts `-fsanitize...`,
same as regular clang.
Also passes no-sanitizer-recover so that tests actually fail.
Fix various ubsan-detected errors, including:
* win: fix req-inl.h ubsan failure
Don't use CONTAINING_RECORD macro from WinSDK, as it doesn't use the
right trick which avoids member access on null pointer.
Fixes:
```
src/win/req-inl.h:86:10: runtime error: member access within null pointer of type 'uv_req_t' (aka 'struct uv_req_s')
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior D:/a/libuv/libuv/src/win/req-inl.h:86:10
```
* test: fix ubsan failure on udp_ref3
Don't call functions through different function type.
Fixes:
```
src/win/udp.c:537:5: runtime error: call to function req_cb through pointer to incorrect function type 'void (*)(struct uv_udp_send_s *, int)'
test\test-ref.c:66: note: req_cb defined here
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/win/udp.c:537:5 in
```
* win: fix process-stdio.c ubsan failure
When accessing HANDLEs within the stdio buffer, use memcpy / memset in order to respect alignment.
Fixes:
```
src/win/process-stdio.c:197:5: runtime error: store to misaligned address 0x0230ee72d107 for type 'HANDLE' (aka 'void *'), which requires 8 byte alignment
0x0230ee72d107: note: pointer points here
00 00 cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd fd fd fd fd
^
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/win/process-stdio.c:197:5 in
```
* win: fix getaddrinfo.c ubsan failure
Reworks buffer alignment handling to respect requirements.
Fixes:
```
src/win/getaddrinfo.c:157:23: runtime error: member access within misaligned address 0x0290e4c6a17c for type 'struct addrinfo', which requires 8 byte alignment
0x0290e4c6a17c: note: pointer points here
00 00 00 00 cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd
^
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/win/getaddrinfo.c:157:23 in
```
* win: fix pipe.c ubsan failure
Changes "random" representation from pointer to number.
Fixes:
```
src/win/pipe.c:234:11: runtime error: applying non-zero offset to non-null pointer 0xffffffffffffffff produced null pointer
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/win/pipe.c:234:11 in
```
* unix: fix stream.c ubsan failure
Avoids performing pointer arithmetic on null pointer.
Fixes:
```
src/unix/stream.c:701:15: runtime error: applying zero offset to null pointer
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /Users/runner/work/libuv/libuv/src/unix/stream.c:701:15 in
```