mirror of
https://github.com/zebrajr/node.git
synced 2025-12-06 12:20:27 +01:00
deps: update libuv to 1.50.0
PR-URL: https://github.com/nodejs/node/pull/56616 Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com> Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Ulises Gascón <ulisesgascongonzalez@gmail.com> Reviewed-By: Richard Lau <rlau@redhat.com>
This commit is contained in:
parent
2e45656eb2
commit
a500382d18
1
deps/uv/.mailmap
vendored
1
deps/uv/.mailmap
vendored
|
|
@ -52,6 +52,7 @@ San-Tai Hsu <vanilla@fatpipi.com>
|
|||
Santiago Gimeno <santiago.gimeno@quantion.es> <santiago.gimeno@gmail.com>
|
||||
Saúl Ibarra Corretgé <s@saghul.net>
|
||||
Saúl Ibarra Corretgé <s@saghul.net> <saghul@gmail.com>
|
||||
Saúl Ibarra Corretgé <saghul@gmail.com> <s@saghul.net>
|
||||
Shigeki Ohtsu <ohtsu@iij.ad.jp> <ohtsu@ohtsu.org>
|
||||
Shuowang (Wayne) Zhang <shuowang.zhang@ibm.com>
|
||||
TK-one <tk5641@naver.com>
|
||||
|
|
|
|||
4
deps/uv/AUTHORS
vendored
4
deps/uv/AUTHORS
vendored
|
|
@ -588,5 +588,7 @@ Raihaan Shouhell <raihaanhimself@gmail.com>
|
|||
Rialbat <miha-wead@mail.ru>
|
||||
Adam <adam@NetBSD.org>
|
||||
Poul T Lomholt <ptlomholt@users.noreply.github.com>
|
||||
dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
|
||||
Thad House <ThadHouse@users.noreply.github.com>
|
||||
Julian A Avar C <28635807+julian-a-avar-c@users.noreply.github.com>
|
||||
amcgoogan <105525867+amcgoogan@users.noreply.github.com>
|
||||
Rafael Gonzaga <rafael.nunu@hotmail.com>
|
||||
|
|
|
|||
5
deps/uv/CMakeLists.txt
vendored
5
deps/uv/CMakeLists.txt
vendored
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.9)
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
if(POLICY CMP0091)
|
||||
cmake_policy(SET CMP0091 NEW) # Enable MSVC_RUNTIME_LIBRARY setting
|
||||
|
|
@ -186,7 +186,7 @@ set(uv_sources
|
|||
src/version.c)
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND uv_defines WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0602 _CRT_DECLARE_NONSTDC_NAMES=0)
|
||||
list(APPEND uv_defines WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0A00 _CRT_DECLARE_NONSTDC_NAMES=0)
|
||||
list(APPEND uv_libraries
|
||||
psapi
|
||||
user32
|
||||
|
|
@ -667,6 +667,7 @@ if(LIBUV_BUILD_TESTS)
|
|||
test/test-thread-affinity.c
|
||||
test/test-thread-equal.c
|
||||
test/test-thread.c
|
||||
test/test-thread-name.c
|
||||
test/test-thread-priority.c
|
||||
test/test-threadpool-cancel.c
|
||||
test/test-threadpool.c
|
||||
|
|
|
|||
83
deps/uv/ChangeLog
vendored
83
deps/uv/ChangeLog
vendored
|
|
@ -1,4 +1,85 @@
|
|||
2024.10.18, Version 1.49.2 (Stable)
|
||||
2025.01.15, Version 1.50.0 (Stable)
|
||||
|
||||
Changes since version 1.49.2:
|
||||
|
||||
* ci: run macOS and iOS tests also on macOS 14 (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix,win: map ENOEXEC errno (Saúl Ibarra Corretgé)
|
||||
|
||||
* test: skip multicast join test on ENOEXEC (Saúl Ibarra Corretgé)
|
||||
|
||||
* ci: make sure the macOS firewall is disabled (Saúl Ibarra Corretgé)
|
||||
|
||||
* darwin,test: squelch EBUSY error on multicast join (Saúl Ibarra Corretgé)
|
||||
|
||||
* build: update minimum cmake to 3.10 (Ben Noordhuis)
|
||||
|
||||
* kqueue: use EVFILT_USER for async if available (Jameson Nash)
|
||||
|
||||
* unix,win: fix off-by-one in uv_wtf8_to_utf16() (Ben Noordhuis)
|
||||
|
||||
* doc: add scala-native-loop to LINKS.md (Julian A Avar C)
|
||||
|
||||
* unix: fix build breakage on haiku, openbsd, etc (Jeffrey H. Johnson)
|
||||
|
||||
* kqueue: lower overhead in uv__io_check_fd (Andy Pan)
|
||||
|
||||
* doc: move cjihrig back to active maintainers (cjihrig)
|
||||
|
||||
* build(deps): bump actions/checkout from 3 to 4 (dependabot[bot])
|
||||
|
||||
* unix,pipe: fix handling null buffer in uv_pipe_get{sock,peer}name (Saúl
|
||||
Ibarra Corretgé)
|
||||
|
||||
* unix,win: harmonize buffer checking (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix,win: add support for detached threads (Juan José Arboleda)
|
||||
|
||||
* src: add uv_thread_set/getname() methods (Santiago Gimeno)
|
||||
|
||||
* build: fix qemu builds (Ben Noordhuis)
|
||||
|
||||
* win: drop support for windows 8 (Ben Noordhuis)
|
||||
|
||||
* linux: fix uv_cpu_info() arm cpu model detection (Ben Noordhuis)
|
||||
|
||||
* linux: always use io_uring for epoll batching (Ben Noordhuis)
|
||||
|
||||
* doc: clarify repeating timer behavior more (Ben Noordhuis)
|
||||
|
||||
* unix,win: handle nbufs=0 in uv_udp_try_send (Ben Noordhuis)
|
||||
|
||||
* win: use GetQueuedCompletionStatusEx directly (Saúl Ibarra Corretgé)
|
||||
|
||||
* win: enable uv_thread_{get,set}name on MinGW (Saúl Ibarra Corretgé)
|
||||
|
||||
* win: drop support for the legacy MinGW (Saúl Ibarra Corretgé)
|
||||
|
||||
* win,fs: get (most) fstat when no permission (Jameson Nash)
|
||||
|
||||
* win: plug uv_fs_event_start memory leak (amcgoogan)
|
||||
|
||||
* test: address FreeBSD kernel bug causing NULL path in fsevents (Juan José
|
||||
Arboleda)
|
||||
|
||||
* unix: refactor udp sendmsg code (Ben Noordhuis)
|
||||
|
||||
* unix,win: add uv_udp_try_send2 (Ben Noordhuis)
|
||||
|
||||
* test: fix flaky flaky udp_mmsg test (Juan José Arboleda)
|
||||
|
||||
* build: enable fdsan in Android (Juan José Arboleda)
|
||||
|
||||
* test: fix udp-multicast-join for FreeBSD (Juan José Arboleda)
|
||||
|
||||
* win: fix leak processing fs event (Saúl Ibarra Corretgé)
|
||||
|
||||
* src: set a default thread name for workers (Rafael Gonzaga)
|
||||
|
||||
* misc: implement uv_getrusage_thread (Juan José Arboleda)
|
||||
|
||||
|
||||
2024.10.18, Version 1.49.2 (Stable), e1095c7a4373ce00cd8874d8e820de5afb25776e
|
||||
|
||||
Changes since version 1.49.1:
|
||||
|
||||
|
|
|
|||
1
deps/uv/LINKS.md
vendored
1
deps/uv/LINKS.md
vendored
|
|
@ -37,6 +37,7 @@
|
|||
* [Pixie-io](https://github.com/pixie-io/pixie): Open-source observability tool for Kubernetes applications.
|
||||
* [potion](https://github.com/perl11/potion)/[p2](https://github.com/perl11/p2): runtime
|
||||
* [racer](https://libraries.io/rubygems/racer): Ruby web server written as an C extension
|
||||
* [scala-native-loop](https://github.com/scala-native/scala-native-loop): Extensible event loop and async-oriented IO for Scala Native; powered by libuv
|
||||
* [Socket Runtime](https://sockets.sh): A runtime for creating native cross-platform software on mobile and desktop using HTML, CSS, and JavaScript
|
||||
* [spider-gazelle](https://github.com/cotag/spider-gazelle): Ruby web server using libuv bindings
|
||||
* [Suave](http://suave.io/): A simple web development F# library providing a lightweight web server and a set of combinators to manipulate route flow and task composition
|
||||
|
|
|
|||
6
deps/uv/MAINTAINERS.md
vendored
6
deps/uv/MAINTAINERS.md
vendored
|
|
@ -4,6 +4,9 @@ libuv is currently managed by the following individuals:
|
|||
|
||||
* **Ben Noordhuis** ([@bnoordhuis](https://github.com/bnoordhuis))
|
||||
- GPG key: D77B 1E34 243F BAF0 5F8E 9CC3 4F55 C8C8 46AB 89B9 (pubkey-bnoordhuis)
|
||||
* **Colin Ihrig** ([@cjihrig](https://github.com/cjihrig))
|
||||
- GPG key: 94AE 3667 5C46 4D64 BAFA 68DD 7434 390B DBE9 B9C5 (pubkey-cjihrig)
|
||||
- GPG key: 5735 3E0D BDAA A7E8 39B6 6A1A FF47 D5E4 AD8B 4FDC (pubkey-cjihrig-kb)
|
||||
* **Jameson Nash** ([@vtjnash](https://github.com/vtjnash))
|
||||
- GPG key: AEAD 0A4B 6867 6775 1A0E 4AEF 34A2 5FB1 2824 6514 (pubkey-vtjnash)
|
||||
- GPG key: CFBB 9CA9 A5BE AFD7 0E2B 3C5A 79A6 7C55 A367 9C8B (pubkey2022-vtjnash)
|
||||
|
|
@ -24,9 +27,6 @@ libuv is currently managed by the following individuals:
|
|||
* **Anna Henningsen** ([@addaleax](https://github.com/addaleax))
|
||||
* **Bartosz Sosnowski** ([@bzoz](https://github.com/bzoz))
|
||||
* **Bert Belder** ([@piscisaureus](https://github.com/piscisaureus))
|
||||
* **Colin Ihrig** ([@cjihrig](https://github.com/cjihrig))
|
||||
- GPG key: 94AE 3667 5C46 4D64 BAFA 68DD 7434 390B DBE9 B9C5 (pubkey-cjihrig)
|
||||
- GPG key: 5735 3E0D BDAA A7E8 39B6 6A1A FF47 D5E4 AD8B 4FDC (pubkey-cjihrig-kb)
|
||||
* **Fedor Indutny** ([@indutny](https://github.com/indutny))
|
||||
- GPG key: AF2E EA41 EC34 47BF DD86 FED9 D706 3CCE 19B7 E890 (pubkey-indutny)
|
||||
* **Imran Iqbal** ([@imran-iq](https://github.com/imran-iq))
|
||||
|
|
|
|||
3
deps/uv/Makefile.am
vendored
3
deps/uv/Makefile.am
vendored
|
|
@ -59,7 +59,7 @@ if WINNT
|
|||
uvinclude_HEADERS += include/uv/win.h include/uv/tree.h
|
||||
AM_CPPFLAGS += -I$(top_srcdir)/src/win \
|
||||
-DWIN32_LEAN_AND_MEAN \
|
||||
-D_WIN32_WINNT=0x0602
|
||||
-D_WIN32_WINNT=0x0A00
|
||||
libuv_la_SOURCES += src/win/async.c \
|
||||
src/win/atomicops-inl.h \
|
||||
src/win/core.c \
|
||||
|
|
@ -294,6 +294,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
|||
test/test-thread-equal.c \
|
||||
test/test-thread.c \
|
||||
test/test-thread-affinity.c \
|
||||
test/test-thread-name.c \
|
||||
test/test-thread-priority.c \
|
||||
test/test-threadpool-cancel.c \
|
||||
test/test-threadpool.c \
|
||||
|
|
|
|||
4
deps/uv/SUPPORTED_PLATFORMS.md
vendored
4
deps/uv/SUPPORTED_PLATFORMS.md
vendored
|
|
@ -4,14 +4,14 @@
|
|||
|---|---|---|---|
|
||||
| GNU/Linux | Tier 1 | Linux >= 3.10 with glibc >= 2.17 | |
|
||||
| macOS | Tier 1 | macOS >= 11 | Currently supported macOS releases |
|
||||
| Windows | Tier 1 | >= Windows 8 | VS 2015 and later are supported |
|
||||
| Windows | Tier 1 | >= Windows 10 | VS 2015 and later are supported |
|
||||
| FreeBSD | Tier 2 | >= 12 | |
|
||||
| AIX | Tier 2 | >= 6 | Maintainers: @libuv/aix |
|
||||
| IBM i | Tier 2 | >= IBM i 7.2 | Maintainers: @libuv/ibmi |
|
||||
| z/OS | Tier 2 | >= V2R2 | Maintainers: @libuv/zos |
|
||||
| Linux with musl | Tier 2 | musl >= 1.0 | |
|
||||
| Android | Tier 3 | NDK >= r15b | Android 7.0, `-DANDROID_PLATFORM=android-24` |
|
||||
| MinGW | Tier 3 | MinGW32 and MinGW-w64 | |
|
||||
| MinGW | Tier 3 | MinGW-w64 | |
|
||||
| SunOS | Tier 3 | Solaris 121 and later | |
|
||||
| Other | Tier 3 | N/A | |
|
||||
|
||||
|
|
|
|||
2
deps/uv/configure.ac
vendored
2
deps/uv/configure.ac
vendored
|
|
@ -13,7 +13,7 @@
|
|||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT([libuv], [1.49.2], [https://github.com/libuv/libuv/issues])
|
||||
AC_INIT([libuv], [1.50.0], [https://github.com/libuv/libuv/issues])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
m4_include([m4/libuv-extra-automake-flags.m4])
|
||||
m4_include([m4/as_case.m4])
|
||||
|
|
|
|||
5
deps/uv/docs/src/fs_event.rst
vendored
5
deps/uv/docs/src/fs_event.rst
vendored
|
|
@ -47,6 +47,11 @@ Data types
|
|||
|
||||
The `events` parameter is an ORed mask of :c:enum:`uv_fs_event` elements.
|
||||
|
||||
.. note::
|
||||
For FreeBSD path could sometimes be `NULL` due to a kernel bug.
|
||||
|
||||
.. _Reference: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=197695
|
||||
|
||||
.. c:enum:: uv_fs_event
|
||||
|
||||
Event types that :c:type:`uv_fs_event_t` handles monitor.
|
||||
|
|
|
|||
11
deps/uv/docs/src/misc.rst
vendored
11
deps/uv/docs/src/misc.rst
vendored
|
|
@ -360,6 +360,17 @@ API
|
|||
On Windows not all fields are set, the unsupported fields are filled with zeroes.
|
||||
See :c:type:`uv_rusage_t` for more details.
|
||||
|
||||
.. c:function:: int uv_getrusage_thread(uv_rusage_t* rusage)
|
||||
|
||||
Gets the resource usage measures for the calling thread.
|
||||
|
||||
.. versionadded:: 1.50.0
|
||||
|
||||
.. note::
|
||||
Not supported on all platforms. May return `UV_ENOTSUP`.
|
||||
On macOS and Windows not all fields are set, the unsupported fields are filled with zeroes.
|
||||
See :c:type:`uv_rusage_t` for more details.
|
||||
|
||||
.. c:function:: uv_pid_t uv_os_getpid(void)
|
||||
|
||||
Returns the current process ID.
|
||||
|
|
|
|||
25
deps/uv/docs/src/threading.rst
vendored
25
deps/uv/docs/src/threading.rst
vendored
|
|
@ -78,6 +78,14 @@ Threads
|
|||
|
||||
.. versionchanged:: 1.4.1 returns a UV_E* error code on failure
|
||||
|
||||
.. c:function:: int uv_thread_detach(uv_thread_t* tid)
|
||||
|
||||
Detaches a thread. Detached threads automatically release their
|
||||
resources upon termination, eliminating the need for the application to
|
||||
call `uv_thread_join`.
|
||||
|
||||
.. versionadded:: 1.50.0
|
||||
|
||||
.. c:function:: int uv_thread_create_ex(uv_thread_t* tid, const uv_thread_options_t* params, uv_thread_cb entry, void* arg)
|
||||
|
||||
Like :c:func:`uv_thread_create`, but additionally specifies options for creating a new thread.
|
||||
|
|
@ -132,6 +140,23 @@ Threads
|
|||
.. c:function:: int uv_thread_join(uv_thread_t *tid)
|
||||
.. c:function:: int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2)
|
||||
|
||||
.. c:function:: int uv_thread_setname(const char* name)
|
||||
|
||||
Sets the name of the current thread. Different platforms define different limits on the max number of characters
|
||||
a thread name can be: Linux, IBM i (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.
|
||||
|
||||
.. versionadded:: 1.50.0
|
||||
|
||||
.. c:function:: int uv_thread_getname(uv_thread_t* tid, char* name, size_t* size)
|
||||
|
||||
Gets the name of the thread specified by `tid`. The thread name is copied, with the trailing NUL, 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
|
||||
with the trailing NUL.
|
||||
|
||||
.. versionadded:: 1.50.0
|
||||
|
||||
.. c:function:: int uv_thread_setpriority(uv_thread_t tid, int priority)
|
||||
If the function succeeds, the return value is 0.
|
||||
If the function fails, the return value is less than zero.
|
||||
|
|
|
|||
2
deps/uv/docs/src/threadpool.rst
vendored
2
deps/uv/docs/src/threadpool.rst
vendored
|
|
@ -17,6 +17,8 @@ is 1024).
|
|||
.. versionchanged:: 1.45.0 threads now have an 8 MB stack instead of the
|
||||
(sometimes too low) platform default.
|
||||
|
||||
.. versionchanged:: 1.50.0 threads now have a default name of libuv-worker.
|
||||
|
||||
The threadpool is global and shared across all event loops. When a particular
|
||||
function makes use of the threadpool (i.e. when using :c:func:`uv_queue_work`)
|
||||
libuv preallocates and initializes the maximum number of threads allowed by
|
||||
|
|
|
|||
14
deps/uv/docs/src/timer.rst
vendored
14
deps/uv/docs/src/timer.rst
vendored
|
|
@ -6,6 +6,15 @@
|
|||
|
||||
Timer handles are used to schedule callbacks to be called in the future.
|
||||
|
||||
Timers are either single-shot or repeating. Repeating timers do not adjust
|
||||
for overhead but are rearmed relative to the event loop's idea of "now".
|
||||
|
||||
Libuv updates its idea of "now" right before executing timer callbacks, and
|
||||
right after waking up from waiting for I/O. See also :c:func:`uv_update_time`.
|
||||
|
||||
Example: a repeating timer with a 50 ms interval whose callback takes 17 ms
|
||||
to complete, runs again 33 ms later. If other tasks take longer than 33 ms,
|
||||
the timer callback runs as soon as possible.
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
|
@ -64,11 +73,6 @@ API
|
|||
duration, and will follow normal timer semantics in the case of a
|
||||
time-slice overrun.
|
||||
|
||||
For example, if a 50ms repeating timer first runs for 17ms, it will be
|
||||
scheduled to run again 33ms later. If other tasks consume more than the
|
||||
33ms following the first timer callback, then the callback will run as soon
|
||||
as possible.
|
||||
|
||||
.. note::
|
||||
If the repeat value is set from a timer callback it does not immediately take effect.
|
||||
If the timer was non-repeating before, it will have been stopped. If it was repeating,
|
||||
|
|
|
|||
14
deps/uv/docs/src/udp.rst
vendored
14
deps/uv/docs/src/udp.rst
vendored
|
|
@ -426,6 +426,20 @@ API
|
|||
|
||||
.. versionchanged:: 1.27.0 added support for connected sockets
|
||||
|
||||
.. c:function:: int uv_udp_try_send2(uv_udp_t* handle, unsigned int count, uv_buf_t* bufs[/*count*/], unsigned int nbufs[/*count*/], struct sockaddr* addrs[/*count*/], unsigned int flags)
|
||||
|
||||
Like :c:func:`uv_udp_try_send`, but can send multiple datagrams.
|
||||
Lightweight abstraction around :man:`sendmmsg(2)`, with a :man:`sendmsg(2)`
|
||||
fallback loop for platforms that do not support the former. The handle must
|
||||
be fully initialized; call c:func:`uv_udp_bind` first.
|
||||
|
||||
:returns: >= 0: number of datagrams sent. Zero only if `count` was zero.
|
||||
< 0: negative error code. Only if sending the first datagram fails,
|
||||
otherwise returns a positive send count. ``UV_EAGAIN`` when datagrams
|
||||
cannot be sent right now; fall back to :c:func:`uv_udp_send`.
|
||||
|
||||
.. versionadded:: 1.50.0
|
||||
|
||||
.. c:function:: int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb, uv_udp_recv_cb recv_cb)
|
||||
|
||||
Prepare for receiving data. If the socket has not previously been bound
|
||||
|
|
|
|||
12
deps/uv/include/uv.h
vendored
12
deps/uv/include/uv.h
vendored
|
|
@ -157,6 +157,7 @@ struct uv__queue {
|
|||
XX(ESOCKTNOSUPPORT, "socket type not supported") \
|
||||
XX(ENODATA, "no data available") \
|
||||
XX(EUNATCH, "protocol driver not attached") \
|
||||
XX(ENOEXEC, "exec format error") \
|
||||
|
||||
#define UV_HANDLE_TYPE_MAP(XX) \
|
||||
XX(ASYNC, async) \
|
||||
|
|
@ -775,6 +776,12 @@ UV_EXTERN int uv_udp_try_send(uv_udp_t* handle,
|
|||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs,
|
||||
const struct sockaddr* addr);
|
||||
UV_EXTERN int uv_udp_try_send2(uv_udp_t* handle,
|
||||
unsigned int count,
|
||||
uv_buf_t* bufs[/*count*/],
|
||||
unsigned int nbufs[/*count*/],
|
||||
struct sockaddr* addrs[/*count*/],
|
||||
unsigned int flags);
|
||||
UV_EXTERN int uv_udp_recv_start(uv_udp_t* handle,
|
||||
uv_alloc_cb alloc_cb,
|
||||
uv_udp_recv_cb recv_cb);
|
||||
|
|
@ -1288,6 +1295,7 @@ typedef struct {
|
|||
} uv_rusage_t;
|
||||
|
||||
UV_EXTERN int uv_getrusage(uv_rusage_t* rusage);
|
||||
UV_EXTERN int uv_getrusage_thread(uv_rusage_t* rusage);
|
||||
|
||||
UV_EXTERN int uv_os_homedir(char* buffer, size_t* size);
|
||||
UV_EXTERN int uv_os_tmpdir(char* buffer, size_t* size);
|
||||
|
|
@ -1869,6 +1877,7 @@ UV_EXTERN int uv_gettimeofday(uv_timeval64_t* tv);
|
|||
typedef void (*uv_thread_cb)(void* arg);
|
||||
|
||||
UV_EXTERN int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg);
|
||||
UV_EXTERN int uv_thread_detach(uv_thread_t* tid);
|
||||
|
||||
typedef enum {
|
||||
UV_THREAD_NO_FLAGS = 0x00,
|
||||
|
|
@ -1898,6 +1907,9 @@ UV_EXTERN int uv_thread_getcpu(void);
|
|||
UV_EXTERN uv_thread_t uv_thread_self(void);
|
||||
UV_EXTERN int uv_thread_join(uv_thread_t *tid);
|
||||
UV_EXTERN int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2);
|
||||
UV_EXTERN int uv_thread_setname(const char* name);
|
||||
UV_EXTERN int uv_thread_getname(uv_thread_t* tid, char* name, size_t size);
|
||||
|
||||
|
||||
/* The presence of these unions force similar struct layout. */
|
||||
#define XX(_, name) uv_ ## name ## _t name;
|
||||
|
|
|
|||
6
deps/uv/include/uv/errno.h
vendored
6
deps/uv/include/uv/errno.h
vendored
|
|
@ -474,4 +474,10 @@
|
|||
# define UV__EUNATCH (-4023)
|
||||
#endif
|
||||
|
||||
#if defined(ENOEXEC) && !defined(_WIN32)
|
||||
# define UV__ENOEXEC UV__ERR(ENOEXEC)
|
||||
#else
|
||||
# define UV__ENOEXEC (-4022)
|
||||
#endif
|
||||
|
||||
#endif /* UV_ERRNO_H_ */
|
||||
|
|
|
|||
5
deps/uv/include/uv/unix.h
vendored
5
deps/uv/include/uv/unix.h
vendored
|
|
@ -271,7 +271,10 @@ typedef struct {
|
|||
|
||||
#define UV_UDP_SEND_PRIVATE_FIELDS \
|
||||
struct uv__queue queue; \
|
||||
struct sockaddr_storage addr; \
|
||||
union { \
|
||||
struct sockaddr addr; \
|
||||
struct sockaddr_storage storage; \
|
||||
} u; \
|
||||
unsigned int nbufs; \
|
||||
uv_buf_t* bufs; \
|
||||
ssize_t status; \
|
||||
|
|
|
|||
4
deps/uv/include/uv/version.h
vendored
4
deps/uv/include/uv/version.h
vendored
|
|
@ -31,8 +31,8 @@
|
|||
*/
|
||||
|
||||
#define UV_VERSION_MAJOR 1
|
||||
#define UV_VERSION_MINOR 49
|
||||
#define UV_VERSION_PATCH 2
|
||||
#define UV_VERSION_MINOR 50
|
||||
#define UV_VERSION_PATCH 0
|
||||
#define UV_VERSION_IS_RELEASE 1
|
||||
#define UV_VERSION_SUFFIX ""
|
||||
|
||||
|
|
|
|||
10
deps/uv/include/uv/win.h
vendored
10
deps/uv/include/uv/win.h
vendored
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
|
||||
#ifndef _WIN32_WINNT
|
||||
# define _WIN32_WINNT 0x0600
|
||||
# define _WIN32_WINNT 0x0A00
|
||||
#endif
|
||||
|
||||
#if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED)
|
||||
|
|
@ -32,14 +32,6 @@ typedef intptr_t ssize_t;
|
|||
|
||||
#include <winsock2.h>
|
||||
|
||||
#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
|
||||
typedef struct pollfd {
|
||||
SOCKET fd;
|
||||
short events;
|
||||
short revents;
|
||||
} WSAPOLLFD, *PWSAPOLLFD, *LPWSAPOLLFD;
|
||||
#endif
|
||||
|
||||
#ifndef LOCALE_INVARIANT
|
||||
# define LOCALE_INVARIANT 0x007f
|
||||
#endif
|
||||
|
|
|
|||
3
deps/uv/src/fs-poll.c
vendored
3
deps/uv/src/fs-poll.c
vendored
|
|
@ -139,6 +139,9 @@ int uv_fs_poll_getpath(uv_fs_poll_t* handle, char* buffer, size_t* size) {
|
|||
struct poll_ctx* ctx;
|
||||
size_t required_len;
|
||||
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (!uv_is_active((uv_handle_t*)handle)) {
|
||||
*size = 0;
|
||||
return UV_EINVAL;
|
||||
|
|
|
|||
2
deps/uv/src/idna.c
vendored
2
deps/uv/src/idna.c
vendored
|
|
@ -393,7 +393,7 @@ void uv_wtf8_to_utf16(const char* source_ptr,
|
|||
code_point = uv__wtf8_decode1(&source_ptr);
|
||||
/* uv_wtf8_length_as_utf16 should have been called and checked first. */
|
||||
assert(code_point >= 0);
|
||||
if (code_point > 0x10000) {
|
||||
if (code_point > 0xFFFF) {
|
||||
assert(code_point < 0x10FFFF);
|
||||
*w_target++ = (((code_point - 0x10000) >> 10) + 0xD800);
|
||||
*w_target++ = ((code_point - 0x10000) & 0x3FF) + 0xDC00;
|
||||
|
|
|
|||
1
deps/uv/src/threadpool.c
vendored
1
deps/uv/src/threadpool.c
vendored
|
|
@ -59,6 +59,7 @@ static void worker(void* arg) {
|
|||
struct uv__queue* q;
|
||||
int is_slow_work;
|
||||
|
||||
uv_thread_setname("libuv-worker");
|
||||
uv_sem_post((uv_sem_t*) arg);
|
||||
arg = NULL;
|
||||
|
||||
|
|
|
|||
83
deps/uv/src/unix/async.c
vendored
83
deps/uv/src/unix/async.c
vendored
|
|
@ -38,6 +38,34 @@
|
|||
#include <sys/eventfd.h>
|
||||
#endif
|
||||
|
||||
#if UV__KQUEUE_EVFILT_USER
|
||||
static uv_once_t kqueue_runtime_detection_guard = UV_ONCE_INIT;
|
||||
static int kqueue_evfilt_user_support = 1;
|
||||
|
||||
|
||||
static void uv__kqueue_runtime_detection(void) {
|
||||
int kq;
|
||||
struct kevent ev[2];
|
||||
struct timespec timeout = {0, 0};
|
||||
|
||||
/* Perform the runtime detection to ensure that kqueue with
|
||||
* EVFILT_USER actually works. */
|
||||
kq = kqueue();
|
||||
EV_SET(ev, UV__KQUEUE_EVFILT_USER_IDENT, EVFILT_USER,
|
||||
EV_ADD | EV_CLEAR, 0, 0, 0);
|
||||
EV_SET(ev + 1, UV__KQUEUE_EVFILT_USER_IDENT, EVFILT_USER,
|
||||
0, NOTE_TRIGGER, 0, 0);
|
||||
if (kevent(kq, ev, 2, ev, 1, &timeout) < 1 ||
|
||||
ev[0].filter != EVFILT_USER ||
|
||||
ev[0].ident != UV__KQUEUE_EVFILT_USER_IDENT ||
|
||||
ev[0].flags & EV_ERROR)
|
||||
/* If we wind up here, we can assume that EVFILT_USER is defined but
|
||||
* broken on the current system. */
|
||||
kqueue_evfilt_user_support = 0;
|
||||
uv__close(kq);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void uv__async_send(uv_loop_t* loop);
|
||||
static int uv__async_start(uv_loop_t* loop);
|
||||
static void uv__cpu_relax(void);
|
||||
|
|
@ -139,7 +167,11 @@ static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
|||
|
||||
assert(w == &loop->async_io_watcher);
|
||||
|
||||
#if UV__KQUEUE_EVFILT_USER
|
||||
for (;!kqueue_evfilt_user_support;) {
|
||||
#else
|
||||
for (;;) {
|
||||
#endif
|
||||
r = read(w->fd, buf, sizeof(buf));
|
||||
|
||||
if (r == sizeof(buf))
|
||||
|
|
@ -195,6 +227,17 @@ static void uv__async_send(uv_loop_t* loop) {
|
|||
len = sizeof(val);
|
||||
fd = loop->async_io_watcher.fd; /* eventfd */
|
||||
}
|
||||
#elif UV__KQUEUE_EVFILT_USER
|
||||
struct kevent ev;
|
||||
|
||||
if (kqueue_evfilt_user_support) {
|
||||
fd = loop->async_io_watcher.fd; /* magic number for EVFILT_USER */
|
||||
EV_SET(&ev, fd, EVFILT_USER, 0, NOTE_TRIGGER, 0, 0);
|
||||
r = kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL);
|
||||
if (r == 0)
|
||||
return;
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
do
|
||||
|
|
@ -215,6 +258,9 @@ static void uv__async_send(uv_loop_t* loop) {
|
|||
static int uv__async_start(uv_loop_t* loop) {
|
||||
int pipefd[2];
|
||||
int err;
|
||||
#if UV__KQUEUE_EVFILT_USER
|
||||
struct kevent ev;
|
||||
#endif
|
||||
|
||||
if (loop->async_io_watcher.fd != -1)
|
||||
return 0;
|
||||
|
|
@ -226,6 +272,36 @@ static int uv__async_start(uv_loop_t* loop) {
|
|||
|
||||
pipefd[0] = err;
|
||||
pipefd[1] = -1;
|
||||
#elif UV__KQUEUE_EVFILT_USER
|
||||
uv_once(&kqueue_runtime_detection_guard, uv__kqueue_runtime_detection);
|
||||
if (kqueue_evfilt_user_support) {
|
||||
/* In order not to break the generic pattern of I/O polling, a valid
|
||||
* file descriptor is required to take up a room in loop->watchers,
|
||||
* thus we create one for that, but this fd will not be actually used,
|
||||
* it's just a placeholder and magic number which is going to be closed
|
||||
* during the cleanup, as other FDs. */
|
||||
err = uv__open_cloexec("/dev/null", O_RDONLY);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
pipefd[0] = err;
|
||||
pipefd[1] = -1;
|
||||
|
||||
/* When using EVFILT_USER event to wake up the kqueue, this event must be
|
||||
* registered beforehand. Otherwise, calling kevent() to issue an
|
||||
* unregistered EVFILT_USER event will get an ENOENT.
|
||||
* Since uv__async_send() may happen before uv__io_poll() with multi-threads,
|
||||
* we can't defer this registration of EVFILT_USER event as we did for other
|
||||
* events, but must perform it right away. */
|
||||
EV_SET(&ev, err, EVFILT_USER, EV_ADD | EV_CLEAR, 0, 0, 0);
|
||||
err = kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL);
|
||||
if (err < 0)
|
||||
return UV__ERR(errno);
|
||||
} else {
|
||||
err = uv__make_pipe(pipefd, UV_NONBLOCK_PIPE);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
err = uv__make_pipe(pipefd, UV_NONBLOCK_PIPE);
|
||||
if (err < 0)
|
||||
|
|
@ -236,6 +312,13 @@ static int uv__async_start(uv_loop_t* loop) {
|
|||
uv__io_start(loop, &loop->async_io_watcher, POLLIN);
|
||||
loop->async_wfd = pipefd[1];
|
||||
|
||||
#if UV__KQUEUE_EVFILT_USER
|
||||
/* Prevent the EVFILT_USER event from being added to kqueue redundantly
|
||||
* and mistakenly later in uv__io_poll(). */
|
||||
if (kqueue_evfilt_user_support)
|
||||
loop->async_io_watcher.events = loop->async_io_watcher.pevents;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
50
deps/uv/src/unix/core.c
vendored
50
deps/uv/src/unix/core.c
vendored
|
|
@ -52,6 +52,8 @@
|
|||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
# include <mach/mach.h>
|
||||
# include <mach/thread_info.h>
|
||||
# include <sys/filio.h>
|
||||
# include <sys/sysctl.h>
|
||||
#endif /* defined(__APPLE__) */
|
||||
|
|
@ -751,7 +753,7 @@ ssize_t uv__recvmsg(int fd, struct msghdr* msg, int flags) {
|
|||
int uv_cwd(char* buffer, size_t* size) {
|
||||
char scratch[1 + UV__PATH_MAX];
|
||||
|
||||
if (buffer == NULL || size == NULL)
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
/* Try to read directly into the user's buffer first... */
|
||||
|
|
@ -999,10 +1001,10 @@ int uv__fd_exists(uv_loop_t* loop, int fd) {
|
|||
}
|
||||
|
||||
|
||||
int uv_getrusage(uv_rusage_t* rusage) {
|
||||
static int uv__getrusage(int who, uv_rusage_t* rusage) {
|
||||
struct rusage usage;
|
||||
|
||||
if (getrusage(RUSAGE_SELF, &usage))
|
||||
if (getrusage(who, &usage))
|
||||
return UV__ERR(errno);
|
||||
|
||||
rusage->ru_utime.tv_sec = usage.ru_utime.tv_sec;
|
||||
|
|
@ -1041,6 +1043,48 @@ int uv_getrusage(uv_rusage_t* rusage) {
|
|||
}
|
||||
|
||||
|
||||
int uv_getrusage(uv_rusage_t* rusage) {
|
||||
return uv__getrusage(RUSAGE_SELF, rusage);
|
||||
}
|
||||
|
||||
|
||||
int uv_getrusage_thread(uv_rusage_t* rusage) {
|
||||
#if defined(__APPLE__)
|
||||
mach_msg_type_number_t count;
|
||||
thread_basic_info_data_t info;
|
||||
kern_return_t kr;
|
||||
thread_t thread;
|
||||
|
||||
thread = mach_thread_self();
|
||||
count = THREAD_BASIC_INFO_COUNT;
|
||||
kr = thread_info(thread,
|
||||
THREAD_BASIC_INFO,
|
||||
(thread_info_t)&info,
|
||||
&count);
|
||||
|
||||
if (kr != KERN_SUCCESS) {
|
||||
mach_port_deallocate(mach_task_self(), thread);
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
memset(rusage, 0, sizeof(*rusage));
|
||||
|
||||
rusage->ru_utime.tv_sec = info.user_time.seconds;
|
||||
rusage->ru_utime.tv_usec = info.user_time.microseconds;
|
||||
rusage->ru_stime.tv_sec = info.system_time.seconds;
|
||||
rusage->ru_stime.tv_usec = info.system_time.microseconds;
|
||||
|
||||
mach_port_deallocate(mach_task_self(), thread);
|
||||
|
||||
return 0;
|
||||
|
||||
#elif defined(RUSAGE_THREAD)
|
||||
return uv__getrusage(RUSAGE_THREAD, rusage);
|
||||
#endif /* defined(__APPLE__) */
|
||||
return UV_ENOTSUP;
|
||||
}
|
||||
|
||||
|
||||
int uv__open_cloexec(const char* path, int flags) {
|
||||
#if defined(O_CLOEXEC)
|
||||
int fd;
|
||||
|
|
|
|||
20
deps/uv/src/unix/darwin-proctitle.c
vendored
20
deps/uv/src/unix/darwin-proctitle.c
vendored
|
|
@ -33,25 +33,9 @@
|
|||
#include "darwin-stub.h"
|
||||
#endif
|
||||
|
||||
|
||||
static int uv__pthread_setname_np(const char* name) {
|
||||
char namebuf[64]; /* MAXTHREADNAMESIZE */
|
||||
int err;
|
||||
|
||||
strncpy(namebuf, name, sizeof(namebuf) - 1);
|
||||
namebuf[sizeof(namebuf) - 1] = '\0';
|
||||
|
||||
err = pthread_setname_np(namebuf);
|
||||
if (err)
|
||||
return UV__ERR(err);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv__set_process_title(const char* title) {
|
||||
#if TARGET_OS_IPHONE
|
||||
return uv__pthread_setname_np(title);
|
||||
return uv__thread_setname(title);
|
||||
#else
|
||||
CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef,
|
||||
const char*,
|
||||
|
|
@ -177,7 +161,7 @@ int uv__set_process_title(const char* title) {
|
|||
goto out;
|
||||
}
|
||||
|
||||
uv__pthread_setname_np(title); /* Don't care if it fails. */
|
||||
uv__thread_setname(title); /* Don't care if it fails. */
|
||||
err = 0;
|
||||
|
||||
out:
|
||||
|
|
|
|||
24
deps/uv/src/unix/internal.h
vendored
24
deps/uv/src/unix/internal.h
vendored
|
|
@ -35,6 +35,10 @@
|
|||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#if defined(__APPLE__) || defined(__DragonFly__) || \
|
||||
defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
#include <sys/event.h>
|
||||
#endif
|
||||
|
||||
#define uv__msan_unpoison(p, n) \
|
||||
do { \
|
||||
|
|
@ -323,6 +327,8 @@ void uv__prepare_close(uv_prepare_t* handle);
|
|||
void uv__process_close(uv_process_t* handle);
|
||||
void uv__stream_close(uv_stream_t* handle);
|
||||
void uv__tcp_close(uv_tcp_t* handle);
|
||||
int uv__thread_setname(const char* name);
|
||||
int uv__thread_getname(uv_thread_t* tid, char* name, size_t size);
|
||||
size_t uv__thread_stack_size(void);
|
||||
void uv__udp_close(uv_udp_t* handle);
|
||||
void uv__udp_finish_close(uv_udp_t* handle);
|
||||
|
|
@ -504,4 +510,22 @@ int uv__get_constrained_cpu(uv__cpu_constraint* constraint);
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(EVFILT_USER) && defined(NOTE_TRIGGER)
|
||||
/* EVFILT_USER is available since OS X 10.6, DragonFlyBSD 4.0,
|
||||
* FreeBSD 8.1, and NetBSD 10.0.
|
||||
*
|
||||
* Note that even though EVFILT_USER is defined on the current system,
|
||||
* it may still fail to work at runtime somehow. In that case, we fall
|
||||
* back to pipe-based signaling.
|
||||
*/
|
||||
#define UV__KQUEUE_EVFILT_USER 1
|
||||
/* Magic number of identifier used for EVFILT_USER during runtime detection.
|
||||
* There are no Google hits for this number when I create it. That way,
|
||||
* people will be directed here if this number gets printed due to some
|
||||
* kqueue error and they google for help. */
|
||||
#define UV__KQUEUE_EVFILT_USER_IDENT 0x1e7e7711
|
||||
#else
|
||||
#define UV__KQUEUE_EVFILT_USER 0
|
||||
#endif
|
||||
|
||||
#endif /* UV_UNIX_INTERNAL_H_ */
|
||||
|
|
|
|||
29
deps/uv/src/unix/kqueue.c
vendored
29
deps/uv/src/unix/kqueue.c
vendored
|
|
@ -97,8 +97,7 @@ int uv__io_fork(uv_loop_t* loop) {
|
|||
|
||||
|
||||
int uv__io_check_fd(uv_loop_t* loop, int fd) {
|
||||
struct kevent ev;
|
||||
int rc;
|
||||
struct kevent ev[2];
|
||||
struct stat sb;
|
||||
#ifdef __APPLE__
|
||||
char path[MAXPATHLEN];
|
||||
|
|
@ -133,17 +132,12 @@ int uv__io_check_fd(uv_loop_t* loop, int fd) {
|
|||
}
|
||||
#endif
|
||||
|
||||
rc = 0;
|
||||
EV_SET(&ev, fd, EVFILT_READ, EV_ADD, 0, 0, 0);
|
||||
if (kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL))
|
||||
rc = UV__ERR(errno);
|
||||
EV_SET(ev, fd, EVFILT_READ, EV_ADD, 0, 0, 0);
|
||||
EV_SET(ev + 1, fd, EVFILT_READ, EV_DELETE, 0, 0, 0);
|
||||
if (kevent(loop->backend_fd, ev, 2, NULL, 0, NULL))
|
||||
return UV__ERR(errno);
|
||||
|
||||
EV_SET(&ev, fd, EVFILT_READ, EV_DELETE, 0, 0, 0);
|
||||
if (rc == 0)
|
||||
if (kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL))
|
||||
abort();
|
||||
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -367,6 +361,17 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
|||
continue;
|
||||
}
|
||||
|
||||
#if UV__KQUEUE_EVFILT_USER
|
||||
if (ev->filter == EVFILT_USER) {
|
||||
w = &loop->async_io_watcher;
|
||||
assert(fd == w->fd);
|
||||
uv__metrics_update_idle_time(loop);
|
||||
w->cb(loop, w, w->events);
|
||||
nevents++;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ev->filter == EVFILT_VNODE) {
|
||||
assert(w->events == POLLIN);
|
||||
assert(w->pevents == POLLIN);
|
||||
|
|
|
|||
77
deps/uv/src/unix/linux.c
vendored
77
deps/uv/src/unix/linux.c
vendored
|
|
@ -455,7 +455,7 @@ int uv__io_uring_register(int fd, unsigned opcode, void* arg, unsigned nargs) {
|
|||
}
|
||||
|
||||
|
||||
static int uv__use_io_uring(void) {
|
||||
static int uv__use_io_uring(uint32_t flags) {
|
||||
#if defined(__ANDROID_API__)
|
||||
return 0; /* Possibly available but blocked by seccomp. */
|
||||
#elif defined(__arm__) && __SIZEOF_POINTER__ == 4
|
||||
|
|
@ -470,25 +470,27 @@ static int uv__use_io_uring(void) {
|
|||
char* val;
|
||||
int use;
|
||||
|
||||
#if defined(__hppa__)
|
||||
/* io_uring first supported on parisc in 6.1, functional in .51
|
||||
* https://lore.kernel.org/all/cb912694-b1fe-dbb0-4d8c-d608f3526905@gmx.de/
|
||||
*/
|
||||
if (uv__kernel_version() < /*6.1.51*/0x060133)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
/* SQPOLL is all kinds of buggy but epoll batching should work fine. */
|
||||
if (0 == (flags & UV__IORING_SETUP_SQPOLL))
|
||||
return 1;
|
||||
|
||||
/* Older kernels have a bug where the sqpoll thread uses 100% CPU. */
|
||||
if (uv__kernel_version() < /*5.10.186*/0x050ABA)
|
||||
return 0;
|
||||
|
||||
use = atomic_load_explicit(&use_io_uring, memory_order_relaxed);
|
||||
|
||||
if (use == 0) {
|
||||
use = uv__kernel_version() >=
|
||||
#if defined(__hppa__)
|
||||
/* io_uring first supported on parisc in 6.1, functional in .51 */
|
||||
/* https://lore.kernel.org/all/cb912694-b1fe-dbb0-4d8c-d608f3526905@gmx.de/ */
|
||||
/* 6.1.51 */ 0x060133
|
||||
#else
|
||||
/* Older kernels have a bug where the sqpoll thread uses 100% CPU. */
|
||||
/* 5.10.186 */ 0x050ABA
|
||||
#endif
|
||||
? 1 : -1;
|
||||
|
||||
/* But users can still enable it if they so desire. */
|
||||
val = getenv("UV_USE_IO_URING");
|
||||
if (val != NULL)
|
||||
use = atoi(val) ? 1 : -1;
|
||||
|
||||
use = val != NULL && atoi(val) > 0 ? 1 : -1;
|
||||
atomic_store_explicit(&use_io_uring, use, memory_order_relaxed);
|
||||
}
|
||||
|
||||
|
|
@ -518,7 +520,7 @@ static void uv__iou_init(int epollfd,
|
|||
sq = MAP_FAILED;
|
||||
sqe = MAP_FAILED;
|
||||
|
||||
if (!uv__use_io_uring())
|
||||
if (!uv__use_io_uring(flags))
|
||||
return;
|
||||
|
||||
kernel_version = uv__kernel_version();
|
||||
|
|
@ -766,14 +768,13 @@ static struct uv__io_uring_sqe* uv__iou_get_sqe(struct uv__iou* iou,
|
|||
*/
|
||||
if (iou->ringfd == -2) {
|
||||
/* By default, the SQPOLL is not created. Enable only if the loop is
|
||||
* configured with UV_LOOP_USE_IO_URING_SQPOLL.
|
||||
* configured with UV_LOOP_USE_IO_URING_SQPOLL and the UV_USE_IO_URING
|
||||
* environment variable is unset or a positive number.
|
||||
*/
|
||||
if ((loop->flags & UV_LOOP_ENABLE_IO_URING_SQPOLL) == 0) {
|
||||
iou->ringfd = -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (loop->flags & UV_LOOP_ENABLE_IO_URING_SQPOLL)
|
||||
if (uv__use_io_uring(UV__IORING_SETUP_SQPOLL))
|
||||
uv__iou_init(loop->backend_fd, iou, 64, UV__IORING_SETUP_SQPOLL);
|
||||
|
||||
if (iou->ringfd == -2)
|
||||
iou->ringfd = -1; /* "failed" */
|
||||
}
|
||||
|
|
@ -1713,16 +1714,22 @@ int uv_uptime(double* uptime) {
|
|||
int uv_cpu_info(uv_cpu_info_t** ci, int* count) {
|
||||
#if defined(__PPC__)
|
||||
static const char model_marker[] = "cpu\t\t: ";
|
||||
static const char model_marker2[] = "";
|
||||
#elif defined(__arm__)
|
||||
static const char model_marker[] = "Processor\t: ";
|
||||
static const char model_marker[] = "model name\t: ";
|
||||
static const char model_marker2[] = "Processor\t: ";
|
||||
#elif defined(__aarch64__)
|
||||
static const char model_marker[] = "CPU part\t: ";
|
||||
static const char model_marker2[] = "";
|
||||
#elif defined(__mips__)
|
||||
static const char model_marker[] = "cpu model\t\t: ";
|
||||
static const char model_marker2[] = "";
|
||||
#elif defined(__loongarch__)
|
||||
static const char model_marker[] = "cpu family\t\t: ";
|
||||
static const char model_marker2[] = "";
|
||||
#else
|
||||
static const char model_marker[] = "model name\t: ";
|
||||
static const char model_marker2[] = "";
|
||||
#endif
|
||||
static const char parts[] =
|
||||
#ifdef __aarch64__
|
||||
|
|
@ -1821,14 +1828,22 @@ int uv_cpu_info(uv_cpu_info_t** ci, int* count) {
|
|||
if (1 != fscanf(fp, "processor\t: %u\n", &cpu))
|
||||
break; /* Parse error. */
|
||||
|
||||
found = 0;
|
||||
while (!found && fgets(buf, sizeof(buf), fp))
|
||||
found = !strncmp(buf, model_marker, sizeof(model_marker) - 1);
|
||||
|
||||
if (!found)
|
||||
goto next;
|
||||
|
||||
while (fgets(buf, sizeof(buf), fp)) {
|
||||
if (!strncmp(buf, model_marker, sizeof(model_marker) - 1)) {
|
||||
p = buf + sizeof(model_marker) - 1;
|
||||
goto parts;
|
||||
}
|
||||
if (!*model_marker2)
|
||||
continue;
|
||||
if (!strncmp(buf, model_marker2, sizeof(model_marker2) - 1)) {
|
||||
p = buf + sizeof(model_marker2) - 1;
|
||||
goto parts;
|
||||
}
|
||||
}
|
||||
|
||||
goto next; /* Not found. */
|
||||
|
||||
parts:
|
||||
n = (int) strcspn(p, "\n");
|
||||
|
||||
/* arm64: translate CPU part code to model name. */
|
||||
|
|
|
|||
30
deps/uv/src/unix/pipe.c
vendored
30
deps/uv/src/unix/pipe.c
vendored
|
|
@ -360,6 +360,9 @@ static int uv__pipe_getsockpeername(const uv_pipe_t* handle,
|
|||
char* p;
|
||||
int err;
|
||||
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
addrlen = sizeof(sa);
|
||||
memset(&sa, 0, addrlen);
|
||||
err = uv__getsockpeername((const uv_handle_t*) handle,
|
||||
|
|
@ -444,7 +447,7 @@ uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle) {
|
|||
int uv_pipe_chmod(uv_pipe_t* handle, int mode) {
|
||||
unsigned desired_mode;
|
||||
struct stat pipe_stat;
|
||||
char* name_buffer;
|
||||
char name_buffer[1 + UV__PATH_MAX];
|
||||
size_t name_len;
|
||||
int r;
|
||||
|
||||
|
|
@ -457,26 +460,14 @@ int uv_pipe_chmod(uv_pipe_t* handle, int mode) {
|
|||
return UV_EINVAL;
|
||||
|
||||
/* Unfortunately fchmod does not work on all platforms, we will use chmod. */
|
||||
name_len = 0;
|
||||
r = uv_pipe_getsockname(handle, NULL, &name_len);
|
||||
if (r != UV_ENOBUFS)
|
||||
return r;
|
||||
|
||||
name_buffer = uv__malloc(name_len);
|
||||
if (name_buffer == NULL)
|
||||
return UV_ENOMEM;
|
||||
|
||||
name_len = sizeof(name_buffer);
|
||||
r = uv_pipe_getsockname(handle, name_buffer, &name_len);
|
||||
if (r != 0) {
|
||||
uv__free(name_buffer);
|
||||
if (r != 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* stat must be used as fstat has a bug on Darwin */
|
||||
if (uv__stat(name_buffer, &pipe_stat) == -1) {
|
||||
uv__free(name_buffer);
|
||||
return -errno;
|
||||
}
|
||||
if (uv__stat(name_buffer, &pipe_stat) == -1)
|
||||
return UV__ERR(errno);
|
||||
|
||||
desired_mode = 0;
|
||||
if (mode & UV_READABLE)
|
||||
|
|
@ -485,15 +476,12 @@ int uv_pipe_chmod(uv_pipe_t* handle, int mode) {
|
|||
desired_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
|
||||
|
||||
/* Exit early if pipe already has desired mode. */
|
||||
if ((pipe_stat.st_mode & desired_mode) == desired_mode) {
|
||||
uv__free(name_buffer);
|
||||
if ((pipe_stat.st_mode & desired_mode) == desired_mode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
pipe_stat.st_mode |= desired_mode;
|
||||
|
||||
r = chmod(name_buffer, pipe_stat.st_mode);
|
||||
uv__free(name_buffer);
|
||||
|
||||
return r != -1 ? 0 : UV__ERR(errno);
|
||||
}
|
||||
|
|
|
|||
98
deps/uv/src/unix/thread.c
vendored
98
deps/uv/src/unix/thread.c
vendored
|
|
@ -23,6 +23,9 @@
|
|||
#include "internal.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#ifdef __OpenBSD__
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
|
@ -126,6 +129,12 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
|
|||
return uv_thread_create_ex(tid, ¶ms, entry, arg);
|
||||
}
|
||||
|
||||
|
||||
int uv_thread_detach(uv_thread_t *tid) {
|
||||
return UV__ERR(pthread_detach(*tid));
|
||||
}
|
||||
|
||||
|
||||
int uv_thread_create_ex(uv_thread_t* tid,
|
||||
const uv_thread_options_t* params,
|
||||
void (*entry)(void *arg),
|
||||
|
|
@ -291,6 +300,18 @@ int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) {
|
|||
return pthread_equal(*t1, *t2);
|
||||
}
|
||||
|
||||
int uv_thread_setname(const char* name) {
|
||||
if (name == NULL)
|
||||
return UV_EINVAL;
|
||||
return uv__thread_setname(name);
|
||||
}
|
||||
|
||||
int uv_thread_getname(uv_thread_t* tid, char* name, size_t size) {
|
||||
if (name == NULL || size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
return uv__thread_getname(tid, name, size);
|
||||
}
|
||||
|
||||
int uv_mutex_init(uv_mutex_t* mutex) {
|
||||
#if defined(NDEBUG) || !defined(PTHREAD_MUTEX_ERRORCHECK)
|
||||
|
|
@ -875,3 +896,80 @@ void uv_key_set(uv_key_t* key, void* value) {
|
|||
if (pthread_setspecific(*key, value))
|
||||
abort();
|
||||
}
|
||||
|
||||
#if defined(_AIX) || defined(__MVS__) || defined(__PASE__)
|
||||
int uv__thread_setname(const char* name) {
|
||||
return UV_ENOSYS;
|
||||
}
|
||||
#elif defined(__APPLE__)
|
||||
int uv__thread_setname(const char* name) {
|
||||
char namebuf[UV_PTHREAD_MAX_NAMELEN_NP];
|
||||
strncpy(namebuf, name, sizeof(namebuf) - 1);
|
||||
namebuf[sizeof(namebuf) - 1] = '\0';
|
||||
int err = pthread_setname_np(namebuf);
|
||||
if (err)
|
||||
return UV__ERR(errno);
|
||||
return 0;
|
||||
}
|
||||
#elif defined(__NetBSD__)
|
||||
int uv__thread_setname(const char* name) {
|
||||
char namebuf[UV_PTHREAD_MAX_NAMELEN_NP];
|
||||
strncpy(namebuf, name, sizeof(namebuf) - 1);
|
||||
namebuf[sizeof(namebuf) - 1] = '\0';
|
||||
return UV__ERR(pthread_setname_np(pthread_self(), "%s", namebuf));
|
||||
}
|
||||
#elif defined(__OpenBSD__)
|
||||
int uv__thread_setname(const char* name) {
|
||||
char namebuf[UV_PTHREAD_MAX_NAMELEN_NP];
|
||||
strncpy(namebuf, name, sizeof(namebuf) - 1);
|
||||
namebuf[sizeof(namebuf) - 1] = '\0';
|
||||
pthread_set_name_np(pthread_self(), namebuf);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int uv__thread_setname(const char* name) {
|
||||
char namebuf[UV_PTHREAD_MAX_NAMELEN_NP];
|
||||
strncpy(namebuf, name, sizeof(namebuf) - 1);
|
||||
namebuf[sizeof(namebuf) - 1] = '\0';
|
||||
return UV__ERR(pthread_setname_np(pthread_self(), namebuf));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined(__ANDROID_API__) && __ANDROID_API__ < 26) || \
|
||||
defined(_AIX) || \
|
||||
defined(__MVS__) || \
|
||||
defined(__PASE__)
|
||||
int uv__thread_getname(uv_thread_t* tid, char* name, size_t size) {
|
||||
return UV_ENOSYS;
|
||||
}
|
||||
#elif defined(__OpenBSD__)
|
||||
int uv__thread_getname(uv_thread_t* tid, char* name, size_t size) {
|
||||
char thread_name[UV_PTHREAD_MAX_NAMELEN_NP];
|
||||
pthread_get_name_np(*tid, thread_name, sizeof(thread_name));
|
||||
strncpy(name, thread_name, size - 1);
|
||||
name[size - 1] = '\0';
|
||||
return 0;
|
||||
}
|
||||
#elif defined(__APPLE__)
|
||||
int uv__thread_getname(uv_thread_t* tid, char* name, size_t size) {
|
||||
char thread_name[UV_PTHREAD_MAX_NAMELEN_NP];
|
||||
if (pthread_getname_np(*tid, thread_name, sizeof(thread_name)) != 0)
|
||||
return UV__ERR(errno);
|
||||
|
||||
strncpy(name, thread_name, size - 1);
|
||||
name[size - 1] = '\0';
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int uv__thread_getname(uv_thread_t* tid, char* name, size_t size) {
|
||||
int r;
|
||||
char thread_name[UV_PTHREAD_MAX_NAMELEN_NP];
|
||||
r = pthread_getname_np(*tid, thread_name, sizeof(thread_name));
|
||||
if (r != 0)
|
||||
return UV__ERR(r);
|
||||
|
||||
strncpy(name, thread_name, size - 1);
|
||||
name[size - 1] = '\0';
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
387
deps/uv/src/unix/udp.c
vendored
387
deps/uv/src/unix/udp.c
vendored
|
|
@ -47,6 +47,10 @@ static void uv__udp_sendmsg(uv_udp_t* handle);
|
|||
static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
|
||||
int domain,
|
||||
unsigned int flags);
|
||||
static int uv__udp_sendmsg1(int fd,
|
||||
const uv_buf_t* bufs,
|
||||
unsigned int nbufs,
|
||||
const struct sockaddr* addr);
|
||||
|
||||
|
||||
void uv__udp_close(uv_udp_t* handle) {
|
||||
|
|
@ -282,169 +286,6 @@ static void uv__udp_recvmsg(uv_udp_t* handle) {
|
|||
&& handle->recv_cb != NULL);
|
||||
}
|
||||
|
||||
static void uv__udp_sendmsg_one(uv_udp_t* handle, uv_udp_send_t* req) {
|
||||
struct uv__queue* q;
|
||||
struct msghdr h;
|
||||
ssize_t size;
|
||||
|
||||
for (;;) {
|
||||
memset(&h, 0, sizeof h);
|
||||
if (req->addr.ss_family == AF_UNSPEC) {
|
||||
h.msg_name = NULL;
|
||||
h.msg_namelen = 0;
|
||||
} else {
|
||||
h.msg_name = &req->addr;
|
||||
if (req->addr.ss_family == AF_INET6)
|
||||
h.msg_namelen = sizeof(struct sockaddr_in6);
|
||||
else if (req->addr.ss_family == AF_INET)
|
||||
h.msg_namelen = sizeof(struct sockaddr_in);
|
||||
else if (req->addr.ss_family == AF_UNIX)
|
||||
h.msg_namelen = sizeof(struct sockaddr_un);
|
||||
else {
|
||||
assert(0 && "unsupported address family");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
h.msg_iov = (struct iovec*) req->bufs;
|
||||
h.msg_iovlen = req->nbufs;
|
||||
|
||||
do
|
||||
size = sendmsg(handle->io_watcher.fd, &h, 0);
|
||||
while (size == -1 && errno == EINTR);
|
||||
|
||||
if (size == -1)
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
|
||||
return;
|
||||
|
||||
req->status = (size == -1 ? UV__ERR(errno) : size);
|
||||
|
||||
/* Sending a datagram is an atomic operation: either all data
|
||||
* is written or nothing is (and EMSGSIZE is raised). That is
|
||||
* why we don't handle partial writes. Just pop the request
|
||||
* off the write queue and onto the completed queue, done.
|
||||
*/
|
||||
uv__queue_remove(&req->queue);
|
||||
uv__queue_insert_tail(&handle->write_completed_queue, &req->queue);
|
||||
uv__io_feed(handle->loop, &handle->io_watcher);
|
||||
|
||||
if (uv__queue_empty(&handle->write_queue))
|
||||
return;
|
||||
|
||||
q = uv__queue_head(&handle->write_queue);
|
||||
req = uv__queue_data(q, uv_udp_send_t, queue);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
|
||||
static void uv__udp_sendmsg_many(uv_udp_t* handle) {
|
||||
uv_udp_send_t* req;
|
||||
struct mmsghdr h[20];
|
||||
struct mmsghdr* p;
|
||||
struct uv__queue* q;
|
||||
ssize_t npkts;
|
||||
size_t pkts;
|
||||
size_t i;
|
||||
|
||||
write_queue_drain:
|
||||
for (pkts = 0, q = uv__queue_head(&handle->write_queue);
|
||||
pkts < ARRAY_SIZE(h) && q != &handle->write_queue;
|
||||
++pkts, q = uv__queue_head(q)) {
|
||||
req = uv__queue_data(q, uv_udp_send_t, queue);
|
||||
|
||||
p = &h[pkts];
|
||||
memset(p, 0, sizeof(*p));
|
||||
if (req->addr.ss_family == AF_UNSPEC) {
|
||||
p->msg_hdr.msg_name = NULL;
|
||||
p->msg_hdr.msg_namelen = 0;
|
||||
} else {
|
||||
p->msg_hdr.msg_name = &req->addr;
|
||||
if (req->addr.ss_family == AF_INET6)
|
||||
p->msg_hdr.msg_namelen = sizeof(struct sockaddr_in6);
|
||||
else if (req->addr.ss_family == AF_INET)
|
||||
p->msg_hdr.msg_namelen = sizeof(struct sockaddr_in);
|
||||
else if (req->addr.ss_family == AF_UNIX)
|
||||
p->msg_hdr.msg_namelen = sizeof(struct sockaddr_un);
|
||||
else {
|
||||
assert(0 && "unsupported address family");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
h[pkts].msg_hdr.msg_iov = (struct iovec*) req->bufs;
|
||||
h[pkts].msg_hdr.msg_iovlen = req->nbufs;
|
||||
}
|
||||
|
||||
#if defined(__APPLE__)
|
||||
do
|
||||
npkts = sendmsg_x(handle->io_watcher.fd, h, pkts, MSG_DONTWAIT);
|
||||
while (npkts == -1 && errno == EINTR);
|
||||
#else
|
||||
do
|
||||
npkts = sendmmsg(handle->io_watcher.fd, h, pkts, 0);
|
||||
while (npkts == -1 && errno == EINTR);
|
||||
#endif
|
||||
|
||||
if (npkts < 1) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
|
||||
return;
|
||||
for (i = 0, q = uv__queue_head(&handle->write_queue);
|
||||
i < pkts && q != &handle->write_queue;
|
||||
++i, q = uv__queue_head(&handle->write_queue)) {
|
||||
req = uv__queue_data(q, uv_udp_send_t, queue);
|
||||
req->status = UV__ERR(errno);
|
||||
uv__queue_remove(&req->queue);
|
||||
uv__queue_insert_tail(&handle->write_completed_queue, &req->queue);
|
||||
}
|
||||
uv__io_feed(handle->loop, &handle->io_watcher);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Safety: npkts known to be >0 below. Hence cast from ssize_t
|
||||
* to size_t safe.
|
||||
*/
|
||||
for (i = 0, q = uv__queue_head(&handle->write_queue);
|
||||
i < (size_t)npkts && q != &handle->write_queue;
|
||||
++i, q = uv__queue_head(&handle->write_queue)) {
|
||||
req = uv__queue_data(q, uv_udp_send_t, queue);
|
||||
req->status = req->bufs[0].len;
|
||||
|
||||
/* Sending a datagram is an atomic operation: either all data
|
||||
* is written or nothing is (and EMSGSIZE is raised). That is
|
||||
* why we don't handle partial writes. Just pop the request
|
||||
* off the write queue and onto the completed queue, done.
|
||||
*/
|
||||
uv__queue_remove(&req->queue);
|
||||
uv__queue_insert_tail(&handle->write_completed_queue, &req->queue);
|
||||
}
|
||||
|
||||
/* couldn't batch everything, continue sending (jump to avoid stack growth) */
|
||||
if (!uv__queue_empty(&handle->write_queue))
|
||||
goto write_queue_drain;
|
||||
|
||||
uv__io_feed(handle->loop, &handle->io_watcher);
|
||||
}
|
||||
#endif /* __linux__ || ____FreeBSD__ || __APPLE__ */
|
||||
|
||||
static void uv__udp_sendmsg(uv_udp_t* handle) {
|
||||
struct uv__queue* q;
|
||||
uv_udp_send_t* req;
|
||||
|
||||
if (uv__queue_empty(&handle->write_queue))
|
||||
return;
|
||||
|
||||
q = uv__queue_head(&handle->write_queue);
|
||||
req = uv__queue_data(q, uv_udp_send_t, queue);
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
|
||||
/* Use sendmmsg() if this send request contains more than one datagram OR
|
||||
* there is more than one send request (because that automatically implies
|
||||
* there is more than one datagram.)
|
||||
*/
|
||||
if (req->nbufs != 1 || &handle->write_queue != uv__queue_next(&req->queue))
|
||||
return uv__udp_sendmsg_many(handle);
|
||||
#endif
|
||||
|
||||
return uv__udp_sendmsg_one(handle, req);
|
||||
}
|
||||
|
||||
/* On the BSDs, SO_REUSEPORT implies SO_REUSEADDR but with some additional
|
||||
* refinements for programs that use multicast. Therefore we preferentially
|
||||
|
|
@ -743,11 +584,11 @@ int uv__udp_send(uv_udp_send_t* req,
|
|||
empty_queue = (handle->send_queue_count == 0);
|
||||
|
||||
uv__req_init(handle->loop, req, UV_UDP_SEND);
|
||||
assert(addrlen <= sizeof(req->addr));
|
||||
assert(addrlen <= sizeof(req->u.storage));
|
||||
if (addr == NULL)
|
||||
req->addr.ss_family = AF_UNSPEC;
|
||||
req->u.storage.ss_family = AF_UNSPEC;
|
||||
else
|
||||
memcpy(&req->addr, addr, addrlen);
|
||||
memcpy(&req->u.storage, addr, addrlen);
|
||||
req->send_cb = send_cb;
|
||||
req->handle = handle;
|
||||
req->nbufs = nbufs;
|
||||
|
|
@ -790,10 +631,9 @@ int uv__udp_try_send(uv_udp_t* handle,
|
|||
const struct sockaddr* addr,
|
||||
unsigned int addrlen) {
|
||||
int err;
|
||||
struct msghdr h;
|
||||
ssize_t size;
|
||||
|
||||
assert(nbufs > 0);
|
||||
if (nbufs < 1)
|
||||
return UV_EINVAL;
|
||||
|
||||
/* already sending a message */
|
||||
if (handle->send_queue_count != 0)
|
||||
|
|
@ -807,24 +647,11 @@ int uv__udp_try_send(uv_udp_t* handle,
|
|||
assert(handle->flags & UV_HANDLE_UDP_CONNECTED);
|
||||
}
|
||||
|
||||
memset(&h, 0, sizeof h);
|
||||
h.msg_name = (struct sockaddr*) addr;
|
||||
h.msg_namelen = addrlen;
|
||||
h.msg_iov = (struct iovec*) bufs;
|
||||
h.msg_iovlen = nbufs;
|
||||
err = uv__udp_sendmsg1(handle->io_watcher.fd, bufs, nbufs, addr);
|
||||
if (err > 0)
|
||||
return uv__count_bufs(bufs, nbufs);
|
||||
|
||||
do {
|
||||
size = sendmsg(handle->io_watcher.fd, &h, 0);
|
||||
} while (size == -1 && errno == EINTR);
|
||||
|
||||
if (size == -1) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
|
||||
return UV_EAGAIN;
|
||||
else
|
||||
return UV__ERR(errno);
|
||||
}
|
||||
|
||||
return size;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1401,3 +1228,191 @@ int uv__udp_recv_stop(uv_udp_t* handle) {
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int uv__udp_prep_pkt(struct msghdr* h,
|
||||
const uv_buf_t* bufs,
|
||||
const unsigned int nbufs,
|
||||
const struct sockaddr* addr) {
|
||||
memset(h, 0, sizeof(*h));
|
||||
h->msg_name = (void*) addr;
|
||||
h->msg_iov = (void*) bufs;
|
||||
h->msg_iovlen = nbufs;
|
||||
if (addr == NULL)
|
||||
return 0;
|
||||
switch (addr->sa_family) {
|
||||
case AF_INET:
|
||||
h->msg_namelen = sizeof(struct sockaddr_in);
|
||||
return 0;
|
||||
case AF_INET6:
|
||||
h->msg_namelen = sizeof(struct sockaddr_in6);
|
||||
return 0;
|
||||
case AF_UNIX:
|
||||
h->msg_namelen = sizeof(struct sockaddr_un);
|
||||
return 0;
|
||||
case AF_UNSPEC:
|
||||
h->msg_name = NULL;
|
||||
return 0;
|
||||
}
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
|
||||
static int uv__udp_sendmsg1(int fd,
|
||||
const uv_buf_t* bufs,
|
||||
unsigned int nbufs,
|
||||
const struct sockaddr* addr) {
|
||||
struct msghdr h;
|
||||
int r;
|
||||
|
||||
if ((r = uv__udp_prep_pkt(&h, bufs, nbufs, addr)))
|
||||
return r;
|
||||
|
||||
do
|
||||
r = sendmsg(fd, &h, 0);
|
||||
while (r == -1 && errno == EINTR);
|
||||
|
||||
if (r < 0) {
|
||||
r = UV__ERR(errno);
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
|
||||
r = UV_EAGAIN;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* UDP sockets don't EOF so we don't have to handle r=0 specially,
|
||||
* that only happens when the input was a zero-sized buffer.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int uv__udp_sendmsgv(int fd,
|
||||
unsigned int count,
|
||||
uv_buf_t* bufs[/*count*/],
|
||||
unsigned int nbufs[/*count*/],
|
||||
struct sockaddr* addrs[/*count*/]) {
|
||||
unsigned int i;
|
||||
int nsent;
|
||||
int r;
|
||||
|
||||
r = 0;
|
||||
nsent = 0;
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
|
||||
if (count > 1) {
|
||||
for (i = 0; i < count; /*empty*/) {
|
||||
struct mmsghdr m[20];
|
||||
unsigned int n;
|
||||
|
||||
for (n = 0; i < count && n < ARRAY_SIZE(m); i++, n++)
|
||||
if ((r = uv__udp_prep_pkt(&m[n].msg_hdr, bufs[i], nbufs[i], addrs[i])))
|
||||
goto exit;
|
||||
|
||||
do
|
||||
#if defined(__APPLE__)
|
||||
r = sendmsg_x(fd, m, n, MSG_DONTWAIT);
|
||||
#else
|
||||
r = sendmmsg(fd, m, n, 0);
|
||||
#endif
|
||||
while (r == -1 && errno == EINTR);
|
||||
|
||||
if (r < 1)
|
||||
goto exit;
|
||||
|
||||
nsent += r;
|
||||
i += r;
|
||||
}
|
||||
|
||||
goto exit;
|
||||
}
|
||||
#endif /* defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) */
|
||||
|
||||
for (i = 0; i < count; i++, nsent++)
|
||||
if ((r = uv__udp_sendmsg1(fd, bufs[i], nbufs[i], addrs[i])))
|
||||
goto exit; /* goto to avoid unused label warning. */
|
||||
|
||||
exit:
|
||||
|
||||
if (nsent > 0)
|
||||
return nsent;
|
||||
|
||||
if (r < 0) {
|
||||
r = UV__ERR(errno);
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
|
||||
r = UV_EAGAIN;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static void uv__udp_sendmsg(uv_udp_t* handle) {
|
||||
static const int N = 20;
|
||||
struct sockaddr* addrs[N];
|
||||
unsigned int nbufs[N];
|
||||
uv_buf_t* bufs[N];
|
||||
struct uv__queue* q;
|
||||
uv_udp_send_t* req;
|
||||
int n;
|
||||
|
||||
if (uv__queue_empty(&handle->write_queue))
|
||||
return;
|
||||
|
||||
again:
|
||||
n = 0;
|
||||
q = uv__queue_head(&handle->write_queue);
|
||||
do {
|
||||
req = uv__queue_data(q, uv_udp_send_t, queue);
|
||||
addrs[n] = &req->u.addr;
|
||||
nbufs[n] = req->nbufs;
|
||||
bufs[n] = req->bufs;
|
||||
q = uv__queue_next(q);
|
||||
n++;
|
||||
} while (n < N && q != &handle->write_queue);
|
||||
|
||||
n = uv__udp_sendmsgv(handle->io_watcher.fd, n, bufs, nbufs, addrs);
|
||||
while (n > 0) {
|
||||
q = uv__queue_head(&handle->write_queue);
|
||||
req = uv__queue_data(q, uv_udp_send_t, queue);
|
||||
req->status = uv__count_bufs(req->bufs, req->nbufs);
|
||||
uv__queue_remove(&req->queue);
|
||||
uv__queue_insert_tail(&handle->write_completed_queue, &req->queue);
|
||||
n--;
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
if (uv__queue_empty(&handle->write_queue))
|
||||
goto feed;
|
||||
goto again;
|
||||
}
|
||||
|
||||
if (n == UV_EAGAIN)
|
||||
return;
|
||||
|
||||
/* Register the error against first request in queue because that
|
||||
* is the request that uv__udp_sendmsgv tried but failed to send,
|
||||
* because if it did send any requests, it won't return an error.
|
||||
*/
|
||||
q = uv__queue_head(&handle->write_queue);
|
||||
req = uv__queue_data(q, uv_udp_send_t, queue);
|
||||
req->status = n;
|
||||
uv__queue_remove(&req->queue);
|
||||
uv__queue_insert_tail(&handle->write_completed_queue, &req->queue);
|
||||
feed:
|
||||
uv__io_feed(handle->loop, &handle->io_watcher);
|
||||
}
|
||||
|
||||
|
||||
int uv__udp_try_send2(uv_udp_t* handle,
|
||||
unsigned int count,
|
||||
uv_buf_t* bufs[/*count*/],
|
||||
unsigned int nbufs[/*count*/],
|
||||
struct sockaddr* addrs[/*count*/]) {
|
||||
int fd;
|
||||
|
||||
fd = handle->io_watcher.fd;
|
||||
if (fd == -1)
|
||||
return UV_EINVAL;
|
||||
|
||||
return uv__udp_sendmsgv(fd, count, bufs, nbufs, addrs);
|
||||
}
|
||||
|
|
|
|||
22
deps/uv/src/uv-common.c
vendored
22
deps/uv/src/uv-common.c
vendored
|
|
@ -514,6 +514,25 @@ int uv_udp_try_send(uv_udp_t* handle,
|
|||
}
|
||||
|
||||
|
||||
int uv_udp_try_send2(uv_udp_t* handle,
|
||||
unsigned int count,
|
||||
uv_buf_t* bufs[/*count*/],
|
||||
unsigned int nbufs[/*count*/],
|
||||
struct sockaddr* addrs[/*count*/],
|
||||
unsigned int flags) {
|
||||
if (count < 1)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (flags != 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (handle->send_queue_count > 0)
|
||||
return UV_EAGAIN;
|
||||
|
||||
return uv__udp_try_send2(handle, count, bufs, nbufs, addrs);
|
||||
}
|
||||
|
||||
|
||||
int uv_udp_recv_start(uv_udp_t* handle,
|
||||
uv_alloc_cb alloc_cb,
|
||||
uv_udp_recv_cb recv_cb) {
|
||||
|
|
@ -644,6 +663,9 @@ int uv_send_buffer_size(uv_handle_t* handle, int *value) {
|
|||
int uv_fs_event_getpath(uv_fs_event_t* handle, char* buffer, size_t* size) {
|
||||
size_t required_len;
|
||||
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (!uv__is_active(handle)) {
|
||||
*size = 0;
|
||||
return UV_EINVAL;
|
||||
|
|
|
|||
20
deps/uv/src/uv-common.h
vendored
20
deps/uv/src/uv-common.h
vendored
|
|
@ -191,6 +191,12 @@ int uv__udp_try_send(uv_udp_t* handle,
|
|||
const struct sockaddr* addr,
|
||||
unsigned int addrlen);
|
||||
|
||||
int uv__udp_try_send2(uv_udp_t* handle,
|
||||
unsigned int count,
|
||||
uv_buf_t* bufs[/*count*/],
|
||||
unsigned int nbufs[/*count*/],
|
||||
struct sockaddr* addrs[/*count*/]);
|
||||
|
||||
int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloccb,
|
||||
uv_udp_recv_cb recv_cb);
|
||||
|
||||
|
|
@ -428,4 +434,18 @@ struct uv__loop_internal_fields_s {
|
|||
#endif /* __linux__ */
|
||||
};
|
||||
|
||||
#if defined(_WIN32)
|
||||
# define UV_PTHREAD_MAX_NAMELEN_NP 32767
|
||||
#elif defined(__APPLE__)
|
||||
# define UV_PTHREAD_MAX_NAMELEN_NP 64
|
||||
#elif defined(__NetBSD__) || defined(__illumos__)
|
||||
# define UV_PTHREAD_MAX_NAMELEN_NP PTHREAD_MAX_NAMELEN_NP
|
||||
#elif defined (__linux__)
|
||||
# define UV_PTHREAD_MAX_NAMELEN_NP 16
|
||||
#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
|
||||
# define UV_PTHREAD_MAX_NAMELEN_NP (MAXCOMLEN + 1)
|
||||
#else
|
||||
# define UV_PTHREAD_MAX_NAMELEN_NP 16
|
||||
#endif
|
||||
|
||||
#endif /* UV_COMMON_H_ */
|
||||
|
|
|
|||
98
deps/uv/src/win/core.c
vendored
98
deps/uv/src/win/core.c
vendored
|
|
@ -423,97 +423,6 @@ int uv_backend_timeout(const uv_loop_t* loop) {
|
|||
}
|
||||
|
||||
|
||||
static void uv__poll_wine(uv_loop_t* loop, DWORD timeout) {
|
||||
uv__loop_internal_fields_t* lfields;
|
||||
DWORD bytes;
|
||||
ULONG_PTR key;
|
||||
OVERLAPPED* overlapped;
|
||||
uv_req_t* req;
|
||||
int repeat;
|
||||
uint64_t timeout_time;
|
||||
uint64_t user_timeout;
|
||||
int reset_timeout;
|
||||
|
||||
lfields = uv__get_internal_fields(loop);
|
||||
timeout_time = loop->time + timeout;
|
||||
|
||||
if (lfields->flags & UV_METRICS_IDLE_TIME) {
|
||||
reset_timeout = 1;
|
||||
user_timeout = timeout;
|
||||
timeout = 0;
|
||||
} else {
|
||||
reset_timeout = 0;
|
||||
}
|
||||
|
||||
for (repeat = 0; ; repeat++) {
|
||||
/* Only need to set the provider_entry_time if timeout != 0. The function
|
||||
* will return early if the loop isn't configured with UV_METRICS_IDLE_TIME.
|
||||
*/
|
||||
if (timeout != 0)
|
||||
uv__metrics_set_provider_entry_time(loop);
|
||||
|
||||
/* Store the current timeout in a location that's globally accessible so
|
||||
* other locations like uv__work_done() can determine whether the queue
|
||||
* of events in the callback were waiting when poll was called.
|
||||
*/
|
||||
lfields->current_timeout = timeout;
|
||||
|
||||
GetQueuedCompletionStatus(loop->iocp,
|
||||
&bytes,
|
||||
&key,
|
||||
&overlapped,
|
||||
timeout);
|
||||
|
||||
if (reset_timeout != 0) {
|
||||
if (overlapped && timeout == 0)
|
||||
uv__metrics_inc_events_waiting(loop, 1);
|
||||
timeout = user_timeout;
|
||||
reset_timeout = 0;
|
||||
}
|
||||
|
||||
/* Placed here because on success the loop will break whether there is an
|
||||
* empty package or not, or if GetQueuedCompletionStatus returned early then
|
||||
* the timeout will be updated and the loop will run again. In either case
|
||||
* the idle time will need to be updated.
|
||||
*/
|
||||
uv__metrics_update_idle_time(loop);
|
||||
|
||||
if (overlapped) {
|
||||
uv__metrics_inc_events(loop, 1);
|
||||
|
||||
/* Package was dequeued */
|
||||
req = uv__overlapped_to_req(overlapped);
|
||||
uv__insert_pending_req(loop, req);
|
||||
|
||||
/* Some time might have passed waiting for I/O,
|
||||
* so update the loop time here.
|
||||
*/
|
||||
uv_update_time(loop);
|
||||
} else if (GetLastError() != WAIT_TIMEOUT) {
|
||||
/* Serious error */
|
||||
uv_fatal_error(GetLastError(), "GetQueuedCompletionStatus");
|
||||
} else if (timeout > 0) {
|
||||
/* GetQueuedCompletionStatus can occasionally return a little early.
|
||||
* Make sure that the desired timeout target time is reached.
|
||||
*/
|
||||
uv_update_time(loop);
|
||||
if (timeout_time > loop->time) {
|
||||
timeout = (DWORD)(timeout_time - loop->time);
|
||||
/* The first call to GetQueuedCompletionStatus should return very
|
||||
* close to the target time and the second should reach it, but
|
||||
* this is not stated in the documentation. To make sure a busy
|
||||
* loop cannot happen, the timeout is increased exponentially
|
||||
* starting on the third round.
|
||||
*/
|
||||
timeout += repeat ? (1 << (repeat - 1)) : 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void uv__poll(uv_loop_t* loop, DWORD timeout) {
|
||||
uv__loop_internal_fields_t* lfields;
|
||||
BOOL success;
|
||||
|
|
@ -553,7 +462,7 @@ static void uv__poll(uv_loop_t* loop, DWORD timeout) {
|
|||
*/
|
||||
lfields->current_timeout = timeout;
|
||||
|
||||
success = pGetQueuedCompletionStatusEx(loop->iocp,
|
||||
success = GetQueuedCompletionStatusEx(loop->iocp,
|
||||
overlappeds,
|
||||
ARRAY_SIZE(overlappeds),
|
||||
&count,
|
||||
|
|
@ -566,7 +475,7 @@ static void uv__poll(uv_loop_t* loop, DWORD timeout) {
|
|||
}
|
||||
|
||||
/* Placed here because on success the loop will break whether there is an
|
||||
* empty package or not, or if pGetQueuedCompletionStatusEx returned early
|
||||
* empty package or not, or if GetQueuedCompletionStatusEx returned early
|
||||
* then the timeout will be updated and the loop will run again. In either
|
||||
* case the idle time will need to be updated.
|
||||
*/
|
||||
|
|
@ -647,10 +556,7 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
|
|||
|
||||
uv__metrics_inc_loop_count(loop);
|
||||
|
||||
if (pGetQueuedCompletionStatusEx)
|
||||
uv__poll(loop, timeout);
|
||||
else
|
||||
uv__poll_wine(loop, timeout);
|
||||
|
||||
/* Process immediate callbacks (e.g. write_cb) a small fixed number of
|
||||
* times to avoid loop starvation.*/
|
||||
|
|
|
|||
4
deps/uv/src/win/fs-event.c
vendored
4
deps/uv/src/win/fs-event.c
vendored
|
|
@ -253,6 +253,8 @@ short_path_done:
|
|||
}
|
||||
|
||||
dir_to_watch = dir;
|
||||
uv__free(short_path);
|
||||
short_path = NULL;
|
||||
uv__free(pathw);
|
||||
pathw = NULL;
|
||||
}
|
||||
|
|
@ -577,6 +579,8 @@ void uv__process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
|
|||
info.DeletePending) {
|
||||
uv__convert_utf16_to_utf8(handle->dirw, -1, &filename);
|
||||
handle->cb(handle, filename, UV_RENAME, 0);
|
||||
uv__free(filename);
|
||||
filename = NULL;
|
||||
} else {
|
||||
handle->cb(handle, NULL, 0, uv_translate_sys_error(err));
|
||||
}
|
||||
|
|
|
|||
205
deps/uv/src/win/fs.c
vendored
205
deps/uv/src/win/fs.c
vendored
|
|
@ -58,6 +58,19 @@
|
|||
#define FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE 0x0010
|
||||
#endif /* FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE */
|
||||
|
||||
NTSTATUS uv__RtlUnicodeStringInit(
|
||||
PUNICODE_STRING DestinationString,
|
||||
PWSTR SourceString,
|
||||
size_t SourceStringLen
|
||||
) {
|
||||
if (SourceStringLen > 0x7FFF)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
DestinationString->MaximumLength = DestinationString->Length =
|
||||
SourceStringLen * sizeof(SourceString[0]);
|
||||
DestinationString->Buffer = SourceString;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define INIT(subtype) \
|
||||
do { \
|
||||
if (req == NULL) \
|
||||
|
|
@ -1689,12 +1702,12 @@ INLINE static fs__stat_path_return_t fs__stat_path(WCHAR* path,
|
|||
uv_stat_t* statbuf, int do_lstat) {
|
||||
FILE_STAT_BASIC_INFORMATION stat_info;
|
||||
|
||||
// Check if the new fast API is available.
|
||||
/* Check if the new fast API is available. */
|
||||
if (!pGetFileInformationByName) {
|
||||
return FS__STAT_PATH_TRY_SLOW;
|
||||
}
|
||||
|
||||
// Check if the API call fails.
|
||||
/* Check if the API call fails. */
|
||||
if (!pGetFileInformationByName(path, FileStatBasicByNameInfo, &stat_info,
|
||||
sizeof(stat_info))) {
|
||||
switch(GetLastError()) {
|
||||
|
|
@ -1708,7 +1721,7 @@ INLINE static fs__stat_path_return_t fs__stat_path(WCHAR* path,
|
|||
return FS__STAT_PATH_TRY_SLOW;
|
||||
}
|
||||
|
||||
// A file handle is needed to get st_size for links.
|
||||
/* A file handle is needed to get st_size for links. */
|
||||
if ((stat_info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
|
||||
return FS__STAT_PATH_TRY_SLOW;
|
||||
}
|
||||
|
|
@ -1802,7 +1815,6 @@ INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf,
|
|||
* detect this failure and retry without do_lstat if appropriate.
|
||||
*/
|
||||
if (fs__readlink_handle(handle, NULL, &target_length) != 0) {
|
||||
fs__stat_assign_statbuf(statbuf, stat_info, do_lstat);
|
||||
return -1;
|
||||
}
|
||||
stat_info.EndOfFile.QuadPart = target_length;
|
||||
|
|
@ -1941,6 +1953,179 @@ INLINE static void fs__stat_prepare_path(WCHAR* pathw) {
|
|||
}
|
||||
}
|
||||
|
||||
INLINE static DWORD fs__stat_directory(WCHAR* path, uv_stat_t* statbuf,
|
||||
int do_lstat, DWORD ret_error) {
|
||||
HANDLE handle = INVALID_HANDLE_VALUE;
|
||||
FILE_STAT_BASIC_INFORMATION stat_info;
|
||||
FILE_ID_FULL_DIR_INFORMATION dir_info;
|
||||
FILE_FS_VOLUME_INFORMATION volume_info;
|
||||
FILE_FS_DEVICE_INFORMATION device_info;
|
||||
IO_STATUS_BLOCK io_status;
|
||||
NTSTATUS nt_status;
|
||||
WCHAR* path_dirpath = NULL;
|
||||
WCHAR* path_filename = NULL;
|
||||
UNICODE_STRING FileMask;
|
||||
size_t len;
|
||||
size_t split;
|
||||
WCHAR splitchar;
|
||||
int includes_name;
|
||||
|
||||
/* AKA strtok or wcscspn, in reverse. */
|
||||
len = wcslen(path);
|
||||
split = len;
|
||||
|
||||
includes_name = 0;
|
||||
while (split > 0 && path[split - 1] != L'\\' && path[split - 1] != L'/' &&
|
||||
path[split - 1] != L':') {
|
||||
/* check if the path contains a character other than /,\,:,. */
|
||||
if (path[split-1] != '.') {
|
||||
includes_name = 1;
|
||||
}
|
||||
split--;
|
||||
}
|
||||
/* If the path is a relative path with a file name or a folder name */
|
||||
if (split == 0 && includes_name) {
|
||||
path_dirpath = L".";
|
||||
/* If there is a slash or a backslash */
|
||||
} else if (path[split - 1] == L'\\' || path[split - 1] == L'/') {
|
||||
path_dirpath = path;
|
||||
/* If there is no filename, consider it as a relative folder path */
|
||||
if (!includes_name) {
|
||||
split = len;
|
||||
/* Else, split it */
|
||||
} else {
|
||||
splitchar = path[split - 1];
|
||||
path[split - 1] = L'\0';
|
||||
}
|
||||
/* e.g. "..", "c:" */
|
||||
} else {
|
||||
path_dirpath = path;
|
||||
split = len;
|
||||
}
|
||||
path_filename = &path[split];
|
||||
|
||||
len = 0;
|
||||
while (1) {
|
||||
if (path_filename[len] == L'\0')
|
||||
break;
|
||||
if (path_filename[len] == L'*' || path_filename[len] == L'?' ||
|
||||
path_filename[len] == L'>' || path_filename[len] == L'<' ||
|
||||
path_filename[len] == L'"') {
|
||||
ret_error = ERROR_INVALID_NAME;
|
||||
goto cleanup;
|
||||
}
|
||||
len++;
|
||||
}
|
||||
|
||||
/* Get directory handle */
|
||||
handle = CreateFileW(path_dirpath,
|
||||
FILE_LIST_DIRECTORY,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS,
|
||||
NULL);
|
||||
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
ret_error = GetLastError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Get files in the directory */
|
||||
nt_status = uv__RtlUnicodeStringInit(&FileMask, path_filename, len);
|
||||
if (!NT_SUCCESS(nt_status)) {
|
||||
ret_error = pRtlNtStatusToDosError(nt_status);
|
||||
goto cleanup;
|
||||
}
|
||||
nt_status = pNtQueryDirectoryFile(handle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&io_status,
|
||||
&dir_info,
|
||||
sizeof(dir_info),
|
||||
FileIdFullDirectoryInformation,
|
||||
TRUE,
|
||||
&FileMask,
|
||||
TRUE);
|
||||
|
||||
/* Buffer overflow (a warning status code) is expected here since there isn't
|
||||
* enough space to store the FileName, and actually indicates success. */
|
||||
if (!NT_SUCCESS(nt_status) && nt_status != STATUS_BUFFER_OVERFLOW) {
|
||||
if (nt_status == STATUS_NO_MORE_FILES)
|
||||
ret_error = ERROR_PATH_NOT_FOUND;
|
||||
else
|
||||
ret_error = pRtlNtStatusToDosError(nt_status);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Assign values to stat_info */
|
||||
memset(&stat_info, 0, sizeof(FILE_STAT_BASIC_INFORMATION));
|
||||
stat_info.FileAttributes = dir_info.FileAttributes;
|
||||
stat_info.CreationTime.QuadPart = dir_info.CreationTime.QuadPart;
|
||||
stat_info.LastAccessTime.QuadPart = dir_info.LastAccessTime.QuadPart;
|
||||
stat_info.LastWriteTime.QuadPart = dir_info.LastWriteTime.QuadPart;
|
||||
if (stat_info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
|
||||
/* A file handle is needed to get st_size for the link (from
|
||||
* FSCTL_GET_REPARSE_POINT), which is required by posix, but we are here
|
||||
* because getting the file handle failed. We could get just the
|
||||
* ReparsePointTag by querying FILE_ID_EXTD_DIR_INFORMATION instead to make
|
||||
* sure this really is a link before giving up here on the uv_fs_stat call,
|
||||
* but that doesn't seem essential. */
|
||||
if (!do_lstat)
|
||||
goto cleanup;
|
||||
stat_info.EndOfFile.QuadPart = 0;
|
||||
stat_info.AllocationSize.QuadPart = 0;
|
||||
} else {
|
||||
stat_info.EndOfFile.QuadPart = dir_info.EndOfFile.QuadPart;
|
||||
stat_info.AllocationSize.QuadPart = dir_info.AllocationSize.QuadPart;
|
||||
}
|
||||
stat_info.ChangeTime.QuadPart = dir_info.ChangeTime.QuadPart;
|
||||
stat_info.FileId.QuadPart = dir_info.FileId.QuadPart;
|
||||
|
||||
/* Finish up by getting device info from the directory handle,
|
||||
* since files presumably must live on their device. */
|
||||
nt_status = pNtQueryVolumeInformationFile(handle,
|
||||
&io_status,
|
||||
&volume_info,
|
||||
sizeof volume_info,
|
||||
FileFsVolumeInformation);
|
||||
|
||||
/* Buffer overflow (a warning status code) is expected here. */
|
||||
if (io_status.Status == STATUS_NOT_IMPLEMENTED) {
|
||||
stat_info.VolumeSerialNumber.QuadPart = 0;
|
||||
} else if (NT_ERROR(nt_status)) {
|
||||
ret_error = pRtlNtStatusToDosError(nt_status);
|
||||
goto cleanup;
|
||||
} else {
|
||||
stat_info.VolumeSerialNumber.QuadPart = volume_info.VolumeSerialNumber;
|
||||
}
|
||||
|
||||
nt_status = pNtQueryVolumeInformationFile(handle,
|
||||
&io_status,
|
||||
&device_info,
|
||||
sizeof device_info,
|
||||
FileFsDeviceInformation);
|
||||
|
||||
/* Buffer overflow (a warning status code) is expected here. */
|
||||
if (NT_ERROR(nt_status)) {
|
||||
ret_error = pRtlNtStatusToDosError(nt_status);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
stat_info.DeviceType = device_info.DeviceType;
|
||||
stat_info.NumberOfLinks = 1; /* No way to recover this info. */
|
||||
|
||||
fs__stat_assign_statbuf(statbuf, stat_info, do_lstat);
|
||||
ret_error = 0;
|
||||
|
||||
cleanup:
|
||||
if (split != 0)
|
||||
path[split - 1] = splitchar;
|
||||
if (handle != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(handle);
|
||||
return ret_error;
|
||||
}
|
||||
|
||||
INLINE static DWORD fs__stat_impl_from_path(WCHAR* path,
|
||||
int do_lstat,
|
||||
|
|
@ -1949,7 +2134,7 @@ INLINE static DWORD fs__stat_impl_from_path(WCHAR* path,
|
|||
DWORD flags;
|
||||
DWORD ret;
|
||||
|
||||
// If new API exists, try to use it.
|
||||
/* If new API exists, try to use it. */
|
||||
switch (fs__stat_path(path, statbuf, do_lstat)) {
|
||||
case FS__STAT_PATH_SUCCESS:
|
||||
return 0;
|
||||
|
|
@ -1959,7 +2144,7 @@ INLINE static DWORD fs__stat_impl_from_path(WCHAR* path,
|
|||
break;
|
||||
}
|
||||
|
||||
// If the new API does not exist, use the old API.
|
||||
/* If the new API does not exist, use the old API. */
|
||||
flags = FILE_FLAG_BACKUP_SEMANTICS;
|
||||
if (do_lstat)
|
||||
flags |= FILE_FLAG_OPEN_REPARSE_POINT;
|
||||
|
|
@ -1972,8 +2157,12 @@ INLINE static DWORD fs__stat_impl_from_path(WCHAR* path,
|
|||
flags,
|
||||
NULL);
|
||||
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
return GetLastError();
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
ret = GetLastError();
|
||||
if (ret != ERROR_ACCESS_DENIED && ret != ERROR_SHARING_VIOLATION)
|
||||
return ret;
|
||||
return fs__stat_directory(path, statbuf, do_lstat, ret);
|
||||
}
|
||||
|
||||
if (fs__stat_handle(handle, statbuf, do_lstat) != 0)
|
||||
ret = GetLastError();
|
||||
|
|
|
|||
6
deps/uv/src/win/pipe.c
vendored
6
deps/uv/src/win/pipe.c
vendored
|
|
@ -2602,6 +2602,9 @@ int uv_pipe_pending_count(uv_pipe_t* handle) {
|
|||
|
||||
|
||||
int uv_pipe_getsockname(const uv_pipe_t* handle, char* buffer, size_t* size) {
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (handle->flags & UV_HANDLE_BOUND)
|
||||
return uv__pipe_getname(handle, buffer, size);
|
||||
|
||||
|
|
@ -2616,6 +2619,9 @@ int uv_pipe_getsockname(const uv_pipe_t* handle, char* buffer, size_t* size) {
|
|||
|
||||
|
||||
int uv_pipe_getpeername(const uv_pipe_t* handle, char* buffer, size_t* size) {
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
/* emulate unix behaviour */
|
||||
if (handle->flags & UV_HANDLE_BOUND)
|
||||
return UV_ENOTCONN;
|
||||
|
|
|
|||
74
deps/uv/src/win/thread.c
vendored
74
deps/uv/src/win/thread.c
vendored
|
|
@ -95,6 +95,15 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
|
|||
return uv_thread_create_ex(tid, ¶ms, entry, arg);
|
||||
}
|
||||
|
||||
|
||||
int uv_thread_detach(uv_thread_t *tid) {
|
||||
if (CloseHandle(*tid) == 0)
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_thread_create_ex(uv_thread_t* tid,
|
||||
const uv_thread_options_t* params,
|
||||
void (*entry)(void *arg),
|
||||
|
|
@ -269,6 +278,71 @@ int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) {
|
|||
}
|
||||
|
||||
|
||||
int uv_thread_setname(const char* name) {
|
||||
HRESULT hr;
|
||||
WCHAR* namew;
|
||||
int err;
|
||||
char namebuf[UV_PTHREAD_MAX_NAMELEN_NP];
|
||||
|
||||
if (name == NULL)
|
||||
return UV_EINVAL;
|
||||
|
||||
strncpy(namebuf, name, sizeof(namebuf) - 1);
|
||||
namebuf[sizeof(namebuf) - 1] = '\0';
|
||||
|
||||
namew = NULL;
|
||||
err = uv__convert_utf8_to_utf16(namebuf, &namew);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
hr = SetThreadDescription(GetCurrentThread(), namew);
|
||||
uv__free(namew);
|
||||
if (FAILED(hr))
|
||||
return uv_translate_sys_error(HRESULT_CODE(hr));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_thread_getname(uv_thread_t* tid, char* name, size_t size) {
|
||||
HRESULT hr;
|
||||
WCHAR* namew;
|
||||
char* thread_name;
|
||||
size_t buf_size;
|
||||
int r;
|
||||
DWORD exit_code;
|
||||
|
||||
if (name == NULL || size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (tid == NULL || *tid == NULL)
|
||||
return UV_EINVAL;
|
||||
|
||||
/* Check if the thread handle is valid */
|
||||
if (!GetExitCodeThread(*tid, &exit_code) || exit_code != STILL_ACTIVE)
|
||||
return UV_ENOENT;
|
||||
|
||||
namew = NULL;
|
||||
thread_name = NULL;
|
||||
hr = GetThreadDescription(*tid, &namew);
|
||||
if (FAILED(hr))
|
||||
return uv_translate_sys_error(HRESULT_CODE(hr));
|
||||
|
||||
buf_size = size;
|
||||
r = uv__copy_utf16_to_utf8(namew, -1, name, &buf_size);
|
||||
if (r == UV_ENOBUFS) {
|
||||
r = uv__convert_utf16_to_utf8(namew, wcslen(namew), &thread_name);
|
||||
if (r == 0) {
|
||||
uv__strscpy(name, thread_name, size);
|
||||
uv__free(thread_name);
|
||||
}
|
||||
}
|
||||
|
||||
LocalFree(namew);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
int uv_mutex_init(uv_mutex_t* mutex) {
|
||||
InitializeCriticalSection(mutex);
|
||||
return 0;
|
||||
|
|
|
|||
21
deps/uv/src/win/udp.c
vendored
21
deps/uv/src/win/udp.c
vendored
|
|
@ -1101,7 +1101,8 @@ int uv__udp_try_send(uv_udp_t* handle,
|
|||
struct sockaddr_storage converted;
|
||||
int err;
|
||||
|
||||
assert(nbufs > 0);
|
||||
if (nbufs < 1)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (addr != NULL) {
|
||||
err = uv__convert_to_localhost_if_unspecified(addr, &converted);
|
||||
|
|
@ -1141,3 +1142,21 @@ int uv__udp_try_send(uv_udp_t* handle,
|
|||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
int uv__udp_try_send2(uv_udp_t* handle,
|
||||
unsigned int count,
|
||||
uv_buf_t* bufs[/*count*/],
|
||||
unsigned int nbufs[/*count*/],
|
||||
struct sockaddr* addrs[/*count*/]) {
|
||||
unsigned int i;
|
||||
int r;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
r = uv_udp_try_send(handle, bufs[i], nbufs[i], addrs[i]);
|
||||
if (r < 0)
|
||||
return i > 0 ? i : r; /* Error if first packet, else send count. */
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
|
|
|||
90
deps/uv/src/win/util.c
vendored
90
deps/uv/src/win/util.c
vendored
|
|
@ -191,7 +191,7 @@ int uv_cwd(char* buffer, size_t* size) {
|
|||
WCHAR *utf16_buffer;
|
||||
int r;
|
||||
|
||||
if (buffer == NULL || size == NULL) {
|
||||
if (buffer == NULL || size == NULL || *size == 0) {
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -874,56 +874,100 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
|||
|
||||
|
||||
int uv_getrusage(uv_rusage_t *uv_rusage) {
|
||||
FILETIME createTime, exitTime, kernelTime, userTime;
|
||||
SYSTEMTIME kernelSystemTime, userSystemTime;
|
||||
PROCESS_MEMORY_COUNTERS memCounters;
|
||||
IO_COUNTERS ioCounters;
|
||||
FILETIME create_time, exit_time, kernel_time, user_time;
|
||||
SYSTEMTIME kernel_system_time, user_system_time;
|
||||
PROCESS_MEMORY_COUNTERS mem_counters;
|
||||
IO_COUNTERS io_counters;
|
||||
int ret;
|
||||
|
||||
ret = GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &kernelTime, &userTime);
|
||||
ret = GetProcessTimes(GetCurrentProcess(),
|
||||
&create_time,
|
||||
&exit_time,
|
||||
&kernel_time,
|
||||
&user_time);
|
||||
if (ret == 0) {
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
}
|
||||
|
||||
ret = FileTimeToSystemTime(&kernelTime, &kernelSystemTime);
|
||||
ret = FileTimeToSystemTime(&kernel_time, &kernel_system_time);
|
||||
if (ret == 0) {
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
}
|
||||
|
||||
ret = FileTimeToSystemTime(&userTime, &userSystemTime);
|
||||
ret = FileTimeToSystemTime(&user_time, &user_system_time);
|
||||
if (ret == 0) {
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
}
|
||||
|
||||
ret = GetProcessMemoryInfo(GetCurrentProcess(),
|
||||
&memCounters,
|
||||
sizeof(memCounters));
|
||||
&mem_counters,
|
||||
sizeof(mem_counters));
|
||||
if (ret == 0) {
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
}
|
||||
|
||||
ret = GetProcessIoCounters(GetCurrentProcess(), &ioCounters);
|
||||
ret = GetProcessIoCounters(GetCurrentProcess(), &io_counters);
|
||||
if (ret == 0) {
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
}
|
||||
|
||||
memset(uv_rusage, 0, sizeof(*uv_rusage));
|
||||
|
||||
uv_rusage->ru_utime.tv_sec = userSystemTime.wHour * 3600 +
|
||||
userSystemTime.wMinute * 60 +
|
||||
userSystemTime.wSecond;
|
||||
uv_rusage->ru_utime.tv_usec = userSystemTime.wMilliseconds * 1000;
|
||||
uv_rusage->ru_utime.tv_sec = user_system_time.wHour * 3600 +
|
||||
user_system_time.wMinute * 60 +
|
||||
user_system_time.wSecond;
|
||||
uv_rusage->ru_utime.tv_usec = user_system_time.wMilliseconds * 1000;
|
||||
|
||||
uv_rusage->ru_stime.tv_sec = kernelSystemTime.wHour * 3600 +
|
||||
kernelSystemTime.wMinute * 60 +
|
||||
kernelSystemTime.wSecond;
|
||||
uv_rusage->ru_stime.tv_usec = kernelSystemTime.wMilliseconds * 1000;
|
||||
uv_rusage->ru_stime.tv_sec = kernel_system_time.wHour * 3600 +
|
||||
kernel_system_time.wMinute * 60 +
|
||||
kernel_system_time.wSecond;
|
||||
uv_rusage->ru_stime.tv_usec = kernel_system_time.wMilliseconds * 1000;
|
||||
|
||||
uv_rusage->ru_majflt = (uint64_t) memCounters.PageFaultCount;
|
||||
uv_rusage->ru_maxrss = (uint64_t) memCounters.PeakWorkingSetSize / 1024;
|
||||
uv_rusage->ru_majflt = (uint64_t) mem_counters.PageFaultCount;
|
||||
uv_rusage->ru_maxrss = (uint64_t) mem_counters.PeakWorkingSetSize / 1024;
|
||||
|
||||
uv_rusage->ru_oublock = (uint64_t) ioCounters.WriteOperationCount;
|
||||
uv_rusage->ru_inblock = (uint64_t) ioCounters.ReadOperationCount;
|
||||
uv_rusage->ru_oublock = (uint64_t) io_counters.WriteOperationCount;
|
||||
uv_rusage->ru_inblock = (uint64_t) io_counters.ReadOperationCount;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_getrusage_thread(uv_rusage_t* uv_rusage) {
|
||||
FILETIME create_time, exit_time, kernel_time, user_time;
|
||||
SYSTEMTIME kernel_system_time, user_system_time;
|
||||
int ret;
|
||||
|
||||
ret = GetThreadTimes(GetCurrentThread(),
|
||||
&create_time,
|
||||
&exit_time,
|
||||
&kernel_time,
|
||||
&user_time);
|
||||
if (ret == 0) {
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
}
|
||||
|
||||
ret = FileTimeToSystemTime(&kernel_time, &kernel_system_time);
|
||||
if (ret == 0) {
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
}
|
||||
|
||||
ret = FileTimeToSystemTime(&user_time, &user_system_time);
|
||||
if (ret == 0) {
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
}
|
||||
|
||||
memset(uv_rusage, 0, sizeof(*uv_rusage));
|
||||
|
||||
uv_rusage->ru_utime.tv_sec = user_system_time.wHour * 3600 +
|
||||
user_system_time.wMinute * 60 +
|
||||
user_system_time.wSecond;
|
||||
uv_rusage->ru_utime.tv_usec = user_system_time.wMilliseconds * 1000;
|
||||
|
||||
uv_rusage->ru_stime.tv_sec = kernel_system_time.wHour * 3600 +
|
||||
kernel_system_time.wMinute * 60 +
|
||||
kernel_system_time.wSecond;
|
||||
uv_rusage->ru_stime.tv_usec = kernel_system_time.wMilliseconds * 1000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
13
deps/uv/src/win/winapi.c
vendored
13
deps/uv/src/win/winapi.c
vendored
|
|
@ -36,9 +36,6 @@ sNtQueryDirectoryFile pNtQueryDirectoryFile;
|
|||
sNtQuerySystemInformation pNtQuerySystemInformation;
|
||||
sNtQueryInformationProcess pNtQueryInformationProcess;
|
||||
|
||||
/* Kernel32 function pointers */
|
||||
sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
|
||||
|
||||
/* Powrprof.dll function pointer */
|
||||
sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
|
||||
|
||||
|
|
@ -55,7 +52,6 @@ void uv__winapi_init(void) {
|
|||
HMODULE ntdll_module;
|
||||
HMODULE powrprof_module;
|
||||
HMODULE user32_module;
|
||||
HMODULE kernel32_module;
|
||||
HMODULE ws2_32_module;
|
||||
HMODULE api_win_core_file_module;
|
||||
|
||||
|
|
@ -121,15 +117,6 @@ void uv__winapi_init(void) {
|
|||
uv_fatal_error(GetLastError(), "GetProcAddress");
|
||||
}
|
||||
|
||||
kernel32_module = GetModuleHandleA("kernel32.dll");
|
||||
if (kernel32_module == NULL) {
|
||||
uv_fatal_error(GetLastError(), "GetModuleHandleA");
|
||||
}
|
||||
|
||||
pGetQueuedCompletionStatusEx = (sGetQueuedCompletionStatusEx) GetProcAddress(
|
||||
kernel32_module,
|
||||
"GetQueuedCompletionStatusEx");
|
||||
|
||||
powrprof_module = LoadLibraryExA("powrprof.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (powrprof_module != NULL) {
|
||||
pPowerRegisterSuspendResumeNotification = (sPowerRegisterSuspendResumeNotification)
|
||||
|
|
|
|||
54
deps/uv/src/win/winapi.h
vendored
54
deps/uv/src/win/winapi.h
vendored
|
|
@ -4150,11 +4150,7 @@ typedef struct _FILE_STAT_BASIC_INFORMATION {
|
|||
} FILE_STAT_BASIC_INFORMATION;
|
||||
#endif
|
||||
|
||||
/* MinGW already has a definition for REPARSE_DATA_BUFFER, but mingw-w64 does
|
||||
* not.
|
||||
*/
|
||||
#if defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR)
|
||||
typedef struct _REPARSE_DATA_BUFFER {
|
||||
typedef struct _REPARSE_DATA_BUFFER {
|
||||
ULONG ReparseTag;
|
||||
USHORT ReparseDataLength;
|
||||
USHORT Reserved;
|
||||
|
|
@ -4182,8 +4178,7 @@ typedef struct _FILE_STAT_BASIC_INFORMATION {
|
|||
WCHAR StringList[1];
|
||||
} AppExecLinkReparseBuffer;
|
||||
};
|
||||
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
|
||||
#endif
|
||||
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
|
||||
|
||||
typedef struct _IO_STATUS_BLOCK {
|
||||
union {
|
||||
|
|
@ -4292,6 +4287,22 @@ typedef struct _FILE_BOTH_DIR_INFORMATION {
|
|||
WCHAR FileName[1];
|
||||
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;
|
||||
|
||||
typedef struct _FILE_ID_FULL_DIR_INFORMATION {
|
||||
ULONG NextEntryOffset;
|
||||
ULONG FileIndex;
|
||||
LARGE_INTEGER CreationTime;
|
||||
LARGE_INTEGER LastAccessTime;
|
||||
LARGE_INTEGER LastWriteTime;
|
||||
LARGE_INTEGER ChangeTime;
|
||||
LARGE_INTEGER EndOfFile;
|
||||
LARGE_INTEGER AllocationSize;
|
||||
ULONG FileAttributes;
|
||||
ULONG FileNameLength;
|
||||
ULONG EaSize;
|
||||
LARGE_INTEGER FileId;
|
||||
WCHAR FileName[1];
|
||||
} FILE_ID_FULL_DIR_INFORMATION, *PFILE_ID_FULL_DIR_INFORMATION;
|
||||
|
||||
typedef struct _FILE_BASIC_INFORMATION {
|
||||
LARGE_INTEGER CreationTime;
|
||||
LARGE_INTEGER LastAccessTime;
|
||||
|
|
@ -4661,15 +4672,6 @@ typedef NTSTATUS (NTAPI *sNtQueryInformationProcess)
|
|||
# define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
|
||||
typedef struct _OVERLAPPED_ENTRY {
|
||||
ULONG_PTR lpCompletionKey;
|
||||
LPOVERLAPPED lpOverlapped;
|
||||
ULONG_PTR Internal;
|
||||
DWORD dwNumberOfBytesTransferred;
|
||||
} OVERLAPPED_ENTRY, *LPOVERLAPPED_ENTRY;
|
||||
#endif
|
||||
|
||||
/* from wincon.h */
|
||||
#ifndef ENABLE_INSERT_MODE
|
||||
# define ENABLE_INSERT_MODE 0x20
|
||||
|
|
@ -4716,14 +4718,6 @@ typedef NTSTATUS (NTAPI *sNtQueryInformationProcess)
|
|||
# define ERROR_MUI_FILE_NOT_LOADED 15105
|
||||
#endif
|
||||
|
||||
typedef BOOL (WINAPI *sGetQueuedCompletionStatusEx)
|
||||
(HANDLE CompletionPort,
|
||||
LPOVERLAPPED_ENTRY lpCompletionPortEntries,
|
||||
ULONG ulCount,
|
||||
PULONG ulNumEntriesRemoved,
|
||||
DWORD dwMilliseconds,
|
||||
BOOL fAlertable);
|
||||
|
||||
/* from powerbase.h */
|
||||
#ifndef DEVICE_NOTIFY_CALLBACK
|
||||
# define DEVICE_NOTIFY_CALLBACK 2
|
||||
|
|
@ -4818,9 +4812,6 @@ extern sNtQueryDirectoryFile pNtQueryDirectoryFile;
|
|||
extern sNtQuerySystemInformation pNtQuerySystemInformation;
|
||||
extern sNtQueryInformationProcess pNtQueryInformationProcess;
|
||||
|
||||
/* Kernel32 function pointers */
|
||||
extern sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
|
||||
|
||||
/* Powrprof.dll function pointer */
|
||||
extern sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
|
||||
|
||||
|
|
@ -4837,4 +4828,13 @@ typedef int (WINAPI *uv_sGetHostNameW)
|
|||
int);
|
||||
extern uv_sGetHostNameW pGetHostNameW;
|
||||
|
||||
/* processthreadsapi.h */
|
||||
#if defined(__MINGW32__)
|
||||
WINBASEAPI
|
||||
HRESULT WINAPI GetThreadDescription(HANDLE hThread,
|
||||
PWSTR *ppszThreadDescription);
|
||||
WINBASEAPI
|
||||
HRESULT WINAPI SetThreadDescription(HANDLE hThread, PCWSTR lpThreadDescription);
|
||||
#endif
|
||||
|
||||
#endif /* UV_WIN_WINAPI_H_ */
|
||||
|
|
|
|||
41
deps/uv/src/win/winsock.h
vendored
41
deps/uv/src/win/winsock.h
vendored
|
|
@ -154,47 +154,6 @@ typedef struct _AFD_RECV_INFO {
|
|||
#define IOCTL_AFD_POLL \
|
||||
_AFD_CONTROL_CODE(AFD_POLL, METHOD_BUFFERED)
|
||||
|
||||
#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
|
||||
typedef struct _IP_ADAPTER_UNICAST_ADDRESS_XP {
|
||||
/* FIXME: __C89_NAMELESS was removed */
|
||||
/* __C89_NAMELESS */ union {
|
||||
ULONGLONG Alignment;
|
||||
/* __C89_NAMELESS */ struct {
|
||||
ULONG Length;
|
||||
DWORD Flags;
|
||||
};
|
||||
};
|
||||
struct _IP_ADAPTER_UNICAST_ADDRESS_XP *Next;
|
||||
SOCKET_ADDRESS Address;
|
||||
IP_PREFIX_ORIGIN PrefixOrigin;
|
||||
IP_SUFFIX_ORIGIN SuffixOrigin;
|
||||
IP_DAD_STATE DadState;
|
||||
ULONG ValidLifetime;
|
||||
ULONG PreferredLifetime;
|
||||
ULONG LeaseLifetime;
|
||||
} IP_ADAPTER_UNICAST_ADDRESS_XP,*PIP_ADAPTER_UNICAST_ADDRESS_XP;
|
||||
|
||||
typedef struct _IP_ADAPTER_UNICAST_ADDRESS_LH {
|
||||
union {
|
||||
ULONGLONG Alignment;
|
||||
struct {
|
||||
ULONG Length;
|
||||
DWORD Flags;
|
||||
};
|
||||
};
|
||||
struct _IP_ADAPTER_UNICAST_ADDRESS_LH *Next;
|
||||
SOCKET_ADDRESS Address;
|
||||
IP_PREFIX_ORIGIN PrefixOrigin;
|
||||
IP_SUFFIX_ORIGIN SuffixOrigin;
|
||||
IP_DAD_STATE DadState;
|
||||
ULONG ValidLifetime;
|
||||
ULONG PreferredLifetime;
|
||||
ULONG LeaseLifetime;
|
||||
UINT8 OnLinkPrefixLength;
|
||||
} IP_ADAPTER_UNICAST_ADDRESS_LH,*PIP_ADAPTER_UNICAST_ADDRESS_LH;
|
||||
|
||||
#endif
|
||||
|
||||
int uv__convert_to_localhost_if_unspecified(const struct sockaddr* addr,
|
||||
struct sockaddr_storage* storage);
|
||||
|
||||
|
|
|
|||
14
deps/uv/test/runner.c
vendored
14
deps/uv/test/runner.c
vendored
|
|
@ -27,6 +27,11 @@
|
|||
#include "task.h"
|
||||
#include "uv.h"
|
||||
|
||||
/* Refs: https://github.com/libuv/libuv/issues/4369 */
|
||||
#if defined(__ANDROID__)
|
||||
#include <android/fdsan.h>
|
||||
#endif
|
||||
|
||||
char executable_path[sizeof(executable_path)];
|
||||
|
||||
|
||||
|
|
@ -142,6 +147,13 @@ void log_tap_result(int test_count,
|
|||
fflush(stdout);
|
||||
}
|
||||
|
||||
void enable_fdsan(void) {
|
||||
/* Refs: https://github.com/libuv/libuv/issues/4369 */
|
||||
#if defined(__ANDROID__)
|
||||
android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int run_test(const char* test,
|
||||
int benchmark_output,
|
||||
|
|
@ -160,6 +172,8 @@ int run_test(const char* test,
|
|||
main_proc = NULL;
|
||||
process_count = 0;
|
||||
|
||||
enable_fdsan();
|
||||
|
||||
#ifndef _WIN32
|
||||
/* Clean up stale socket from previous run. */
|
||||
remove(TEST_PIPENAME);
|
||||
|
|
|
|||
9
deps/uv/test/test-fs-event.c
vendored
9
deps/uv/test/test-fs-event.c
vendored
|
|
@ -153,7 +153,14 @@ static void fs_event_cb_del_dir(uv_fs_event_t* handle,
|
|||
ASSERT_PTR_EQ(handle, &fs_event);
|
||||
ASSERT_OK(status);
|
||||
ASSERT(events == UV_CHANGE || events == UV_RENAME);
|
||||
/* There is a bug in the FreeBSD kernel where the filename is sometimes NULL.
|
||||
* Refs: https://github.com/libuv/libuv/issues/4606
|
||||
*/
|
||||
#if defined(__FreeBSD__)
|
||||
ASSERT(filename == NULL || strcmp(filename, "watch_del_dir") == 0);
|
||||
#else
|
||||
ASSERT_OK(strcmp(filename, "watch_del_dir"));
|
||||
#endif
|
||||
ASSERT_OK(uv_fs_event_stop(handle));
|
||||
uv_close((uv_handle_t*)handle, close_cb);
|
||||
}
|
||||
|
|
@ -1121,7 +1128,7 @@ TEST_IMPL(fs_event_getpath) {
|
|||
ASSERT_EQ(r, UV_EINVAL);
|
||||
r = uv_fs_event_start(&fs_event, fail_cb, watch_dir[i], 0);
|
||||
ASSERT_OK(r);
|
||||
len = 0;
|
||||
len = 1;
|
||||
r = uv_fs_event_getpath(&fs_event, buf, &len);
|
||||
ASSERT_EQ(r, UV_ENOBUFS);
|
||||
ASSERT_LT(len, sizeof buf); /* sanity check */
|
||||
|
|
|
|||
54
deps/uv/test/test-fs.c
vendored
54
deps/uv/test/test-fs.c
vendored
|
|
@ -4507,6 +4507,60 @@ TEST_IMPL(fs_open_readonly_acl) {
|
|||
MAKE_VALGRIND_HAPPY(loop);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_stat_no_permission) {
|
||||
uv_passwd_t pwd;
|
||||
uv_fs_t req;
|
||||
int r;
|
||||
char* filename = "test_file_no_permission.txt";
|
||||
|
||||
/* Setup - clear the ACL and remove the file */
|
||||
loop = uv_default_loop();
|
||||
r = uv_os_get_passwd(&pwd);
|
||||
ASSERT_OK(r);
|
||||
call_icacls("icacls %s /remove *S-1-1-0:(F)", filename);
|
||||
unlink(filename);
|
||||
|
||||
/* Create the file */
|
||||
r = uv_fs_open(loop,
|
||||
&open_req1,
|
||||
filename,
|
||||
UV_FS_O_RDONLY | UV_FS_O_CREAT,
|
||||
S_IRUSR,
|
||||
NULL);
|
||||
ASSERT_GE(r, 0);
|
||||
ASSERT_GE(open_req1.result, 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
r = uv_fs_close(NULL, &close_req, open_req1.result, NULL);
|
||||
ASSERT_OK(r);
|
||||
ASSERT_OK(close_req.result);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
/* Set up ACL */
|
||||
r = call_icacls("icacls %s /deny *S-1-1-0:(F)", filename);
|
||||
if (r != 0) {
|
||||
goto acl_cleanup;
|
||||
}
|
||||
|
||||
/* Read file stats */
|
||||
r = uv_fs_stat(NULL, &req, filename, NULL);
|
||||
if (r != 0) {
|
||||
goto acl_cleanup;
|
||||
}
|
||||
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
acl_cleanup:
|
||||
/* Cleanup */
|
||||
call_icacls("icacls %s /reset", filename);
|
||||
uv_fs_unlink(NULL, &unlink_req, filename, NULL);
|
||||
uv_fs_req_cleanup(&unlink_req);
|
||||
unlink(filename);
|
||||
uv_os_free_passwd(&pwd);
|
||||
ASSERT_OK(r);
|
||||
MAKE_VALGRIND_HAPPY(loop);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
|
|
|||
26
deps/uv/test/test-idna.c
vendored
26
deps/uv/test/test-idna.c
vendored
|
|
@ -39,7 +39,7 @@ TEST_IMPL(utf8_decode1) {
|
|||
|
||||
/* Two-byte sequences. */
|
||||
p = b;
|
||||
snprintf(b, sizeof(b), "\xC2\x80\xDF\xBF");
|
||||
snprintf(b, sizeof(b), "%s", "\xC2\x80\xDF\xBF");
|
||||
ASSERT_EQ(128, uv__utf8_decode1(&p, b + sizeof(b)));
|
||||
ASSERT_PTR_EQ(p, b + 2);
|
||||
ASSERT_EQ(0x7FF, uv__utf8_decode1(&p, b + sizeof(b)));
|
||||
|
|
@ -47,7 +47,7 @@ TEST_IMPL(utf8_decode1) {
|
|||
|
||||
/* Three-byte sequences. */
|
||||
p = b;
|
||||
snprintf(b, sizeof(b), "\xE0\xA0\x80\xEF\xBF\xBF");
|
||||
snprintf(b, sizeof(b), "%s", "\xE0\xA0\x80\xEF\xBF\xBF");
|
||||
ASSERT_EQ(0x800, uv__utf8_decode1(&p, b + sizeof(b)));
|
||||
ASSERT_PTR_EQ(p, b + 3);
|
||||
ASSERT_EQ(0xFFFF, uv__utf8_decode1(&p, b + sizeof(b)));
|
||||
|
|
@ -55,7 +55,7 @@ TEST_IMPL(utf8_decode1) {
|
|||
|
||||
/* Four-byte sequences. */
|
||||
p = b;
|
||||
snprintf(b, sizeof(b), "\xF0\x90\x80\x80\xF4\x8F\xBF\xBF");
|
||||
snprintf(b, sizeof(b), "%s", "\xF0\x90\x80\x80\xF4\x8F\xBF\xBF");
|
||||
ASSERT_EQ(0x10000, uv__utf8_decode1(&p, b + sizeof(b)));
|
||||
ASSERT_PTR_EQ(p, b + 4);
|
||||
ASSERT_EQ(0x10FFFF, uv__utf8_decode1(&p, b + sizeof(b)));
|
||||
|
|
@ -63,7 +63,7 @@ TEST_IMPL(utf8_decode1) {
|
|||
|
||||
/* Four-byte sequences > U+10FFFF; disallowed. */
|
||||
p = b;
|
||||
snprintf(b, sizeof(b), "\xF4\x90\xC0\xC0\xF7\xBF\xBF\xBF");
|
||||
snprintf(b, sizeof(b), "%s", "\xF4\x90\xC0\xC0\xF7\xBF\xBF\xBF");
|
||||
ASSERT_EQ((unsigned) -1, uv__utf8_decode1(&p, b + sizeof(b)));
|
||||
ASSERT_PTR_EQ(p, b + 4);
|
||||
ASSERT_EQ((unsigned) -1, uv__utf8_decode1(&p, b + sizeof(b)));
|
||||
|
|
@ -71,7 +71,7 @@ TEST_IMPL(utf8_decode1) {
|
|||
|
||||
/* Overlong; disallowed. */
|
||||
p = b;
|
||||
snprintf(b, sizeof(b), "\xC0\x80\xC1\x80");
|
||||
snprintf(b, sizeof(b), "%s", "\xC0\x80\xC1\x80");
|
||||
ASSERT_EQ((unsigned) -1, uv__utf8_decode1(&p, b + sizeof(b)));
|
||||
ASSERT_PTR_EQ(p, b + 2);
|
||||
ASSERT_EQ((unsigned) -1, uv__utf8_decode1(&p, b + sizeof(b)));
|
||||
|
|
@ -79,7 +79,7 @@ TEST_IMPL(utf8_decode1) {
|
|||
|
||||
/* Surrogate pairs; disallowed. */
|
||||
p = b;
|
||||
snprintf(b, sizeof(b), "\xED\xA0\x80\xED\xA3\xBF");
|
||||
snprintf(b, sizeof(b), "%s", "\xED\xA0\x80\xED\xA3\xBF");
|
||||
ASSERT_EQ((unsigned) -1, uv__utf8_decode1(&p, b + sizeof(b)));
|
||||
ASSERT_PTR_EQ(p, b + 3);
|
||||
ASSERT_EQ((unsigned) -1, uv__utf8_decode1(&p, b + sizeof(b)));
|
||||
|
|
@ -87,7 +87,7 @@ TEST_IMPL(utf8_decode1) {
|
|||
|
||||
/* Simply illegal. */
|
||||
p = b;
|
||||
snprintf(b, sizeof(b), "\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
|
||||
snprintf(b, sizeof(b), "%s", "\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF");
|
||||
|
||||
for (i = 1; i <= 8; i++) {
|
||||
ASSERT_EQ((unsigned) -1, uv__utf8_decode1(&p, b + sizeof(b)));
|
||||
|
|
@ -218,3 +218,15 @@ TEST_IMPL(idna_toascii) {
|
|||
#undef T
|
||||
|
||||
#endif /* __MVS__ */
|
||||
|
||||
TEST_IMPL(wtf8) {
|
||||
static const char input[] = "ᜄȺy𐞲:𞢢𘴇𐀀'¥3̞[<i$";
|
||||
uint16_t buf[32];
|
||||
ssize_t len;
|
||||
|
||||
len = uv_wtf8_length_as_utf16(input);
|
||||
ASSERT_GT(len, 0);
|
||||
ASSERT_LT(len, ARRAY_SIZE(buf));
|
||||
uv_wtf8_to_utf16(input, buf, len);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
10
deps/uv/test/test-list.h
vendored
10
deps/uv/test/test-list.h
vendored
|
|
@ -466,6 +466,7 @@ TEST_DECLARE (threadpool_cancel_work)
|
|||
TEST_DECLARE (threadpool_cancel_fs)
|
||||
TEST_DECLARE (threadpool_cancel_single)
|
||||
TEST_DECLARE (threadpool_cancel_when_busy)
|
||||
TEST_DECLARE (thread_detach)
|
||||
TEST_DECLARE (thread_local_storage)
|
||||
TEST_DECLARE (thread_stack_size)
|
||||
TEST_DECLARE (thread_stack_size_explicit)
|
||||
|
|
@ -477,6 +478,8 @@ TEST_DECLARE (thread_create)
|
|||
TEST_DECLARE (thread_equal)
|
||||
TEST_DECLARE (thread_affinity)
|
||||
TEST_DECLARE (thread_priority)
|
||||
TEST_DECLARE (thread_name)
|
||||
TEST_DECLARE (thread_name_threadpool)
|
||||
TEST_DECLARE (dlerror)
|
||||
#if (defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))) && \
|
||||
!defined(__sun)
|
||||
|
|
@ -512,6 +515,7 @@ TEST_DECLARE (environment_creation)
|
|||
TEST_DECLARE (listen_with_simultaneous_accepts)
|
||||
TEST_DECLARE (listen_no_simultaneous_accepts)
|
||||
TEST_DECLARE (fs_stat_root)
|
||||
TEST_DECLARE (fs_stat_no_permission)
|
||||
TEST_DECLARE (spawn_with_an_odd_path)
|
||||
TEST_DECLARE (spawn_no_path)
|
||||
TEST_DECLARE (spawn_no_ext)
|
||||
|
|
@ -572,6 +576,7 @@ TEST_DECLARE (fork_threadpool_queue_work_simple)
|
|||
|
||||
TEST_DECLARE (iouring_pollhup)
|
||||
|
||||
TEST_DECLARE (wtf8)
|
||||
TEST_DECLARE (idna_toascii)
|
||||
TEST_DECLARE (utf8_decode1)
|
||||
TEST_DECLARE (utf8_decode1_overrun)
|
||||
|
|
@ -1040,6 +1045,7 @@ TASK_LIST_START
|
|||
TEST_ENTRY (listen_with_simultaneous_accepts)
|
||||
TEST_ENTRY (listen_no_simultaneous_accepts)
|
||||
TEST_ENTRY (fs_stat_root)
|
||||
TEST_ENTRY (fs_stat_no_permission)
|
||||
TEST_ENTRY (spawn_with_an_odd_path)
|
||||
TEST_ENTRY (spawn_no_path)
|
||||
TEST_ENTRY (spawn_no_ext)
|
||||
|
|
@ -1179,6 +1185,7 @@ TASK_LIST_START
|
|||
TEST_ENTRY (threadpool_cancel_fs)
|
||||
TEST_ENTRY (threadpool_cancel_single)
|
||||
TEST_ENTRY (threadpool_cancel_when_busy)
|
||||
TEST_ENTRY (thread_detach)
|
||||
TEST_ENTRY (thread_local_storage)
|
||||
TEST_ENTRY (thread_stack_size)
|
||||
TEST_ENTRY (thread_stack_size_explicit)
|
||||
|
|
@ -1190,6 +1197,8 @@ TASK_LIST_START
|
|||
TEST_ENTRY (thread_equal)
|
||||
TEST_ENTRY (thread_affinity)
|
||||
TEST_ENTRY (thread_priority)
|
||||
TEST_ENTRY (thread_name)
|
||||
TEST_ENTRY (thread_name_threadpool)
|
||||
TEST_ENTRY (dlerror)
|
||||
TEST_ENTRY (ip4_addr)
|
||||
TEST_ENTRY (ip6_addr_link_local)
|
||||
|
|
@ -1223,6 +1232,7 @@ TASK_LIST_START
|
|||
|
||||
TEST_ENTRY (iouring_pollhup)
|
||||
|
||||
TEST_ENTRY (wtf8)
|
||||
TEST_ENTRY (utf8_decode1)
|
||||
TEST_ENTRY (utf8_decode1_overrun)
|
||||
TEST_ENTRY (uname)
|
||||
|
|
|
|||
9
deps/uv/test/test-pipe-getsockname.c
vendored
9
deps/uv/test/test-pipe-getsockname.c
vendored
|
|
@ -154,6 +154,15 @@ TEST_IMPL(pipe_getsockname) {
|
|||
ASSERT_STR_EQ(pipe_server.pipe_fname, TEST_PIPENAME);
|
||||
#endif
|
||||
|
||||
r = uv_pipe_getsockname(&pipe_server, NULL, &len);
|
||||
ASSERT_EQ(r, UV_EINVAL);
|
||||
|
||||
r = uv_pipe_getsockname(&pipe_server, buf, NULL);
|
||||
ASSERT_EQ(r, UV_EINVAL);
|
||||
|
||||
r = uv_pipe_getsockname(&pipe_server, NULL, NULL);
|
||||
ASSERT_EQ(r, UV_EINVAL);
|
||||
|
||||
len = sizeof(TEST_PIPENAME) - 1;
|
||||
ASSERT_EQ(UV_ENOBUFS, uv_pipe_getsockname(&pipe_server, buf, &len));
|
||||
|
||||
|
|
|
|||
16
deps/uv/test/test-platform-output.c
vendored
16
deps/uv/test/test-platform-output.c
vendored
|
|
@ -236,5 +236,21 @@ TEST_IMPL(platform_output) {
|
|||
printf(" version: %s\n", uname.version);
|
||||
printf(" machine: %s\n", uname.machine);
|
||||
|
||||
ASSERT_OK(uv_getrusage_thread(&rusage));
|
||||
ASSERT_UINT64_GE(rusage.ru_utime.tv_sec, 0);
|
||||
ASSERT_UINT64_GE(rusage.ru_utime.tv_usec, 0);
|
||||
ASSERT_UINT64_GE(rusage.ru_stime.tv_sec, 0);
|
||||
ASSERT_UINT64_GE(rusage.ru_stime.tv_usec, 0);
|
||||
printf("uv_getrusage_thread:\n");
|
||||
printf(" user: %llu sec %llu microsec\n",
|
||||
(unsigned long long) rusage.ru_utime.tv_sec,
|
||||
(unsigned long long) rusage.ru_utime.tv_usec);
|
||||
printf(" system: %llu sec %llu microsec\n",
|
||||
(unsigned long long) rusage.ru_stime.tv_sec,
|
||||
(unsigned long long) rusage.ru_stime.tv_usec);
|
||||
printf(" page faults: %llu\n", (unsigned long long) rusage.ru_majflt);
|
||||
printf(" maximum resident set size: %llu\n",
|
||||
(unsigned long long) rusage.ru_maxrss);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
2
deps/uv/test/test-spawn.c
vendored
2
deps/uv/test/test-spawn.c
vendored
|
|
@ -1329,9 +1329,7 @@ TEST_IMPL(environment_creation) {
|
|||
}
|
||||
}
|
||||
if (prev) { /* verify sort order */
|
||||
#if !defined(__MINGW32__) || defined(__MINGW64_VERSION_MAJOR)
|
||||
ASSERT_EQ(1, CompareStringOrdinal(prev, -1, str, -1, TRUE));
|
||||
#endif
|
||||
}
|
||||
ASSERT(found); /* verify that we expected this variable */
|
||||
}
|
||||
|
|
|
|||
189
deps/uv/test/test-thread-name.c
vendored
Normal file
189
deps/uv/test/test-thread-name.c
vendored
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
/* Copyright libuv project contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "task.h"
|
||||
#include "../src/uv-common.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
struct semaphores {
|
||||
uv_sem_t main;
|
||||
uv_sem_t worker;
|
||||
};
|
||||
|
||||
static void thread_run(void* arg) {
|
||||
int r;
|
||||
char thread_name[16];
|
||||
struct semaphores* sem;
|
||||
uv_thread_t thread;
|
||||
|
||||
sem = arg;
|
||||
|
||||
#ifdef _WIN32
|
||||
/* uv_thread_self isn't defined for the main thread on Windows. */
|
||||
thread = GetCurrentThread();
|
||||
#else
|
||||
thread = uv_thread_self();
|
||||
#endif
|
||||
|
||||
r = uv_thread_setname("worker-thread");
|
||||
ASSERT_OK(r);
|
||||
|
||||
uv_sem_post(&sem->worker);
|
||||
|
||||
r = uv_thread_getname(&thread, thread_name, sizeof(thread_name));
|
||||
ASSERT_OK(r);
|
||||
|
||||
ASSERT_STR_EQ(thread_name, "worker-thread");
|
||||
|
||||
uv_sem_wait(&sem->main);
|
||||
}
|
||||
|
||||
TEST_IMPL(thread_name) {
|
||||
int r;
|
||||
uv_thread_t threads[2];
|
||||
char tn[UV_PTHREAD_MAX_NAMELEN_NP];
|
||||
char thread_name[UV_PTHREAD_MAX_NAMELEN_NP];
|
||||
char long_thread_name[UV_PTHREAD_MAX_NAMELEN_NP + 1];
|
||||
struct semaphores sem;
|
||||
|
||||
#if defined(__ANDROID_API__) && __ANDROID_API__ < 26 || \
|
||||
defined(_AIX) || \
|
||||
defined(__MVS__) || \
|
||||
defined(__PASE__)
|
||||
RETURN_SKIP("API not available on this platform");
|
||||
#endif
|
||||
|
||||
ASSERT_OK(uv_sem_init(&sem.main, 0));
|
||||
ASSERT_OK(uv_sem_init(&sem.worker, 0));
|
||||
|
||||
memset(thread_name, 'a', sizeof(thread_name) - 1);
|
||||
thread_name[sizeof(thread_name) - 1] = '\0';
|
||||
|
||||
memset(long_thread_name, 'a', sizeof(long_thread_name) - 1);
|
||||
long_thread_name[sizeof(long_thread_name) - 1] = '\0';
|
||||
|
||||
#ifdef _WIN32
|
||||
/* uv_thread_self isn't defined for the main thread on Windows. */
|
||||
threads[0] = GetCurrentThread();
|
||||
#else
|
||||
threads[0] = uv_thread_self();
|
||||
#endif
|
||||
|
||||
r = uv_thread_getname(&threads[0], tn, sizeof(tn));
|
||||
ASSERT_OK(r);
|
||||
|
||||
r = uv_thread_setname(long_thread_name);
|
||||
ASSERT_OK(r);
|
||||
|
||||
r = uv_thread_getname(&threads[0], tn, sizeof(tn));
|
||||
ASSERT_OK(r);
|
||||
ASSERT_STR_EQ(tn, thread_name);
|
||||
|
||||
r = uv_thread_setname(thread_name);
|
||||
ASSERT_OK(r);
|
||||
|
||||
r = uv_thread_getname(&threads[0], tn, sizeof(tn));
|
||||
ASSERT_OK(r);
|
||||
ASSERT_STR_EQ(tn, thread_name);
|
||||
|
||||
r = uv_thread_getname(&threads[0], tn, 3);
|
||||
ASSERT_OK(r);
|
||||
ASSERT_EQ(strlen(tn), 2);
|
||||
ASSERT_OK(memcmp(thread_name, tn, 2));
|
||||
|
||||
/* Illumos doesn't support non-ASCII thread names. */
|
||||
#ifndef __illumos__
|
||||
r = uv_thread_setname("~½¬{½");
|
||||
ASSERT_OK(r);
|
||||
|
||||
r = uv_thread_getname(&threads[0], tn, sizeof(tn));
|
||||
ASSERT_OK(r);
|
||||
ASSERT_STR_EQ(tn, "~½¬{½");
|
||||
#endif
|
||||
|
||||
ASSERT_OK(uv_thread_create(threads + 1, thread_run, &sem));
|
||||
|
||||
uv_sem_wait(&sem.worker);
|
||||
|
||||
r = uv_thread_getname(threads + 1, tn, sizeof(tn));
|
||||
ASSERT_OK(r);
|
||||
|
||||
ASSERT_STR_EQ(tn, "worker-thread");
|
||||
|
||||
uv_sem_post(&sem.main);
|
||||
|
||||
ASSERT_OK(uv_thread_join(threads + 1));
|
||||
|
||||
uv_sem_destroy(&sem.main);
|
||||
uv_sem_destroy(&sem.worker);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAX_THREADS 4
|
||||
|
||||
static void* executedThreads[MAX_THREADS] = { NULL };
|
||||
static int size;
|
||||
static uv_loop_t* loop;
|
||||
|
||||
static unsigned short int key_exists(void* key) {
|
||||
size_t i;
|
||||
for (i = 0; i < MAX_THREADS; i++) {
|
||||
if (executedThreads[i] == key) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void work_cb(uv_work_t* req) {
|
||||
uv_thread_t thread = uv_thread_self();
|
||||
req->data = &thread;
|
||||
char tn[UV_PTHREAD_MAX_NAMELEN_NP];
|
||||
ASSERT_OK(uv_thread_getname(&thread, tn, sizeof(tn)));
|
||||
ASSERT_STR_EQ(tn, "libuv-worker");
|
||||
}
|
||||
|
||||
static void after_work_cb(uv_work_t* req, int status) {
|
||||
ASSERT_OK(status);
|
||||
if (!key_exists(req->data)) {
|
||||
executedThreads[size++] = req->data;
|
||||
}
|
||||
|
||||
if (size == MAX_THREADS) {
|
||||
return;
|
||||
}
|
||||
|
||||
uv_queue_work(loop, req, work_cb, after_work_cb);
|
||||
}
|
||||
|
||||
TEST_IMPL(thread_name_threadpool) {
|
||||
uv_work_t req;
|
||||
loop = uv_default_loop();
|
||||
// Just to make sure all workers will be executed
|
||||
// with the correct thread name
|
||||
ASSERT_OK(uv_queue_work(loop, &req, work_cb, after_work_cb));
|
||||
uv_run(loop, UV_RUN_DEFAULT);
|
||||
MAKE_VALGRIND_HAPPY(uv_default_loop());
|
||||
return 0;
|
||||
}
|
||||
10
deps/uv/test/test-thread.c
vendored
10
deps/uv/test/test-thread.c
vendored
|
|
@ -294,3 +294,13 @@ TEST_IMPL(thread_stack_size_explicit) {
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void thread_detach_cb(void* arg) {}
|
||||
|
||||
TEST_IMPL(thread_detach) {
|
||||
uv_thread_t thread;
|
||||
ASSERT_OK(uv_thread_create(&thread, thread_detach_cb, NULL));
|
||||
ASSERT_OK(uv_thread_detach(&thread));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
5
deps/uv/test/test-udp-mmsg.c
vendored
5
deps/uv/test/test-udp-mmsg.c
vendored
|
|
@ -32,12 +32,12 @@
|
|||
#define BUFFER_MULTIPLIER 20
|
||||
#define MAX_DGRAM_SIZE (64 * 1024)
|
||||
#define NUM_SENDS 40
|
||||
#define EXPECTED_MMSG_ALLOCS (NUM_SENDS / BUFFER_MULTIPLIER)
|
||||
|
||||
static uv_udp_t recver;
|
||||
static uv_udp_t sender;
|
||||
static int recv_cb_called;
|
||||
static int received_datagrams;
|
||||
static int read_bytes;
|
||||
static int close_cb_called;
|
||||
static int alloc_cb_called;
|
||||
|
||||
|
|
@ -74,6 +74,7 @@ static void recv_cb(uv_udp_t* handle,
|
|||
const struct sockaddr* addr,
|
||||
unsigned flags) {
|
||||
ASSERT_GE(nread, 0);
|
||||
read_bytes += nread;
|
||||
|
||||
/* free and return if this is a mmsg free-only callback invocation */
|
||||
if (flags & UV_UDP_MMSG_FREE) {
|
||||
|
|
@ -140,7 +141,7 @@ TEST_IMPL(udp_mmsg) {
|
|||
|
||||
/* On platforms that don't support mmsg, each recv gets its own alloc */
|
||||
if (uv_udp_using_recvmmsg(&recver))
|
||||
ASSERT_EQ(alloc_cb_called, EXPECTED_MMSG_ALLOCS);
|
||||
ASSERT_EQ(read_bytes, NUM_SENDS * 4); /* we're sending 4 bytes per datagram */
|
||||
else
|
||||
ASSERT_EQ(alloc_cb_called, recv_cb_called);
|
||||
|
||||
|
|
|
|||
19
deps/uv/test/test-udp-multicast-join.c
vendored
19
deps/uv/test/test-udp-multicast-join.c
vendored
|
|
@ -36,10 +36,9 @@ static uv_udp_t client;
|
|||
static uv_udp_send_t req;
|
||||
static uv_udp_send_t req_ss;
|
||||
|
||||
static int darwin_ebusy_errors;
|
||||
static int cl_recv_cb_called;
|
||||
|
||||
static int sv_send_cb_called;
|
||||
|
||||
static int close_cb_called;
|
||||
|
||||
static void alloc_cb(uv_handle_t* handle,
|
||||
|
|
@ -128,6 +127,13 @@ static void cl_recv_cb(uv_udp_t* handle,
|
|||
|
||||
#if !defined(__NetBSD__)
|
||||
r = uv_udp_set_source_membership(&server, MULTICAST_ADDR, NULL, source_addr, UV_JOIN_GROUP);
|
||||
#if defined(__APPLE__)
|
||||
if (r == UV_EBUSY) {
|
||||
uv_close((uv_handle_t*) &server, close_cb);
|
||||
darwin_ebusy_errors++;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
ASSERT_OK(r);
|
||||
#endif
|
||||
|
||||
|
|
@ -160,7 +166,13 @@ TEST_IMPL(udp_multicast_join) {
|
|||
r = uv_udp_set_membership(&server, MULTICAST_ADDR, NULL, UV_JOIN_GROUP);
|
||||
if (r == UV_ENODEV)
|
||||
RETURN_SKIP("No multicast support.");
|
||||
if (r == UV_ENOEXEC)
|
||||
RETURN_SKIP("No multicast support (likely a firewall issue).");
|
||||
ASSERT_OK(r);
|
||||
#if defined(__ANDROID__)
|
||||
/* It returns an ENOSYS error */
|
||||
RETURN_SKIP("Test does not currently work in ANDROID");
|
||||
#endif
|
||||
|
||||
r = uv_udp_recv_start(&server, alloc_cb, cl_recv_cb);
|
||||
ASSERT_OK(r);
|
||||
|
|
@ -175,6 +187,9 @@ TEST_IMPL(udp_multicast_join) {
|
|||
/* run the loop till all events are processed */
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
|
||||
if (darwin_ebusy_errors > 0)
|
||||
RETURN_SKIP("Unexplained macOS IP_ADD_SOURCE_MEMBERSHIP EBUSY bug");
|
||||
|
||||
ASSERT_EQ(2, cl_recv_cb_called);
|
||||
ASSERT_EQ(2, sv_send_cb_called);
|
||||
ASSERT_EQ(2, close_cb_called);
|
||||
|
|
|
|||
1
deps/uv/test/test-udp-multicast-join6.c
vendored
1
deps/uv/test/test-udp-multicast-join6.c
vendored
|
|
@ -33,6 +33,7 @@
|
|||
#if defined(__APPLE__) || \
|
||||
defined(_AIX) || \
|
||||
defined(__MVS__) || \
|
||||
defined(__FreeBSD__) || \
|
||||
defined(__NetBSD__) || \
|
||||
defined(__OpenBSD__)
|
||||
#define MULTICAST_ADDR "ff02::1%lo0"
|
||||
|
|
|
|||
36
deps/uv/test/test-udp-try-send.c
vendored
36
deps/uv/test/test-udp-try-send.c
vendored
|
|
@ -60,8 +60,6 @@ static void sv_recv_cb(uv_udp_t* handle,
|
|||
const uv_buf_t* rcvbuf,
|
||||
const struct sockaddr* addr,
|
||||
unsigned flags) {
|
||||
ASSERT_GT(nread, 0);
|
||||
|
||||
if (nread == 0) {
|
||||
ASSERT_NULL(addr);
|
||||
return;
|
||||
|
|
@ -70,11 +68,17 @@ static void sv_recv_cb(uv_udp_t* handle,
|
|||
ASSERT_EQ(4, nread);
|
||||
ASSERT_NOT_NULL(addr);
|
||||
|
||||
ASSERT_OK(memcmp("EXIT", rcvbuf->base, nread));
|
||||
if (!memcmp("EXIT", rcvbuf->base, nread)) {
|
||||
uv_close((uv_handle_t*) handle, close_cb);
|
||||
uv_close((uv_handle_t*) &client, close_cb);
|
||||
} else {
|
||||
ASSERT_MEM_EQ(rcvbuf->base, "HELO", 4);
|
||||
}
|
||||
|
||||
sv_recv_cb_called++;
|
||||
|
||||
if (sv_recv_cb_called == 2)
|
||||
uv_udp_recv_stop(handle);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -101,9 +105,33 @@ TEST_IMPL(udp_try_send) {
|
|||
ASSERT_OK(r);
|
||||
|
||||
buf = uv_buf_init(buffer, sizeof(buffer));
|
||||
|
||||
r = uv_udp_try_send(&client, &buf, 0, (const struct sockaddr*) &addr);
|
||||
ASSERT_EQ(r, UV_EINVAL);
|
||||
|
||||
r = uv_udp_try_send(&client, &buf, 1, (const struct sockaddr*) &addr);
|
||||
ASSERT_EQ(r, UV_EMSGSIZE);
|
||||
|
||||
uv_buf_t* bufs[] = {&buf, &buf};
|
||||
unsigned int nbufs[] = {1, 1};
|
||||
struct sockaddr* addrs[] = {
|
||||
(struct sockaddr*) &addr,
|
||||
(struct sockaddr*) &addr,
|
||||
};
|
||||
|
||||
ASSERT_EQ(0, sv_recv_cb_called);
|
||||
|
||||
buf = uv_buf_init("HELO", 4);
|
||||
r = uv_udp_try_send2(&client, 2, bufs, nbufs, addrs, /*flags*/0);
|
||||
ASSERT_EQ(r, 2);
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
|
||||
ASSERT_EQ(2, sv_recv_cb_called);
|
||||
|
||||
r = uv_udp_recv_start(&server, alloc_cb, sv_recv_cb);
|
||||
ASSERT_OK(r);
|
||||
|
||||
buf = uv_buf_init("EXIT", 4);
|
||||
r = uv_udp_try_send(&client, &buf, 1, (const struct sockaddr*) &addr);
|
||||
ASSERT_EQ(4, r);
|
||||
|
|
@ -111,7 +139,7 @@ TEST_IMPL(udp_try_send) {
|
|||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
|
||||
ASSERT_EQ(2, close_cb_called);
|
||||
ASSERT_EQ(1, sv_recv_cb_called);
|
||||
ASSERT_EQ(3, sv_recv_cb_called);
|
||||
|
||||
ASSERT_OK(client.send_queue_size);
|
||||
ASSERT_OK(server.send_queue_size);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user