mirror of
https://github.com/nodejs/node.git
synced 2026-11-09 15:11:11 -05:00
deps: update libuv to 1.52.1
PR-URL: https://github.com/nodejs/node/pull/61829 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
This commit is contained in:
1 parent
9b1900617c
commit
7fc381f834
122 files changed
+2885
-1390
No files matched your search
Vendored
+47
@@ -0,0 +1,47 @@
|
||||
---
|
||||
# Configuration file for clang-tidy
|
||||
# This configuration is tailored for the libuv C library project
|
||||
|
||||
# Use default checks with minimal necessary disables
|
||||
Checks:
|
||||
# don't suggest reordering struct definitions
|
||||
- -clang-analyzer-optin.performance.Padding
|
||||
# allow memcpy (instead of memcpy_s)
|
||||
- -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling
|
||||
# allow strcpy
|
||||
- -clang-analyzer-security.insecureAPI.strcpy
|
||||
# allow TBAA
|
||||
- -clang-analyzer-unix.MallocSizeof
|
||||
# always allow `if () statement;` instead of `if () { statement; }`
|
||||
- -readability-braces-around-statements
|
||||
# allow any use of case and _ conventions in names
|
||||
- -readability-identifier-naming
|
||||
# allow defining a function prototype without naming all arguments
|
||||
- -readability-named-parameter
|
||||
# allow 1u instead of 1U constants
|
||||
- -readability-uppercase-literal-suffix
|
||||
|
||||
# Configure specific check options
|
||||
CheckOptions:
|
||||
- key: performance-unnecessary-value-param.AllowedTypes
|
||||
value: 'uv_.*_t'
|
||||
- key: readability-braces-around-statements.ShortStatementLines
|
||||
value: '2'
|
||||
- key: readability-function-size.LineThreshold
|
||||
value: '150'
|
||||
- key: readability-function-size.StatementThreshold
|
||||
value: '80'
|
||||
- key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
|
||||
value: 'true'
|
||||
|
||||
# Header filter - only analyze project files, not system headers
|
||||
HeaderFilterRegex: '^.*/(src|include|test)/.*\.(h|c)$'
|
||||
|
||||
# Format style for fix suggestions
|
||||
FormatStyle: file
|
||||
|
||||
# Treat warnings as errors
|
||||
WarningsAsErrors: false
|
||||
|
||||
# Use color, even when run through a program like ninja
|
||||
UseColor: true
|
||||
Vendored
+4
-1
@@ -27,8 +27,10 @@ Jesse Gorzinski <jgorzinski@gmail.com>
|
||||
Jesse Gorzinski <jgorzinski@gmail.com> <jgorzins@us.ibm.com>
|
||||
Juan José Arboleda <soyjuanarbol@gmail.com>
|
||||
Justin Venus <justin.venus@gmail.com> <justin.venus@orbitz.com>
|
||||
Keno Fischer <kenof@stanford.edu> <keno@juliahub.com>
|
||||
Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu>
|
||||
Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu>
|
||||
Lawrence Stubbs <technoexpressnet@gmail.com> <lstubbs@techno.express>
|
||||
Leith Bade <leith@leithalweapon.geek.nz> <leith@mapbox.com>
|
||||
Leonard Hecker <leonard.hecker91@gmail.com> <leonard@hecker.io>
|
||||
Lewis Russell <me@lewisr.dev> <lewis6991@gmail.com>
|
||||
@@ -42,7 +44,8 @@ Nick Logan <ugexe@cpan.org> <nlogan@gmail.com>
|
||||
Olivier Valentin <ovalenti@redhat.com> <valentio@free.fr>
|
||||
Rasmus Christian Pedersen <zerhacken@yahoo.com>
|
||||
Rasmus Christian Pedersen <zerhacken@yahoo.com> <ruysch@outlook.com>
|
||||
Richard Lau <rlau@redhat.com> <riclau@uk.ibm.com>
|
||||
Richard Lau <richard.lau@ibm.com> <riclau@uk.ibm.com>
|
||||
Richard Lau <richard.lau@ibm.com> <rlau@redhat.com>
|
||||
Robert Mustacchi <rm@joyent.com> <rm@fingolfin.org>
|
||||
Ryan Dahl <ryan@joyent.com> <ry@tinyclouds.org>
|
||||
Ryan Emery <seebees@gmail.com>
|
||||
|
||||
Vendored
+31
-1
@@ -210,7 +210,7 @@ guworks <ground.up.works@gmail.com>
|
||||
RossBencina <rossb@audiomulch.com>
|
||||
Roger A. Light <roger@atchoo.org>
|
||||
chenttuuvv <chenttuuvv@yahoo.com>
|
||||
Richard Lau <rlau@redhat.com>
|
||||
Richard Lau <richard.lau@ibm.com>
|
||||
ronkorving <rkorving@wizcorp.jp>
|
||||
Corbin Simpson <MostAwesomeDude@gmail.com>
|
||||
Zachary Hamm <zsh@imipolexg.org>
|
||||
@@ -604,3 +604,33 @@ mugitya03 <mugitya233@outlook.com>
|
||||
Itay Bookstein <ibookstein@gmail.com>
|
||||
crupest <crupest@outlook.com>
|
||||
AE1020 <68134252+AE1020@users.noreply.github.com>
|
||||
dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
|
||||
jhnh204 <51738134+jhnh204@users.noreply.github.com>
|
||||
chemodax <53048645+chemodax@users.noreply.github.com>
|
||||
Deep C <dchordia@blackberry.com>
|
||||
Luca Saccarola <96259932+saccarosium@users.noreply.github.com>
|
||||
wisemanny <118970226+wisemanny@users.noreply.github.com>
|
||||
Sean Dewar <6256228+seandewar@users.noreply.github.com>
|
||||
Lawrence Stubbs <technoexpressnet@gmail.com>
|
||||
Emily <hello@emily.moe>
|
||||
Anton Kirilov <anton.kirilov@arm.com>
|
||||
Savas Sahin <savashn@proton.me>
|
||||
m0cg <mane9999@gmail.com>
|
||||
moe li <creeperblin@outlook.com>
|
||||
green-br <thomas.green@bristol.ac.uk>
|
||||
Christian Guinard <28689358+christiangnrd@users.noreply.github.com>
|
||||
Gang Zhuo <gang.zhuo@gmail.com>
|
||||
Ayush Kumar <ayushkumarkvs160@gmail.com>
|
||||
Ambuj Vashistha <ambujva123@gmail.com>
|
||||
Bart Louwers <bart.louwers@gmail.com>
|
||||
Kartik Puri <84309847+BOXER78@users.noreply.github.com>
|
||||
Oblivionsage <126214490+Oblivionsage@users.noreply.github.com>
|
||||
Cody Tapscott <84105208+topolarity@users.noreply.github.com>
|
||||
tobil4sk <tobil4sk@outlook.com>
|
||||
Han Gao <rabenda.cn@gmail.com>
|
||||
mischief <mischief@offblast.org>
|
||||
StefanStojanovic <stefan.stojanovic@janeasystems.com>
|
||||
Przemysław Sobala <przemyslaw.sobala@grupawp.pl>
|
||||
Quaylyn Rimer <31830590+killerdevildog@users.noreply.github.com>
|
||||
Yasser Nascimento <dev@yasser.email>
|
||||
Rudi Heitbaum <rudi@heitbaum.com>
|
||||
Vendored
+90
@@ -24,6 +24,7 @@ set(CMAKE_C_STANDARD 11)
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
|
||||
option(LIBUV_BUILD_SHARED "Build shared lib" ON)
|
||||
|
||||
cmake_dependent_option(LIBUV_BUILD_TESTS
|
||||
@@ -700,6 +701,8 @@ if(LIBUV_BUILD_TESTS)
|
||||
test/test-udp-send-immediate.c
|
||||
test/test-udp-sendmmsg-error.c
|
||||
test/test-udp-send-unreachable.c
|
||||
test/test-udp-recv-cb-close-pollerr.c
|
||||
test/test-udp-recvmsg-unreachable-error.c
|
||||
test/test-udp-try-send.c
|
||||
test/test-udp-recv-in-a-row.c
|
||||
test/test-udp-reuseport.c
|
||||
@@ -747,6 +750,14 @@ if(LIBUV_BUILD_TESTS)
|
||||
"$<TARGET_FILE:uv_run_tests_a>"
|
||||
"$<TARGET_FILE_DIR:uv_run_tests_a>/uv_run_tests_a_no_ext")
|
||||
endif()
|
||||
|
||||
if(QNX)
|
||||
install(TARGETS uv_run_tests uv_run_tests_a uv_run_benchmarks_a
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR}/libuv_tests)
|
||||
|
||||
install(DIRECTORY test/fixtures
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR}/libuv_tests)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Now for some gibbering horrors from beyond the stars...
|
||||
@@ -774,6 +785,11 @@ install(TARGETS uv_a EXPORT libuvConfig
|
||||
install(EXPORT libuvConfig
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libuv
|
||||
NAMESPACE libuv::)
|
||||
write_basic_package_version_file(libuvConfigVersion.cmake
|
||||
VERSION ${PACKAGE_VERSION}
|
||||
COMPATIBILITY SameMajorVersion)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libuvConfigVersion.cmake
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libuv)
|
||||
|
||||
if(LIBUV_BUILD_SHARED)
|
||||
# The version in the filename is mirroring the behaviour of autotools.
|
||||
@@ -814,3 +830,77 @@ message(STATUS "summary of build options:
|
||||
C compiler: ${CMAKE_C_COMPILER} (${CMAKE_C_COMPILER_ID})
|
||||
CFLAGS: ${CMAKE_C_FLAGS_${_build_type}} ${CMAKE_C_FLAGS}
|
||||
")
|
||||
|
||||
# clang-tidy support
|
||||
option(ENABLE_CLANG_TIDY "Enable clang-tidy checks" ON)
|
||||
if(ENABLE_CLANG_TIDY)
|
||||
find_program(CLANG_TIDY_EXE NAMES "clang-tidy")
|
||||
if(CLANG_TIDY_EXE)
|
||||
set(CMAKE_C_CLANG_TIDY "${CLANG_TIDY_EXE}")
|
||||
message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}")
|
||||
else()
|
||||
set(CMAKE_C_CLANG_TIDY "clang-tidy")
|
||||
message(STATUS "clang-tidy not found: install clang-tidy or set -DCLANG_TIDY_EXE to run tidy analysis on this platform")
|
||||
endif()
|
||||
|
||||
# Collect source files from existing targets (deduplicated)
|
||||
set(ALL_SOURCE_FILES)
|
||||
set(SRC_TARGETS)
|
||||
set(TEST_TARGETS)
|
||||
set(TIDY_TARGETS)
|
||||
|
||||
# Add main library sources
|
||||
list(APPEND ALL_SOURCE_FILES ${uv_sources})
|
||||
|
||||
# Add test sources if tests are enabled
|
||||
if(LIBUV_BUILD_TESTS)
|
||||
list(APPEND ALL_SOURCE_FILES ${uv_test_sources})
|
||||
endif()
|
||||
|
||||
# Remove duplicates and non-existent files
|
||||
list(REMOVE_DUPLICATES ALL_SOURCE_FILES)
|
||||
|
||||
foreach(SOURCE_FILE ${ALL_SOURCE_FILES})
|
||||
# Create a clean target name
|
||||
string(REPLACE "/" "-" TARGET_NAME ${SOURCE_FILE})
|
||||
string(REGEX REPLACE "\\.[^.]*$" "" TARGET_NAME ${TARGET_NAME})
|
||||
set(FULL_TARGET_NAME "tidy-${TARGET_NAME}")
|
||||
|
||||
# Create individual target for this source file
|
||||
add_custom_target(${FULL_TARGET_NAME}
|
||||
COMMAND ${CMAKE_C_CLANG_TIDY} -p "${CMAKE_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/${SOURCE_FILE}"
|
||||
COMMENT "Running clang-tidy on ${SOURCE_FILE}"
|
||||
VERBATIM)
|
||||
|
||||
# Add to appropriate folder list
|
||||
if(SOURCE_FILE MATCHES "^src/")
|
||||
list(APPEND SRC_TARGETS ${FULL_TARGET_NAME})
|
||||
elseif(SOURCE_FILE MATCHES "^test/")
|
||||
list(APPEND TEST_TARGETS ${FULL_TARGET_NAME})
|
||||
endif()
|
||||
|
||||
# Add to list of all tidy targets
|
||||
list(APPEND TIDY_TARGETS ${FULL_TARGET_NAME})
|
||||
endforeach()
|
||||
|
||||
# Create folder-based targets
|
||||
if(SRC_TARGETS)
|
||||
add_custom_target(tidy-src
|
||||
COMMENT "Running clang-tidy on src files"
|
||||
VERBATIM)
|
||||
add_dependencies(tidy-src ${SRC_TARGETS})
|
||||
endif()
|
||||
|
||||
if(TEST_TARGETS)
|
||||
add_custom_target(tidy-test
|
||||
COMMENT "Running clang-tidy on test files"
|
||||
VERBATIM)
|
||||
add_dependencies(tidy-test ${TEST_TARGETS})
|
||||
endif()
|
||||
|
||||
# Create main tidy target that depends on all individual targets
|
||||
add_custom_target(tidy
|
||||
COMMENT "Running clang-tidy on all source files"
|
||||
VERBATIM)
|
||||
add_dependencies(tidy ${TIDY_TARGETS})
|
||||
endif()
|
||||
Vendored
+269
-1
@@ -1,4 +1,272 @@
|
||||
2025.04.25, Version 1.51.0 (Stable)
|
||||
2026.03.06, Version 1.52.1 (Stable)
|
||||
|
||||
Changes since version 1.52.0:
|
||||
|
||||
* misc: add simple clang-tidy setup (Jameson Nash)
|
||||
|
||||
* unix: check RLIMIT_AS and RLIMIT_DATA in uv_get_constrained_memory (Jameson
|
||||
Nash)
|
||||
|
||||
* win: add fs-fd-hash-inl.h to tarball (tobil4sk)
|
||||
|
||||
* unix,win: support NULL loop for sync uv_getaddrinfo (Saúl Ibarra Corretgé)
|
||||
|
||||
* Fix const-correctness warning in linux.c (Quaylyn Rimer)
|
||||
|
||||
* build(deps): bump actions/upload-artifact from 6 to 7 (dependabot[bot])
|
||||
|
||||
* build(deps): bump actions/download-artifact from 7 to 8 (dependabot[bot])
|
||||
|
||||
* unix: fix compilation warnings with GCC 15 (Saúl Ibarra Corretgé)
|
||||
|
||||
* test: remove conditionals from `uv_thread_self` usage (Yasser Nascimento)
|
||||
|
||||
* unix: fix discard const (Rudi Heitbaum)
|
||||
|
||||
* unix: do not cast to char variables that are const char (Rudi Heitbaum)
|
||||
|
||||
* linux: fix crash if poll callback closes handle before `POLLERR` (Juan José
|
||||
Arboleda)
|
||||
|
||||
|
||||
2026.02.11, Version 1.52.0 (Stable), b556c0629d0fd250b5feefbc91b84c6f5e3dae48
|
||||
|
||||
Changes since version 1.51.0:
|
||||
|
||||
* src: remove unused include of <assert.h> in timer.c (Juan José Arboleda)
|
||||
|
||||
* test: skip `udp_multicast_join` if not system-wide available (Juan José
|
||||
Arboleda)
|
||||
|
||||
* test: remove unused include of <limits.h> in runner.h (Juan José Arboleda)
|
||||
|
||||
* doc: don't mention UV_LOOP_ENABLE_IO_URING_SQPOLL (Poul T Lomholt)
|
||||
|
||||
* unix: fix uv_thread_{get,set}priority error codes (Ryan Liptak)
|
||||
|
||||
* build: dedup sanitizer jobs using matrix strategy (Juan José Arboleda)
|
||||
|
||||
* doc: update ncurses link (Saúl Ibarra Corretgé)
|
||||
|
||||
* tcp: support customizing TCP_KEEPINTVL and TCP_KEEPCNT (Andy Pan)
|
||||
|
||||
* linux: fix -Wformat-truncation warning (Ben Noordhuis)
|
||||
|
||||
* src: fix nullptr dereference in uv__print_handles (jhnh204)
|
||||
|
||||
* build: make automake link libm on bsd-likes (Juan José Arboleda)
|
||||
|
||||
* include: remove unused macro undefs from uv.h (Juan José Arboleda)
|
||||
|
||||
* win: handle empty string in uv_get_process_title (Ben Noordhuis)
|
||||
|
||||
* win: use WSA_FLAG_NO_HANDLE_INHERIT in WSASocketW (chemodax)
|
||||
|
||||
* unix: handle possible `ENOMEM` in `uv__tcp_listen` (Juan José Arboleda)
|
||||
|
||||
* win: replace GetModuleHandleA with GetModuleHandleW (chemodax)
|
||||
|
||||
* qnx: add qnx 8 support (Deep C)
|
||||
|
||||
* mailmap: update email address for Richard Lau (Richard Lau)
|
||||
|
||||
* win: remove obsolete comment (Ben Noordhuis)
|
||||
|
||||
* unix: handle possible `ENOMEM` in `uv__pipe_listen` (Juan José Arboleda)
|
||||
|
||||
* unix: deduplicate uv_free_interface_addresses (Juan José Arboleda)
|
||||
|
||||
* test: pass correct string type to GetModuleHandleW (Ben Noordhuis)
|
||||
|
||||
* win: remove unnecessary inlining from fs.c (Ben Noordhuis)
|
||||
|
||||
* win: move uv__process_reqs to core.c (Ben Noordhuis)
|
||||
|
||||
* win: remove unnecessary inlining from header file (Ben Noordhuis)
|
||||
|
||||
* test: skip slow process title test on asan+macos (Ben Noordhuis)
|
||||
|
||||
* win: dissolve atomicops-inl.h (Ben Noordhuis)
|
||||
|
||||
* win: move uv__process_endgames to core.c (Ben Noordhuis)
|
||||
|
||||
* win: move uv__insert_pending_req to core.c (Ben Noordhuis)
|
||||
|
||||
* win: replace inline asm with compiler intrinsic (Ben Noordhuis)
|
||||
|
||||
* win,pipe: minimal fix to uv_read_cb->uv_read_start recursion bug (Jameson
|
||||
Nash)
|
||||
|
||||
* doc: make requirements work with newer python (Luca Saccarola)
|
||||
|
||||
* win: fix -Wcast-function-type warnings in winapi.c (Ben Noordhuis)
|
||||
|
||||
* win: fix -Wsign-compare warnings (Ben Noordhuis)
|
||||
|
||||
* test: simplify ASSERT_OK macro for static analysis (Jameson Nash)
|
||||
|
||||
* win: add arm64 machine type to uv_os_uname (wisemanny)
|
||||
|
||||
* win: use ProcessPrng (Ben Noordhuis)
|
||||
|
||||
* win: work around wine bug in uv_fs_{unlink,rmdir} (Keno Fischer)
|
||||
|
||||
* doc: fix return value for uv_pipe_connect2 (Sean Dewar)
|
||||
|
||||
* unix: fix udp sendmmsg fallback path (Ben Noordhuis)
|
||||
|
||||
* doc: add binding `C framework` uv_coroutine to LINKS.md (Lawrence Stubbs)
|
||||
|
||||
* linux: handle cgroups cpu.max with limit < period (Ben Noordhuis)
|
||||
|
||||
* doc: update link, repo name change to c-asio (Lawrence Stubbs)
|
||||
|
||||
* build(deps): bump actions/download-artifact from 4 to 5 (dependabot[bot])
|
||||
|
||||
* doc: remove nodeuv from LINKS.md (Ben Noordhuis)
|
||||
|
||||
* test: use relative paths for pipes and unix sockets (Emily)
|
||||
|
||||
* build(deps): bump actions/checkout from 4 to 5 (dependabot[bot])
|
||||
|
||||
* unix: improve uv__cpu_relax() on arm (Anton Kirilov)
|
||||
|
||||
* win: fix compiler warnings (Savas Sahin)
|
||||
|
||||
* unix: replace uv__io_t callback pointer with enum (Ben Noordhuis)
|
||||
|
||||
* test,win: fix -Wunused-function warnings (Ben Noordhuis)
|
||||
|
||||
* test,win: fix -Wcast-function-type warnings (Ben Noordhuis)
|
||||
|
||||
* test,win: fix -Wattributes warnings (Ben Noordhuis)
|
||||
|
||||
* win: shrink fd hash table from 2592k to 162k (Ben Noordhuis)
|
||||
|
||||
* unix: fix build on the bsds (Ben Noordhuis)
|
||||
|
||||
* netbsd: fix thread affinity compilation error (Santiago Gimeno)
|
||||
|
||||
* unix: remove UV__SIGNAL_EVENT dispatch from uv__io_cb (Juan José Arboleda)
|
||||
|
||||
* build: add -Werror when testing -Wflags (Jameson Nash)
|
||||
|
||||
* win: fix path size calculation (Ben Noordhuis)
|
||||
|
||||
* doc: correct uv_cancel return value (m0cg)
|
||||
|
||||
* unix,win: look up UV_THREADPOOL_SIZE with uv_os_getenv (moe li)
|
||||
|
||||
* build(deps): bump actions/setup-python from 5 to 6 (dependabot[bot])
|
||||
|
||||
* unix: fix uv__signal_loop_cleanup call in init (Jameson Nash)
|
||||
|
||||
* aix: fix nullptr check in uv__skip_lines (Ben Noordhuis)
|
||||
|
||||
* unix: add neoverse-v2 cpu identifier (green-br)
|
||||
|
||||
* test: make `thread_priority` robust against system default nice levels
|
||||
|
||||
(Juan José Arboleda)
|
||||
|
||||
* unix,win: implement `uv_udp_open_ex` (Juan José Arboleda)
|
||||
|
||||
* aix: add stub function to satisfy linker (Ben Noordhuis)
|
||||
|
||||
* linux: add MSG_ERRQUEUE ipv4/ipv6 udp support (Juan José Arboleda)
|
||||
|
||||
* ibmi: add stub function to satisfy linker (Ben Noordhuis)
|
||||
|
||||
* darwin: better heuristic for available memory (Christian Guinard)
|
||||
|
||||
* build(deps): bump actions/download-artifact from 5 to 6 (dependabot[bot])
|
||||
|
||||
* build(deps): bump actions/upload-artifact from 4 to 5 (dependabot[bot])
|
||||
|
||||
* unix: fix use of uninitialized variable (Ben Noordhuis)
|
||||
|
||||
* doc: fix documentation for uv_utf16_to_wtf8() function (Gang Zhuo)
|
||||
|
||||
* win: rename minimal_windows10_version1709() for libuv's convention (Andy Pan)
|
||||
|
||||
* build(deps): bump actions/checkout from 5 to 6 (dependabot[bot])
|
||||
|
||||
* win: fix race in uv_fs_event_start() (Ben Noordhuis)
|
||||
|
||||
* unix: support nanosecond resolution in uv__fs_to_timespec (Ayush Kumar)
|
||||
|
||||
* win: handle sshfs-win quirk in uv_fs_readdir() (Ben Noordhuis)
|
||||
|
||||
* unix,win: fix leak in uv_os_environ error path (Ambuj Vashistha)
|
||||
|
||||
* test: add macros to run fs tests with io_uring (Santiago Gimeno)
|
||||
|
||||
* linux: fix uv_fs_ftruncate io_uring implementation (Santiago Gimeno)
|
||||
|
||||
* Update OS X reference to macOS in README (Bart Louwers)
|
||||
|
||||
* ci: update macos runner images (Ben Noordhuis)
|
||||
|
||||
* doc: add example usage for uv_sleep (Kartik Puri)
|
||||
|
||||
* ci: add macos-15-intel to matrix (Ben Noordhuis)
|
||||
|
||||
* win: Optimize file/directory delete. (chemodax)
|
||||
|
||||
* build(deps): bump actions/download-artifact from 6 to 7 (dependabot[bot])
|
||||
|
||||
* build(deps): bump actions/upload-artifact from 5 to 6 (dependabot[bot])
|
||||
|
||||
* test: run more fs tests using io_uring too (Santiago Gimeno)
|
||||
|
||||
* doc: add handle and request usage guidelines (Ben Noordhuis)
|
||||
|
||||
* unix: remove handle from queue on uv_spawn() error (Oblivionsage)
|
||||
|
||||
* doc: remove hp-ux from supported platforms list (Ben Noordhuis)
|
||||
|
||||
* unix,win: add f_frsize field to uv_statfs_t (Ben Noordhuis)
|
||||
|
||||
* test: fix -Wuninitialized-const-pointer warning (Ben Noordhuis)
|
||||
|
||||
* test: fix -Wstringop-overread warning (Ben Noordhuis)
|
||||
|
||||
* test: make pty test work under asan (Ben Noordhuis)
|
||||
|
||||
* win: readlink support for IO_REPARSE_TAG_LX_SYMLINK (Cody Tapscott)
|
||||
|
||||
* unix: fix partial read handling after POLLHUP (Ben Noordhuis)
|
||||
|
||||
* unix: factor out common i/o poll code (Ben Noordhuis)
|
||||
|
||||
* test: disable udp_reuseport test under qemu (Ben Noordhuis)
|
||||
|
||||
* test: disable tcp_reuseport test under qemu (Ben Noordhuis)
|
||||
|
||||
* unix,win: check nbufs argument is reasonable (Ben Noordhuis)
|
||||
|
||||
* win: refactor to support large statfs blocks (Santiago Gimeno)
|
||||
|
||||
* unix: remove sunpro references (Ben Noordhuis)
|
||||
|
||||
* idna: fix assert in wtf8_to_utf16 conversion (tobil4sk)
|
||||
|
||||
* aix,ibmi: fix test suite build breakage (Ben Noordhuis)
|
||||
|
||||
* unix: implement cpu_relax() for riscv64 (Han Gao)
|
||||
|
||||
* doc: add setuid warning to uv_exepath (Ben Noordhuis)
|
||||
|
||||
* unix: make OpenBSD uv_exepath work (mischief)
|
||||
|
||||
* win: fix uv_get_process_title (StefanStojanovic)
|
||||
|
||||
* unix,udp: fix -Wgnu-folding-constant warning (Saúl Ibarra Corretgé)
|
||||
|
||||
* cmake: add libuvConfigVersion.cmake file (Przemysław Sobala)
|
||||
|
||||
|
||||
2025.04.25, Version 1.51.0 (Stable), 5152db2cbfeb5582e9c27c5ea1dba2cd9e10759b
|
||||
|
||||
Changes since version 1.50.0:
|
||||
|
||||
|
||||
Vendored
+3
-2
@@ -30,7 +30,6 @@
|
||||
* [node9](https://github.com/jvburnes/node9): A portable, hybrid, distributed OS based on Inferno, LuaJIT and Libuv
|
||||
* [node.js](http://www.nodejs.org/): Javascript (using Google's V8) + libuv
|
||||
* [node.native](https://github.com/d5/node.native): node.js-like API for C++11
|
||||
* [nodeuv](https://github.com/nodeuv): An organization with several c++ wrappers for libs which are used in node.js.
|
||||
* [phastlight](https://github.com/phastlight/phastlight): Command line tool and web server written in PHP 5.3+ inspired by Node.js
|
||||
* [pilight](https://www.pilight.org/): home automation ("domotica")
|
||||
* [pixie](https://github.com/pixie-lang/pixie): clojure-inspired lisp with a tracing JIT
|
||||
@@ -109,4 +108,6 @@
|
||||
* Haskell
|
||||
* [Z.Haskell](https://z.haskell.world)
|
||||
* C3
|
||||
* [libuv.c3l](https://github.com/velikoss/libuv.c3l)
|
||||
* [libuv.c3l](https://github.com/velikoss/libuv.c3l)
|
||||
* C
|
||||
* [c-asio](https://github.com/zelang-dev/c-asio) A memory safe focus *C framework*, combining [c-raii](https://zelang-dev.github.io/c-raii), `libuv`, **coroutine** and other concurrency primitives.
|
||||
Vendored
+9
-7
@@ -61,13 +61,13 @@ AM_CPPFLAGS += -I$(top_srcdir)/src/win \
|
||||
-DWIN32_LEAN_AND_MEAN \
|
||||
-D_WIN32_WINNT=0x0A00
|
||||
libuv_la_SOURCES += src/win/async.c \
|
||||
src/win/atomicops-inl.h \
|
||||
src/win/core.c \
|
||||
src/win/detect-wakeup.c \
|
||||
src/win/dl.c \
|
||||
src/win/error.c \
|
||||
src/win/fs-event.c \
|
||||
src/win/fs.c \
|
||||
src/win/fs-fd-hash-inl.h \
|
||||
src/win/getaddrinfo.c \
|
||||
src/win/getnameinfo.c \
|
||||
src/win/handle.c \
|
||||
@@ -326,6 +326,8 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
||||
test/test-udp-send-immediate.c \
|
||||
test/test-udp-sendmmsg-error.c \
|
||||
test/test-udp-send-unreachable.c \
|
||||
test/test-udp-recv-cb-close-pollerr.c \
|
||||
test/test-udp-recvmsg-unreachable-error.c \
|
||||
test/test-udp-try-send.c \
|
||||
test/test-udp-recv-in-a-row.c \
|
||||
test/test-udp-reuseport.c \
|
||||
@@ -438,7 +440,7 @@ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
|
||||
src/unix/kqueue.c \
|
||||
src/unix/proctitle.c \
|
||||
src/unix/random-getentropy.c
|
||||
test_run_tests_LDFLAGS += -lutil
|
||||
test_run_tests_LDFLAGS += -lutil -lm
|
||||
endif
|
||||
|
||||
if DRAGONFLY
|
||||
@@ -448,7 +450,7 @@ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
|
||||
src/unix/freebsd.c \
|
||||
src/unix/kqueue.c \
|
||||
src/unix/posix-hrtime.c
|
||||
test_run_tests_LDFLAGS += -lutil
|
||||
test_run_tests_LDFLAGS += -lutil -lm
|
||||
endif
|
||||
|
||||
if FREEBSD
|
||||
@@ -459,7 +461,7 @@ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
|
||||
src/unix/kqueue.c \
|
||||
src/unix/posix-hrtime.c \
|
||||
src/unix/random-getrandom.c
|
||||
test_run_tests_LDFLAGS += -lutil
|
||||
test_run_tests_LDFLAGS += -lutil -lm
|
||||
endif
|
||||
|
||||
if HAIKU
|
||||
@@ -491,7 +493,7 @@ libuv_la_SOURCES += src/unix/linux.c \
|
||||
src/unix/proctitle.c \
|
||||
src/unix/random-getrandom.c \
|
||||
src/unix/random-sysctl-linux.c
|
||||
test_run_tests_LDFLAGS += -lutil
|
||||
test_run_tests_LDFLAGS += -lutil -lm
|
||||
endif
|
||||
|
||||
if MSYS
|
||||
@@ -514,7 +516,7 @@ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
|
||||
src/unix/kqueue.c \
|
||||
src/unix/netbsd.c \
|
||||
src/unix/posix-hrtime.c
|
||||
test_run_tests_LDFLAGS += -lutil
|
||||
test_run_tests_LDFLAGS += -lutil -lm
|
||||
endif
|
||||
|
||||
if OPENBSD
|
||||
@@ -525,7 +527,7 @@ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
|
||||
src/unix/openbsd.c \
|
||||
src/unix/posix-hrtime.c \
|
||||
src/unix/random-getentropy.c
|
||||
test_run_tests_LDFLAGS += -lutil
|
||||
test_run_tests_LDFLAGS += -lutil -lm
|
||||
endif
|
||||
|
||||
if SUNOS
|
||||
|
||||
Vendored
+1
-1
@@ -215,7 +215,7 @@ $ cmake ../.. \
|
||||
$ brew install --HEAD libuv
|
||||
```
|
||||
|
||||
Note to OS X users:
|
||||
Note to macOS users:
|
||||
|
||||
Make sure that you specify the architecture you wish to build for in the
|
||||
"ARCHS" flag. You can specify more than one by delimiting with a space
|
||||
|
||||
Vendored
-1
@@ -12,7 +12,6 @@
|
||||
| Linux with musl | Tier 2 | musl >= 1.0 | |
|
||||
| Android | Tier 3 | NDK >= r15b | Android 7.0, `-DANDROID_PLATFORM=android-24` |
|
||||
| MinGW | Tier 3 | MinGW-w64 | |
|
||||
| SunOS | Tier 3 | Solaris 121 and later | |
|
||||
| Other | Tier 3 | N/A | |
|
||||
|
||||
## Support types
|
||||
|
||||
Vendored
+2
-2
@@ -13,7 +13,7 @@
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT([libuv], [1.51.0], [https://github.com/libuv/libuv/issues])
|
||||
AC_INIT([libuv], [1.52.1], [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])
|
||||
@@ -27,7 +27,7 @@ AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
|
||||
CC_ATTRIBUTE_VISIBILITY([default], [
|
||||
CC_FLAG_VISIBILITY([CFLAGS="${CFLAGS} -fvisibility=hidden"])
|
||||
CC_CHECK_CFLAG_APPEND([-fvisibility=hidden])
|
||||
])
|
||||
# Xlc has a flag "-f<filename>". Need to use CC_CHECK_FLAG_SUPPORTED_APPEND so
|
||||
# we exclude -fno-strict-aliasing for xlc
|
||||
|
||||
Vendored
+22
-29
@@ -1,36 +1,29 @@
|
||||
# primary
|
||||
furo==2023.5.20
|
||||
Sphinx==6.1.3
|
||||
furo==2024.8.6
|
||||
Sphinx==7.0.1
|
||||
|
||||
# dependencies
|
||||
alabaster==0.7.13
|
||||
Babel==2.11.0
|
||||
beautifulsoup4==4.12.2
|
||||
certifi==2022.12.7
|
||||
charset-normalizer==3.0.1
|
||||
colorama==0.4.6
|
||||
docutils==0.19
|
||||
idna==3.4
|
||||
alabaster==0.7.16
|
||||
babel==2.17.0
|
||||
beautifulsoup4==4.13.3
|
||||
certifi==2025.1.31
|
||||
charset-normalizer==3.4.1
|
||||
docutils==0.20.1
|
||||
idna==3.10
|
||||
imagesize==1.4.1
|
||||
importlib-metadata==6.0.0
|
||||
Jinja2==3.1.2
|
||||
livereload==2.6.3
|
||||
MarkupSafe==2.1.2
|
||||
packaging==23.0
|
||||
Pygments==2.14.0
|
||||
pytz==2022.7.1
|
||||
requests==2.28.2
|
||||
six==1.16.0
|
||||
Jinja2==3.1.6
|
||||
MarkupSafe==3.0.2
|
||||
packaging==24.2
|
||||
Pygments==2.19.1
|
||||
requests==2.32.3
|
||||
snowballstemmer==2.2.0
|
||||
soupsieve==2.4.1
|
||||
sphinx-autobuild==2021.3.14
|
||||
soupsieve==2.6
|
||||
sphinx-basic-ng==1.0.0b2
|
||||
sphinxcontrib-devhelp==1.0.2
|
||||
sphinxcontrib-htmlhelp==2.0.0
|
||||
sphinxcontrib-applehelp==2.0.0
|
||||
sphinxcontrib-devhelp==2.0.0
|
||||
sphinxcontrib-htmlhelp==2.1.0
|
||||
sphinxcontrib-jsmath==1.0.1
|
||||
sphinxcontrib-qthelp==1.0.3
|
||||
sphinxcontrib-serializinghtml==1.1.5
|
||||
sphinxcontrib.applehelp==1.0.3
|
||||
tornado==6.3.2
|
||||
urllib3==1.26.14
|
||||
zipp==3.11.0
|
||||
sphinxcontrib-qthelp==2.0.0
|
||||
sphinxcontrib-serializinghtml==2.0.0
|
||||
typing_extensions==4.13.0
|
||||
urllib3==2.3.0
|
||||
Vendored
+25
@@ -36,6 +36,31 @@ Requests represent (typically) short-lived operations. These operations can be p
|
||||
handle: write requests are used to write data on a handle; or standalone: getaddrinfo requests
|
||||
don't need a handle they run directly on the loop.
|
||||
|
||||
Guidelines for dealing with handles and requests:
|
||||
|
||||
1. If `uv_foo_init()` succeeds in initializing the handle, you must call
|
||||
:c:func:`uv_close()`. If the handle's init function errors, you don't
|
||||
need to do anything.
|
||||
|
||||
2. Only handles are closed, not requests. For example, :c:type:`uv_tcp_t`
|
||||
is a handle, :c:type:`uv_write_t` is a request.
|
||||
|
||||
3. The handle's memory can only be reclaimed or reused from inside the
|
||||
:c:type:`uv_close_cb` or afterwards, not before.
|
||||
|
||||
4. Most handles have init + start/stop functions; some handles don't.
|
||||
Example: :c:type:`uv_tcp_t` vs. :c:type:`uv_process_t`; :c:func:`uv_spawn()`
|
||||
combines handle initialization and process start into one.
|
||||
|
||||
5. Requests are closed automatically when they complete, or when they are
|
||||
cancelled with :c:func:`uv_cancel()`.
|
||||
|
||||
6. No additional cleanup is needed except for :c:type:`uv_fs_t` and
|
||||
:c:type:`uv_getaddrinfo_t` requests. For :c:type:`uv_fs_t`, call
|
||||
:c:func:`uv_fs_req_cleanup()` once you are done with it; for
|
||||
:c:type:`uv_getaddrinfo_t`, that's :c:func:`uv_freeaddrinfo()`.
|
||||
|
||||
7. The request's memory can only be reclaimed or reused from that point onward.
|
||||
|
||||
The I/O loop
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Vendored
+3
-2
@@ -19,7 +19,7 @@ observable behavior. Libuv reverts to using its threadpool when the necessary
|
||||
kernel features are unavailable or unsuitable. Starting with libuv v1.49.0 this
|
||||
behavior was reverted and Libuv on Linux by default will be using the threadpool
|
||||
again. In order to enable io_uring the :c:type:`uv_loop_t` instance must be
|
||||
configured with the :c:type:`UV_LOOP_ENABLE_IO_URING_SQPOLL` option.
|
||||
configured with the :c:type:`UV_LOOP_USE_IO_URING_SQPOLL` option.
|
||||
|
||||
.. note::
|
||||
On Windows `uv_fs_*` functions use utf-8 encoding.
|
||||
@@ -129,7 +129,8 @@ Data types
|
||||
uint64_t f_bavail;
|
||||
uint64_t f_files;
|
||||
uint64_t f_ffree;
|
||||
uint64_t f_spare[4];
|
||||
uint64_t f_frsize;
|
||||
uint64_t f_spare[3];
|
||||
} uv_statfs_t;
|
||||
|
||||
.. c:enum:: uv_dirent_type_t
|
||||
|
||||
Vendored
+2
-2
@@ -86,12 +86,12 @@ API
|
||||
|
||||
This option is necessary to use :c:func:`uv_metrics_idle_time`.
|
||||
|
||||
- UV_LOOP_ENABLE_IO_URING_SQPOLL: Enable SQPOLL io_uring instance to handle
|
||||
- UV_LOOP_USE_IO_URING_SQPOLL: Enable SQPOLL io_uring instance to handle
|
||||
asynchronous file system operations.
|
||||
|
||||
.. versionchanged:: 1.39.0 added the UV_METRICS_IDLE_TIME option.
|
||||
|
||||
.. versionchanged:: 1.49.0 added the UV_LOOP_ENABLE_IO_URING_SQPOLL option.
|
||||
.. versionchanged:: 1.49.0 added the UV_LOOP_USE_IO_URING_SQPOLL option.
|
||||
|
||||
.. c:function:: int uv_loop_close(uv_loop_t* loop)
|
||||
|
||||
|
||||
Vendored
+15
-1
@@ -522,6 +522,10 @@ API
|
||||
Gets the executable path. You *must* call `uv_setup_args` before calling
|
||||
this function.
|
||||
|
||||
Be careful in setuid executables. On some platforms the executable path
|
||||
is an arbitrary string that is controlled by the user. On other platforms
|
||||
environment variables are consulted that may be under control of the user.
|
||||
|
||||
.. c:function:: int uv_cwd(char* buffer, size_t* size)
|
||||
|
||||
Gets the current working directory, and stores it in `buffer`. If the
|
||||
@@ -892,6 +896,16 @@ API
|
||||
|
||||
.. versionadded:: 1.34.0
|
||||
|
||||
.. code-block:: c
|
||||
#include <uv.h>
|
||||
#include <stdio.h>
|
||||
int main() {
|
||||
printf("Sleeping for 1 second...\n");
|
||||
uv_sleep(1000);
|
||||
printf("Awake!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
String manipulation functions
|
||||
-----------------------------
|
||||
|
||||
@@ -913,7 +927,7 @@ is not complete.
|
||||
`utf16_len` count (in characters) gives the length of `utf16`. If `utf16`
|
||||
is NUL terminated, `utf16_len` can be set to -1, otherwise it must be
|
||||
specified. If `wtf8_ptr` is `NULL`, no result will be computed, but the
|
||||
length (equal to `uv_utf16_length_as_wtf8`) will be stored in `wtf8_ptr`.
|
||||
length (equal to `uv_utf16_length_as_wtf8`) will be stored in `wtf8_len_ptr`.
|
||||
If `*wtf8_ptr` is `NULL`, space for the conversion will be allocated and
|
||||
returned in `wtf8_ptr` and the length will be returned in `wtf8_len_ptr`.
|
||||
Otherwise, the length of `*wtf8_ptr` must be passed in `wtf8_len_ptr`. The
|
||||
|
||||
Vendored
+1
-1
@@ -94,7 +94,7 @@ API
|
||||
Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes,
|
||||
typically between 92 and 108 bytes.
|
||||
|
||||
.. c:function:: void uv_pipe_connect2(uv_connect_t* req, uv_pipe_t* handle, const char* name, size_t namelen, unsigned int flags, uv_connect_cb cb)
|
||||
.. c:function:: int uv_pipe_connect2(uv_connect_t* req, uv_pipe_t* handle, const char* name, size_t namelen, unsigned int flags, uv_connect_cb cb)
|
||||
|
||||
Connect to the Unix domain socket or the Windows named pipe.
|
||||
|
||||
|
||||
Vendored
+28
@@ -91,6 +91,34 @@ API
|
||||
|
||||
.. versionchanged:: 1.49.0 If `delay` is less than 1 then ``UV_EINVAL``` is returned.
|
||||
|
||||
.. c:function:: int uv_tcp_keepalive_ex(uv_tcp_t* handle, int on, unsigned int idle, unsigned int intvl, unsigned int cnt)
|
||||
|
||||
Enable / disable TCP keep-alive with all socket options: `TCP_KEEPIDLE`, `TCP_KEEPINTVL` and `TCP_KEEPCNT`.
|
||||
`idle` is the value for `TCP_KEEPIDLE`, `intvl` is the value for `TCP_KEEPINTVL`,
|
||||
`cnt` is the value for `TCP_KEEPCNT`, ignored when `on` is zero.
|
||||
|
||||
With TCP keep-alive enabled, `idle` is the time (in seconds) the connection needs to remain idle before
|
||||
TCP starts sending keep-alive probes. `intvl` is the time (in seconds) between individual keep-alive probes.
|
||||
TCP will drop the connection after sending `cnt` probes without getting any replies from the peer, then the
|
||||
handle is destroyed with a ``UV_ETIMEDOUT`` error passed to the corresponding callback.
|
||||
|
||||
If one of `idle`, `intvl`, or `cnt` is less than 1, ``UV_EINVAL`` is returned.
|
||||
|
||||
.. versionchanged:: 1.52.0 added support of setting `TCP_KEEPINTVL` and `TCP_KEEPCNT` socket options.
|
||||
|
||||
.. note::
|
||||
Ensure that the socket options are supported by the underlying operating system.
|
||||
Currently supported platforms:
|
||||
- AIX
|
||||
- DragonFlyBSD
|
||||
- FreeBSD
|
||||
- illumos
|
||||
- Linux
|
||||
- macOS
|
||||
- NetBSD
|
||||
- Solaris
|
||||
- Windows
|
||||
|
||||
.. c:function:: int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable)
|
||||
|
||||
Enable / disable simultaneous asynchronous accept requests that are
|
||||
|
||||
Vendored
+20
@@ -173,6 +173,22 @@ API
|
||||
.. versionadded:: 1.7.0
|
||||
.. versionchanged:: 1.37.0 added the `UV_UDP_RECVMMSG` flag.
|
||||
|
||||
.. c:function:: int uv_udp_open_ex(uv_udp_t* handle, uv_os_sock_t sock, unsigned int flags)
|
||||
|
||||
Opens an existing file descriptor or Windows SOCKET as a UDP handle.
|
||||
|
||||
:param handle: UDP handle. Should have been initialized with
|
||||
:c:func:`uv_udp_init`.
|
||||
|
||||
:param sock: An existing socket to associate with the handle.
|
||||
|
||||
:param flags: Flags that control socket behavior,
|
||||
``UV_UDP_REUSEADDR``, and ``UV_UDP_REUSEPORT`` are supported.
|
||||
|
||||
:returns: 0 on success, or an error code < 0 on failure.
|
||||
|
||||
.. versionadded:: 1.52.0
|
||||
|
||||
.. c:function:: int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock)
|
||||
|
||||
Opens an existing file descriptor or Windows SOCKET as a UDP handle.
|
||||
@@ -189,6 +205,10 @@ API
|
||||
The passed file descriptor or SOCKET is not checked for its type, but
|
||||
it's required that it represents a valid datagram socket.
|
||||
|
||||
Internally sets the SO_REUSEADDR socket option unconditionally. This
|
||||
means the reuse flag is always enabled, regardless of user intent. For
|
||||
more control use :c:func:`uv_udp_open_ex`.
|
||||
|
||||
.. c:function:: int uv_udp_bind(uv_udp_t* handle, const struct sockaddr* addr, unsigned int flags)
|
||||
|
||||
Bind the UDP handle to an IP address and port.
|
||||
|
||||
Vendored
+12
-8
@@ -44,10 +44,8 @@ extern "C" {
|
||||
/* Building static library. */
|
||||
# define UV_EXTERN /* nothing */
|
||||
# endif
|
||||
#elif __GNUC__ >= 4
|
||||
#elif defined(__GNUC__)
|
||||
# define UV_EXTERN __attribute__((visibility("default")))
|
||||
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) /* Sun Studio >= 8 */
|
||||
# define UV_EXTERN __global
|
||||
#else
|
||||
# define UV_EXTERN /* nothing */
|
||||
#endif
|
||||
@@ -604,6 +602,11 @@ UV_EXTERN int uv_tcp_nodelay(uv_tcp_t* handle, int enable);
|
||||
UV_EXTERN int uv_tcp_keepalive(uv_tcp_t* handle,
|
||||
int enable,
|
||||
unsigned int delay);
|
||||
UV_EXTERN int uv_tcp_keepalive_ex(uv_tcp_t* handle,
|
||||
int on,
|
||||
unsigned int idle,
|
||||
unsigned int intvl,
|
||||
unsigned int cnt);
|
||||
UV_EXTERN int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable);
|
||||
|
||||
enum uv_tcp_flags {
|
||||
@@ -741,6 +744,9 @@ struct uv_udp_send_s {
|
||||
UV_EXTERN int uv_udp_init(uv_loop_t*, uv_udp_t* handle);
|
||||
UV_EXTERN int uv_udp_init_ex(uv_loop_t*, uv_udp_t* handle, unsigned int flags);
|
||||
UV_EXTERN int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock);
|
||||
UV_EXTERN int uv_udp_open_ex(uv_udp_t* handle,
|
||||
uv_os_sock_t sock,
|
||||
unsigned int flags);
|
||||
UV_EXTERN int uv_udp_bind(uv_udp_t* handle,
|
||||
const struct sockaddr* addr,
|
||||
unsigned int flags);
|
||||
@@ -1203,7 +1209,7 @@ struct uv_cpu_times_s {
|
||||
};
|
||||
|
||||
struct uv_cpu_info_s {
|
||||
char* model;
|
||||
const char* model;
|
||||
int speed;
|
||||
struct uv_cpu_times_s cpu_times;
|
||||
};
|
||||
@@ -1254,7 +1260,8 @@ struct uv_statfs_s {
|
||||
uint64_t f_bavail;
|
||||
uint64_t f_files;
|
||||
uint64_t f_ffree;
|
||||
uint64_t f_spare[4];
|
||||
uint64_t f_frsize;
|
||||
uint64_t f_spare[3];
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
@@ -1964,7 +1971,6 @@ UV_EXTERN void uv_wtf8_to_utf16(const char* wtf8,
|
||||
size_t utf16_len);
|
||||
|
||||
/* Don't export the private CPP symbols. */
|
||||
#undef UV_HANDLE_TYPE_PRIVATE
|
||||
#undef UV_REQ_TYPE_PRIVATE
|
||||
#undef UV_REQ_PRIVATE_FIELDS
|
||||
#undef UV_STREAM_PRIVATE_FIELDS
|
||||
@@ -1976,12 +1982,10 @@ UV_EXTERN void uv_wtf8_to_utf16(const char* wtf8,
|
||||
#undef UV_TIMER_PRIVATE_FIELDS
|
||||
#undef UV_GETADDRINFO_PRIVATE_FIELDS
|
||||
#undef UV_GETNAMEINFO_PRIVATE_FIELDS
|
||||
#undef UV_FS_REQ_PRIVATE_FIELDS
|
||||
#undef UV_WORK_PRIVATE_FIELDS
|
||||
#undef UV_FS_EVENT_PRIVATE_FIELDS
|
||||
#undef UV_SIGNAL_PRIVATE_FIELDS
|
||||
#undef UV_LOOP_PRIVATE_FIELDS
|
||||
#undef UV_LOOP_PRIVATE_PLATFORM_FIELDS
|
||||
#undef UV__ERR
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
Vendored
+1
-4
@@ -85,13 +85,10 @@
|
||||
struct uv__io_s;
|
||||
struct uv_loop_s;
|
||||
|
||||
typedef void (*uv__io_cb)(struct uv_loop_s* loop,
|
||||
struct uv__io_s* w,
|
||||
unsigned int events);
|
||||
typedef struct uv__io_s uv__io_t;
|
||||
|
||||
struct uv__io_s {
|
||||
uv__io_cb cb;
|
||||
uintptr_t bits;
|
||||
struct uv__queue pending_queue;
|
||||
struct uv__queue watcher_queue;
|
||||
unsigned int pevents; /* Pending event mask i.e. mask at next tick. */
|
||||
|
||||
Vendored
+2
-2
@@ -31,8 +31,8 @@
|
||||
*/
|
||||
|
||||
#define UV_VERSION_MAJOR 1
|
||||
#define UV_VERSION_MINOR 51
|
||||
#define UV_VERSION_PATCH 0
|
||||
#define UV_VERSION_MINOR 52
|
||||
#define UV_VERSION_PATCH 1
|
||||
#define UV_VERSION_IS_RELEASE 1
|
||||
#define UV_VERSION_SUFFIX ""
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -279,7 +279,7 @@ typedef struct {
|
||||
DWORD tls_index;
|
||||
} uv_key_t;
|
||||
|
||||
#define UV_ONCE_INIT { 0, NULL }
|
||||
#define UV_ONCE_INIT { 0, { NULL } }
|
||||
|
||||
typedef struct uv_once_s {
|
||||
unsigned char unused;
|
||||
|
||||
Vendored
+21
-21
@@ -50,6 +50,24 @@ AC_DEFUN([CC_CHECK_CFLAGS_SILENT], [
|
||||
[$2], [$3])
|
||||
])
|
||||
|
||||
dnl Check if the flag is supported by compiler with werror
|
||||
dnl CC_CHECK_CFLAGS_SILENT_WERROR([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
|
||||
|
||||
AC_DEFUN([CC_CHECK_CFLAGS_SILENT_WERROR], [
|
||||
AC_REQUIRE([CC_CHECK_WERROR])
|
||||
AC_CACHE_VAL(AS_TR_SH([cc_cv_cflags_werror_$1]),
|
||||
[ac_save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $cc_cv_werror $1"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a;])],
|
||||
[eval "AS_TR_SH([cc_cv_cflags_werror_$1])='yes'"],
|
||||
[eval "AS_TR_SH([cc_cv_cflags_werror_$1])='no'"])
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
])
|
||||
|
||||
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_werror_$1])[ = xyes],
|
||||
[$2], [$3])
|
||||
])
|
||||
|
||||
dnl Check if the flag is supported by compiler (cacheable)
|
||||
dnl CC_CHECK_CFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
|
||||
|
||||
@@ -67,11 +85,11 @@ dnl CC_CHECK_CFLAG_APPEND(FLAG, [action-if-found], [action-if-not-found])
|
||||
dnl Check for CFLAG and appends them to AM_CFLAGS if supported
|
||||
AC_DEFUN([CC_CHECK_CFLAG_APPEND], [
|
||||
AC_CACHE_CHECK([if $CC supports $1 flag],
|
||||
AS_TR_SH([cc_cv_cflags_$1]),
|
||||
CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here!
|
||||
AS_TR_SH([cc_cv_cflags_werror_$1]),
|
||||
CC_CHECK_CFLAGS_SILENT_WERROR([$1]) dnl Don't execute actions here!
|
||||
)
|
||||
|
||||
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
|
||||
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_werror_$1])[ = xyes],
|
||||
[AM_CFLAGS="$AM_CFLAGS $1"; DEBUG_CFLAGS="$DEBUG_CFLAGS $1"; $2], [$3])
|
||||
|
||||
AC_SUBST([AM_CFLAGS])
|
||||
@@ -268,24 +286,6 @@ AC_DEFUN([CC_ATTRIBUTE_CONST], [
|
||||
[$1], [$2])
|
||||
])
|
||||
|
||||
AC_DEFUN([CC_FLAG_VISIBILITY], [
|
||||
AC_REQUIRE([CC_CHECK_WERROR])
|
||||
AC_CACHE_CHECK([if $CC supports -fvisibility=hidden],
|
||||
[cc_cv_flag_visibility],
|
||||
[cc_flag_visibility_save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $cc_cv_werror"
|
||||
CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden],
|
||||
cc_cv_flag_visibility='yes',
|
||||
cc_cv_flag_visibility='no')
|
||||
CFLAGS="$cc_flag_visibility_save_CFLAGS"])
|
||||
|
||||
AS_IF([test "x$cc_cv_flag_visibility" = "xyes"],
|
||||
[AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1,
|
||||
[Define this if the compiler supports the -fvisibility flag])
|
||||
$1],
|
||||
[$2])
|
||||
])
|
||||
|
||||
AC_DEFUN([CC_FUNC_EXPECT], [
|
||||
AC_REQUIRE([CC_CHECK_WERROR])
|
||||
AC_CACHE_CHECK([if compiler has __builtin_expect function],
|
||||
|
||||
Vendored
+1
-1
@@ -394,7 +394,7 @@ void uv_wtf8_to_utf16(const char* source_ptr,
|
||||
/* uv_wtf8_length_as_utf16 should have been called and checked first. */
|
||||
assert(code_point >= 0);
|
||||
if (code_point > 0xFFFF) {
|
||||
assert(code_point < 0x10FFFF);
|
||||
assert(code_point <= 0x10FFFF);
|
||||
*w_target++ = (((code_point - 0x10000) >> 10) + 0xD800);
|
||||
*w_target++ = ((code_point - 0x10000) & 0x3FF) + 0xDC00;
|
||||
w_target_len -= 2;
|
||||
|
||||
Vendored
+6
-6
@@ -151,19 +151,19 @@ int uv_inet_pton(int af, const char* src, void* dst) {
|
||||
case AF_INET:
|
||||
return (inet_pton4(src, dst));
|
||||
case AF_INET6: {
|
||||
int len;
|
||||
char tmp[UV__INET6_ADDRSTRLEN], *s, *p;
|
||||
s = (char*) src;
|
||||
const char *p;
|
||||
p = strchr(src, '%');
|
||||
if (p != NULL) {
|
||||
s = tmp;
|
||||
int len;
|
||||
char s[UV__INET6_ADDRSTRLEN];
|
||||
len = p - src;
|
||||
if (len > UV__INET6_ADDRSTRLEN-1)
|
||||
return UV_EINVAL;
|
||||
memcpy(s, src, len);
|
||||
s[len] = '\0';
|
||||
}
|
||||
return inet_pton6(s, dst);
|
||||
return inet_pton6(s, dst);
|
||||
} else
|
||||
return inet_pton6(src, dst);
|
||||
}
|
||||
default:
|
||||
return UV_EAFNOSUPPORT;
|
||||
|
||||
Vendored
+1
-1
@@ -61,7 +61,7 @@ static int uv__random(void* buf, size_t buflen) {
|
||||
# endif
|
||||
#elif defined(_WIN32)
|
||||
uv__once_init();
|
||||
rc = uv__random_rtlgenrandom(buf, buflen);
|
||||
rc = uv__random_winrandom(buf, buflen);
|
||||
#else
|
||||
rc = uv__random_devurandom(buf, buflen);
|
||||
#endif
|
||||
|
||||
Vendored
+11
-1
@@ -194,11 +194,21 @@ void uv__threadpool_cleanup(void) {
|
||||
static void init_threads(void) {
|
||||
uv_thread_options_t config;
|
||||
unsigned int i;
|
||||
size_t buflen;
|
||||
char buf[16];
|
||||
const char* val;
|
||||
int err;
|
||||
|
||||
uv_sem_t sem;
|
||||
|
||||
nthreads = ARRAY_SIZE(default_threads);
|
||||
val = getenv("UV_THREADPOOL_SIZE");
|
||||
|
||||
buflen = ARRAY_SIZE(buf);
|
||||
err = uv_os_getenv("UV_THREADPOOL_SIZE", buf, &buflen);
|
||||
val = NULL;
|
||||
if (err == 0)
|
||||
val = buf;
|
||||
|
||||
if (val != NULL)
|
||||
nthreads = atoi(val);
|
||||
if (nthreads == 0)
|
||||
|
||||
Vendored
-1
@@ -22,7 +22,6 @@
|
||||
#include "uv-common.h"
|
||||
#include "heap-inl.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
|
||||
Vendored
+13
-31
@@ -229,28 +229,12 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
/* 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;
|
||||
|
||||
uv__io_poll_prepare(loop, NULL, timeout);
|
||||
nfds = pollset_poll(loop->backend_fd,
|
||||
events,
|
||||
ARRAY_SIZE(events),
|
||||
timeout);
|
||||
|
||||
/* Update loop->time unconditionally. It's tempting to skip the update when
|
||||
* timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
|
||||
* operating system didn't reschedule our process while in the syscall.
|
||||
*/
|
||||
SAVE_ERRNO(uv__update_time(loop));
|
||||
uv__io_poll_check(loop, NULL);
|
||||
|
||||
if (nfds == 0) {
|
||||
if (reset_timeout != 0) {
|
||||
@@ -324,7 +308,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
have_signals = 1;
|
||||
} else {
|
||||
uv__metrics_update_idle_time(loop);
|
||||
w->cb(loop, w, pe->revents);
|
||||
uv__io_cb(loop, w, pe->revents);
|
||||
}
|
||||
|
||||
nevents++;
|
||||
@@ -339,7 +323,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
|
||||
if (have_signals != 0) {
|
||||
uv__metrics_update_idle_time(loop);
|
||||
loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
|
||||
uv__signal_event(loop, &loop->signal_io_watcher, POLLIN);
|
||||
}
|
||||
|
||||
loop->watchers[loop->nwatchers] = NULL;
|
||||
@@ -396,7 +380,7 @@ uint64_t uv_get_total_memory(void) {
|
||||
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0; /* Memory constraints are unknown. */
|
||||
return uv__get_rlimit_max_memory();
|
||||
}
|
||||
|
||||
|
||||
@@ -632,7 +616,7 @@ static int uv__skip_lines(char **p, int n) {
|
||||
|
||||
while(n > 0) {
|
||||
*p = strchr(*p, '\n');
|
||||
if (!p)
|
||||
if (!*p)
|
||||
return lines;
|
||||
|
||||
(*p)++;
|
||||
@@ -716,7 +700,7 @@ static int uv__parse_data(char *buf, int *events, uv_fs_event_t* handle) {
|
||||
|
||||
|
||||
/* This is the internal callback */
|
||||
static void uv__ahafs_event(uv_loop_t* loop, uv__io_t* event_watch, unsigned int fflags) {
|
||||
void uv__ahafs_event(uv_loop_t* loop, uv__io_t* event_watch, unsigned int fflags) {
|
||||
char result_data[RDWR_BUF_SIZE];
|
||||
int bytes, rc = 0;
|
||||
uv_fs_event_t* handle;
|
||||
@@ -767,7 +751,11 @@ static void uv__ahafs_event(uv_loop_t* loop, uv__io_t* event_watch, unsigned int
|
||||
|
||||
handle->cb(handle, fname, events, 0);
|
||||
}
|
||||
#endif
|
||||
#else /* !HAVE_SYS_AHAFS_EVPRODS_H */
|
||||
void uv__ahafs_event(uv_loop_t* loop, uv__io_t* event_watch, unsigned int fflags) {
|
||||
/* Stub function to satisfy the linker. */
|
||||
}
|
||||
#endif /* HAVE_SYS_AHAFS_EVPRODS_H */
|
||||
|
||||
|
||||
int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
|
||||
@@ -828,7 +816,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
|
||||
|
||||
/* Setup/Initialize all the libuv routines */
|
||||
uv__handle_start(handle);
|
||||
uv__io_init(&handle->event_watcher, uv__ahafs_event, fd);
|
||||
uv__io_init(&handle->event_watcher, UV__AHAFS_EVENT, fd);
|
||||
handle->path = uv__strdup(filename);
|
||||
handle->cb = cb;
|
||||
handle->dir_filename = NULL;
|
||||
@@ -1288,12 +1276,6 @@ cleanup:
|
||||
}
|
||||
|
||||
|
||||
void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
||||
int count) {
|
||||
uv__free(addresses);
|
||||
}
|
||||
|
||||
|
||||
void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
|
||||
struct pollfd* events;
|
||||
uintptr_t i;
|
||||
|
||||
Vendored
+5
-3
@@ -157,7 +157,7 @@ void uv__async_close(uv_async_t* handle) {
|
||||
}
|
||||
|
||||
|
||||
static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
char buf[1024];
|
||||
ssize_t r;
|
||||
struct uv__queue queue;
|
||||
@@ -308,7 +308,7 @@ static int uv__async_start(uv_loop_t* loop) {
|
||||
return err;
|
||||
#endif
|
||||
|
||||
err = uv__io_init_start(loop, &loop->async_io_watcher, uv__async_io,
|
||||
err = uv__io_init_start(loop, &loop->async_io_watcher, UV__ASYNC_IO,
|
||||
pipefd[0], POLLIN);
|
||||
if (err < 0) {
|
||||
uv__close(pipefd[0]);
|
||||
@@ -409,10 +409,12 @@ static void uv__cpu_relax(void) {
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
__asm__ __volatile__ ("rep; nop" ::: "memory"); /* a.k.a. PAUSE */
|
||||
#elif (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__)
|
||||
__asm__ __volatile__ ("yield" ::: "memory");
|
||||
__asm__ __volatile__ ("isb" ::: "memory");
|
||||
#elif (defined(__ppc__) || defined(__ppc64__)) && defined(__APPLE__)
|
||||
__asm volatile ("" : : : "memory");
|
||||
#elif !defined(__APPLE__) && (defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__))
|
||||
__asm__ __volatile__ ("or 1,1,1; or 2,2,2" ::: "memory");
|
||||
#elif defined(__riscv) && __riscv_xlen == 64
|
||||
__asm__ volatile(".insn 0x0100000f" ::: "memory"); /* FENCE */
|
||||
#endif
|
||||
}
|
||||
Vendored
-7
@@ -155,10 +155,3 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* TODO(bnoordhuis) share with linux.c */
|
||||
void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
||||
int count) {
|
||||
uv__free(addresses);
|
||||
}
|
||||
Vendored
+2
-1
@@ -29,7 +29,7 @@
|
||||
static uv_mutex_t process_title_mutex;
|
||||
static uv_once_t process_title_mutex_once = UV_ONCE_INIT;
|
||||
static char* process_title;
|
||||
|
||||
char* uv_saved_argv0;
|
||||
|
||||
static void init_process_title_mutex_once(void) {
|
||||
if (uv_mutex_init(&process_title_mutex))
|
||||
@@ -45,6 +45,7 @@ void uv__process_title_cleanup(void) {
|
||||
|
||||
char** uv_setup_args(int argc, char** argv) {
|
||||
process_title = argc > 0 ? uv__strdup(argv[0]) : NULL;
|
||||
uv_saved_argv0 = argc > 0 ? uv__strdup(argv[0]) : NULL;
|
||||
return argv;
|
||||
}
|
||||
|
||||
|
||||
Vendored
+117
-13
@@ -275,7 +275,7 @@ void uv__make_close_pending(uv_handle_t* handle) {
|
||||
int uv__getiovmax(void) {
|
||||
#if defined(IOV_MAX)
|
||||
return IOV_MAX;
|
||||
#elif defined(_SC_IOV_MAX)
|
||||
#elif defined(_SC_IOV_MAX) && !defined(__QNX__)
|
||||
static _Atomic int iovmax_cached = -1;
|
||||
int iovmax;
|
||||
|
||||
@@ -851,7 +851,7 @@ static void uv__run_pending(uv_loop_t* loop) {
|
||||
uv__queue_remove(q);
|
||||
uv__queue_init(q);
|
||||
w = uv__queue_data(q, uv__io_t, pending_queue);
|
||||
w->cb(loop, w, POLLOUT);
|
||||
uv__io_cb(loop, w, POLLOUT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -903,20 +903,58 @@ static int maybe_resize(uv_loop_t* loop, unsigned int len) {
|
||||
}
|
||||
|
||||
|
||||
void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd) {
|
||||
void uv__io_cb(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
switch (uv__io_cb_get(w)) {
|
||||
case UV__AHAFS_EVENT:
|
||||
uv__ahafs_event(loop, w, events);
|
||||
break;
|
||||
case UV__ASYNC_IO:
|
||||
uv__async_io(loop, w, events);
|
||||
break;
|
||||
case UV__FS_EVENT:
|
||||
uv__fs_event(loop, w, events);
|
||||
break;
|
||||
case UV__FS_EVENT_READ:
|
||||
uv__fs_event_read(loop, w, events);
|
||||
break;
|
||||
case UV__INOTIFY_READ:
|
||||
uv__inotify_read(loop, w, events);
|
||||
break;
|
||||
case UV__POLL_IO:
|
||||
uv__poll_io(loop, w, events);
|
||||
break;
|
||||
case UV__SERVER_IO:
|
||||
uv__server_io(loop, w, events);
|
||||
break;
|
||||
case UV__STREAM_IO:
|
||||
uv__stream_io(loop, w, events);
|
||||
break;
|
||||
case UV__UDP_IO:
|
||||
uv__udp_io(loop, w, events);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uv__io_init(uv__io_t* w, uv__io_cb_t cb, int fd) {
|
||||
assert(fd >= -1);
|
||||
uv__queue_init(&w->pending_queue);
|
||||
uv__queue_init(&w->watcher_queue);
|
||||
w->cb = cb;
|
||||
w->fd = fd;
|
||||
w->bits = 0;
|
||||
w->events = 0;
|
||||
w->pevents = 0;
|
||||
uv__io_cb_set(w, cb);
|
||||
}
|
||||
|
||||
|
||||
int uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
int err;
|
||||
|
||||
assert(uv__io_cb_get(w) >= UV__AHAFS_EVENT);
|
||||
assert(uv__io_cb_get(w) <= UV__UDP_IO);
|
||||
assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI)));
|
||||
assert(0 != events);
|
||||
assert(w->fd >= 0);
|
||||
@@ -950,17 +988,16 @@ int uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
|
||||
int uv__io_init_start(uv_loop_t* loop,
|
||||
uv__io_t* w,
|
||||
uv__io_cb cb,
|
||||
uv__io_cb_t cb,
|
||||
int fd,
|
||||
unsigned int events) {
|
||||
int err;
|
||||
|
||||
assert(cb != NULL);
|
||||
assert(fd > -1);
|
||||
uv__io_init(w, cb, fd);
|
||||
err = uv__io_start(loop, w, events);
|
||||
if (err)
|
||||
uv__io_init(w, NULL, -1);
|
||||
uv__io_init(w, UV__NO_IO_CB, -1);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -1019,6 +1056,39 @@ int uv__io_active(const uv__io_t* w, unsigned int events) {
|
||||
}
|
||||
|
||||
|
||||
void uv__io_poll_prepare(uv_loop_t* loop, sigset_t* pset, int timeout) {
|
||||
uv__loop_internal_fields_t* lfields;
|
||||
|
||||
/* 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 = uv__get_internal_fields(loop);
|
||||
lfields->current_timeout = timeout;
|
||||
|
||||
if (pset != NULL)
|
||||
if (pthread_sigmask(SIG_BLOCK, pset, NULL))
|
||||
abort();
|
||||
}
|
||||
|
||||
void uv__io_poll_check(uv_loop_t* loop, sigset_t* pset) {
|
||||
if (pset != NULL)
|
||||
if (pthread_sigmask(SIG_UNBLOCK, pset, NULL))
|
||||
abort();
|
||||
|
||||
/* Update loop->time unconditionally. It's tempting to skip the update when
|
||||
* timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
|
||||
* operating system didn't reschedule our process while in the syscall.
|
||||
*/
|
||||
SAVE_ERRNO(uv__update_time(loop));
|
||||
}
|
||||
|
||||
int uv__fd_exists(uv_loop_t* loop, int fd) {
|
||||
return (unsigned) fd < loop->nwatchers && loop->watchers[fd] != NULL;
|
||||
}
|
||||
@@ -1496,7 +1566,7 @@ int uv_os_environ(uv_env_item_t** envitems, int* count) {
|
||||
|
||||
fail:
|
||||
for (i = 0; i < cnt; i++) {
|
||||
envitem = &(*envitems)[cnt];
|
||||
envitem = &(*envitems)[i];
|
||||
uv__free(envitem->name);
|
||||
}
|
||||
uv__free(*envitems);
|
||||
@@ -1611,6 +1681,10 @@ int uv_cpumask_size(void) {
|
||||
}
|
||||
|
||||
int uv_os_getpriority(uv_pid_t pid, int* priority) {
|
||||
#if defined(__QNX__)
|
||||
/* QNX priority is not process-based */
|
||||
return UV_ENOSYS;
|
||||
#else
|
||||
int r;
|
||||
|
||||
if (priority == NULL)
|
||||
@@ -1624,10 +1698,15 @@ int uv_os_getpriority(uv_pid_t pid, int* priority) {
|
||||
|
||||
*priority = r;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int uv_os_setpriority(uv_pid_t pid, int priority) {
|
||||
#if defined(__QNX__)
|
||||
/* QNX priority is not process-based */
|
||||
return UV_ENOSYS;
|
||||
#else
|
||||
if (priority < UV_PRIORITY_HIGHEST || priority > UV_PRIORITY_LOW)
|
||||
return UV_EINVAL;
|
||||
|
||||
@@ -1635,6 +1714,7 @@ int uv_os_setpriority(uv_pid_t pid, int priority) {
|
||||
return UV__ERR(errno);
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1656,7 +1736,7 @@ int uv_thread_getpriority(uv_thread_t tid, int* priority) {
|
||||
|
||||
r = pthread_getschedparam(tid, &policy, ¶m);
|
||||
if (r != 0)
|
||||
return UV__ERR(errno);
|
||||
return UV__ERR(r);
|
||||
|
||||
#ifdef __linux__
|
||||
if (SCHED_OTHER == policy && pthread_equal(tid, pthread_self())) {
|
||||
@@ -1709,7 +1789,7 @@ int uv_thread_setpriority(uv_thread_t tid, int priority) {
|
||||
|
||||
r = pthread_getschedparam(tid, &policy, ¶m);
|
||||
if (r != 0)
|
||||
return UV__ERR(errno);
|
||||
return UV__ERR(r);
|
||||
|
||||
#ifdef __linux__
|
||||
/**
|
||||
@@ -1757,7 +1837,7 @@ int uv_thread_setpriority(uv_thread_t tid, int priority) {
|
||||
param.sched_priority = prio;
|
||||
r = pthread_setschedparam(tid, policy, ¶m);
|
||||
if (r != 0)
|
||||
return UV__ERR(errno);
|
||||
return UV__ERR(r);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1998,8 +2078,8 @@ unsigned int uv_available_parallelism(void) {
|
||||
#elif defined(__NetBSD__)
|
||||
cpuset_t* set = cpuset_create();
|
||||
if (set != NULL) {
|
||||
if (0 == sched_getaffinity_np(getpid(), sizeof(set), &set))
|
||||
rc = uv__cpu_count(&set);
|
||||
if (0 == sched_getaffinity_np(getpid(), cpuset_size(set), set))
|
||||
rc = uv__cpu_count(set);
|
||||
cpuset_destroy(set);
|
||||
}
|
||||
#elif defined(__APPLE__)
|
||||
@@ -2102,3 +2182,27 @@ int uv__sock_reuseport(int fd) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check if rlimit has any expressed restrictions on usable memory. */
|
||||
uint64_t uv__get_rlimit_max_memory(void) {
|
||||
struct rlimit rl;
|
||||
uint64_t result = 0;
|
||||
uint64_t rlimit_value;
|
||||
|
||||
#if defined(RLIMIT_AS)
|
||||
if (getrlimit(RLIMIT_AS, &rl) == 0 && rl.rlim_cur != RLIM_INFINITY) {
|
||||
rlimit_value = rl.rlim_cur;
|
||||
result = rlimit_value;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(RLIMIT_DATA)
|
||||
if (getrlimit(RLIMIT_DATA, &rl) == 0 && rl.rlim_cur != RLIM_INFINITY) {
|
||||
rlimit_value = rl.rlim_cur;
|
||||
if (result == 0 || rlimit_value < result)
|
||||
result = rlimit_value;
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
Vendored
+1
-1
@@ -85,7 +85,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
|
||||
}
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0; /* Memory constraints are unknown. */
|
||||
return uv__get_rlimit_max_memory();
|
||||
}
|
||||
|
||||
uint64_t uv_get_available_memory(void) {
|
||||
|
||||
Vendored
+10
-2
@@ -121,12 +121,20 @@ uint64_t uv_get_total_memory(void) {
|
||||
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0; /* Memory constraints are unknown. */
|
||||
return uv__get_rlimit_max_memory();
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv_get_available_memory(void) {
|
||||
return uv_get_free_memory();
|
||||
vm_statistics_data_t info;
|
||||
mach_msg_type_number_t count = sizeof(info) / sizeof(integer_t);
|
||||
|
||||
if (host_statistics(mach_host_self(), HOST_VM_INFO,
|
||||
(host_info_t)&info, &count) != KERN_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ((uint64_t) info.free_count + (uint64_t) info.inactive_count + (uint64_t) info.purgeable_count) * sysconf(_SC_PAGESIZE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -117,7 +117,7 @@ uint64_t uv_get_total_memory(void) {
|
||||
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0; /* Memory constraints are unknown. */
|
||||
return uv__get_rlimit_max_memory();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vendored
+13
-11
@@ -211,7 +211,8 @@ static ssize_t uv__fs_fdatasync(uv_fs_t* req) {
|
||||
|| defined(__NetBSD__) \
|
||||
|| defined(__OpenBSD__) \
|
||||
|| defined(__linux__) \
|
||||
|| defined(__sun)
|
||||
|| defined(__sun) \
|
||||
|| defined(__QNX__)
|
||||
static struct timespec uv__fs_to_timespec(double time) {
|
||||
struct timespec ts;
|
||||
|
||||
@@ -223,13 +224,6 @@ static struct timespec uv__fs_to_timespec(double time) {
|
||||
ts.tv_sec = time;
|
||||
ts.tv_nsec = (time - ts.tv_sec) * 1e9;
|
||||
|
||||
/* TODO(bnoordhuis) Remove this. utimesat() has nanosecond resolution but we
|
||||
* stick to microsecond resolution for the sake of consistency with other
|
||||
* platforms. I'm the original author of this compatibility hack but I'm
|
||||
* less convinced it's useful nowadays.
|
||||
*/
|
||||
ts.tv_nsec -= ts.tv_nsec % 1000;
|
||||
|
||||
if (ts.tv_nsec < 0) {
|
||||
ts.tv_nsec += 1e9;
|
||||
ts.tv_sec -= 1;
|
||||
@@ -248,7 +242,8 @@ static ssize_t uv__fs_futime(uv_fs_t* req) {
|
||||
|| defined(__NetBSD__) \
|
||||
|| defined(__OpenBSD__) \
|
||||
|| defined(__linux__) \
|
||||
|| defined(__sun)
|
||||
|| defined(__sun) \
|
||||
|| defined(__QNX__)
|
||||
struct timespec ts[2];
|
||||
ts[0] = uv__fs_to_timespec(req->atime);
|
||||
ts[1] = uv__fs_to_timespec(req->mtime);
|
||||
@@ -716,6 +711,11 @@ static int uv__fs_statfs(uv_fs_t* req) {
|
||||
stat_fs->f_bavail = buf.f_bavail;
|
||||
stat_fs->f_files = buf.f_files;
|
||||
stat_fs->f_ffree = buf.f_ffree;
|
||||
#if defined(__linux__)
|
||||
stat_fs->f_frsize = buf.f_frsize;
|
||||
#else
|
||||
stat_fs->f_frsize = buf.f_bsize;
|
||||
#endif
|
||||
req->ptr = stat_fs;
|
||||
return 0;
|
||||
}
|
||||
@@ -1147,7 +1147,8 @@ static ssize_t uv__fs_utime(uv_fs_t* req) {
|
||||
|| defined(__NetBSD__) \
|
||||
|| defined(__OpenBSD__) \
|
||||
|| defined(__linux__) \
|
||||
|| defined(__sun)
|
||||
|| defined(__sun) \
|
||||
|| defined(__QNX__)
|
||||
struct timespec ts[2];
|
||||
ts[0] = uv__fs_to_timespec(req->atime);
|
||||
ts[1] = uv__fs_to_timespec(req->mtime);
|
||||
@@ -1181,7 +1182,8 @@ static ssize_t uv__fs_lutime(uv_fs_t* req) {
|
||||
|| defined(__NetBSD__) \
|
||||
|| defined(__OpenBSD__) \
|
||||
|| defined(__linux__) \
|
||||
|| defined(__sun)
|
||||
|| defined(__sun) \
|
||||
|| defined(__QNX__)
|
||||
struct timespec ts[2];
|
||||
ts[0] = uv__fs_to_timespec(req->atime);
|
||||
ts[1] = uv__fs_to_timespec(req->mtime);
|
||||
|
||||
Vendored
+9
-4
@@ -89,9 +89,7 @@ int uv__getaddrinfo_translate_error(int sys_err) {
|
||||
}
|
||||
assert(!"unknown EAI_* error code");
|
||||
abort();
|
||||
#ifndef __SUNPRO_C
|
||||
return 0; /* Pacify compiler. */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -109,7 +107,9 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) {
|
||||
uv_getaddrinfo_t* req;
|
||||
|
||||
req = container_of(w, uv_getaddrinfo_t, work_req);
|
||||
uv__req_unregister(req->loop);
|
||||
|
||||
if (req->loop != NULL)
|
||||
uv__req_unregister(req->loop);
|
||||
|
||||
/* See initialization in uv_getaddrinfo(). */
|
||||
if (req->hints)
|
||||
@@ -151,6 +151,8 @@ int uv_getaddrinfo(uv_loop_t* loop,
|
||||
|
||||
if (req == NULL || (hostname == NULL && service == NULL))
|
||||
return UV_EINVAL;
|
||||
if (loop == NULL && cb != NULL)
|
||||
return UV_EINVAL;
|
||||
|
||||
/* FIXME(bnoordhuis) IDNA does not seem to work z/OS,
|
||||
* probably because it uses EBCDIC rather than ASCII.
|
||||
@@ -177,7 +179,10 @@ int uv_getaddrinfo(uv_loop_t* loop,
|
||||
if (buf == NULL)
|
||||
return UV_ENOMEM;
|
||||
|
||||
uv__req_init(loop, req, UV_GETADDRINFO);
|
||||
UV_REQ_INIT(req, UV_GETADDRINFO);
|
||||
if (loop != NULL)
|
||||
uv__req_register(loop);
|
||||
|
||||
req->loop = loop;
|
||||
req->cb = cb;
|
||||
req->addrinfo = NULL;
|
||||
|
||||
Vendored
+1
-1
@@ -80,7 +80,7 @@ uint64_t uv_get_total_memory(void) {
|
||||
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0; /* Memory constraints are unknown. */
|
||||
return uv__get_rlimit_max_memory();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -163,7 +163,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
|
||||
}
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0; /* Memory constraints are unknown. */
|
||||
return uv__get_rlimit_max_memory();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vendored
+7
-6
@@ -245,7 +245,7 @@ uint64_t uv_get_total_memory(void) {
|
||||
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0; /* Memory constraints are unknown. */
|
||||
return uv__get_rlimit_max_memory();
|
||||
}
|
||||
|
||||
|
||||
@@ -505,11 +505,6 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
||||
}
|
||||
|
||||
|
||||
void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
||||
int count) {
|
||||
uv__free(addresses);
|
||||
}
|
||||
|
||||
char** uv_setup_args(int argc, char** argv) {
|
||||
char exepath[UV__PATH_MAX];
|
||||
char* s;
|
||||
@@ -543,3 +538,9 @@ int uv_get_process_title(char* buffer, size_t size) {
|
||||
|
||||
void uv__process_title_cleanup(void) {
|
||||
}
|
||||
|
||||
void uv__ahafs_event(uv_loop_t* loop,
|
||||
uv__io_t* event_watch,
|
||||
unsigned int fflags) {
|
||||
/* Stub function to satisfy the linker. */
|
||||
}
|
||||
Vendored
+73
-6
@@ -141,6 +141,11 @@ union uv__sockaddr {
|
||||
/* Leans on the fact that, on Linux, POLLRDHUP == EPOLLRDHUP. */
|
||||
#ifdef POLLRDHUP
|
||||
# define UV__POLLRDHUP POLLRDHUP
|
||||
#elif defined(__QNX__)
|
||||
/* On QNX, POLLRDHUP is not available and the 0x2000 workaround
|
||||
* leads to undefined bahavior.
|
||||
*/
|
||||
# define UV__POLLRDHUP 0
|
||||
#else
|
||||
# define UV__POLLRDHUP 0x2000
|
||||
#endif
|
||||
@@ -256,11 +261,64 @@ ssize_t uv__recvmsg(int fd, struct msghdr *msg, int flags);
|
||||
void uv__make_close_pending(uv_handle_t* handle);
|
||||
int uv__getiovmax(void);
|
||||
|
||||
void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd);
|
||||
typedef enum {
|
||||
UV__NO_IO_CB,
|
||||
UV__AHAFS_EVENT,
|
||||
UV__ASYNC_IO,
|
||||
UV__FS_EVENT,
|
||||
UV__FS_EVENT_READ,
|
||||
UV__INOTIFY_READ,
|
||||
UV__POLL_IO,
|
||||
UV__SIGNAL_EVENT,
|
||||
UV__SERVER_IO,
|
||||
UV__STREAM_IO,
|
||||
UV__UDP_IO,
|
||||
} uv__io_cb_t;
|
||||
|
||||
#define uv__io_cb_get(w) ((uv__io_cb_t)((w)->bits & 15))
|
||||
#define uv__io_cb_set(w, cb) \
|
||||
do { \
|
||||
(w)->bits -= uv__io_cb_get(w); \
|
||||
(w)->bits |= (cb) & 15; \
|
||||
} while (0)
|
||||
|
||||
void uv__ahafs_event(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
||||
void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
||||
void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
||||
void uv__fs_event_read(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
||||
void uv__inotify_read(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
||||
void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
||||
void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
||||
void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
||||
void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
||||
void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
||||
|
||||
#ifndef _AIX
|
||||
#define uv__ahafs_event(loop, w, events) UNREACHABLE()
|
||||
#endif
|
||||
|
||||
#if !defined(__APPLE__) && \
|
||||
!defined(__DragonFly__) && \
|
||||
!defined(__FreeBSD__) && \
|
||||
!defined(__NetBSD__) && \
|
||||
!defined(__OpenBSD__)
|
||||
#define uv__fs_event(loop, w, events) UNREACHABLE()
|
||||
#endif
|
||||
|
||||
#ifndef __linux__
|
||||
#define uv__inotify_read(loop, w, events) UNREACHABLE()
|
||||
#endif
|
||||
|
||||
#ifndef __sun__
|
||||
#define uv__fs_event_read(loop, w, events) UNREACHABLE()
|
||||
#endif
|
||||
|
||||
void uv__io_cb(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
||||
void uv__io_init(uv__io_t* w, uv__io_cb_t cb, int fd);
|
||||
int uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
||||
int uv__io_init_start(uv_loop_t* loop,
|
||||
uv__io_t* w,
|
||||
uv__io_cb cb,
|
||||
uv__io_cb_t cb,
|
||||
int fd,
|
||||
unsigned int events);
|
||||
void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
||||
@@ -270,6 +328,8 @@ int uv__io_active(const uv__io_t* w, unsigned int events);
|
||||
int uv__io_check_fd(uv_loop_t* loop, int fd);
|
||||
void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */
|
||||
int uv__io_fork(uv_loop_t* loop);
|
||||
void uv__io_poll_prepare(uv_loop_t* loop, sigset_t* pset, int timeout);
|
||||
void uv__io_poll_check(uv_loop_t* loop, sigset_t* pset);
|
||||
int uv__fd_exists(uv_loop_t* loop, int fd);
|
||||
|
||||
/* async */
|
||||
@@ -299,7 +359,11 @@ int uv__slurp(const char* filename, char* buf, size_t len);
|
||||
/* tcp */
|
||||
int uv__tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb);
|
||||
int uv__tcp_nodelay(int fd, int on);
|
||||
int uv__tcp_keepalive(int fd, int on, unsigned int delay);
|
||||
int uv__tcp_keepalive(int fd,
|
||||
int on,
|
||||
unsigned int idle,
|
||||
unsigned int intvl,
|
||||
unsigned int cnt);
|
||||
|
||||
/* tty */
|
||||
void uv__tty_close(uv_tty_t* handle);
|
||||
@@ -315,6 +379,7 @@ int uv__signal_loop_fork(uv_loop_t* loop);
|
||||
|
||||
/* platform specific */
|
||||
uint64_t uv__hrtime(uv_clocktype_t type);
|
||||
uint64_t uv__get_rlimit_max_memory(void);
|
||||
int uv__kqueue_init(uv_loop_t* loop);
|
||||
int uv__platform_loop_init(uv_loop_t* loop);
|
||||
void uv__platform_loop_delete(uv_loop_t* loop);
|
||||
@@ -405,12 +470,12 @@ UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) {
|
||||
loop->time = uv__hrtime(UV_CLOCK_FAST) / 1000000;
|
||||
}
|
||||
|
||||
UV_UNUSED(static char* uv__basename_r(const char* path)) {
|
||||
char* s;
|
||||
UV_UNUSED(static const char* uv__basename_r(const char* path)) {
|
||||
const char* s;
|
||||
|
||||
s = strrchr(path, '/');
|
||||
if (s == NULL)
|
||||
return (char*) path;
|
||||
return path;
|
||||
|
||||
return s + 1;
|
||||
}
|
||||
@@ -527,4 +592,6 @@ int uv__get_constrained_cpu(long long* quota);
|
||||
#define UV__KQUEUE_EVFILT_USER 0
|
||||
#endif
|
||||
|
||||
extern char* uv_saved_argv0;
|
||||
|
||||
#endif /* UV_UNIX_INTERNAL_H_ */
|
||||
Vendored
+9
-33
@@ -48,8 +48,6 @@
|
||||
#define EV_OOBAND EV_FLAG1
|
||||
#endif
|
||||
|
||||
static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags);
|
||||
|
||||
|
||||
int uv__kqueue_init(uv_loop_t* loop) {
|
||||
loop->backend_fd = kqueue();
|
||||
@@ -204,7 +202,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
fflags = 0;
|
||||
op = EV_ADD;
|
||||
|
||||
if (w->cb == uv__fs_event) {
|
||||
if (UV__FS_EVENT == uv__io_cb_get(w)) {
|
||||
filter = EVFILT_VNODE;
|
||||
fflags = NOTE_ATTRIB | NOTE_WRITE | NOTE_RENAME
|
||||
| NOTE_DELETE | NOTE_EXTEND | NOTE_REVOKE;
|
||||
@@ -263,32 +261,19 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
}
|
||||
|
||||
for (;; nevents = 0) {
|
||||
/* 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);
|
||||
|
||||
if (timeout != -1) {
|
||||
spec.tv_sec = timeout / 1000;
|
||||
spec.tv_nsec = (timeout % 1000) * 1000000;
|
||||
}
|
||||
|
||||
if (pset != NULL)
|
||||
pthread_sigmask(SIG_BLOCK, pset, NULL);
|
||||
|
||||
/* 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;
|
||||
|
||||
uv__io_poll_prepare(loop, pset, timeout);
|
||||
nfds = kevent(loop->backend_fd,
|
||||
events,
|
||||
nevents,
|
||||
events,
|
||||
ARRAY_SIZE(events),
|
||||
timeout == -1 ? NULL : &spec);
|
||||
uv__io_poll_check(loop, pset);
|
||||
|
||||
if (nfds == -1)
|
||||
assert(errno == EINTR);
|
||||
@@ -296,15 +281,6 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
/* Unlimited timeout should only return with events or signal. */
|
||||
assert(timeout != -1);
|
||||
|
||||
if (pset != NULL)
|
||||
pthread_sigmask(SIG_UNBLOCK, pset, NULL);
|
||||
|
||||
/* Update loop->time unconditionally. It's tempting to skip the update when
|
||||
* timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
|
||||
* operating system didn't reschedule our process while in the syscall.
|
||||
*/
|
||||
uv__update_time(loop);
|
||||
|
||||
if (nfds == 0 || nfds == -1) {
|
||||
/* If kqueue is empty or interrupted, we might still have children ready
|
||||
* to reap immediately. */
|
||||
@@ -366,7 +342,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
w = &loop->async_io_watcher;
|
||||
assert(fd == w->fd);
|
||||
uv__metrics_update_idle_time(loop);
|
||||
w->cb(loop, w, w->events);
|
||||
uv__io_cb(loop, w, w->events);
|
||||
nevents++;
|
||||
continue;
|
||||
}
|
||||
@@ -376,7 +352,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
assert(w->events == POLLIN);
|
||||
assert(w->pevents == POLLIN);
|
||||
uv__metrics_update_idle_time(loop);
|
||||
w->cb(loop, w, ev->fflags); /* XXX always uv__fs_event() */
|
||||
uv__io_cb(loop, w, ev->fflags); /* XXX always uv__fs_event() */
|
||||
nevents++;
|
||||
continue;
|
||||
}
|
||||
@@ -420,7 +396,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
have_signals = 1;
|
||||
} else {
|
||||
uv__metrics_update_idle_time(loop);
|
||||
w->cb(loop, w, revents);
|
||||
uv__io_cb(loop, w, revents);
|
||||
}
|
||||
|
||||
nevents++;
|
||||
@@ -440,7 +416,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
|
||||
if (have_signals != 0) {
|
||||
uv__metrics_update_idle_time(loop);
|
||||
loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
|
||||
uv__signal_event(loop, &loop->signal_io_watcher, POLLIN);
|
||||
}
|
||||
|
||||
loop->watchers[loop->nwatchers] = NULL;
|
||||
@@ -496,7 +472,7 @@ void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
|
||||
}
|
||||
|
||||
|
||||
static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags) {
|
||||
void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags) {
|
||||
uv_fs_event_t* handle;
|
||||
struct kevent ev;
|
||||
int events;
|
||||
@@ -622,7 +598,7 @@ fallback:
|
||||
|
||||
r = uv__io_init_start(handle->loop,
|
||||
&handle->event_watcher,
|
||||
uv__fs_event,
|
||||
UV__FS_EVENT,
|
||||
fd,
|
||||
POLLIN);
|
||||
|
||||
|
||||
Vendored
+27
-44
@@ -267,9 +267,6 @@ struct watcher_root {
|
||||
};
|
||||
|
||||
static int uv__inotify_fork(uv_loop_t* loop, struct watcher_list* root);
|
||||
static void uv__inotify_read(uv_loop_t* loop,
|
||||
uv__io_t* w,
|
||||
unsigned int revents);
|
||||
static int compare_watchers(const struct watcher_list* a,
|
||||
const struct watcher_list* b);
|
||||
static void maybe_free_watcher_list(struct watcher_list* w,
|
||||
@@ -878,7 +875,7 @@ int uv__iou_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req) {
|
||||
return 0;
|
||||
|
||||
sqe->fd = req->file;
|
||||
sqe->len = req->off;
|
||||
sqe->off = req->off;
|
||||
sqe->opcode = UV__IORING_OP_FTRUNCATE;
|
||||
uv__iou_submit(iou);
|
||||
|
||||
@@ -1450,25 +1447,9 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
while (*ctl->sqhead != *ctl->sqtail)
|
||||
uv__epoll_ctl_flush(epollfd, ctl, &prep);
|
||||
|
||||
/* 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;
|
||||
|
||||
uv__io_poll_prepare(loop, NULL, timeout);
|
||||
nfds = epoll_pwait(epollfd, events, ARRAY_SIZE(events), timeout, sigmask);
|
||||
|
||||
/* Update loop->time unconditionally. It's tempting to skip the update when
|
||||
* timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
|
||||
* operating system didn't reschedule our process while in the syscall.
|
||||
*/
|
||||
SAVE_ERRNO(uv__update_time(loop));
|
||||
uv__io_poll_check(loop, NULL);
|
||||
|
||||
if (nfds == -1)
|
||||
assert(errno == EINTR);
|
||||
@@ -1562,7 +1543,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
have_signals = 1;
|
||||
} else {
|
||||
uv__metrics_update_idle_time(loop);
|
||||
w->cb(loop, w, pe->events);
|
||||
uv__io_cb(loop, w, pe->events);
|
||||
}
|
||||
|
||||
nevents++;
|
||||
@@ -1578,7 +1559,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
|
||||
if (have_signals != 0) {
|
||||
uv__metrics_update_idle_time(loop);
|
||||
loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
|
||||
uv__signal_event(loop, &loop->signal_io_watcher, POLLIN);
|
||||
}
|
||||
|
||||
lfields->inv = NULL;
|
||||
@@ -1750,7 +1731,7 @@ int uv_cpu_info(uv_cpu_info_t** ci, int* count) {
|
||||
"0xd0b\nCortex-A76\n" "0xd0c\nNeoverse-N1\n" "0xd0d\nCortex-A77\n"
|
||||
"0xd0e\nCortex-A76AE\n" "0xd13\nCortex-R52\n" "0xd20\nCortex-M23\n"
|
||||
"0xd21\nCortex-M33\n" "0xd41\nCortex-A78\n" "0xd42\nCortex-A78AE\n"
|
||||
"0xd4a\nNeoverse-E1\n" "0xd4b\nCortex-A78C\n"
|
||||
"0xd4a\nNeoverse-E1\n" "0xd4b\nCortex-A78C\n" "0xd4f\nNeoverse-V2\n"
|
||||
#endif
|
||||
"";
|
||||
struct cpu {
|
||||
@@ -1758,7 +1739,7 @@ int uv_cpu_info(uv_cpu_info_t** ci, int* count) {
|
||||
unsigned model;
|
||||
};
|
||||
FILE* fp;
|
||||
char* p;
|
||||
const char* p;
|
||||
int found;
|
||||
int n;
|
||||
unsigned i;
|
||||
@@ -2045,13 +2026,6 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
||||
}
|
||||
|
||||
|
||||
/* TODO(bnoordhuis) share with bsd-ifaddrs.c */
|
||||
void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
||||
int count) {
|
||||
uv__free(addresses);
|
||||
}
|
||||
|
||||
|
||||
void uv__set_process_title(const char* title) {
|
||||
#if defined(PR_SET_NAME)
|
||||
prctl(PR_SET_NAME, title); /* Only copies first 16 characters. */
|
||||
@@ -2227,11 +2201,20 @@ static uint64_t uv__get_cgroup_constrained_memory(char buf[static 1024]) {
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
char buf[1024];
|
||||
uint64_t cgroup_limit;
|
||||
uint64_t rlimit_limit;
|
||||
|
||||
if (uv__slurp("/proc/self/cgroup", buf, sizeof(buf)))
|
||||
return 0;
|
||||
cgroup_limit = 0;
|
||||
if (uv__slurp("/proc/self/cgroup", buf, sizeof(buf)) == 0)
|
||||
cgroup_limit = uv__get_cgroup_constrained_memory(buf);
|
||||
rlimit_limit = uv__get_rlimit_max_memory();
|
||||
|
||||
return uv__get_cgroup_constrained_memory(buf);
|
||||
/* Return the minimum of cgroup and rlimit constraints. */
|
||||
if (cgroup_limit == 0)
|
||||
return rlimit_limit;
|
||||
if (rlimit_limit == 0)
|
||||
return cgroup_limit;
|
||||
return cgroup_limit < rlimit_limit ? cgroup_limit : rlimit_limit;
|
||||
}
|
||||
|
||||
|
||||
@@ -2309,8 +2292,8 @@ static int uv__get_cgroupv2_constrained_cpu(const char* cgroup,
|
||||
static const char cgroup_mount[] = "/sys/fs/cgroup";
|
||||
const char* cgroup_trimmed;
|
||||
char buf[1024];
|
||||
char full_path[256];
|
||||
char path[256];
|
||||
char full_path[sizeof(path) + sizeof("/cpu.max")];
|
||||
char quota_buf[16];
|
||||
char* last_slash;
|
||||
int cgroup_size;
|
||||
@@ -2370,6 +2353,8 @@ static int uv__get_cgroupv2_constrained_cpu(const char* cgroup,
|
||||
goto next;
|
||||
|
||||
*quota = limit / period;
|
||||
if (*quota == 0)
|
||||
*quota = 1;
|
||||
if (*quota < min_quota)
|
||||
min_quota = *quota;
|
||||
|
||||
@@ -2386,10 +2371,10 @@ next:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char* uv__cgroup1_find_cpu_controller(const char* cgroup,
|
||||
static const char* uv__cgroup1_find_cpu_controller(const char* cgroup,
|
||||
int* cgroup_size) {
|
||||
/* Seek to the cpu controller line. */
|
||||
char* cgroup_cpu = strstr(cgroup, ":cpu,");
|
||||
const char* cgroup_cpu = strstr(cgroup, ":cpu,");
|
||||
|
||||
if (cgroup_cpu != NULL) {
|
||||
/* Skip the controller prefix to the start of the cgroup path. */
|
||||
@@ -2406,7 +2391,7 @@ static int uv__get_cgroupv1_constrained_cpu(const char* cgroup,
|
||||
char path[256];
|
||||
char buf[1024];
|
||||
int cgroup_size;
|
||||
char* cgroup_cpu;
|
||||
const char* cgroup_cpu;
|
||||
long long period_length;
|
||||
long long quota_per_period;
|
||||
|
||||
@@ -2499,7 +2484,7 @@ static int init_inotify(uv_loop_t* loop) {
|
||||
if (fd < 0)
|
||||
return UV__ERR(errno);
|
||||
|
||||
err = uv__io_init_start(loop, &loop->inotify_read_watcher, uv__inotify_read,
|
||||
err = uv__io_init_start(loop, &loop->inotify_read_watcher, UV__INOTIFY_READ,
|
||||
fd, POLLIN);
|
||||
if (err) {
|
||||
uv__close(fd);
|
||||
@@ -2595,9 +2580,7 @@ static void maybe_free_watcher_list(struct watcher_list* w, uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
static void uv__inotify_read(uv_loop_t* loop,
|
||||
uv__io_t* dummy,
|
||||
unsigned int events) {
|
||||
void uv__inotify_read(uv_loop_t* loop, uv__io_t* dummy, unsigned int events) {
|
||||
const struct inotify_event* e;
|
||||
struct watcher_list* w;
|
||||
uv_fs_event_t* h;
|
||||
|
||||
Vendored
+2
-3
@@ -83,7 +83,7 @@ int uv_loop_init(uv_loop_t* loop) {
|
||||
uv__signal_global_once_init();
|
||||
err = uv__process_init(loop);
|
||||
if (err)
|
||||
goto fail_signal_init;
|
||||
goto fail_process_init;
|
||||
uv__queue_init(&loop->process_handles);
|
||||
|
||||
err = uv_rwlock_init(&loop->cloexec_lock);
|
||||
@@ -110,9 +110,8 @@ fail_mutex_init:
|
||||
uv_rwlock_destroy(&loop->cloexec_lock);
|
||||
|
||||
fail_rwlock_init:
|
||||
fail_process_init:
|
||||
uv__signal_loop_cleanup(loop);
|
||||
|
||||
fail_signal_init:
|
||||
uv__platform_loop_delete(loop);
|
||||
|
||||
if (loop->backend_fd != -1) {
|
||||
|
||||
Vendored
+1
-1
@@ -127,7 +127,7 @@ uint64_t uv_get_total_memory(void) {
|
||||
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0; /* Memory constraints are unknown. */
|
||||
return uv__get_rlimit_max_memory();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vendored
+4
-45
@@ -59,54 +59,13 @@ void uv_loadavg(double avg[3]) {
|
||||
|
||||
|
||||
int uv_exepath(char* buffer, size_t* size) {
|
||||
int mib[4];
|
||||
char **argsbuf = NULL;
|
||||
size_t argsbuf_size = 100U;
|
||||
size_t exepath_size;
|
||||
pid_t mypid;
|
||||
int err;
|
||||
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
mypid = getpid();
|
||||
for (;;) {
|
||||
err = UV_ENOMEM;
|
||||
argsbuf = uv__reallocf(argsbuf, argsbuf_size);
|
||||
if (argsbuf == NULL)
|
||||
goto out;
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_PROC_ARGS;
|
||||
mib[2] = mypid;
|
||||
mib[3] = KERN_PROC_ARGV;
|
||||
if (sysctl(mib, ARRAY_SIZE(mib), argsbuf, &argsbuf_size, NULL, 0) == 0) {
|
||||
break;
|
||||
}
|
||||
if (errno != ENOMEM) {
|
||||
err = UV__ERR(errno);
|
||||
goto out;
|
||||
}
|
||||
argsbuf_size *= 2U;
|
||||
}
|
||||
if (uv_saved_argv0 == NULL)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (argsbuf[0] == NULL) {
|
||||
err = UV_EINVAL; /* FIXME(bnoordhuis) More appropriate error. */
|
||||
goto out;
|
||||
}
|
||||
|
||||
*size -= 1;
|
||||
exepath_size = strlen(argsbuf[0]);
|
||||
if (*size > exepath_size)
|
||||
*size = exepath_size;
|
||||
|
||||
memcpy(buffer, argsbuf[0], *size);
|
||||
buffer[*size] = '\0';
|
||||
err = 0;
|
||||
|
||||
out:
|
||||
uv__free(argsbuf);
|
||||
|
||||
return err;
|
||||
return uv__search_path(uv_saved_argv0, buffer, size);
|
||||
}
|
||||
|
||||
|
||||
@@ -135,7 +94,7 @@ uint64_t uv_get_total_memory(void) {
|
||||
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0; /* Memory constraints are unknown. */
|
||||
return uv__get_rlimit_max_memory();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vendored
+19
-23
@@ -188,12 +188,23 @@ uint64_t uv_get_total_memory(void) {
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
struct rlimit rl;
|
||||
uint64_t memlimit;
|
||||
uint64_t rlimit_limit;
|
||||
|
||||
/* RLIMIT_MEMLIMIT return value is in megabytes rather than bytes. */
|
||||
if (getrlimit(RLIMIT_MEMLIMIT, &rl) == 0)
|
||||
return rl.rlim_cur * 1024 * 1024;
|
||||
memlimit = 0;
|
||||
if (getrlimit(RLIMIT_MEMLIMIT, &rl) == 0 && rl.rlim_cur != RLIM_INFINITY)
|
||||
memlimit = rl.rlim_cur * 1024 * 1024;
|
||||
|
||||
return 0; /* There is no memory limit set. */
|
||||
/* Also check RLIMIT_AS and RLIMIT_DATA. */
|
||||
rlimit_limit = uv__get_rlimit_max_memory();
|
||||
|
||||
/* Return the minimum of RLIMIT_MEMLIMIT and other rlimits. */
|
||||
if (memlimit == 0)
|
||||
return rlimit_limit;
|
||||
if (rlimit_limit == 0)
|
||||
return memlimit;
|
||||
return memlimit < rlimit_limit ? memlimit : rlimit_limit;
|
||||
}
|
||||
|
||||
|
||||
@@ -892,30 +903,15 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
|
||||
nfds = 0;
|
||||
for (;;) {
|
||||
/* 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);
|
||||
|
||||
if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout)
|
||||
timeout = max_safe_timeout;
|
||||
|
||||
/* 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;
|
||||
|
||||
uv__io_poll_prepare(loop, NULL, timeout);
|
||||
nfds = epoll_wait(loop->ep, events,
|
||||
ARRAY_SIZE(events), timeout);
|
||||
|
||||
/* Update loop->time unconditionally. It's tempting to skip the update when
|
||||
* timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
|
||||
* operating system didn't reschedule our process while in the syscall.
|
||||
*/
|
||||
base = loop->time;
|
||||
SAVE_ERRNO(uv__update_time(loop));
|
||||
uv__io_poll_check(loop, NULL);
|
||||
|
||||
if (nfds == 0) {
|
||||
assert(timeout != -1);
|
||||
|
||||
@@ -1008,7 +1004,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
have_signals = 1;
|
||||
} else {
|
||||
uv__metrics_update_idle_time(loop);
|
||||
w->cb(loop, w, pe->events);
|
||||
uv__io_cb(loop, w, pe->events);
|
||||
}
|
||||
nevents++;
|
||||
}
|
||||
@@ -1023,7 +1019,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
|
||||
if (have_signals != 0) {
|
||||
uv__metrics_update_idle_time(loop);
|
||||
loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
|
||||
uv__signal_event(loop, &loop->signal_io_watcher, POLLIN);
|
||||
}
|
||||
|
||||
loop->watchers[loop->nwatchers] = NULL;
|
||||
|
||||
Vendored
+2
-3
@@ -170,9 +170,8 @@ int uv__pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
|
||||
return UV__ERR(errno);
|
||||
|
||||
handle->connection_cb = cb;
|
||||
handle->io_watcher.cb = uv__server_io;
|
||||
uv__io_start(handle->loop, &handle->io_watcher, POLLIN);
|
||||
return 0;
|
||||
uv__io_cb_set(&handle->io_watcher, UV__SERVER_IO);
|
||||
return uv__io_start(handle->loop, &handle->io_watcher, POLLIN);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vendored
+2
-2
@@ -26,7 +26,7 @@
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
uv_poll_t* handle;
|
||||
int pevents;
|
||||
|
||||
@@ -87,7 +87,7 @@ int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
|
||||
return err;
|
||||
|
||||
uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL);
|
||||
uv__io_init(&handle->io_watcher, uv__poll_io, fd);
|
||||
uv__io_init(&handle->io_watcher, UV__POLL_IO, fd);
|
||||
handle->poll_cb = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Vendored
+4
-26
@@ -195,31 +195,9 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
* our caller then we need to loop around and poll() again.
|
||||
*/
|
||||
for (;;) {
|
||||
/* 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;
|
||||
|
||||
if (pset != NULL)
|
||||
if (pthread_sigmask(SIG_BLOCK, pset, NULL))
|
||||
abort();
|
||||
uv__io_poll_prepare(loop, pset, timeout);
|
||||
nfds = poll(loop->poll_fds, (nfds_t)loop->poll_fds_used, timeout);
|
||||
if (pset != NULL)
|
||||
if (pthread_sigmask(SIG_UNBLOCK, pset, NULL))
|
||||
abort();
|
||||
|
||||
/* Update loop->time unconditionally. It's tempting to skip the update when
|
||||
* timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
|
||||
* operating system didn't reschedule our process while in the syscall.
|
||||
*/
|
||||
SAVE_ERRNO(uv__update_time(loop));
|
||||
uv__io_poll_check(loop, pset);
|
||||
|
||||
if (nfds == 0) {
|
||||
if (reset_timeout != 0) {
|
||||
@@ -294,7 +272,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
have_signals = 1;
|
||||
} else {
|
||||
uv__metrics_update_idle_time(loop);
|
||||
w->cb(loop, w, pe->revents);
|
||||
uv__io_cb(loop, w, pe->revents);
|
||||
}
|
||||
|
||||
nevents++;
|
||||
@@ -310,7 +288,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
|
||||
if (have_signals != 0) {
|
||||
uv__metrics_update_idle_time(loop);
|
||||
loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
|
||||
uv__signal_event(loop, &loop->signal_io_watcher, POLLIN);
|
||||
}
|
||||
|
||||
loop->poll_fds_iterating = 0;
|
||||
|
||||
Vendored
+1
@@ -1073,6 +1073,7 @@ int uv_spawn(uv_loop_t* loop,
|
||||
return exec_errorno;
|
||||
|
||||
error:
|
||||
uv__queue_remove(&process->handle_queue);
|
||||
if (pipes != NULL) {
|
||||
for (i = 0; i < stdio_count; i++) {
|
||||
if (i < options->stdio_count)
|
||||
|
||||
Vendored
+44
-8
@@ -28,6 +28,14 @@
|
||||
#include <sys/memmsg.h>
|
||||
#include <sys/syspage.h>
|
||||
#include <sys/procfs.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#if __QNX__ >= 800
|
||||
#define cpuinfo_val cpuinfo
|
||||
#else
|
||||
#define cpuinfo_val new_cpuinfo
|
||||
#endif
|
||||
|
||||
static void
|
||||
get_mem_info(uint64_t* totalmem, uint64_t* freemem) {
|
||||
@@ -67,24 +75,50 @@ int uv_exepath(char* buffer, size_t* size) {
|
||||
}
|
||||
|
||||
|
||||
static uint64_t uv__read_pidin_info(const char* what) {
|
||||
uint64_t rc;
|
||||
char* p;
|
||||
char buf[2048];
|
||||
|
||||
FILE* fp = popen("pidin info", "r");
|
||||
if (fp == NULL)
|
||||
return 0;
|
||||
|
||||
size_t sz = fread(buf, 1, sizeof(buf) - 1, fp);
|
||||
buf[sz] = '\0';
|
||||
|
||||
pclose(fp);
|
||||
|
||||
p = strstr(buf, what);
|
||||
if (p == NULL)
|
||||
return 0;
|
||||
|
||||
p += strlen(what);
|
||||
|
||||
rc = 0;
|
||||
sscanf(p, "%" PRIu64 " MB", &rc);
|
||||
|
||||
return rc * 1024 * 1024;
|
||||
}
|
||||
|
||||
uint64_t uv_get_free_memory(void) {
|
||||
uint64_t totalmem;
|
||||
uint64_t freemem;
|
||||
get_mem_info(&totalmem, &freemem);
|
||||
|
||||
freemem = uv__read_pidin_info("FreeMem:");
|
||||
return freemem;
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv_get_total_memory(void) {
|
||||
uint64_t totalmem;
|
||||
uint64_t freemem;
|
||||
get_mem_info(&totalmem, &freemem);
|
||||
|
||||
totalmem = uv__read_pidin_info("MB/");
|
||||
return totalmem;
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0;
|
||||
return uv__get_rlimit_max_memory();
|
||||
}
|
||||
|
||||
|
||||
@@ -113,15 +147,17 @@ int uv_resident_set_memory(size_t* rss) {
|
||||
|
||||
|
||||
int uv_uptime(double* uptime) {
|
||||
struct qtime_entry* qtime = _SYSPAGE_ENTRY(_syspage_ptr, qtime);
|
||||
*uptime = (qtime->nsec / 1000000000.0);
|
||||
struct timespec ts;
|
||||
if(clock_gettime(CLOCK_MONOTONIC, &ts))
|
||||
return UV__ERR(errno);
|
||||
*uptime = (double)ts.tv_sec;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
|
||||
struct cpuinfo_entry* cpuinfo =
|
||||
(struct cpuinfo_entry*)_SYSPAGE_ENTRY(_syspage_ptr, new_cpuinfo);
|
||||
(struct cpuinfo_entry*)_SYSPAGE_ENTRY(_syspage_ptr, cpuinfo_val);
|
||||
size_t cpuinfo_size = _SYSPAGE_ELEMENT_SIZE(_syspage_ptr, cpuinfo);
|
||||
struct strings_entry* strings = _SYSPAGE_ENTRY(_syspage_ptr, strings);
|
||||
int num_cpus = _syspage_ptr->num_cpu;
|
||||
|
||||
Vendored
+2
-5
@@ -45,7 +45,6 @@ static int uv__signal_start(uv_signal_t* handle,
|
||||
uv_signal_cb signal_cb,
|
||||
int signum,
|
||||
int oneshot);
|
||||
static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
||||
static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2);
|
||||
static void uv__signal_stop(uv_signal_t* handle);
|
||||
static void uv__signal_unregister_handler(int signum);
|
||||
@@ -271,7 +270,7 @@ static int uv__signal_loop_once_init(uv_loop_t* loop) {
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = uv__io_init_start(loop, &loop->signal_io_watcher, uv__signal_event,
|
||||
err = uv__io_init_start(loop, &loop->signal_io_watcher, UV__SIGNAL_EVENT,
|
||||
pipefd[0], POLLIN);
|
||||
if (err) {
|
||||
uv__close(pipefd[0]);
|
||||
@@ -436,9 +435,7 @@ static int uv__signal_start(uv_signal_t* handle,
|
||||
}
|
||||
|
||||
|
||||
static void uv__signal_event(uv_loop_t* loop,
|
||||
uv__io_t* w,
|
||||
unsigned int events) {
|
||||
void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
uv__signal_msg_t* msg;
|
||||
uv_signal_t* handle;
|
||||
char buf[sizeof(uv__signal_msg_t) * 32];
|
||||
|
||||
Vendored
+26
-18
@@ -73,7 +73,6 @@ STATIC_ASSERT(256 == sizeof(union uv__cmsg));
|
||||
static void uv__stream_connect(uv_stream_t*);
|
||||
static void uv__write(uv_stream_t* stream);
|
||||
static void uv__read(uv_stream_t* stream);
|
||||
static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
||||
static void uv__write_callbacks(uv_stream_t* stream);
|
||||
static size_t uv__write_req_size(uv_write_t* req);
|
||||
static void uv__drain(uv_stream_t* stream);
|
||||
@@ -113,7 +112,7 @@ void uv__stream_init(uv_loop_t* loop,
|
||||
stream->select = NULL;
|
||||
#endif /* defined(__APPLE_) */
|
||||
|
||||
uv__io_init(&stream->io_watcher, uv__stream_io, -1);
|
||||
uv__io_init(&stream->io_watcher, UV__STREAM_IO, -1);
|
||||
}
|
||||
|
||||
|
||||
@@ -417,7 +416,7 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
|
||||
|
||||
/* TODO Use delay the user passed in. */
|
||||
if ((stream->flags & UV_HANDLE_TCP_KEEPALIVE) &&
|
||||
uv__tcp_keepalive(fd, 1, 60)) {
|
||||
uv__tcp_keepalive(fd, 1, 60, 1, 10)) {
|
||||
return UV__ERR(errno);
|
||||
}
|
||||
}
|
||||
@@ -1031,8 +1030,6 @@ static void uv__read(uv_stream_t* stream) {
|
||||
int err;
|
||||
int is_ipc;
|
||||
|
||||
stream->flags &= ~UV_HANDLE_READ_PARTIAL;
|
||||
|
||||
/* Prevent loop starvation when the data comes in as fast as (or faster than)
|
||||
* we can read it. XXX Need to rearm fd if we switch to edge-triggered I/O.
|
||||
*/
|
||||
@@ -1147,11 +1144,15 @@ static void uv__read(uv_stream_t* stream) {
|
||||
#endif
|
||||
stream->read_cb(stream, nread, &buf);
|
||||
|
||||
/* Return if we didn't fill the buffer, there is no more data to read. */
|
||||
if (nread < buflen) {
|
||||
stream->flags |= UV_HANDLE_READ_PARTIAL;
|
||||
/* Save a system call and return if we didn't fill the buffer
|
||||
* completely, on the assumption the next read() will fail with EOF.
|
||||
*
|
||||
* Devices like PTYs sometimes operate in a packet-like mode where
|
||||
* they don't return all available data in a single read but we'll
|
||||
* catch it on the next read because of level-triggered I/O.
|
||||
*/
|
||||
if (nread < buflen)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1186,7 +1187,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) {
|
||||
}
|
||||
|
||||
|
||||
static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
uv_stream_t* stream;
|
||||
|
||||
stream = container_of(w, uv_stream_t, io_watcher);
|
||||
@@ -1203,22 +1204,23 @@ static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
|
||||
assert(uv__stream_fd(stream) >= 0);
|
||||
|
||||
/* Ignore POLLHUP here. Even if it's set, there may still be data to read. */
|
||||
if (events & (POLLIN | POLLERR | POLLHUP))
|
||||
if (events & (POLLIN | POLLERR))
|
||||
uv__read(stream);
|
||||
|
||||
if (uv__stream_fd(stream) == -1)
|
||||
return; /* read_cb closed stream. */
|
||||
|
||||
/* Short-circuit iff POLLHUP is set, the user is still interested in read
|
||||
* events and uv__read() reported a partial read but not EOF. If the EOF
|
||||
* flag is set, uv__read() called read_cb with err=UV_EOF and we don't
|
||||
* have to do anything. If the partial read flag is not set, we can't
|
||||
* report the EOF yet because there is still data to read.
|
||||
* events and uv__read() didn't see EOF. If the EOF flag is set, uv__read()
|
||||
* called read_cb with err=UV_EOF and we don't have to do anything.
|
||||
*
|
||||
* POLLIN should not be set because, at least on Linux and possibly other
|
||||
* operating systems, devices like PTYs sometimes produce partial reads even
|
||||
* when more data is available.
|
||||
*/
|
||||
if ((events & POLLHUP) &&
|
||||
!(events & POLLIN) &&
|
||||
(stream->flags & UV_HANDLE_READING) &&
|
||||
(stream->flags & UV_HANDLE_READ_PARTIAL) &&
|
||||
!(stream->flags & UV_HANDLE_READ_EOF)) {
|
||||
uv_buf_t buf = { NULL, 0 };
|
||||
uv__stream_eof(stream, &buf);
|
||||
@@ -1295,12 +1297,18 @@ static void uv__stream_connect(uv_stream_t* stream) {
|
||||
static int uv__check_before_write(uv_stream_t* stream,
|
||||
unsigned int nbufs,
|
||||
uv_stream_t* send_handle) {
|
||||
assert(nbufs > 0);
|
||||
assert((stream->type == UV_TCP ||
|
||||
stream->type == UV_NAMED_PIPE ||
|
||||
stream->type == UV_TTY) &&
|
||||
"uv_write (unix) does not yet support other types of streams");
|
||||
|
||||
/* We're not beholden to IOV_MAX but limit the buffer count to catch sign
|
||||
* conversion bugs where a caller passes in a signed negative number that
|
||||
* then gets converted to a really large unsigned number.
|
||||
*/
|
||||
if (nbufs < 1 || nbufs > 1024*1024)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (uv__stream_fd(stream) < 0)
|
||||
return UV_EBADF;
|
||||
|
||||
|
||||
Vendored
+7
-30
@@ -210,12 +210,6 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
/* 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);
|
||||
|
||||
if (timeout != -1) {
|
||||
spec.tv_sec = timeout / 1000;
|
||||
spec.tv_nsec = (timeout % 1000) * 1000000;
|
||||
@@ -227,17 +221,13 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
nfds = 1;
|
||||
saved_errno = 0;
|
||||
|
||||
if (pset != NULL)
|
||||
pthread_sigmask(SIG_BLOCK, pset, NULL);
|
||||
|
||||
uv__io_poll_prepare(loop, pset, timeout);
|
||||
err = port_getn(loop->backend_fd,
|
||||
events,
|
||||
ARRAY_SIZE(events),
|
||||
&nfds,
|
||||
timeout == -1 ? NULL : &spec);
|
||||
|
||||
if (pset != NULL)
|
||||
pthread_sigmask(SIG_UNBLOCK, pset, NULL);
|
||||
uv__io_poll_check(loop, pset);
|
||||
|
||||
if (err) {
|
||||
/* Work around another kernel bug: port_getn() may return events even
|
||||
@@ -251,12 +241,6 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Update loop->time unconditionally. It's tempting to skip the update when
|
||||
* timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
|
||||
* operating system didn't reschedule our process while in the syscall.
|
||||
*/
|
||||
SAVE_ERRNO(uv__update_time(loop));
|
||||
|
||||
if (events[0].portev_source == 0) {
|
||||
if (reset_timeout != 0) {
|
||||
timeout = user_timeout;
|
||||
@@ -307,7 +291,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
have_signals = 1;
|
||||
} else {
|
||||
uv__metrics_update_idle_time(loop);
|
||||
w->cb(loop, w, pe->portev_events);
|
||||
uv__io_cb(loop, w, pe->portev_events);
|
||||
}
|
||||
|
||||
nevents++;
|
||||
@@ -329,7 +313,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
|
||||
if (have_signals != 0) {
|
||||
uv__metrics_update_idle_time(loop);
|
||||
loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
|
||||
uv__signal_event(loop, &loop->signal_io_watcher, POLLIN);
|
||||
}
|
||||
|
||||
loop->watchers[loop->nwatchers] = NULL;
|
||||
@@ -413,7 +397,7 @@ uint64_t uv_get_total_memory(void) {
|
||||
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0; /* Memory constraints are unknown. */
|
||||
return uv__get_rlimit_max_memory();
|
||||
}
|
||||
|
||||
|
||||
@@ -446,9 +430,7 @@ static int uv__fs_event_rearm(uv_fs_event_t *handle) {
|
||||
}
|
||||
|
||||
|
||||
static void uv__fs_event_read(uv_loop_t* loop,
|
||||
uv__io_t* w,
|
||||
unsigned int revents) {
|
||||
void uv__fs_event_read(uv_loop_t* loop, uv__io_t* w, unsigned int revents) {
|
||||
uv_fs_event_t *handle = NULL;
|
||||
timespec_t timeout;
|
||||
port_event_t pe;
|
||||
@@ -548,7 +530,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
|
||||
if (first_run) {
|
||||
err = uv__io_init_start(handle->loop,
|
||||
&handle->loop->fs_event_watcher,
|
||||
uv__fs_event_read,
|
||||
UV__FS_EVENT_READ,
|
||||
portfd,
|
||||
POLLIN);
|
||||
if (err)
|
||||
@@ -898,11 +880,6 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
||||
}
|
||||
#endif /* SUNOS_NO_IFADDRS */
|
||||
|
||||
void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
||||
int count) {
|
||||
uv__free(addresses);
|
||||
}
|
||||
|
||||
|
||||
#if !defined(_POSIX_VERSION) || _POSIX_VERSION < 200809L
|
||||
size_t strnlen(const char* s, size_t maxlen) {
|
||||
|
||||
Vendored
+27
-25
@@ -444,10 +444,9 @@ int uv__tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
|
||||
tcp->flags |= UV_HANDLE_BOUND;
|
||||
|
||||
/* Start listening for connections. */
|
||||
tcp->io_watcher.cb = uv__server_io;
|
||||
uv__io_start(tcp->loop, &tcp->io_watcher, POLLIN);
|
||||
uv__io_cb_set(&tcp->io_watcher, UV__SERVER_IO);
|
||||
|
||||
return 0;
|
||||
return uv__io_start(tcp->loop, &tcp->io_watcher, POLLIN);
|
||||
}
|
||||
|
||||
|
||||
@@ -466,22 +465,18 @@ int uv__tcp_nodelay(int fd, int on) {
|
||||
#else
|
||||
#define UV_KEEPALIVE_FACTOR(x)
|
||||
#endif
|
||||
int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
|
||||
int idle;
|
||||
int intvl;
|
||||
int cnt;
|
||||
|
||||
(void) &idle;
|
||||
(void) &intvl;
|
||||
(void) &cnt;
|
||||
|
||||
int uv__tcp_keepalive(int fd,
|
||||
int on,
|
||||
unsigned int idle,
|
||||
unsigned int intvl,
|
||||
unsigned int cnt) {
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)))
|
||||
return UV__ERR(errno);
|
||||
|
||||
if (!on)
|
||||
return 0;
|
||||
|
||||
if (delay < 1)
|
||||
if (idle < 1 || intvl < 1 || cnt < 1)
|
||||
return UV_EINVAL;
|
||||
|
||||
#ifdef __sun
|
||||
@@ -507,13 +502,16 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
|
||||
* The TCP connection will be aborted after certain amount of probes, which is set by TCP_KEEPCNT, without receiving response.
|
||||
*/
|
||||
|
||||
idle = delay;
|
||||
/* Kernel expects at least 10 seconds. */
|
||||
/* Kernel expects at least 10 seconds for TCP_KEEPIDLE and TCP_KEEPINTVL. */
|
||||
if (idle < 10)
|
||||
idle = 10;
|
||||
/* Kernel expects at most 10 days. */
|
||||
if (intvl < 10)
|
||||
intvl = 10;
|
||||
/* Kernel expects at most 10 days for TCP_KEEPIDLE and TCP_KEEPINTVL. */
|
||||
if (idle > 10*24*60*60)
|
||||
idle = 10*24*60*60;
|
||||
if (intvl > 10*24*60*60)
|
||||
intvl = 10*24*60*60;
|
||||
|
||||
UV_KEEPALIVE_FACTOR(idle);
|
||||
|
||||
@@ -523,12 +521,10 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
|
||||
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle)))
|
||||
return UV__ERR(errno);
|
||||
|
||||
intvl = 10; /* required at least 10 seconds */
|
||||
UV_KEEPALIVE_FACTOR(intvl);
|
||||
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl)))
|
||||
return UV__ERR(errno);
|
||||
|
||||
cnt = 1; /* 1 retry, ensure (TCP_KEEPINTVL * TCP_KEEPCNT) is 10 seconds */
|
||||
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt)))
|
||||
return UV__ERR(errno);
|
||||
#else
|
||||
@@ -540,7 +536,7 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
|
||||
|
||||
/* Note that the consequent probes will not be sent at equal intervals on Solaris,
|
||||
* but will be sent using the exponential backoff algorithm. */
|
||||
int time_to_abort = 10; /* 10 seconds */
|
||||
unsigned int time_to_abort = intvl * cnt;
|
||||
UV_KEEPALIVE_FACTOR(time_to_abort);
|
||||
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE_ABORT_THRESHOLD, &time_to_abort, sizeof(time_to_abort)))
|
||||
return UV__ERR(errno);
|
||||
@@ -548,7 +544,6 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
|
||||
|
||||
#else /* !defined(__sun) */
|
||||
|
||||
idle = delay;
|
||||
UV_KEEPALIVE_FACTOR(idle);
|
||||
#ifdef TCP_KEEPIDLE
|
||||
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle)))
|
||||
@@ -560,14 +555,12 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
|
||||
#endif
|
||||
|
||||
#ifdef TCP_KEEPINTVL
|
||||
intvl = 1; /* 1 second; same as default on Win32 */
|
||||
UV_KEEPALIVE_FACTOR(intvl);
|
||||
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl)))
|
||||
return UV__ERR(errno);
|
||||
#endif
|
||||
|
||||
#ifdef TCP_KEEPCNT
|
||||
cnt = 10; /* 10 retries; same as hardcoded on Win32 */
|
||||
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt)))
|
||||
return UV__ERR(errno);
|
||||
#endif
|
||||
@@ -595,11 +588,20 @@ int uv_tcp_nodelay(uv_tcp_t* handle, int on) {
|
||||
}
|
||||
|
||||
|
||||
int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) {
|
||||
int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int idle) {
|
||||
return uv_tcp_keepalive_ex(handle, on, idle, 1, 10);
|
||||
}
|
||||
|
||||
|
||||
int uv_tcp_keepalive_ex(uv_tcp_t* handle,
|
||||
int on,
|
||||
unsigned int idle,
|
||||
unsigned int intvl,
|
||||
unsigned int cnt) {
|
||||
int err;
|
||||
|
||||
if (uv__stream_fd(handle) != -1) {
|
||||
err =uv__tcp_keepalive(uv__stream_fd(handle), on, delay);
|
||||
err = uv__tcp_keepalive(uv__stream_fd(handle), on, idle, intvl, cnt);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
@@ -609,7 +611,7 @@ int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) {
|
||||
else
|
||||
handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE;
|
||||
|
||||
/* TODO Store delay if uv__stream_fd(handle) == -1 but don't want to enlarge
|
||||
/* TODO Store idle if uv__stream_fd(handle) == -1 but don't want to enlarge
|
||||
* uv_tcp_t with an int that's almost never used...
|
||||
*/
|
||||
|
||||
|
||||
Vendored
-2
@@ -870,9 +870,7 @@ int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) {
|
||||
return UV_ETIMEDOUT;
|
||||
|
||||
abort();
|
||||
#ifndef __SUNPRO_C
|
||||
return UV_EINVAL; /* Satisfy the compiler. */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vendored
+134
-37
@@ -32,6 +32,10 @@
|
||||
#endif
|
||||
#include <sys/un.h>
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <linux/errqueue.h>
|
||||
#endif
|
||||
|
||||
#if defined(IPV6_JOIN_GROUP) && !defined(IPV6_ADD_MEMBERSHIP)
|
||||
# define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
|
||||
#endif
|
||||
@@ -41,8 +45,7 @@
|
||||
#endif
|
||||
|
||||
static void uv__udp_run_completed(uv_udp_t* handle);
|
||||
static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents);
|
||||
static void uv__udp_recvmsg(uv_udp_t* handle);
|
||||
static void uv__udp_recvmsg(uv_udp_t* handle, int flag);
|
||||
static void uv__udp_sendmsg(uv_udp_t* handle);
|
||||
static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
|
||||
int domain,
|
||||
@@ -136,14 +139,57 @@ static void uv__udp_run_completed(uv_udp_t* handle) {
|
||||
}
|
||||
|
||||
|
||||
static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents) {
|
||||
#if defined(__linux__)
|
||||
static int uv__udp_recvmsg_errqueue(uv_udp_t* handle,
|
||||
struct msghdr* h,
|
||||
uv_buf_t* buf,
|
||||
const struct sockaddr* peer,
|
||||
int flags) {
|
||||
struct cmsghdr* cmsg;
|
||||
struct sock_extended_err* serr;
|
||||
struct sockaddr* offender;
|
||||
|
||||
if (!(h->msg_flags & MSG_ERRQUEUE))
|
||||
return 0;
|
||||
|
||||
flags |= UV_UDP_LINUX_RECVERR;
|
||||
for (cmsg = CMSG_FIRSTHDR(h); cmsg != NULL; cmsg = CMSG_NXTHDR(h, cmsg)) {
|
||||
if ((cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR) ||
|
||||
(cmsg->cmsg_level == SOL_IPV6 && cmsg->cmsg_type == IPV6_RECVERR)) {
|
||||
serr = (struct sock_extended_err*) CMSG_DATA(cmsg);
|
||||
|
||||
offender = SO_EE_OFFENDER(serr);
|
||||
handle->recv_cb(handle,
|
||||
UV__ERR(serr->ee_errno),
|
||||
buf,
|
||||
offender,
|
||||
flags);
|
||||
return 1; /* handled */
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents) {
|
||||
uv_udp_t* handle;
|
||||
|
||||
handle = container_of(w, uv_udp_t, io_watcher);
|
||||
assert(handle->type == UV_UDP);
|
||||
|
||||
if (revents & POLLIN)
|
||||
uv__udp_recvmsg(handle);
|
||||
uv__udp_recvmsg(handle, 0);
|
||||
|
||||
/* Just Linux support for now. */
|
||||
#if defined(__linux__)
|
||||
/* Guard against the case where the POLLIN callback above (e.g. via
|
||||
* uv_udp_recv_stop + uv_close) already cleared recv_cb in the same
|
||||
* revents iteration. uv__udp_recvmsg asserts recv_cb != NULL, so
|
||||
* calling it with a NULL recv_cb would be wrong regardless of POLLERR. */
|
||||
if ((revents & POLLERR) && uv__is_active(handle))
|
||||
uv__udp_recvmsg(handle, MSG_ERRQUEUE);
|
||||
#endif
|
||||
|
||||
if (revents & POLLOUT && !uv__is_closing(handle)) {
|
||||
uv__udp_sendmsg(handle);
|
||||
@@ -151,7 +197,7 @@ static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents) {
|
||||
}
|
||||
}
|
||||
|
||||
static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
|
||||
static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf, int flag) {
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
|
||||
struct sockaddr_in6 peers[20];
|
||||
struct iovec iov[ARRAY_SIZE(peers)];
|
||||
@@ -161,6 +207,9 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
|
||||
size_t chunks;
|
||||
int flags;
|
||||
size_t k;
|
||||
#if defined(__linux__)
|
||||
char control[ARRAY_SIZE(peers)][64];
|
||||
#endif
|
||||
|
||||
/* prepare structures for recvmmsg */
|
||||
chunks = buf->len / UV__UDP_DGRAM_MAXSIZE;
|
||||
@@ -178,6 +227,12 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
|
||||
msgs[k].msg_hdr.msg_controllen = 0;
|
||||
msgs[k].msg_hdr.msg_flags = 0;
|
||||
msgs[k].msg_len = 0;
|
||||
#if defined(__linux__)
|
||||
if (flag & MSG_ERRQUEUE) {
|
||||
msgs[k].msg_hdr.msg_control = control[k];
|
||||
msgs[k].msg_hdr.msg_controllen = sizeof(control[k]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__APPLE__)
|
||||
@@ -186,7 +241,7 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
|
||||
while (nread == -1 && errno == EINTR);
|
||||
#else
|
||||
do
|
||||
nread = recvmmsg(handle->io_watcher.fd, msgs, chunks, 0, NULL);
|
||||
nread = recvmmsg(handle->io_watcher.fd, msgs, chunks, flag, NULL);
|
||||
while (nread == -1 && errno == EINTR);
|
||||
#endif
|
||||
|
||||
@@ -203,6 +258,13 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
|
||||
flags |= UV_UDP_PARTIAL;
|
||||
|
||||
chunk_buf = uv_buf_init(iov[k].iov_base, iov[k].iov_len);
|
||||
#if defined(__linux__)
|
||||
if ((flag & MSG_ERRQUEUE) &&
|
||||
uv__udp_recvmsg_errqueue(handle, &msgs[k].msg_hdr, &chunk_buf,
|
||||
(const struct sockaddr*) &peers[k], flags)) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
handle->recv_cb(handle,
|
||||
msgs[k].msg_len,
|
||||
&chunk_buf,
|
||||
@@ -220,13 +282,16 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
|
||||
#endif /* __linux__ || ____FreeBSD__ || __APPLE__ */
|
||||
}
|
||||
|
||||
static void uv__udp_recvmsg(uv_udp_t* handle) {
|
||||
static void uv__udp_recvmsg(uv_udp_t* handle, int flag) {
|
||||
struct sockaddr_storage peer;
|
||||
struct msghdr h;
|
||||
ssize_t nread;
|
||||
uv_buf_t buf;
|
||||
int flags;
|
||||
int count;
|
||||
#if defined(__linux__)
|
||||
char control[256];
|
||||
#endif
|
||||
|
||||
assert(handle->recv_cb != NULL);
|
||||
assert(handle->alloc_cb != NULL);
|
||||
@@ -246,7 +311,7 @@ static void uv__udp_recvmsg(uv_udp_t* handle) {
|
||||
assert(buf.base != NULL);
|
||||
|
||||
if (uv_udp_using_recvmmsg(handle)) {
|
||||
nread = uv__udp_recvmmsg(handle, &buf);
|
||||
nread = uv__udp_recvmmsg(handle, &buf, flag);
|
||||
if (nread > 0)
|
||||
count -= nread;
|
||||
continue;
|
||||
@@ -258,25 +323,36 @@ static void uv__udp_recvmsg(uv_udp_t* handle) {
|
||||
h.msg_namelen = sizeof(peer);
|
||||
h.msg_iov = (void*) &buf;
|
||||
h.msg_iovlen = 1;
|
||||
|
||||
do {
|
||||
nread = recvmsg(handle->io_watcher.fd, &h, 0);
|
||||
#if defined(__linux__)
|
||||
if (flag & MSG_ERRQUEUE) {
|
||||
h.msg_control = control;
|
||||
h.msg_controllen = sizeof(control);
|
||||
}
|
||||
#endif
|
||||
|
||||
do
|
||||
nread = recvmsg(handle->io_watcher.fd, &h, flag);
|
||||
while (nread == -1 && errno == EINTR);
|
||||
|
||||
if (nread == -1) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
handle->recv_cb(handle, 0, &buf, NULL, 0);
|
||||
else
|
||||
handle->recv_cb(handle, UV__ERR(errno), &buf, NULL, 0);
|
||||
}
|
||||
else {
|
||||
flags = 0;
|
||||
flags = 0;
|
||||
if (nread != -1)
|
||||
if (h.msg_flags & MSG_TRUNC)
|
||||
flags |= UV_UDP_PARTIAL;
|
||||
|
||||
handle->recv_cb(handle, nread, &buf, (const struct sockaddr*) &peer, flags);
|
||||
#if defined(__linux__)
|
||||
if ((flag & MSG_ERRQUEUE) &&
|
||||
uv__udp_recvmsg_errqueue(handle, &h, &buf, (void*) &peer, flags)) {
|
||||
count--;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (nread != -1)
|
||||
handle->recv_cb(handle, nread, &buf, (void*) &peer, flags);
|
||||
else if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
handle->recv_cb(handle, 0, &buf, NULL, 0);
|
||||
else
|
||||
handle->recv_cb(handle, UV__ERR(errno), &buf, NULL, 0);
|
||||
count--;
|
||||
}
|
||||
/* recv_cb callback may decide to pause or close the handle */
|
||||
@@ -560,7 +636,7 @@ int uv__udp_disconnect(uv_udp_t* handle) {
|
||||
} while (r == -1 && errno == EINTR);
|
||||
|
||||
if (r == -1) {
|
||||
#if defined(BSD) /* The macro BSD is from sys/param.h */
|
||||
#if defined(BSD) || defined(__QNX__) /* The macro BSD is from sys/param.h */
|
||||
if (errno != EAFNOSUPPORT && errno != EINVAL)
|
||||
return UV__ERR(errno);
|
||||
#else
|
||||
@@ -661,10 +737,10 @@ int uv__udp_try_send(uv_udp_t* handle,
|
||||
}
|
||||
|
||||
err = uv__udp_sendmsg1(handle->io_watcher.fd, bufs, nbufs, addr);
|
||||
if (err > 0)
|
||||
return uv__count_bufs(bufs, nbufs);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return err;
|
||||
return uv__count_bufs(bufs, nbufs);
|
||||
}
|
||||
|
||||
|
||||
@@ -766,8 +842,8 @@ static int uv__udp_set_membership6(uv_udp_t* handle,
|
||||
!defined(__NetBSD__) && \
|
||||
!defined(__ANDROID__) && \
|
||||
!defined(__DragonFly__) && \
|
||||
!defined(__QNX__) && \
|
||||
!defined(__GNU__)
|
||||
!defined(__GNU__) && \
|
||||
!defined(QNX_IOPKT)
|
||||
static int uv__udp_set_source_membership4(uv_udp_t* handle,
|
||||
const struct sockaddr_in* multicast_addr,
|
||||
const char* interface_addr,
|
||||
@@ -881,7 +957,7 @@ int uv__udp_init_ex(uv_loop_t* loop,
|
||||
handle->recv_cb = NULL;
|
||||
handle->send_queue_size = 0;
|
||||
handle->send_queue_count = 0;
|
||||
uv__io_init(&handle->io_watcher, uv__udp_io, fd);
|
||||
uv__io_init(&handle->io_watcher, UV__UDP_IO, fd);
|
||||
uv__queue_init(&handle->write_queue);
|
||||
uv__queue_init(&handle->write_completed_queue);
|
||||
|
||||
@@ -898,9 +974,13 @@ int uv_udp_using_recvmmsg(const uv_udp_t* handle) {
|
||||
}
|
||||
|
||||
|
||||
int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
|
||||
int uv_udp_open_ex(uv_udp_t* handle, uv_os_sock_t sock, unsigned int flags) {
|
||||
int err;
|
||||
|
||||
/* Check for bad flags. */
|
||||
if (flags & ~(UV_UDP_REUSEADDR | UV_UDP_REUSEPORT))
|
||||
return UV_EINVAL;
|
||||
|
||||
/* Check for already active socket. */
|
||||
if (handle->io_watcher.fd != -1)
|
||||
return UV_EBUSY;
|
||||
@@ -912,9 +992,17 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = uv__sock_reuseaddr(sock);
|
||||
if (err)
|
||||
return err;
|
||||
if (flags & UV_UDP_REUSEADDR) {
|
||||
err = uv__sock_reuseaddr(sock);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (flags & UV_UDP_REUSEPORT) {
|
||||
err = uv__sock_reuseport(sock);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
handle->io_watcher.fd = sock;
|
||||
if (uv__udp_is_connected(handle))
|
||||
@@ -924,6 +1012,15 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
|
||||
}
|
||||
|
||||
|
||||
int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
|
||||
/*
|
||||
* Keep backward compatibility, always set REUSEADDR.
|
||||
* Refs: https://github.com/libuv/libuv/issues/4551
|
||||
*/
|
||||
return uv_udp_open_ex(handle, sock, UV_UDP_REUSEADDR);
|
||||
}
|
||||
|
||||
|
||||
int uv_udp_set_membership(uv_udp_t* handle,
|
||||
const char* multicast_addr,
|
||||
const char* interface_addr,
|
||||
@@ -957,8 +1054,8 @@ int uv_udp_set_source_membership(uv_udp_t* handle,
|
||||
!defined(__NetBSD__) && \
|
||||
!defined(__ANDROID__) && \
|
||||
!defined(__DragonFly__) && \
|
||||
!defined(__QNX__) && \
|
||||
!defined(__GNU__)
|
||||
!defined(__GNU__) && \
|
||||
!defined(QNX_IOPKT)
|
||||
int err;
|
||||
union uv__sockaddr mcast_addr;
|
||||
union uv__sockaddr src_addr;
|
||||
@@ -1295,7 +1392,7 @@ static int uv__udp_sendmsg1(int fd,
|
||||
/* 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;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1312,7 +1409,7 @@ static int uv__udp_sendmsgv(int fd,
|
||||
nsent = 0;
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \
|
||||
(defined(__sun__) && defined(MSG_WAITFORONE))
|
||||
(defined(__sun__) && defined(MSG_WAITFORONE)) || defined(__QNX__)
|
||||
if (count > 1) {
|
||||
for (i = 0; i < count; /*empty*/) {
|
||||
struct mmsghdr m[20];
|
||||
@@ -1340,7 +1437,7 @@ static int uv__udp_sendmsgv(int fd,
|
||||
goto exit;
|
||||
}
|
||||
#endif /* defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) ||
|
||||
* (defined(__sun__) && defined(MSG_WAITFORONE))
|
||||
* (defined(__sun__) && defined(MSG_WAITFORONE)) || defined(__QNX__)
|
||||
*/
|
||||
|
||||
for (i = 0; i < count; i++, nsent++)
|
||||
@@ -1363,7 +1460,7 @@ exit:
|
||||
|
||||
|
||||
static void uv__udp_sendmsg(uv_udp_t* handle) {
|
||||
static const int N = 20;
|
||||
enum { N = 20 };
|
||||
struct sockaddr* addrs[N];
|
||||
unsigned int nbufs[N];
|
||||
uv_buf_t* bufs[N];
|
||||
|
||||
Vendored
+16
-3
@@ -575,12 +575,17 @@ static void uv__print_handles(uv_loop_t* loop, int only_active, FILE* stream) {
|
||||
struct uv__queue* q;
|
||||
uv_handle_t* h;
|
||||
|
||||
if (loop == NULL)
|
||||
loop = uv_default_loop();
|
||||
|
||||
if (stream == NULL)
|
||||
stream = stderr;
|
||||
|
||||
if (loop == NULL) {
|
||||
loop = uv_default_loop();
|
||||
if (loop == NULL) {
|
||||
fprintf(stream, "uv_default_loop() failed\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uv__queue_foreach(q, &loop->handle_queue) {
|
||||
h = uv__queue_data(q, uv_handle_t, handle_queue);
|
||||
|
||||
@@ -1049,3 +1054,11 @@ uint64_t uv_metrics_idle_time(uv_loop_t* loop) {
|
||||
idle_time += uv_hrtime() - entry_time;
|
||||
return idle_time;
|
||||
}
|
||||
|
||||
/* OS390 needs a different implementation, already provided in os390.c. */
|
||||
#ifndef __MVS__
|
||||
void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
||||
int count) {
|
||||
uv__free(addresses);
|
||||
}
|
||||
#endif /* !__MVS__ */
|
||||
Vendored
-1
@@ -90,7 +90,6 @@ enum {
|
||||
UV_HANDLE_LISTENING = 0x00000040,
|
||||
UV_HANDLE_CONNECTION = 0x00000080,
|
||||
UV_HANDLE_SHUT = 0x00000200,
|
||||
UV_HANDLE_READ_PARTIAL = 0x00000400,
|
||||
UV_HANDLE_READ_EOF = 0x00000800,
|
||||
|
||||
/* Used by streams and UDP handles. */
|
||||
|
||||
Vendored
+19
-1
@@ -23,10 +23,28 @@
|
||||
|
||||
#include "uv.h"
|
||||
#include "internal.h"
|
||||
#include "atomicops-inl.h"
|
||||
#include "handle-inl.h"
|
||||
#include "req-inl.h"
|
||||
|
||||
#ifdef _MSC_VER /* MSVC */
|
||||
|
||||
/* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less
|
||||
* efficient than InterlockedExchange, but InterlockedExchange8 does not exist,
|
||||
* and interlocked operations on larger targets might require the target to be
|
||||
* aligned. */
|
||||
#pragma intrinsic(_InterlockedOr8)
|
||||
|
||||
static char uv__atomic_exchange_set(char volatile* target) {
|
||||
return _InterlockedOr8(target, 1);
|
||||
}
|
||||
|
||||
#else /* GCC, Clang in mingw mode */
|
||||
|
||||
static char uv__atomic_exchange_set(char volatile* target) {
|
||||
return __sync_fetch_and_or(target, 1);
|
||||
}
|
||||
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
void uv__async_endgame(uv_loop_t* loop, uv_async_t* handle) {
|
||||
if (handle->flags & UV_HANDLE_CLOSING &&
|
||||
|
||||
Vendored
-61
@@ -1,61 +0,0 @@
|
||||
/* Copyright Joyent, Inc. and other Node 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.
|
||||
*/
|
||||
|
||||
#ifndef UV_WIN_ATOMICOPS_INL_H_
|
||||
#define UV_WIN_ATOMICOPS_INL_H_
|
||||
|
||||
#include "uv.h"
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
/* Atomic set operation on char */
|
||||
#ifdef _MSC_VER /* MSVC */
|
||||
|
||||
/* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less
|
||||
* efficient than InterlockedExchange, but InterlockedExchange8 does not exist,
|
||||
* and interlocked operations on larger targets might require the target to be
|
||||
* aligned. */
|
||||
#pragma intrinsic(_InterlockedOr8)
|
||||
|
||||
static char INLINE uv__atomic_exchange_set(char volatile* target) {
|
||||
return _InterlockedOr8(target, 1);
|
||||
}
|
||||
|
||||
#else /* GCC, Clang in mingw mode */
|
||||
|
||||
static inline char uv__atomic_exchange_set(char volatile* target) {
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
/* Mingw-32 version, hopefully this works for 64-bit gcc as well. */
|
||||
const char one = 1;
|
||||
char old_value;
|
||||
__asm__ __volatile__ ("lock xchgb %0, %1\n\t"
|
||||
: "=r"(old_value), "=m"(*target)
|
||||
: "0"(one), "m"(*target)
|
||||
: "memory");
|
||||
return old_value;
|
||||
#else
|
||||
return __sync_fetch_and_or(target, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* UV_WIN_ATOMICOPS_INL_H_ */
|
||||
Vendored
+197
-1
@@ -428,6 +428,7 @@ static void uv__poll(uv_loop_t* loop, DWORD timeout) {
|
||||
BOOL success;
|
||||
uv_req_t* req;
|
||||
OVERLAPPED_ENTRY overlappeds[128];
|
||||
OVERLAPPED* overlapped;
|
||||
ULONG count;
|
||||
ULONG i;
|
||||
int repeat;
|
||||
@@ -491,7 +492,8 @@ static void uv__poll(uv_loop_t* loop, DWORD timeout) {
|
||||
if (actual_timeout == 0)
|
||||
uv__metrics_inc_events_waiting(loop, 1);
|
||||
|
||||
req = uv__overlapped_to_req(overlappeds[i].lpOverlapped);
|
||||
overlapped = overlappeds[i].lpOverlapped;
|
||||
req = container_of(overlapped, uv_req_t, u.io.overlapped);
|
||||
uv__insert_pending_req(loop, req);
|
||||
}
|
||||
}
|
||||
@@ -525,6 +527,177 @@ static void uv__poll(uv_loop_t* loop, DWORD timeout) {
|
||||
}
|
||||
|
||||
|
||||
#define DELEGATE_STREAM_REQ(loop, req, method, handle_at) \
|
||||
do { \
|
||||
switch (((uv_handle_t*) (req)->handle_at)->type) { \
|
||||
case UV_TCP: \
|
||||
uv__process_tcp_##method##_req(loop, \
|
||||
(uv_tcp_t*) ((req)->handle_at), \
|
||||
req); \
|
||||
break; \
|
||||
\
|
||||
case UV_NAMED_PIPE: \
|
||||
uv__process_pipe_##method##_req(loop, \
|
||||
(uv_pipe_t*) ((req)->handle_at), \
|
||||
req); \
|
||||
break; \
|
||||
\
|
||||
case UV_TTY: \
|
||||
uv__process_tty_##method##_req(loop, \
|
||||
(uv_tty_t*) ((req)->handle_at), \
|
||||
req); \
|
||||
break; \
|
||||
\
|
||||
default: \
|
||||
assert(0); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
static void uv__process_reqs(uv_loop_t* loop) {
|
||||
uv_req_t* req;
|
||||
uv_req_t* first;
|
||||
uv_req_t* next;
|
||||
|
||||
if (loop->pending_reqs_tail == NULL)
|
||||
return;
|
||||
|
||||
first = loop->pending_reqs_tail->next_req;
|
||||
next = first;
|
||||
loop->pending_reqs_tail = NULL;
|
||||
|
||||
while (next != NULL) {
|
||||
req = next;
|
||||
next = req->next_req != first ? req->next_req : NULL;
|
||||
|
||||
switch (req->type) {
|
||||
case UV_READ:
|
||||
DELEGATE_STREAM_REQ(loop, req, read, data);
|
||||
break;
|
||||
|
||||
case UV_WRITE:
|
||||
DELEGATE_STREAM_REQ(loop, (uv_write_t*) req, write, handle);
|
||||
break;
|
||||
|
||||
case UV_ACCEPT:
|
||||
DELEGATE_STREAM_REQ(loop, req, accept, data);
|
||||
break;
|
||||
|
||||
case UV_CONNECT:
|
||||
DELEGATE_STREAM_REQ(loop, (uv_connect_t*) req, connect, handle);
|
||||
break;
|
||||
|
||||
case UV_SHUTDOWN:
|
||||
DELEGATE_STREAM_REQ(loop, (uv_shutdown_t*) req, shutdown, handle);
|
||||
break;
|
||||
|
||||
case UV_UDP_RECV:
|
||||
uv__process_udp_recv_req(loop, (uv_udp_t*) req->data, req);
|
||||
break;
|
||||
|
||||
case UV_UDP_SEND:
|
||||
uv__process_udp_send_req(loop,
|
||||
((uv_udp_send_t*) req)->handle,
|
||||
(uv_udp_send_t*) req);
|
||||
break;
|
||||
|
||||
case UV_WAKEUP:
|
||||
uv__process_async_wakeup_req(loop, (uv_async_t*) req->data, req);
|
||||
break;
|
||||
|
||||
case UV_SIGNAL_REQ:
|
||||
uv__process_signal_req(loop, (uv_signal_t*) req->data, req);
|
||||
break;
|
||||
|
||||
case UV_POLL_REQ:
|
||||
uv__process_poll_req(loop, (uv_poll_t*) req->data, req);
|
||||
break;
|
||||
|
||||
case UV_PROCESS_EXIT:
|
||||
uv__process_proc_exit(loop, (uv_process_t*) req->data);
|
||||
break;
|
||||
|
||||
case UV_FS_EVENT_REQ:
|
||||
uv__process_fs_event_req(loop, req, (uv_fs_event_t*) req->data);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef DELEGATE_STREAM_REQ
|
||||
|
||||
static void uv__process_endgames(uv_loop_t* loop) {
|
||||
uv_handle_t* handle;
|
||||
|
||||
while (loop->endgame_handles) {
|
||||
handle = loop->endgame_handles;
|
||||
loop->endgame_handles = handle->endgame_next;
|
||||
|
||||
handle->flags &= ~UV_HANDLE_ENDGAME_QUEUED;
|
||||
|
||||
switch (handle->type) {
|
||||
case UV_TCP:
|
||||
uv__tcp_endgame(loop, (uv_tcp_t*) handle);
|
||||
break;
|
||||
|
||||
case UV_NAMED_PIPE:
|
||||
uv__pipe_endgame(loop, (uv_pipe_t*) handle);
|
||||
break;
|
||||
|
||||
case UV_TTY:
|
||||
uv__tty_endgame(loop, (uv_tty_t*) handle);
|
||||
break;
|
||||
|
||||
case UV_UDP:
|
||||
uv__udp_endgame(loop, (uv_udp_t*) handle);
|
||||
break;
|
||||
|
||||
case UV_POLL:
|
||||
uv__poll_endgame(loop, (uv_poll_t*) handle);
|
||||
break;
|
||||
|
||||
case UV_TIMER:
|
||||
uv__timer_close((uv_timer_t*) handle);
|
||||
uv__handle_close(handle);
|
||||
break;
|
||||
|
||||
case UV_PREPARE:
|
||||
case UV_CHECK:
|
||||
case UV_IDLE:
|
||||
uv__loop_watcher_endgame(loop, handle);
|
||||
break;
|
||||
|
||||
case UV_ASYNC:
|
||||
uv__async_endgame(loop, (uv_async_t*) handle);
|
||||
break;
|
||||
|
||||
case UV_SIGNAL:
|
||||
uv__signal_endgame(loop, (uv_signal_t*) handle);
|
||||
break;
|
||||
|
||||
case UV_PROCESS:
|
||||
uv__process_endgame(loop, (uv_process_t*) handle);
|
||||
break;
|
||||
|
||||
case UV_FS_EVENT:
|
||||
uv__fs_event_endgame(loop, (uv_fs_event_t*) handle);
|
||||
break;
|
||||
|
||||
case UV_FS_POLL:
|
||||
uv__fs_poll_endgame(loop, (uv_fs_poll_t*) handle);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int uv_run(uv_loop_t *loop, uv_run_mode mode) {
|
||||
DWORD timeout;
|
||||
int r;
|
||||
@@ -681,3 +854,26 @@ int uv__getsockpeername(const uv_handle_t* handle,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uv__insert_pending_req(uv_loop_t* loop, uv_req_t* req) {
|
||||
req->next_req = NULL;
|
||||
if (loop->pending_reqs_tail) {
|
||||
#ifdef _DEBUG
|
||||
/* Ensure the request is not already in the queue, or the queue
|
||||
* will get corrupted.
|
||||
*/
|
||||
uv_req_t* current = loop->pending_reqs_tail;
|
||||
do {
|
||||
assert(req != current);
|
||||
current = current->next_req;
|
||||
} while (current != loop->pending_reqs_tail);
|
||||
#endif
|
||||
|
||||
req->next_req = loop->pending_reqs_tail->next_req;
|
||||
loop->pending_reqs_tail->next_req = req;
|
||||
loop->pending_reqs_tail = req;
|
||||
} else {
|
||||
req->next_req = req;
|
||||
loop->pending_reqs_tail = req;
|
||||
}
|
||||
}
|
||||
Vendored
+59
-49
@@ -158,14 +158,14 @@ int uv_fs_event_start(uv_fs_event_t* handle,
|
||||
const char* path,
|
||||
unsigned int flags) {
|
||||
int is_path_dir;
|
||||
size_t size;
|
||||
DWORD attr, last_error;
|
||||
WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL;
|
||||
DWORD last_error;
|
||||
WCHAR* dir, *pathw = NULL;
|
||||
DWORD short_path_buffer_len;
|
||||
WCHAR *short_path_buffer;
|
||||
WCHAR* short_path, *long_path;
|
||||
WCHAR* short_path = NULL;
|
||||
HANDLE file_handle = INVALID_HANDLE_VALUE;
|
||||
BY_HANDLE_FILE_INFORMATION info;
|
||||
|
||||
short_path = NULL;
|
||||
if (uv__is_active(handle))
|
||||
return UV_EINVAL;
|
||||
|
||||
@@ -181,43 +181,26 @@ int uv_fs_event_start(uv_fs_event_t* handle,
|
||||
if (last_error)
|
||||
goto error_uv;
|
||||
|
||||
/* Determine whether path is a file or a directory. */
|
||||
attr = GetFileAttributesW(pathw);
|
||||
if (attr == INVALID_FILE_ATTRIBUTES) {
|
||||
file_handle = CreateFileW(pathw,
|
||||
FILE_LIST_DIRECTORY,
|
||||
FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED,
|
||||
NULL);
|
||||
if (file_handle == INVALID_HANDLE_VALUE) {
|
||||
last_error = GetLastError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
is_path_dir = (attr & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0;
|
||||
if (!GetFileInformationByHandle(file_handle, &info)) {
|
||||
last_error = GetLastError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (is_path_dir) {
|
||||
/* path is a directory, so that's the directory that we will watch. */
|
||||
is_path_dir = (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0;
|
||||
|
||||
/* Convert to long path. */
|
||||
size = GetLongPathNameW(pathw, NULL, 0);
|
||||
|
||||
if (size) {
|
||||
long_path = (WCHAR*)uv__malloc(size * sizeof(WCHAR));
|
||||
if (!long_path) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
|
||||
}
|
||||
|
||||
size = GetLongPathNameW(pathw, long_path, size);
|
||||
if (size) {
|
||||
long_path[size] = '\0';
|
||||
} else {
|
||||
uv__free(long_path);
|
||||
long_path = NULL;
|
||||
}
|
||||
|
||||
if (long_path) {
|
||||
uv__free(pathw);
|
||||
pathw = long_path;
|
||||
}
|
||||
}
|
||||
|
||||
dir_to_watch = pathw;
|
||||
} else {
|
||||
if (!is_path_dir) {
|
||||
/*
|
||||
* path is a file. So we split path into dir & file parts, and
|
||||
* watch the dir directory.
|
||||
@@ -252,28 +235,50 @@ short_path_done:
|
||||
goto error;
|
||||
}
|
||||
|
||||
dir_to_watch = dir;
|
||||
uv__free(short_path);
|
||||
short_path = NULL;
|
||||
uv__free(pathw);
|
||||
pathw = NULL;
|
||||
}
|
||||
|
||||
handle->dir_handle = CreateFileW(dir_to_watch,
|
||||
FILE_LIST_DIRECTORY,
|
||||
FILE_SHARE_READ | FILE_SHARE_DELETE |
|
||||
FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS |
|
||||
FILE_FLAG_OVERLAPPED,
|
||||
NULL);
|
||||
|
||||
if (dir) {
|
||||
/* Open the containing directory and watch that instead. Events for
|
||||
* other files are filtered out in uv__process_fs_event_req().
|
||||
* Not super efficient but c'est ça.
|
||||
*/
|
||||
CloseHandle(file_handle);
|
||||
file_handle = CreateFileW(dir,
|
||||
FILE_LIST_DIRECTORY,
|
||||
FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED,
|
||||
NULL);
|
||||
uv__free(dir);
|
||||
dir = NULL;
|
||||
if (file_handle == INVALID_HANDLE_VALUE) {
|
||||
last_error = GetLastError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!GetFileInformationByHandle(file_handle, &info)) {
|
||||
last_error = GetLastError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Race with another process: directory foo in foo/bar was replaced
|
||||
* with a file. Bail out with an error, we're not recursing upwards.
|
||||
*/
|
||||
if (!(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
/* TODO(bnoordhuis) ERROR_DIRECTORY is translated to UV_ENOENT,
|
||||
* there's currently nothing that maps to UV_ENOTDIR.
|
||||
*/
|
||||
last_error = ERROR_DIRECTORY;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
handle->dir_handle = file_handle;
|
||||
file_handle = INVALID_HANDLE_VALUE;
|
||||
|
||||
if (handle->dir_handle == INVALID_HANDLE_VALUE) {
|
||||
last_error = GetLastError();
|
||||
goto error;
|
||||
@@ -325,6 +330,11 @@ error:
|
||||
last_error = uv_translate_sys_error(last_error);
|
||||
|
||||
error_uv:
|
||||
if (file_handle != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(file_handle);
|
||||
file_handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (handle->path) {
|
||||
uv__free(handle->path);
|
||||
handle->path = NULL;
|
||||
|
||||
Vendored
+7
-8
@@ -69,11 +69,11 @@ struct uv__fd_hash_bucket_s {
|
||||
static uv_mutex_t uv__fd_hash_mutex;
|
||||
|
||||
static struct uv__fd_hash_entry_group_s
|
||||
uv__fd_hash_entry_initial[UV__FD_HASH_SIZE * UV__FD_HASH_GROUP_SIZE];
|
||||
uv__fd_hash_entry_initial[UV__FD_HASH_SIZE];
|
||||
static struct uv__fd_hash_bucket_s uv__fd_hash[UV__FD_HASH_SIZE];
|
||||
|
||||
|
||||
INLINE static void uv__fd_hash_init(void) {
|
||||
static void uv__fd_hash_init(void) {
|
||||
size_t i;
|
||||
int err;
|
||||
|
||||
@@ -82,10 +82,9 @@ INLINE static void uv__fd_hash_init(void) {
|
||||
uv_fatal_error(err, "uv_mutex_init");
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(uv__fd_hash); ++i) {
|
||||
for (i = 0; i < ARRAY_SIZE(uv__fd_hash); i++) {
|
||||
uv__fd_hash[i].size = 0;
|
||||
uv__fd_hash[i].data =
|
||||
uv__fd_hash_entry_initial + i * UV__FD_HASH_GROUP_SIZE;
|
||||
uv__fd_hash[i].data = &uv__fd_hash_entry_initial[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,7 +118,7 @@ INLINE static void uv__fd_hash_init(void) {
|
||||
FIND_IN_GROUP_PTR(UV__FD_HASH_GROUP_SIZE); \
|
||||
} while (0)
|
||||
|
||||
INLINE static int uv__fd_hash_get(int fd, struct uv__fd_info_s* info) {
|
||||
static int uv__fd_hash_get(int fd, struct uv__fd_info_s* info) {
|
||||
FIND_COMMON_VARIABLES
|
||||
|
||||
uv_mutex_lock(&uv__fd_hash_mutex);
|
||||
@@ -134,7 +133,7 @@ INLINE static int uv__fd_hash_get(int fd, struct uv__fd_info_s* info) {
|
||||
return entry_ptr != NULL;
|
||||
}
|
||||
|
||||
INLINE static void uv__fd_hash_add(int fd, struct uv__fd_info_s* info) {
|
||||
static void uv__fd_hash_add(int fd, struct uv__fd_info_s* info) {
|
||||
FIND_COMMON_VARIABLES
|
||||
|
||||
uv_mutex_lock(&uv__fd_hash_mutex);
|
||||
@@ -164,7 +163,7 @@ INLINE static void uv__fd_hash_add(int fd, struct uv__fd_info_s* info) {
|
||||
uv_mutex_unlock(&uv__fd_hash_mutex);
|
||||
}
|
||||
|
||||
INLINE static int uv__fd_hash_remove(int fd, struct uv__fd_info_s* info) {
|
||||
static int uv__fd_hash_remove(int fd, struct uv__fd_info_s* info) {
|
||||
FIND_COMMON_VARIABLES
|
||||
|
||||
uv_mutex_lock(&uv__fd_hash_mutex);
|
||||
|
||||
Vendored
+141
-104
@@ -167,9 +167,10 @@ typedef enum {
|
||||
FS__STAT_PATH_TRY_SLOW
|
||||
} fs__stat_path_return_t;
|
||||
|
||||
INLINE static void fs__stat_assign_statbuf_null(uv_stat_t* statbuf);
|
||||
INLINE static void fs__stat_assign_statbuf(uv_stat_t* statbuf,
|
||||
FILE_STAT_BASIC_INFORMATION stat_info, int do_lstat);
|
||||
static void fs__stat_assign_statbuf_null(uv_stat_t* statbuf);
|
||||
static void fs__stat_assign_statbuf(uv_stat_t* statbuf,
|
||||
FILE_STAT_BASIC_INFORMATION stat_info,
|
||||
int do_lstat);
|
||||
|
||||
|
||||
void uv__fs_init(void) {
|
||||
@@ -182,9 +183,9 @@ void uv__fs_init(void) {
|
||||
}
|
||||
|
||||
|
||||
INLINE static int fs__readlink_handle(HANDLE handle,
|
||||
char** target_ptr,
|
||||
size_t* target_len_ptr) {
|
||||
static int fs__readlink_handle(HANDLE handle,
|
||||
char** target_ptr,
|
||||
size_t* target_len_ptr) {
|
||||
char buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
|
||||
REPARSE_DATA_BUFFER* reparse_data = (REPARSE_DATA_BUFFER*) buffer;
|
||||
WCHAR* w_target;
|
||||
@@ -246,6 +247,32 @@ INLINE static int fs__readlink_handle(HANDLE handle,
|
||||
}
|
||||
}
|
||||
|
||||
} else if (reparse_data->ReparseTag == IO_REPARSE_TAG_LX_SYMLINK) {
|
||||
/* Real (Linux) symlink */
|
||||
char* buffer;
|
||||
char* target;
|
||||
size_t target_len;
|
||||
|
||||
target_len = (reparse_data->ReparseDataLength -
|
||||
sizeof(ULONG)); /* Version field */
|
||||
buffer = (char*) reparse_data->LinuxSymbolicLinkReparseBuffer.PathBuffer;
|
||||
|
||||
if (target_len_ptr != NULL) {
|
||||
*target_len_ptr = target_len;
|
||||
}
|
||||
|
||||
if (target_ptr != NULL) {
|
||||
assert(*target_ptr == NULL);
|
||||
target = uv__malloc(target_len + 1);
|
||||
if (target == NULL) {
|
||||
return UV_ENOMEM;
|
||||
}
|
||||
memcpy(target, buffer, target_len);
|
||||
target[target_len] = '\0';
|
||||
*target_ptr = target;
|
||||
}
|
||||
return 0;
|
||||
|
||||
} else if (reparse_data->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) {
|
||||
/* Junction. */
|
||||
w_target = reparse_data->MountPointReparseBuffer.PathBuffer +
|
||||
@@ -319,8 +346,10 @@ INLINE static int fs__readlink_handle(HANDLE handle,
|
||||
}
|
||||
|
||||
|
||||
INLINE static int fs__capture_path(uv_fs_t* req, const char* path,
|
||||
const char* new_path, const int copy_path) {
|
||||
static int fs__capture_path(uv_fs_t* req,
|
||||
const char* path,
|
||||
const char* new_path,
|
||||
const int copy_path) {
|
||||
WCHAR* buf;
|
||||
WCHAR* pos;
|
||||
size_t buf_sz = 0;
|
||||
@@ -394,8 +423,10 @@ INLINE static int fs__capture_path(uv_fs_t* req, const char* path,
|
||||
}
|
||||
|
||||
|
||||
INLINE static void uv__fs_req_init(uv_loop_t* loop, uv_fs_t* req,
|
||||
uv_fs_type fs_type, const uv_fs_cb cb) {
|
||||
static void uv__fs_req_init(uv_loop_t* loop,
|
||||
uv_fs_t* req,
|
||||
uv_fs_type fs_type,
|
||||
const uv_fs_cb cb) {
|
||||
uv__once_init();
|
||||
UV_REQ_INIT(req, UV_FS);
|
||||
req->loop = loop;
|
||||
@@ -1099,7 +1130,7 @@ void fs__write(uv_fs_t* req) {
|
||||
static void fs__unlink_rmdir(uv_fs_t* req, BOOL isrmdir) {
|
||||
const WCHAR* pathw = req->file.pathw;
|
||||
HANDLE handle;
|
||||
BY_HANDLE_FILE_INFORMATION info;
|
||||
FILE_BASIC_INFO info;
|
||||
FILE_DISPOSITION_INFORMATION disposition;
|
||||
FILE_DISPOSITION_INFORMATION_EX disposition_ex;
|
||||
IO_STATUS_BLOCK iosb;
|
||||
@@ -1107,7 +1138,7 @@ static void fs__unlink_rmdir(uv_fs_t* req, BOOL isrmdir) {
|
||||
DWORD error;
|
||||
|
||||
handle = CreateFileW(pathw,
|
||||
FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | DELETE,
|
||||
FILE_READ_ATTRIBUTES | DELETE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
@@ -1119,13 +1150,13 @@ static void fs__unlink_rmdir(uv_fs_t* req, BOOL isrmdir) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GetFileInformationByHandle(handle, &info)) {
|
||||
if (!GetFileInformationByHandleEx(handle, FileBasicInfo, &info, sizeof info)) {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
CloseHandle(handle);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isrmdir && !(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
if (isrmdir && !(info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
/* Error if we're in rmdir mode but it is not a dir.
|
||||
* TODO: change it to UV_NOTDIR in v2. */
|
||||
SET_REQ_UV_ERROR(req, UV_ENOENT, ERROR_DIRECTORY);
|
||||
@@ -1133,13 +1164,13 @@ static void fs__unlink_rmdir(uv_fs_t* req, BOOL isrmdir) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isrmdir && (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
if (!isrmdir && (info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
/* If not explicitly allowed, do not allow deletion of directories, unless
|
||||
* it is a symlink. When the path refers to a non-symlink directory, report
|
||||
* EPERM as mandated by POSIX.1. */
|
||||
|
||||
/* Check if it is a reparse point. If it's not, it's a normal directory. */
|
||||
if (!(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
|
||||
if (!(info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
|
||||
SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED);
|
||||
CloseHandle(handle);
|
||||
return;
|
||||
@@ -1178,18 +1209,37 @@ static void fs__unlink_rmdir(uv_fs_t* req, BOOL isrmdir) {
|
||||
error == ERROR_INVALID_PARAMETER /* pre Windows 10 error */ ||
|
||||
error == ERROR_INVALID_FUNCTION /* pre Windows 10 1607 error */) {
|
||||
/* posix delete not supported so try fallback */
|
||||
if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
|
||||
if (info.FileAttributes & FILE_ATTRIBUTE_READONLY) {
|
||||
/* Remove read-only attribute */
|
||||
FILE_BASIC_INFORMATION basic = { 0 };
|
||||
|
||||
basic.FileAttributes = (info.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY) |
|
||||
/* We opened the handle above without FILE_WRITE_ATTRIBUTES access, which
|
||||
* is not required in the happy path. On windows, it would probably
|
||||
* be ok to ask for them anyway, but Wine has a bug that causes such calls
|
||||
* to fail (https://bugs.winehq.org/show_bug.cgi?id=50771). To work around
|
||||
* this bug, we re-open the handle here */
|
||||
HANDLE write_attributes_handle;
|
||||
|
||||
basic.FileAttributes = (info.FileAttributes & ~FILE_ATTRIBUTE_READONLY) |
|
||||
FILE_ATTRIBUTE_ARCHIVE;
|
||||
|
||||
status = pNtSetInformationFile(handle,
|
||||
write_attributes_handle = ReOpenFile(handle, FILE_WRITE_ATTRIBUTES,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE |
|
||||
FILE_SHARE_DELETE,
|
||||
FILE_FLAG_OPEN_REPARSE_POINT |
|
||||
FILE_FLAG_BACKUP_SEMANTICS);
|
||||
if (write_attributes_handle == INVALID_HANDLE_VALUE) {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
CloseHandle(handle);
|
||||
return;
|
||||
}
|
||||
|
||||
status = pNtSetInformationFile(write_attributes_handle,
|
||||
&iosb,
|
||||
&basic,
|
||||
sizeof basic,
|
||||
FileBasicInformation);
|
||||
CloseHandle(write_attributes_handle);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status));
|
||||
CloseHandle(handle);
|
||||
@@ -1264,7 +1314,7 @@ void fs__mktemp(uv_fs_t* req, uv__fs_mktemp_func func) {
|
||||
|
||||
tries = TMP_MAX;
|
||||
do {
|
||||
if (uv__random_rtlgenrandom((void *)&v, sizeof(v)) < 0) {
|
||||
if (uv__random_winrandom(&v, sizeof(v)) < 0) {
|
||||
SET_REQ_UV_ERROR(req, UV_EIO, ERROR_IO_DEVICE);
|
||||
goto clobber;
|
||||
}
|
||||
@@ -1638,6 +1688,21 @@ void fs__readdir(uv_fs_t* req) {
|
||||
dir = req->ptr;
|
||||
dirents = dir->dirents;
|
||||
memset(dirents, 0, dir->nentries * sizeof(*dir->dirents));
|
||||
|
||||
/* Initial FindFirstFile can fail with ERROR_FILE_NOT_FOUND, meaning
|
||||
* no matches, which leaves dir_handle set to INVALID_HANDLE_VALUE,
|
||||
* see fs__opendir(). Not an actual error, just means no results.
|
||||
*
|
||||
* sshfs-win apparently works that way but reading an empty directory
|
||||
* on a regular drive doesn't trigger that particular code path.
|
||||
*
|
||||
* See https://github.com/libuv/libuv/issues/4952
|
||||
*/
|
||||
if (dir->dir_handle == INVALID_HANDLE_VALUE) {
|
||||
SET_REQ_RESULT(req, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
find_data = &dir->find_data;
|
||||
dirent_idx = 0;
|
||||
|
||||
@@ -1698,8 +1763,9 @@ void fs__closedir(uv_fs_t* req) {
|
||||
SET_REQ_RESULT(req, 0);
|
||||
}
|
||||
|
||||
INLINE static fs__stat_path_return_t fs__stat_path(WCHAR* path,
|
||||
uv_stat_t* statbuf, int do_lstat) {
|
||||
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. */
|
||||
@@ -1735,8 +1801,7 @@ INLINE static fs__stat_path_return_t fs__stat_path(WCHAR* path,
|
||||
return FS__STAT_PATH_SUCCESS;
|
||||
}
|
||||
|
||||
INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf,
|
||||
int do_lstat) {
|
||||
static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf, int do_lstat) {
|
||||
size_t target_length = 0;
|
||||
FILE_FS_DEVICE_INFORMATION device_info;
|
||||
FILE_ALL_INFORMATION file_info;
|
||||
@@ -1827,7 +1892,7 @@ INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf,
|
||||
return 0;
|
||||
}
|
||||
|
||||
INLINE static void fs__stat_assign_statbuf_null(uv_stat_t* statbuf) {
|
||||
static void fs__stat_assign_statbuf_null(uv_stat_t* statbuf) {
|
||||
memset(statbuf, 0, sizeof(uv_stat_t));
|
||||
statbuf->st_mode = _S_IFCHR;
|
||||
statbuf->st_mode |= (_S_IREAD | _S_IWRITE) | ((_S_IREAD | _S_IWRITE) >> 3) |
|
||||
@@ -1837,8 +1902,9 @@ INLINE static void fs__stat_assign_statbuf_null(uv_stat_t* statbuf) {
|
||||
statbuf->st_rdev = FILE_DEVICE_NULL << 16;
|
||||
}
|
||||
|
||||
INLINE static void fs__stat_assign_statbuf(uv_stat_t* statbuf,
|
||||
FILE_STAT_BASIC_INFORMATION stat_info, int do_lstat) {
|
||||
static void fs__stat_assign_statbuf(uv_stat_t* statbuf,
|
||||
FILE_STAT_BASIC_INFORMATION stat_info,
|
||||
int do_lstat) {
|
||||
statbuf->st_dev = stat_info.VolumeSerialNumber.LowPart;
|
||||
|
||||
/* Todo: st_mode should probably always be 0666 for everyone. We might also
|
||||
@@ -1943,18 +2009,19 @@ INLINE static void fs__stat_assign_statbuf(uv_stat_t* statbuf,
|
||||
}
|
||||
|
||||
|
||||
INLINE static void fs__stat_prepare_path(WCHAR* pathw) {
|
||||
static void fs__stat_prepare_path(WCHAR* pathw) {
|
||||
size_t len = wcslen(pathw);
|
||||
|
||||
/* TODO: ignore namespaced paths. */
|
||||
if (len > 1 && pathw[len - 2] != L':' &&
|
||||
(pathw[len - 1] == L'\\' || pathw[len - 1] == L'/')) {
|
||||
pathw[len - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
INLINE static DWORD fs__stat_directory(WCHAR* path, uv_stat_t* statbuf,
|
||||
int do_lstat, DWORD ret_error) {
|
||||
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;
|
||||
@@ -2127,9 +2194,9 @@ cleanup:
|
||||
return ret_error;
|
||||
}
|
||||
|
||||
INLINE static DWORD fs__stat_impl_from_path(WCHAR* path,
|
||||
int do_lstat,
|
||||
uv_stat_t* statbuf) {
|
||||
static DWORD fs__stat_impl_from_path(WCHAR* path,
|
||||
int do_lstat,
|
||||
uv_stat_t* statbuf) {
|
||||
HANDLE handle;
|
||||
DWORD flags;
|
||||
DWORD ret;
|
||||
@@ -2174,7 +2241,7 @@ INLINE static DWORD fs__stat_impl_from_path(WCHAR* path,
|
||||
}
|
||||
|
||||
|
||||
INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) {
|
||||
static void fs__stat_impl(uv_fs_t* req, int do_lstat) {
|
||||
DWORD error;
|
||||
|
||||
error = fs__stat_impl_from_path(req->file.pathw, do_lstat, &req->statbuf);
|
||||
@@ -2197,7 +2264,7 @@ INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) {
|
||||
}
|
||||
|
||||
|
||||
INLINE static int fs__fstat_handle(int fd, HANDLE handle, uv_stat_t* statbuf) {
|
||||
static int fs__fstat_handle(int fd, HANDLE handle, uv_stat_t* statbuf) {
|
||||
DWORD file_type;
|
||||
|
||||
/* Each file type is processed differently. */
|
||||
@@ -2273,7 +2340,7 @@ static void fs__rename(uv_fs_t* req) {
|
||||
}
|
||||
|
||||
|
||||
INLINE static void fs__sync_impl(uv_fs_t* req) {
|
||||
static void fs__sync_impl(uv_fs_t* req) {
|
||||
int fd = req->file.fd;
|
||||
int result;
|
||||
|
||||
@@ -2579,7 +2646,7 @@ fchmod_cleanup:
|
||||
}
|
||||
|
||||
|
||||
INLINE static int fs__utime_handle(HANDLE handle, double atime, double mtime) {
|
||||
static int fs__utime_handle(HANDLE handle, double atime, double mtime) {
|
||||
FILETIME filetime_as, *filetime_a = &filetime_as;
|
||||
FILETIME filetime_ms, *filetime_m = &filetime_ms;
|
||||
FILETIME now;
|
||||
@@ -2607,10 +2674,10 @@ INLINE static int fs__utime_handle(HANDLE handle, double atime, double mtime) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
INLINE static DWORD fs__utime_impl_from_path(WCHAR* path,
|
||||
double atime,
|
||||
double mtime,
|
||||
int do_lutime) {
|
||||
static DWORD fs__utime_impl_from_path(WCHAR* path,
|
||||
double atime,
|
||||
double mtime,
|
||||
int do_lutime) {
|
||||
HANDLE handle;
|
||||
DWORD flags;
|
||||
DWORD ret;
|
||||
@@ -2640,7 +2707,7 @@ INLINE static DWORD fs__utime_impl_from_path(WCHAR* path,
|
||||
return ret;
|
||||
}
|
||||
|
||||
INLINE static void fs__utime_impl(uv_fs_t* req, int do_lutime) {
|
||||
static void fs__utime_impl(uv_fs_t* req, int do_lutime) {
|
||||
DWORD error;
|
||||
|
||||
error = fs__utime_impl_from_path(req->file.pathw,
|
||||
@@ -3042,67 +3109,35 @@ static void fs__lchown(uv_fs_t* req) {
|
||||
|
||||
|
||||
static void fs__statfs(uv_fs_t* req) {
|
||||
FILE_FS_FULL_SIZE_INFORMATION info;
|
||||
IO_STATUS_BLOCK io_status;
|
||||
uv_statfs_t* stat_fs;
|
||||
DWORD sectors_per_cluster;
|
||||
DWORD bytes_per_sector;
|
||||
DWORD free_clusters;
|
||||
DWORD total_clusters;
|
||||
WCHAR* pathw;
|
||||
NTSTATUS nt_status;
|
||||
HANDLE handle;
|
||||
|
||||
pathw = req->file.pathw;
|
||||
retry_get_disk_free_space:
|
||||
if (0 == GetDiskFreeSpaceW(pathw,
|
||||
§ors_per_cluster,
|
||||
&bytes_per_sector,
|
||||
&free_clusters,
|
||||
&total_clusters)) {
|
||||
DWORD err;
|
||||
WCHAR* fpart;
|
||||
size_t len;
|
||||
DWORD ret;
|
||||
BOOL is_second;
|
||||
handle = CreateFileW(req->file.pathw,
|
||||
FILE_READ_ATTRIBUTES,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS,
|
||||
NULL);
|
||||
|
||||
err = GetLastError();
|
||||
is_second = pathw != req->file.pathw;
|
||||
if (err != ERROR_DIRECTORY || is_second) {
|
||||
if (is_second)
|
||||
uv__free(pathw);
|
||||
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return;
|
||||
}
|
||||
|
||||
len = MAX_PATH + 1;
|
||||
pathw = uv__malloc(len * sizeof(*pathw));
|
||||
if (pathw == NULL) {
|
||||
SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
|
||||
return;
|
||||
}
|
||||
retry_get_full_path_name:
|
||||
ret = GetFullPathNameW(req->file.pathw,
|
||||
len,
|
||||
pathw,
|
||||
&fpart);
|
||||
if (ret == 0) {
|
||||
uv__free(pathw);
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return;
|
||||
} else if (ret > len) {
|
||||
len = ret;
|
||||
pathw = uv__reallocf(pathw, len * sizeof(*pathw));
|
||||
if (pathw == NULL) {
|
||||
SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
|
||||
return;
|
||||
}
|
||||
goto retry_get_full_path_name;
|
||||
}
|
||||
if (fpart != 0)
|
||||
*fpart = L'\0';
|
||||
|
||||
goto retry_get_disk_free_space;
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
return;
|
||||
}
|
||||
if (pathw != req->file.pathw) {
|
||||
uv__free(pathw);
|
||||
|
||||
nt_status = pNtQueryVolumeInformationFile(handle,
|
||||
&io_status,
|
||||
&info,
|
||||
sizeof info,
|
||||
FileFsFullSizeInformation);
|
||||
CloseHandle(handle);
|
||||
|
||||
if (NT_ERROR(nt_status)) {
|
||||
SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status));
|
||||
return;
|
||||
}
|
||||
|
||||
stat_fs = uv__malloc(sizeof(*stat_fs));
|
||||
@@ -3112,10 +3147,12 @@ retry_get_full_path_name:
|
||||
}
|
||||
|
||||
stat_fs->f_type = 0;
|
||||
stat_fs->f_bsize = bytes_per_sector * sectors_per_cluster;
|
||||
stat_fs->f_blocks = total_clusters;
|
||||
stat_fs->f_bfree = free_clusters;
|
||||
stat_fs->f_bavail = free_clusters;
|
||||
stat_fs->f_bsize = (uint64_t)info.SectorsPerAllocationUnit *
|
||||
info.BytesPerSector;
|
||||
stat_fs->f_frsize = stat_fs->f_bsize;
|
||||
stat_fs->f_blocks = info.TotalAllocationUnits.QuadPart;
|
||||
stat_fs->f_bfree = info.ActualAvailableAllocationUnits.QuadPart;
|
||||
stat_fs->f_bavail = info.CallerAvailableAllocationUnits.QuadPart;
|
||||
stat_fs->f_files = 0;
|
||||
stat_fs->f_ffree = 0;
|
||||
req->ptr = stat_fs;
|
||||
|
||||
Vendored
+12
-7
@@ -208,7 +208,8 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) {
|
||||
}
|
||||
|
||||
complete:
|
||||
uv__req_unregister(req->loop);
|
||||
if (req->loop != NULL)
|
||||
uv__req_unregister(req->loop);
|
||||
|
||||
/* finally do callback with converted result */
|
||||
if (req->getaddrinfo_cb)
|
||||
@@ -239,7 +240,7 @@ void uv_freeaddrinfo(struct addrinfo* ai) {
|
||||
*/
|
||||
int uv_getaddrinfo(uv_loop_t* loop,
|
||||
uv_getaddrinfo_t* req,
|
||||
uv_getaddrinfo_cb getaddrinfo_cb,
|
||||
uv_getaddrinfo_cb cb,
|
||||
const char* node,
|
||||
const char* service,
|
||||
const struct addrinfo* hints) {
|
||||
@@ -252,12 +253,15 @@ int uv_getaddrinfo(uv_loop_t* loop,
|
||||
size_t hintoff = 0;
|
||||
ssize_t rc;
|
||||
|
||||
if (req == NULL || (node == NULL && service == NULL)) {
|
||||
if (req == NULL || (node == NULL && service == NULL))
|
||||
return UV_EINVAL;
|
||||
}
|
||||
if (loop == NULL && cb != NULL)
|
||||
return UV_EINVAL;
|
||||
|
||||
uv__once_init();
|
||||
|
||||
UV_REQ_INIT(req, UV_GETADDRINFO);
|
||||
req->getaddrinfo_cb = getaddrinfo_cb;
|
||||
req->getaddrinfo_cb = cb;
|
||||
req->addrinfo = NULL;
|
||||
req->loop = loop;
|
||||
req->retcode = 0;
|
||||
@@ -330,9 +334,10 @@ int uv_getaddrinfo(uv_loop_t* loop,
|
||||
req->addrinfow = NULL;
|
||||
}
|
||||
|
||||
uv__req_register(loop);
|
||||
if (loop != NULL)
|
||||
uv__req_register(loop);
|
||||
|
||||
if (getaddrinfo_cb) {
|
||||
if (cb) {
|
||||
uv__work_submit(loop,
|
||||
&req->work_req,
|
||||
UV__WORK_SLOW_IO,
|
||||
|
||||
Vendored
-68
@@ -95,74 +95,6 @@ INLINE static void uv__want_endgame(uv_loop_t* loop, uv_handle_t* handle) {
|
||||
}
|
||||
|
||||
|
||||
INLINE static void uv__process_endgames(uv_loop_t* loop) {
|
||||
uv_handle_t* handle;
|
||||
|
||||
while (loop->endgame_handles) {
|
||||
handle = loop->endgame_handles;
|
||||
loop->endgame_handles = handle->endgame_next;
|
||||
|
||||
handle->flags &= ~UV_HANDLE_ENDGAME_QUEUED;
|
||||
|
||||
switch (handle->type) {
|
||||
case UV_TCP:
|
||||
uv__tcp_endgame(loop, (uv_tcp_t*) handle);
|
||||
break;
|
||||
|
||||
case UV_NAMED_PIPE:
|
||||
uv__pipe_endgame(loop, (uv_pipe_t*) handle);
|
||||
break;
|
||||
|
||||
case UV_TTY:
|
||||
uv__tty_endgame(loop, (uv_tty_t*) handle);
|
||||
break;
|
||||
|
||||
case UV_UDP:
|
||||
uv__udp_endgame(loop, (uv_udp_t*) handle);
|
||||
break;
|
||||
|
||||
case UV_POLL:
|
||||
uv__poll_endgame(loop, (uv_poll_t*) handle);
|
||||
break;
|
||||
|
||||
case UV_TIMER:
|
||||
uv__timer_close((uv_timer_t*) handle);
|
||||
uv__handle_close(handle);
|
||||
break;
|
||||
|
||||
case UV_PREPARE:
|
||||
case UV_CHECK:
|
||||
case UV_IDLE:
|
||||
uv__loop_watcher_endgame(loop, handle);
|
||||
break;
|
||||
|
||||
case UV_ASYNC:
|
||||
uv__async_endgame(loop, (uv_async_t*) handle);
|
||||
break;
|
||||
|
||||
case UV_SIGNAL:
|
||||
uv__signal_endgame(loop, (uv_signal_t*) handle);
|
||||
break;
|
||||
|
||||
case UV_PROCESS:
|
||||
uv__process_endgame(loop, (uv_process_t*) handle);
|
||||
break;
|
||||
|
||||
case UV_FS_EVENT:
|
||||
uv__fs_event_endgame(loop, (uv_fs_event_t*) handle);
|
||||
break;
|
||||
|
||||
case UV_FS_POLL:
|
||||
uv__fs_poll_endgame(loop, (uv_fs_poll_t*) handle);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INLINE static HANDLE uv__get_osfhandle(int fd)
|
||||
{
|
||||
/* _get_osfhandle() raises an assert in debug builds if the FD is invalid.
|
||||
|
||||
Vendored
+1
-1
@@ -269,7 +269,7 @@ int uv__getsockpeername(const uv_handle_t* handle,
|
||||
int* namelen,
|
||||
int delayed_error);
|
||||
|
||||
int uv__random_rtlgenrandom(void* buf, size_t buflen);
|
||||
int uv__random_winrandom(void* buf, size_t buflen);
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Vendored
+2
-1
@@ -2149,7 +2149,8 @@ void uv__process_pipe_read_req(uv_loop_t* loop,
|
||||
} else {
|
||||
/* The zero-read completed without error, indicating there is data
|
||||
* available in the kernel buffer. */
|
||||
while (handle->flags & UV_HANDLE_READING) {
|
||||
while (handle->flags & UV_HANDLE_READING &&
|
||||
!(handle->flags & UV_HANDLE_READ_PENDING)) {
|
||||
bytes_requested = 65536;
|
||||
/* Depending on the type of pipe, read either IPC frames or raw data. */
|
||||
if (handle->ipc)
|
||||
|
||||
Vendored
+1
-5
@@ -211,15 +211,11 @@ static SOCKET uv__fast_poll_create_peer_socket(HANDLE iocp,
|
||||
protocol_info->iProtocol,
|
||||
protocol_info,
|
||||
0,
|
||||
WSA_FLAG_OVERLAPPED);
|
||||
WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT);
|
||||
if (sock == INVALID_SOCKET) {
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
if (!SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)) {
|
||||
goto error;
|
||||
};
|
||||
|
||||
if (CreateIoCompletionPort((HANDLE) sock,
|
||||
iocp,
|
||||
(ULONG_PTR) sock,
|
||||
|
||||
Vendored
+2
-2
@@ -1220,7 +1220,7 @@ static int uv__kill(HANDLE process_handle, int signum) {
|
||||
NULL,
|
||||
&localappdata);
|
||||
_snwprintf_s(dump_folder,
|
||||
sizeof(dump_folder),
|
||||
ARRAY_SIZE(dump_folder),
|
||||
_TRUNCATE,
|
||||
L"%ls\\CrashDumps",
|
||||
localappdata);
|
||||
@@ -1233,7 +1233,7 @@ static int uv__kill(HANDLE process_handle, int signum) {
|
||||
|
||||
/* Construct dump filename from process name and PID. */
|
||||
_snwprintf_s(dump_name,
|
||||
sizeof(dump_name),
|
||||
ARRAY_SIZE(dump_name),
|
||||
_TRUNCATE,
|
||||
L"%ls\\%ls.%d.dmp",
|
||||
dump_folder,
|
||||
|
||||
Vendored
+1
-129
@@ -81,134 +81,6 @@
|
||||
uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); \
|
||||
}
|
||||
|
||||
|
||||
INLINE static uv_req_t* uv__overlapped_to_req(OVERLAPPED* overlapped) {
|
||||
return container_of(overlapped, uv_req_t, u.io.overlapped);
|
||||
}
|
||||
|
||||
|
||||
INLINE static void uv__insert_pending_req(uv_loop_t* loop, uv_req_t* req) {
|
||||
req->next_req = NULL;
|
||||
if (loop->pending_reqs_tail) {
|
||||
#ifdef _DEBUG
|
||||
/* Ensure the request is not already in the queue, or the queue
|
||||
* will get corrupted.
|
||||
*/
|
||||
uv_req_t* current = loop->pending_reqs_tail;
|
||||
do {
|
||||
assert(req != current);
|
||||
current = current->next_req;
|
||||
} while(current != loop->pending_reqs_tail);
|
||||
#endif
|
||||
|
||||
req->next_req = loop->pending_reqs_tail->next_req;
|
||||
loop->pending_reqs_tail->next_req = req;
|
||||
loop->pending_reqs_tail = req;
|
||||
} else {
|
||||
req->next_req = req;
|
||||
loop->pending_reqs_tail = req;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define DELEGATE_STREAM_REQ(loop, req, method, handle_at) \
|
||||
do { \
|
||||
switch (((uv_handle_t*) (req)->handle_at)->type) { \
|
||||
case UV_TCP: \
|
||||
uv__process_tcp_##method##_req(loop, \
|
||||
(uv_tcp_t*) ((req)->handle_at), \
|
||||
req); \
|
||||
break; \
|
||||
\
|
||||
case UV_NAMED_PIPE: \
|
||||
uv__process_pipe_##method##_req(loop, \
|
||||
(uv_pipe_t*) ((req)->handle_at), \
|
||||
req); \
|
||||
break; \
|
||||
\
|
||||
case UV_TTY: \
|
||||
uv__process_tty_##method##_req(loop, \
|
||||
(uv_tty_t*) ((req)->handle_at), \
|
||||
req); \
|
||||
break; \
|
||||
\
|
||||
default: \
|
||||
assert(0); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
INLINE static void uv__process_reqs(uv_loop_t* loop) {
|
||||
uv_req_t* req;
|
||||
uv_req_t* first;
|
||||
uv_req_t* next;
|
||||
|
||||
if (loop->pending_reqs_tail == NULL)
|
||||
return;
|
||||
|
||||
first = loop->pending_reqs_tail->next_req;
|
||||
next = first;
|
||||
loop->pending_reqs_tail = NULL;
|
||||
|
||||
while (next != NULL) {
|
||||
req = next;
|
||||
next = req->next_req != first ? req->next_req : NULL;
|
||||
|
||||
switch (req->type) {
|
||||
case UV_READ:
|
||||
DELEGATE_STREAM_REQ(loop, req, read, data);
|
||||
break;
|
||||
|
||||
case UV_WRITE:
|
||||
DELEGATE_STREAM_REQ(loop, (uv_write_t*) req, write, handle);
|
||||
break;
|
||||
|
||||
case UV_ACCEPT:
|
||||
DELEGATE_STREAM_REQ(loop, req, accept, data);
|
||||
break;
|
||||
|
||||
case UV_CONNECT:
|
||||
DELEGATE_STREAM_REQ(loop, (uv_connect_t*) req, connect, handle);
|
||||
break;
|
||||
|
||||
case UV_SHUTDOWN:
|
||||
DELEGATE_STREAM_REQ(loop, (uv_shutdown_t*) req, shutdown, handle);
|
||||
break;
|
||||
|
||||
case UV_UDP_RECV:
|
||||
uv__process_udp_recv_req(loop, (uv_udp_t*) req->data, req);
|
||||
break;
|
||||
|
||||
case UV_UDP_SEND:
|
||||
uv__process_udp_send_req(loop,
|
||||
((uv_udp_send_t*) req)->handle,
|
||||
(uv_udp_send_t*) req);
|
||||
break;
|
||||
|
||||
case UV_WAKEUP:
|
||||
uv__process_async_wakeup_req(loop, (uv_async_t*) req->data, req);
|
||||
break;
|
||||
|
||||
case UV_SIGNAL_REQ:
|
||||
uv__process_signal_req(loop, (uv_signal_t*) req->data, req);
|
||||
break;
|
||||
|
||||
case UV_POLL_REQ:
|
||||
uv__process_poll_req(loop, (uv_poll_t*) req->data, req);
|
||||
break;
|
||||
|
||||
case UV_PROCESS_EXIT:
|
||||
uv__process_proc_exit(loop, (uv_process_t*) req->data);
|
||||
break;
|
||||
|
||||
case UV_FS_EVENT_REQ:
|
||||
uv__process_fs_event_req(loop, req, (uv_fs_event_t*) req->data);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
void uv__insert_pending_req(uv_loop_t* loop, uv_req_t* req);
|
||||
|
||||
#endif /* UV_WIN_REQ_INL_H_ */
|
||||
Vendored
+32
-6
@@ -111,6 +111,23 @@ int uv_read_stop(uv_stream_t* handle) {
|
||||
}
|
||||
|
||||
|
||||
static int uv__check_before_write(uv_stream_t* handle, unsigned int nbufs) {
|
||||
/* We're not beholden to IOV_MAX but limit the buffer count to catch sign
|
||||
* conversion bugs where a caller passes in a signed negative number that
|
||||
* then gets converted to a really large unsigned number.
|
||||
*/
|
||||
if (nbufs < 1 || nbufs > 1024*1024) {
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
if (!(handle->flags & UV_HANDLE_WRITABLE)) {
|
||||
return UV_EPIPE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_write(uv_write_t* req,
|
||||
uv_stream_t* handle,
|
||||
const uv_buf_t bufs[],
|
||||
@@ -119,8 +136,9 @@ int uv_write(uv_write_t* req,
|
||||
uv_loop_t* loop = handle->loop;
|
||||
int err;
|
||||
|
||||
if (!(handle->flags & UV_HANDLE_WRITABLE)) {
|
||||
return UV_EPIPE;
|
||||
err = uv__check_before_write(handle, nbufs);
|
||||
if (err != 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = ERROR_INVALID_PARAMETER;
|
||||
@@ -156,10 +174,13 @@ int uv_write2(uv_write_t* req,
|
||||
return uv_write(req, handle, bufs, nbufs, cb);
|
||||
}
|
||||
|
||||
err = uv__check_before_write(handle, nbufs);
|
||||
if (err != 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (handle->type != UV_NAMED_PIPE || !((uv_pipe_t*) handle)->ipc) {
|
||||
return UV_EINVAL;
|
||||
} else if (!(handle->flags & UV_HANDLE_WRITABLE)) {
|
||||
return UV_EPIPE;
|
||||
}
|
||||
|
||||
err = uv__pipe_write(
|
||||
@@ -171,10 +192,15 @@ int uv_write2(uv_write_t* req,
|
||||
int uv_try_write(uv_stream_t* stream,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs) {
|
||||
int err;
|
||||
|
||||
err = uv__check_before_write(stream, nbufs);
|
||||
if (err != 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (stream->flags & UV_HANDLE_CLOSING)
|
||||
return UV_EBADF;
|
||||
if (!(stream->flags & UV_HANDLE_WRITABLE))
|
||||
return UV_EPIPE;
|
||||
|
||||
switch (stream->type) {
|
||||
case UV_TCP:
|
||||
|
||||
Vendored
+95
-31
@@ -49,29 +49,99 @@ static int uv__tcp_nodelay(uv_tcp_t* handle, SOCKET socket, int enable) {
|
||||
}
|
||||
|
||||
|
||||
static int uv__tcp_keepalive(uv_tcp_t* handle, SOCKET socket, int enable, unsigned int delay) {
|
||||
/*
|
||||
* Check if Windows version is 10.0.16299 (Windows 10, version 1709) or later.
|
||||
*/
|
||||
static int uv__windows10_version1709(void) {
|
||||
OSVERSIONINFOW os_info;
|
||||
if (!pRtlGetVersion)
|
||||
return 0;
|
||||
pRtlGetVersion(&os_info);
|
||||
if (os_info.dwMajorVersion < 10)
|
||||
return 0;
|
||||
if (os_info.dwMajorVersion > 10)
|
||||
return 1;
|
||||
if (os_info.dwMinorVersion > 0)
|
||||
return 1;
|
||||
return os_info.dwBuildNumber >= 16299;
|
||||
}
|
||||
|
||||
|
||||
static int uv__tcp_keepalive(uv_tcp_t* handle,
|
||||
SOCKET socket,
|
||||
int on,
|
||||
unsigned int idle,
|
||||
unsigned int intvl,
|
||||
unsigned int cnt) {
|
||||
if (setsockopt(socket,
|
||||
SOL_SOCKET,
|
||||
SO_KEEPALIVE,
|
||||
(const char*)&enable,
|
||||
sizeof enable) == -1) {
|
||||
(const char*)&on,
|
||||
sizeof on) == -1) {
|
||||
return WSAGetLastError();
|
||||
}
|
||||
|
||||
if (!enable)
|
||||
if (!on)
|
||||
return 0;
|
||||
|
||||
if (delay < 1)
|
||||
if (idle < 1 || intvl < 1 || cnt < 1)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (setsockopt(socket,
|
||||
IPPROTO_TCP,
|
||||
TCP_KEEPALIVE,
|
||||
(const char*)&delay,
|
||||
sizeof delay) == -1) {
|
||||
return WSAGetLastError();
|
||||
/* Windows 10, version 1709 (build 10.0.16299) and later require second units
|
||||
* for TCP keepalive options. */
|
||||
if (uv__windows10_version1709()) {
|
||||
if (setsockopt(socket,
|
||||
IPPROTO_TCP,
|
||||
TCP_KEEPIDLE,
|
||||
(const char*)&idle,
|
||||
sizeof idle) == -1) {
|
||||
return WSAGetLastError();
|
||||
}
|
||||
|
||||
if (setsockopt(socket,
|
||||
IPPROTO_TCP,
|
||||
TCP_KEEPINTVL,
|
||||
(const char*)&intvl,
|
||||
sizeof intvl) == -1) {
|
||||
return WSAGetLastError();
|
||||
}
|
||||
|
||||
if (setsockopt(socket,
|
||||
IPPROTO_TCP,
|
||||
TCP_KEEPCNT,
|
||||
(const char*)&cnt,
|
||||
sizeof cnt) == -1) {
|
||||
return WSAGetLastError();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* For those versions prior to Windows 10 version 1709,
|
||||
* we fall back to SIO_KEEPALIVE_VALS that expects millisecond units.
|
||||
* The SIO_KEEPALIVE_VALS IOCTL is supported on Windows 2000
|
||||
* and later versions of the operating system. */
|
||||
struct tcp_keepalive keepalive;
|
||||
keepalive.onoff = on;
|
||||
keepalive.keepalivetime = idle * 1000;
|
||||
keepalive.keepaliveinterval = intvl * 1000;
|
||||
/* On Windows Vista and later, the number of keep-alive probes
|
||||
* (data retransmissions) is set to 10 and cannot be changed.
|
||||
* On Windows Server 2003, Windows XP, and Windows 2000, the default setting
|
||||
* for number of keep-alive probes is 5 and cannot be changed programmatically.
|
||||
*/
|
||||
DWORD dummy;
|
||||
if (WSAIoctl(socket,
|
||||
SIO_KEEPALIVE_VALS,
|
||||
(LPVOID) &keepalive,
|
||||
sizeof keepalive,
|
||||
NULL,
|
||||
0,
|
||||
&dummy,
|
||||
NULL,
|
||||
NULL) == -1)
|
||||
return WSAGetLastError();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -132,7 +202,7 @@ static int uv__tcp_set_socket(uv_loop_t* loop,
|
||||
|
||||
/* TODO: Use stored delay. */
|
||||
if (handle->flags & UV_HANDLE_TCP_KEEPALIVE) {
|
||||
err = uv__tcp_keepalive(handle, socket, 1, 60);
|
||||
err = uv__tcp_keepalive(handle, socket, 1, 60, 1, 10);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
@@ -749,20 +819,6 @@ static int uv__is_loopback(const struct sockaddr_storage* storage) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check if Windows version is 10.0.16299 or later
|
||||
static int uv__is_fast_loopback_fail_supported(void) {
|
||||
OSVERSIONINFOW os_info;
|
||||
if (!pRtlGetVersion)
|
||||
return 0;
|
||||
pRtlGetVersion(&os_info);
|
||||
if (os_info.dwMajorVersion < 10)
|
||||
return 0;
|
||||
if (os_info.dwMajorVersion > 10)
|
||||
return 1;
|
||||
if (os_info.dwMinorVersion > 0)
|
||||
return 1;
|
||||
return os_info.dwBuildNumber >= 16299;
|
||||
}
|
||||
|
||||
static int uv__tcp_try_connect(uv_connect_t* req,
|
||||
uv_tcp_t* handle,
|
||||
@@ -809,7 +865,7 @@ static int uv__tcp_try_connect(uv_connect_t* req,
|
||||
* is not reachable, instead of waiting for 2s. We do not care if this fails.
|
||||
* This only works on Windows version 10.0.16299 and later.
|
||||
*/
|
||||
if (uv__is_fast_loopback_fail_supported() && uv__is_loopback(&converted)) {
|
||||
if (uv__windows10_version1709() && uv__is_loopback(&converted)) {
|
||||
memset(&retransmit_ioctl, 0, sizeof(retransmit_ioctl));
|
||||
retransmit_ioctl.Rtt = TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS;
|
||||
retransmit_ioctl.MaxSynRetransmissions = TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS;
|
||||
@@ -1335,22 +1391,30 @@ int uv_tcp_nodelay(uv_tcp_t* handle, int enable) {
|
||||
}
|
||||
|
||||
|
||||
int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
|
||||
int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int idle) {
|
||||
return uv_tcp_keepalive_ex(handle, on, idle, 1, 10);
|
||||
}
|
||||
|
||||
int uv_tcp_keepalive_ex(uv_tcp_t* handle,
|
||||
int on,
|
||||
unsigned int idle,
|
||||
unsigned int intvl,
|
||||
unsigned int cnt) {
|
||||
int err;
|
||||
|
||||
if (handle->socket != INVALID_SOCKET) {
|
||||
err = uv__tcp_keepalive(handle, handle->socket, enable, delay);
|
||||
err = uv__tcp_keepalive(handle, handle->socket, on, idle, intvl, cnt);
|
||||
if (err)
|
||||
return uv_translate_sys_error(err);
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
if (on) {
|
||||
handle->flags |= UV_HANDLE_TCP_KEEPALIVE;
|
||||
} else {
|
||||
handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE;
|
||||
}
|
||||
|
||||
/* TODO: Store delay if handle->socket isn't created yet. */
|
||||
/* TODO: Store idle if handle->socket isn't created yet. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -284,7 +284,7 @@ int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) {
|
||||
static void uv__thread_name_init_once(void) {
|
||||
HMODULE m;
|
||||
|
||||
m = GetModuleHandleA("api-ms-win-core-processthreads-l1-1-3.dll");
|
||||
m = GetModuleHandleW(L"api-ms-win-core-processthreads-l1-1-3.dll");
|
||||
if (m != NULL) {
|
||||
pGetThreadDescription = (void*) GetProcAddress(m, "GetThreadDescription");
|
||||
pSetThreadDescription = (void*) GetProcAddress(m, "SetThreadDescription");
|
||||
|
||||
Vendored
+36
-5
@@ -204,7 +204,7 @@ static int uv__udp_maybe_bind(uv_udp_t* handle,
|
||||
* so we just return an error directly when UV_UDP_REUSEPORT is requested
|
||||
* for binding the socket. */
|
||||
if (flags & UV_UDP_REUSEPORT)
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
return UV_ENOTSUP;
|
||||
|
||||
if ((flags & UV_UDP_IPV6ONLY) && addr->sa_family != AF_INET6) {
|
||||
/* UV_UDP_IPV6ONLY is supported only for IPV6 sockets */
|
||||
@@ -908,11 +908,15 @@ int uv__udp_is_bound(uv_udp_t* handle) {
|
||||
}
|
||||
|
||||
|
||||
int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
|
||||
int uv_udp_open_ex(uv_udp_t* handle, uv_os_sock_t sock, unsigned int flags) {
|
||||
WSAPROTOCOL_INFOW protocol_info;
|
||||
int opt_len;
|
||||
int err;
|
||||
|
||||
/* Check for bad flags. */
|
||||
if (flags & ~(UV_UDP_REUSEADDR | UV_UDP_REUSEPORT))
|
||||
return UV_EINVAL;
|
||||
|
||||
/* Detect the address family of the socket. */
|
||||
opt_len = (int) sizeof protocol_info;
|
||||
if (getsockopt(sock,
|
||||
@@ -930,6 +934,25 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
|
||||
if (err)
|
||||
return uv_translate_sys_error(err);
|
||||
|
||||
/* There is no SO_REUSEPORT on Windows, Windows only knows SO_REUSEADDR.
|
||||
* so we just return an error directly when UV_UDP_REUSEPORT is requested
|
||||
* for binding the socket. */
|
||||
if (flags & UV_UDP_REUSEPORT)
|
||||
return UV_ENOTSUP;
|
||||
|
||||
if (flags & UV_UDP_REUSEADDR) {
|
||||
DWORD yes = 1;
|
||||
/* Set SO_REUSEADDR on the socket. */
|
||||
if (setsockopt(handle->socket,
|
||||
SOL_SOCKET,
|
||||
SO_REUSEADDR,
|
||||
(char*) &yes,
|
||||
sizeof yes) == SOCKET_ERROR) {
|
||||
err = WSAGetLastError();
|
||||
return uv_translate_sys_error(err);
|
||||
}
|
||||
}
|
||||
|
||||
if (uv__udp_is_bound(handle))
|
||||
handle->flags |= UV_HANDLE_BOUND;
|
||||
|
||||
@@ -940,6 +963,11 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
|
||||
}
|
||||
|
||||
|
||||
int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
|
||||
return uv_udp_open_ex(handle, sock, 0);
|
||||
}
|
||||
|
||||
|
||||
#define SOCKOPT_SETTER(name, option4, option6, validate) \
|
||||
int uv_udp_set_##name(uv_udp_t* handle, int value) { \
|
||||
DWORD optval = (DWORD) value; \
|
||||
@@ -1149,13 +1177,16 @@ int uv__udp_try_send2(uv_udp_t* handle,
|
||||
uv_buf_t* bufs[/*count*/],
|
||||
unsigned int nbufs[/*count*/],
|
||||
struct sockaddr* addrs[/*count*/]) {
|
||||
unsigned int i;
|
||||
int i;
|
||||
int r;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (count > INT_MAX)
|
||||
return UV_EINVAL;
|
||||
|
||||
for (i = 0; i < (int) 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 > 0 ? i : (int) r; /* Error if first packet, else send count. */
|
||||
}
|
||||
|
||||
return i;
|
||||
|
||||
Vendored
+27
-17
@@ -376,10 +376,10 @@ done:
|
||||
|
||||
|
||||
static int uv__get_process_title(void) {
|
||||
WCHAR title_w[MAX_TITLE_LENGTH];
|
||||
WCHAR title_w[MAX_PATH];
|
||||
DWORD wlen;
|
||||
|
||||
wlen = GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR));
|
||||
wlen = GetModuleFileNameW(NULL, title_w, MAX_PATH);
|
||||
if (wlen == 0)
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
|
||||
@@ -508,15 +508,15 @@ int uv_uptime(double* uptime) {
|
||||
unsigned int uv_available_parallelism(void) {
|
||||
DWORD_PTR procmask;
|
||||
DWORD_PTR sysmask;
|
||||
int count;
|
||||
int i;
|
||||
unsigned count;
|
||||
unsigned i;
|
||||
|
||||
/* TODO(bnoordhuis) Use GetLogicalProcessorInformationEx() to support systems
|
||||
* with > 64 CPUs? See https://github.com/libuv/libuv/pull/3458
|
||||
*/
|
||||
count = 0;
|
||||
if (GetProcessAffinityMask(GetCurrentProcess(), &procmask, &sysmask))
|
||||
for (i = 0; i < 8 * sizeof(procmask); i++)
|
||||
for (i = 0; i < 8u * sizeof(procmask); i++)
|
||||
count += 1 & (procmask >> i);
|
||||
|
||||
if (count > 0)
|
||||
@@ -867,12 +867,6 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
|
||||
}
|
||||
|
||||
|
||||
void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
||||
int count) {
|
||||
uv__free(addresses);
|
||||
}
|
||||
|
||||
|
||||
int uv_getrusage(uv_rusage_t *uv_rusage) {
|
||||
FILETIME create_time, exit_time, kernel_time, user_time;
|
||||
SYSTEMTIME kernel_system_time, user_system_time;
|
||||
@@ -1281,7 +1275,7 @@ fail:
|
||||
FreeEnvironmentStringsW(env);
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
envitem = &(*envitems)[cnt];
|
||||
envitem = &(*envitems)[i];
|
||||
uv__free(envitem->name);
|
||||
}
|
||||
uv__free(*envitems);
|
||||
@@ -1519,20 +1513,26 @@ int uv_os_setpriority(uv_pid_t pid, int priority) {
|
||||
}
|
||||
|
||||
int uv_thread_getpriority(uv_thread_t tid, int* priority) {
|
||||
DWORD err;
|
||||
int r;
|
||||
|
||||
if (priority == NULL)
|
||||
return UV_EINVAL;
|
||||
|
||||
r = GetThreadPriority(tid);
|
||||
if (r == THREAD_PRIORITY_ERROR_RETURN)
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
if (r == THREAD_PRIORITY_ERROR_RETURN) {
|
||||
err = GetLastError();
|
||||
if (err == ERROR_INVALID_HANDLE)
|
||||
return UV_ESRCH;
|
||||
return uv_translate_sys_error(err);
|
||||
}
|
||||
|
||||
*priority = r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uv_thread_setpriority(uv_thread_t tid, int priority) {
|
||||
DWORD err;
|
||||
int r;
|
||||
|
||||
switch (priority) {
|
||||
@@ -1555,8 +1555,12 @@ int uv_thread_setpriority(uv_thread_t tid, int priority) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (r == 0)
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
if (r == 0) {
|
||||
err = GetLastError();
|
||||
if (err == ERROR_INVALID_HANDLE)
|
||||
return UV_ESRCH;
|
||||
return uv_translate_sys_error(err);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1703,6 +1707,9 @@ int uv_os_uname(uv_utsname_t* buffer) {
|
||||
case PROCESSOR_ARCHITECTURE_ARM:
|
||||
uv__strscpy(buffer->machine, "arm", sizeof(buffer->machine));
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_ARM64:
|
||||
uv__strscpy(buffer->machine, "arm64", sizeof(buffer->machine));
|
||||
break;
|
||||
default:
|
||||
uv__strscpy(buffer->machine, "unknown", sizeof(buffer->machine));
|
||||
break;
|
||||
@@ -1735,10 +1742,13 @@ int uv_gettimeofday(uv_timeval64_t* tv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uv__random_rtlgenrandom(void* buf, size_t buflen) {
|
||||
int uv__random_winrandom(void* buf, size_t buflen) {
|
||||
if (buflen == 0)
|
||||
return 0;
|
||||
|
||||
if (pProcessPrng != NULL && pProcessPrng(buf, buflen))
|
||||
return 0;
|
||||
|
||||
if (SystemFunction036(buf, buflen) == FALSE)
|
||||
return UV_EIO;
|
||||
|
||||
|
||||
Vendored
+68
-39
@@ -39,6 +39,9 @@ sNtQueryInformationProcess pNtQueryInformationProcess;
|
||||
/* Powrprof.dll function pointer */
|
||||
sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
|
||||
|
||||
/* bcryptprimitives.dll function pointer */
|
||||
sProcessPrng pProcessPrng;
|
||||
|
||||
/* User32.dll function pointer */
|
||||
sSetWinEventHook pSetWinEventHook;
|
||||
|
||||
@@ -53,92 +56,118 @@ void uv__winapi_init(void) {
|
||||
HMODULE powrprof_module;
|
||||
HMODULE user32_module;
|
||||
HMODULE ws2_32_module;
|
||||
HMODULE bcryptprimitives_module;
|
||||
HMODULE api_win_core_file_module;
|
||||
|
||||
ntdll_module = GetModuleHandleA("ntdll.dll");
|
||||
union {
|
||||
FARPROC proc;
|
||||
sRtlGetVersion pRtlGetVersion;
|
||||
sRtlNtStatusToDosError pRtlNtStatusToDosError;
|
||||
sNtDeviceIoControlFile pNtDeviceIoControlFile;
|
||||
sNtQueryInformationFile pNtQueryInformationFile;
|
||||
sNtSetInformationFile pNtSetInformationFile;
|
||||
sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile;
|
||||
sNtQueryDirectoryFile pNtQueryDirectoryFile;
|
||||
sNtQuerySystemInformation pNtQuerySystemInformation;
|
||||
sNtQueryInformationProcess pNtQueryInformationProcess;
|
||||
sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
|
||||
sProcessPrng pProcessPrng;
|
||||
sSetWinEventHook pSetWinEventHook;
|
||||
uv_sGetHostNameW pGetHostNameW;
|
||||
sGetFileInformationByName pGetFileInformationByName;
|
||||
} u;
|
||||
|
||||
ntdll_module = GetModuleHandleW(L"ntdll.dll");
|
||||
if (ntdll_module == NULL) {
|
||||
uv_fatal_error(GetLastError(), "GetModuleHandleA");
|
||||
uv_fatal_error(GetLastError(), "GetModuleHandleW");
|
||||
}
|
||||
|
||||
pRtlGetVersion = (sRtlGetVersion) GetProcAddress(ntdll_module,
|
||||
"RtlGetVersion");
|
||||
u.proc = GetProcAddress(ntdll_module, "RtlGetVersion");
|
||||
pRtlGetVersion = u.pRtlGetVersion;
|
||||
|
||||
pRtlNtStatusToDosError = (sRtlNtStatusToDosError) GetProcAddress(
|
||||
ntdll_module,
|
||||
"RtlNtStatusToDosError");
|
||||
u.proc = GetProcAddress(ntdll_module, "RtlNtStatusToDosError");
|
||||
pRtlNtStatusToDosError = u.pRtlNtStatusToDosError;
|
||||
if (pRtlNtStatusToDosError == NULL) {
|
||||
uv_fatal_error(GetLastError(), "GetProcAddress");
|
||||
}
|
||||
|
||||
pNtDeviceIoControlFile = (sNtDeviceIoControlFile) GetProcAddress(
|
||||
ntdll_module,
|
||||
"NtDeviceIoControlFile");
|
||||
u.proc = GetProcAddress(ntdll_module, "NtDeviceIoControlFile");
|
||||
pNtDeviceIoControlFile = u.pNtDeviceIoControlFile;
|
||||
if (pNtDeviceIoControlFile == NULL) {
|
||||
uv_fatal_error(GetLastError(), "GetProcAddress");
|
||||
}
|
||||
|
||||
pNtQueryInformationFile = (sNtQueryInformationFile) GetProcAddress(
|
||||
ntdll_module,
|
||||
"NtQueryInformationFile");
|
||||
u.proc = GetProcAddress(ntdll_module, "NtQueryInformationFile");
|
||||
pNtQueryInformationFile = u.pNtQueryInformationFile;
|
||||
if (pNtQueryInformationFile == NULL) {
|
||||
uv_fatal_error(GetLastError(), "GetProcAddress");
|
||||
}
|
||||
|
||||
pNtSetInformationFile = (sNtSetInformationFile) GetProcAddress(
|
||||
ntdll_module,
|
||||
"NtSetInformationFile");
|
||||
u.proc = GetProcAddress(ntdll_module, "NtSetInformationFile");
|
||||
pNtSetInformationFile = u.pNtSetInformationFile;
|
||||
if (pNtSetInformationFile == NULL) {
|
||||
uv_fatal_error(GetLastError(), "GetProcAddress");
|
||||
}
|
||||
|
||||
pNtQueryVolumeInformationFile = (sNtQueryVolumeInformationFile)
|
||||
GetProcAddress(ntdll_module, "NtQueryVolumeInformationFile");
|
||||
u.proc = GetProcAddress(ntdll_module, "NtQueryVolumeInformationFile");
|
||||
pNtQueryVolumeInformationFile = u.pNtQueryVolumeInformationFile;
|
||||
if (pNtQueryVolumeInformationFile == NULL) {
|
||||
uv_fatal_error(GetLastError(), "GetProcAddress");
|
||||
}
|
||||
|
||||
pNtQueryDirectoryFile = (sNtQueryDirectoryFile)
|
||||
GetProcAddress(ntdll_module, "NtQueryDirectoryFile");
|
||||
u.proc = GetProcAddress(ntdll_module, "NtQueryDirectoryFile");
|
||||
pNtQueryDirectoryFile = u.pNtQueryDirectoryFile;
|
||||
if (pNtQueryDirectoryFile == NULL) {
|
||||
uv_fatal_error(GetLastError(), "GetProcAddress");
|
||||
}
|
||||
|
||||
pNtQuerySystemInformation = (sNtQuerySystemInformation) GetProcAddress(
|
||||
ntdll_module,
|
||||
"NtQuerySystemInformation");
|
||||
u.proc = GetProcAddress(ntdll_module, "NtQuerySystemInformation");
|
||||
pNtQuerySystemInformation = u.pNtQuerySystemInformation;
|
||||
if (pNtQuerySystemInformation == NULL) {
|
||||
uv_fatal_error(GetLastError(), "GetProcAddress");
|
||||
}
|
||||
|
||||
pNtQueryInformationProcess = (sNtQueryInformationProcess) GetProcAddress(
|
||||
ntdll_module,
|
||||
"NtQueryInformationProcess");
|
||||
u.proc = GetProcAddress(ntdll_module, "NtQueryInformationProcess");
|
||||
pNtQueryInformationProcess = u.pNtQueryInformationProcess;
|
||||
if (pNtQueryInformationProcess == NULL) {
|
||||
uv_fatal_error(GetLastError(), "GetProcAddress");
|
||||
}
|
||||
|
||||
powrprof_module = LoadLibraryExA("powrprof.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
powrprof_module = LoadLibraryExA("powrprof.dll",
|
||||
NULL,
|
||||
LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (powrprof_module != NULL) {
|
||||
pPowerRegisterSuspendResumeNotification = (sPowerRegisterSuspendResumeNotification)
|
||||
GetProcAddress(powrprof_module, "PowerRegisterSuspendResumeNotification");
|
||||
u.proc = GetProcAddress(powrprof_module,
|
||||
"PowerRegisterSuspendResumeNotification");
|
||||
pPowerRegisterSuspendResumeNotification =
|
||||
u.pPowerRegisterSuspendResumeNotification;
|
||||
}
|
||||
|
||||
user32_module = GetModuleHandleA("user32.dll");
|
||||
bcryptprimitives_module = LoadLibraryExA("bcryptprimitives.dll",
|
||||
NULL,
|
||||
LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (bcryptprimitives_module != NULL) {
|
||||
u.proc = GetProcAddress(bcryptprimitives_module, "ProcessPrng");
|
||||
pProcessPrng = u.pProcessPrng;
|
||||
}
|
||||
|
||||
user32_module = GetModuleHandleW(L"user32.dll");
|
||||
if (user32_module != NULL) {
|
||||
pSetWinEventHook = (sSetWinEventHook)
|
||||
GetProcAddress(user32_module, "SetWinEventHook");
|
||||
u.proc = GetProcAddress(user32_module, "SetWinEventHook");
|
||||
pSetWinEventHook = u.pSetWinEventHook;
|
||||
}
|
||||
|
||||
ws2_32_module = GetModuleHandleA("ws2_32.dll");
|
||||
ws2_32_module = GetModuleHandleW(L"ws2_32.dll");
|
||||
if (ws2_32_module != NULL) {
|
||||
pGetHostNameW = (uv_sGetHostNameW) GetProcAddress(
|
||||
ws2_32_module,
|
||||
"GetHostNameW");
|
||||
u.proc = GetProcAddress(ws2_32_module, "GetHostNameW");
|
||||
pGetHostNameW = u.pGetHostNameW;
|
||||
}
|
||||
|
||||
api_win_core_file_module = GetModuleHandleA("api-ms-win-core-file-l2-1-4.dll");
|
||||
api_win_core_file_module =
|
||||
GetModuleHandleW(L"api-ms-win-core-file-l2-1-4.dll");
|
||||
if (api_win_core_file_module != NULL) {
|
||||
pGetFileInformationByName = (sGetFileInformationByName)GetProcAddress(
|
||||
api_win_core_file_module, "GetFileInformationByName");
|
||||
u.proc = GetProcAddress(api_win_core_file_module,
|
||||
"GetFileInformationByName");
|
||||
pGetFileInformationByName = u.pGetFileInformationByName;
|
||||
}
|
||||
}
|
||||
Vendored
+12
@@ -4163,6 +4163,10 @@ typedef struct _REPARSE_DATA_BUFFER {
|
||||
ULONG Flags;
|
||||
WCHAR PathBuffer[1];
|
||||
} SymbolicLinkReparseBuffer;
|
||||
struct {
|
||||
ULONG Version;
|
||||
UCHAR PathBuffer[1];
|
||||
} LinuxSymbolicLinkReparseBuffer;
|
||||
struct {
|
||||
USHORT SubstituteNameOffset;
|
||||
USHORT SubstituteNameLength;
|
||||
@@ -4582,6 +4586,9 @@ typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
|
||||
#ifndef IO_REPARSE_TAG_SYMLINK
|
||||
# define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
|
||||
#endif
|
||||
#ifndef IO_REPARSE_TAG_LX_SYMLINK
|
||||
# define IO_REPARSE_TAG_LX_SYMLINK (0xA000001DL)
|
||||
#endif
|
||||
#ifndef IO_REPARSE_TAG_APPEXECLINK
|
||||
# define IO_REPARSE_TAG_APPEXECLINK (0x8000001BL)
|
||||
#endif
|
||||
@@ -4751,6 +4758,8 @@ typedef DWORD (WINAPI *sPowerRegisterSuspendResumeNotification)
|
||||
HANDLE Recipient,
|
||||
_PHPOWERNOTIFY RegistrationHandle);
|
||||
|
||||
typedef BOOL (WINAPI *sProcessPrng)(/*_Out_*/PBYTE pbData, SIZE_T cbData);
|
||||
|
||||
/* from Winuser.h */
|
||||
typedef VOID (CALLBACK* WINEVENTPROC)
|
||||
(HWINEVENTHOOK hWinEventHook,
|
||||
@@ -4815,6 +4824,9 @@ extern sNtQueryInformationProcess pNtQueryInformationProcess;
|
||||
/* Powrprof.dll function pointer */
|
||||
extern sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
|
||||
|
||||
/* bcryptprimitives.dll function pointer */
|
||||
extern sProcessPrng pProcessPrng;
|
||||
|
||||
/* User32.dll function pointer */
|
||||
extern sSetWinEventHook pSetWinEventHook;
|
||||
|
||||
|
||||
Vendored
+24
-4
@@ -38,10 +38,6 @@
|
||||
# define SO_UPDATE_CONNECT_CONTEXT 0x7010
|
||||
#endif
|
||||
|
||||
#ifndef TCP_KEEPALIVE
|
||||
# define TCP_KEEPALIVE 3
|
||||
#endif
|
||||
|
||||
#ifndef IPV6_V6ONLY
|
||||
# define IPV6_V6ONLY 27
|
||||
#endif
|
||||
@@ -62,6 +58,30 @@
|
||||
# define MCAST_LEAVE_SOURCE_GROUP 46
|
||||
#endif
|
||||
|
||||
#ifndef SIO_KEEPALIVE_VALS
|
||||
#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)
|
||||
struct tcp_keepalive {
|
||||
u_long onoff;
|
||||
u_long keepalivetime;
|
||||
u_long keepaliveinterval;
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TCP keepalive definitions on MinGW are located in <netinet/tcp.h>.
|
||||
*/
|
||||
#ifndef TCP_KEEPIDLE
|
||||
#define TCP_KEEPIDLE 0x03 /* start keepalives after this period */
|
||||
#endif
|
||||
|
||||
#ifndef TCP_KEEPINTVL
|
||||
#define TCP_KEEPINTVL 0x11 /* interval between keepalives */
|
||||
#endif
|
||||
|
||||
#ifndef TCP_KEEPCNT
|
||||
#define TCP_KEEPCNT 0x10 /* number of keepalives before death */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TDI defines that are only in the DDK.
|
||||
* We only need receive flags so far.
|
||||
|
||||
Vendored
+1
-1
@@ -31,7 +31,7 @@
|
||||
#ifdef __MVS__
|
||||
#include "zos-base.h"
|
||||
/* Initialize environment and zoslib */
|
||||
__attribute__((constructor)) void init() {
|
||||
__attribute__((constructor)) void init(void) {
|
||||
zoslib_config_t config;
|
||||
init_zoslib_config(&config);
|
||||
init_zoslib(config);
|
||||
|
||||
Vendored
+9
-7
@@ -40,7 +40,7 @@
|
||||
#ifdef __MVS__
|
||||
#include "zos-base.h"
|
||||
/* Initialize environment and zoslib */
|
||||
__attribute__((constructor)) void init() {
|
||||
__attribute__((constructor)) void init(void) {
|
||||
zoslib_config_t config;
|
||||
init_zoslib_config(&config);
|
||||
init_zoslib(config);
|
||||
@@ -214,7 +214,10 @@ static int maybe_run_test(int argc, char **argv) {
|
||||
#ifdef _WIN32
|
||||
DWORD flags;
|
||||
HMODULE kernelbase_module;
|
||||
sCompareObjectHandles pCompareObjectHandles; /* function introduced in Windows 10 */
|
||||
union {
|
||||
FARPROC proc;
|
||||
sCompareObjectHandles pCompareObjectHandles; /* Windows >= 10 */
|
||||
} u;
|
||||
#endif
|
||||
notify_parent_process();
|
||||
ASSERT_EQ(sizeof(closed_fd), read(0, &closed_fd, sizeof(closed_fd)));
|
||||
@@ -223,11 +226,10 @@ static int maybe_run_test(int argc, char **argv) {
|
||||
ASSERT_GT((intptr_t) closed_fd, 0);
|
||||
ASSERT_GT((intptr_t) open_fd, 0);
|
||||
ASSERT_NE(0, GetHandleInformation(open_fd, &flags));
|
||||
kernelbase_module = GetModuleHandleA("kernelbase.dll");
|
||||
pCompareObjectHandles = (sCompareObjectHandles)
|
||||
GetProcAddress(kernelbase_module, "CompareObjectHandles");
|
||||
ASSERT_NE(pCompareObjectHandles == NULL || \
|
||||
!pCompareObjectHandles(open_fd, closed_fd), 0);
|
||||
kernelbase_module = GetModuleHandleW(L"kernelbase.dll");
|
||||
u.proc = GetProcAddress(kernelbase_module, "CompareObjectHandles");
|
||||
if (u.pCompareObjectHandles != NULL)
|
||||
ASSERT_EQ(FALSE, u.pCompareObjectHandles(open_fd, closed_fd));
|
||||
#else
|
||||
ASSERT_GT(open_fd, 2);
|
||||
ASSERT_GT(closed_fd, 2);
|
||||
|
||||
Vendored
+1
-1
@@ -340,7 +340,7 @@ static int clear_line(void) {
|
||||
}
|
||||
|
||||
|
||||
void rewind_cursor() {
|
||||
void rewind_cursor(void) {
|
||||
if (clear_line() == -1) {
|
||||
/* If clear_line fails (stdout is not a console), print a newline. */
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
Vendored
+18
-2
@@ -22,7 +22,6 @@
|
||||
#ifndef RUNNER_H_
|
||||
#define RUNNER_H_
|
||||
|
||||
#include <limits.h> /* PATH_MAX */
|
||||
#include <stdio.h> /* FILE */
|
||||
|
||||
|
||||
@@ -57,7 +56,7 @@ typedef struct {
|
||||
task_entry_t TASKS[] = {
|
||||
|
||||
#define TASK_LIST_END \
|
||||
{ 0, 0, 0, 0, 0, 0 } \
|
||||
{ 0, 0, 0, 0, 0, 0 } \
|
||||
};
|
||||
|
||||
#define TEST_DECLARE(name) \
|
||||
@@ -69,6 +68,23 @@ typedef struct {
|
||||
#define TEST_ENTRY_CUSTOM(name, is_helper, show_output, timeout) \
|
||||
{ #name, #name, &run_test_##name, is_helper, show_output, timeout },
|
||||
|
||||
/*
|
||||
* Macros for fs tests that, on linux, generate both normal and io_uring
|
||||
* versions.
|
||||
*/
|
||||
#ifdef __linux__
|
||||
#define TEST_FS_DECLARE(name) \
|
||||
TEST_DECLARE(name) \
|
||||
TEST_DECLARE(name##_iouring)
|
||||
|
||||
#define TEST_FS_ENTRY(name) \
|
||||
TEST_ENTRY(name) \
|
||||
TEST_ENTRY(name##_iouring)
|
||||
#else
|
||||
#define TEST_FS_DECLARE(name) TEST_DECLARE(name)
|
||||
#define TEST_FS_ENTRY(name) TEST_ENTRY(name)
|
||||
#endif
|
||||
|
||||
#define BENCHMARK_DECLARE(name) \
|
||||
int run_benchmark_##name(void);
|
||||
|
||||
|
||||
Vendored
+51
-24
@@ -53,14 +53,10 @@
|
||||
# define TEST_PIPENAME "\\\\.\\pipe\\uv-test"
|
||||
# define TEST_PIPENAME_2 "\\\\.\\pipe\\uv-test2"
|
||||
# define TEST_PIPENAME_3 "\\\\.\\pipe\\uv-test3"
|
||||
#elif __ANDROID__
|
||||
# define TEST_PIPENAME "/data/local/tmp/uv-test-sock"
|
||||
# define TEST_PIPENAME_2 "/data/local/tmp/uv-test-sock2"
|
||||
# define TEST_PIPENAME_3 "/data/local/tmp/uv-test-sock3"
|
||||
#else
|
||||
# define TEST_PIPENAME "/tmp/uv-test-sock"
|
||||
# define TEST_PIPENAME_2 "/tmp/uv-test-sock2"
|
||||
# define TEST_PIPENAME_3 "/tmp/uv-test-sock3"
|
||||
# define TEST_PIPENAME "uv-test-sock"
|
||||
# define TEST_PIPENAME_2 "uv-test-sock2"
|
||||
# define TEST_PIPENAME_3 "uv-test-sock3"
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -113,8 +109,8 @@ typedef enum {
|
||||
|
||||
#define ASSERT_BASE(a, operator, b, type, conv) \
|
||||
do { \
|
||||
volatile type eval_a = (type) (a); \
|
||||
volatile type eval_b = (type) (b); \
|
||||
type const eval_a = (a); \
|
||||
type const eval_b = (b); \
|
||||
if (!(eval_a operator eval_b)) { \
|
||||
fprintf(stderr, \
|
||||
"Assertion failed in %s on line %d: `%s %s %s` " \
|
||||
@@ -131,6 +127,21 @@ typedef enum {
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ASSERT_OK(a) \
|
||||
do { \
|
||||
int64_t const eval_a = (a); \
|
||||
if (eval_a) { \
|
||||
fprintf(stderr, \
|
||||
"Assertion failed in %s on line %d: `%s` okay " \
|
||||
"(error: %"PRId64")\n", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
#a, \
|
||||
eval_a); \
|
||||
abort(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ASSERT_BASE_STR(expr, a, operator, b, type, conv) \
|
||||
do { \
|
||||
if (!(expr)) { \
|
||||
@@ -173,8 +184,8 @@ typedef enum {
|
||||
do { \
|
||||
if (!(expr)) { \
|
||||
int i; \
|
||||
unsigned char* a_ = (unsigned char*)a; \
|
||||
unsigned char* b_ = (unsigned char*)b; \
|
||||
const unsigned char* a_ = (a); \
|
||||
const unsigned char* b_ = (b); \
|
||||
fprintf(stderr, \
|
||||
"Assertion failed in %s on line %d: `%s %s %s` (", \
|
||||
__FILE__, \
|
||||
@@ -202,7 +213,6 @@ typedef enum {
|
||||
#define ASSERT_LE(a, b) ASSERT_BASE(a, <=, b, int64_t, PRId64)
|
||||
#define ASSERT_LT(a, b) ASSERT_BASE(a, <, b, int64_t, PRId64)
|
||||
#define ASSERT_NE(a, b) ASSERT_BASE(a, !=, b, int64_t, PRId64)
|
||||
#define ASSERT_OK(a) ASSERT_BASE(a, ==, 0, int64_t, PRId64)
|
||||
|
||||
#define ASSERT_UINT64_EQ(a, b) ASSERT_BASE(a, ==, b, uint64_t, PRIu64)
|
||||
#define ASSERT_UINT64_GE(a, b) ASSERT_BASE(a, >=, b, uint64_t, PRIu64)
|
||||
@@ -211,12 +221,12 @@ typedef enum {
|
||||
#define ASSERT_UINT64_LT(a, b) ASSERT_BASE(a, <, b, uint64_t, PRIu64)
|
||||
#define ASSERT_UINT64_NE(a, b) ASSERT_BASE(a, !=, b, uint64_t, PRIu64)
|
||||
|
||||
#define ASSERT_DOUBLE_EQ(a, b) ASSERT_BASE(a, ==, b, double, "f")
|
||||
#define ASSERT_DOUBLE_GE(a, b) ASSERT_BASE(a, >=, b, double, "f")
|
||||
#define ASSERT_DOUBLE_GT(a, b) ASSERT_BASE(a, >, b, double, "f")
|
||||
#define ASSERT_DOUBLE_LE(a, b) ASSERT_BASE(a, <=, b, double, "f")
|
||||
#define ASSERT_DOUBLE_LT(a, b) ASSERT_BASE(a, <, b, double, "f")
|
||||
#define ASSERT_DOUBLE_NE(a, b) ASSERT_BASE(a, !=, b, double, "f")
|
||||
#define ASSERT_DOUBLE_EQ(a, b) ASSERT_BASE(a, ==, b, volatile double, "f")
|
||||
#define ASSERT_DOUBLE_GE(a, b) ASSERT_BASE(a, >=, b, volatile double, "f")
|
||||
#define ASSERT_DOUBLE_GT(a, b) ASSERT_BASE(a, >, b, volatile double, "f")
|
||||
#define ASSERT_DOUBLE_LE(a, b) ASSERT_BASE(a, <=, b, volatile double, "f")
|
||||
#define ASSERT_DOUBLE_LT(a, b) ASSERT_BASE(a, <, b, volatile double, "f")
|
||||
#define ASSERT_DOUBLE_NE(a, b) ASSERT_BASE(a, !=, b, volatile double, "f")
|
||||
|
||||
#define ASSERT_STR_EQ(a, b) \
|
||||
ASSERT_BASE_STR(strcmp(a, b) == 0, a, == , b, char*, "s")
|
||||
@@ -237,19 +247,23 @@ typedef enum {
|
||||
ASSERT_BASE_HEX(memcmp(a, b, size) != 0, a, !=, b, size)
|
||||
|
||||
#define ASSERT_NULL(a) \
|
||||
ASSERT_BASE(a, ==, NULL, void*, "p")
|
||||
ASSERT_BASE(a, ==, NULL, const void*, "p")
|
||||
|
||||
#define ASSERT_NOT_NULL(a) \
|
||||
ASSERT_BASE(a, !=, NULL, void*, "p")
|
||||
ASSERT_BASE(a, !=, NULL, const void*, "p")
|
||||
|
||||
#define ASSERT_PTR_EQ(a, b) \
|
||||
ASSERT_BASE(a, ==, b, void*, "p")
|
||||
ASSERT_BASE(a, ==, b, const void*, "p")
|
||||
|
||||
#define ASSERT_PTR_NE(a, b) \
|
||||
ASSERT_BASE(a, !=, b, void*, "p")
|
||||
ASSERT_BASE(a, !=, b, const void*, "p")
|
||||
|
||||
#define ASSERT_PTR_LT(a, b) \
|
||||
ASSERT_BASE(a, <, b, void*, "p")
|
||||
ASSERT_BASE(a, <, b, const void*, "p")
|
||||
#define ASSERT_PTR_LE(a, b) \
|
||||
ASSERT_BASE(a, <=, b, const void*, "p")
|
||||
#define ASSERT_PTR_GE(a, b) \
|
||||
ASSERT_BASE(a, >=, b, const void*, "p")
|
||||
|
||||
/* This macro cleans up the event loop. This is used to avoid valgrind
|
||||
* warnings about memory being "leaked" by the event loop.
|
||||
@@ -270,6 +284,19 @@ typedef enum {
|
||||
int run_benchmark_##name(void); \
|
||||
int run_benchmark_##name(void)
|
||||
|
||||
#ifdef __linux__
|
||||
#define TEST_FS_IMPL(name) \
|
||||
int run_test_##name(void); \
|
||||
int run_test_##name##_iouring(void) { \
|
||||
uv_os_setenv("UV_USE_IO_URING", "1"); \
|
||||
uv_loop_configure(uv_default_loop(), UV_LOOP_USE_IO_URING_SQPOLL); \
|
||||
return run_test_##name(); \
|
||||
} \
|
||||
int run_test_##name(void)
|
||||
#else
|
||||
#define TEST_FS_IMPL(name) TEST_IMPL(name)
|
||||
#endif
|
||||
|
||||
#define HELPER_IMPL(name) \
|
||||
int run_helper_##name(void); \
|
||||
int run_helper_##name(void)
|
||||
@@ -358,7 +385,7 @@ UNUSED static int can_ipv6(void) {
|
||||
return supported;
|
||||
}
|
||||
|
||||
#if defined(__CYGWIN__) || defined(__MSYS__) || defined(__PASE__)
|
||||
#if defined(__CYGWIN__) || defined(__MSYS__) || defined(__PASE__) || defined(__QNX__)
|
||||
# define NO_FS_EVENTS "Filesystem watching not supported on this platform."
|
||||
#endif
|
||||
|
||||
|
||||
Vendored
+2
-2
@@ -25,7 +25,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if !defined(_WIN32) && !defined(_AIX)
|
||||
#if !defined(_WIN32) && !defined(_AIX) && !defined(__QNX__)
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
@@ -56,7 +56,7 @@ TEST_IMPL(embed) {
|
||||
ASSERT_LE(0, uv_barrier_wait(&barrier));
|
||||
|
||||
while (uv_loop_alive(loop)) {
|
||||
#if defined(_WIN32) || defined(_AIX)
|
||||
#if defined(_WIN32) || defined(_AIX) || defined(__QNX__)
|
||||
ASSERT_LE(0, uv_run(loop, UV_RUN_ONCE));
|
||||
#else
|
||||
int rc;
|
||||
|
||||
Vendored
+8
-3
@@ -102,7 +102,7 @@ static void touch_file(const char* name, unsigned int size) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_copyfile) {
|
||||
TEST_FS_IMPL(fs_copyfile) {
|
||||
const char src[] = "test_file_src";
|
||||
uv_loop_t* loop;
|
||||
uv_fs_t req;
|
||||
@@ -220,8 +220,13 @@ TEST_IMPL(fs_copyfile) {
|
||||
r = uv_fs_copyfile(NULL, &req, fixture, dst, 0, NULL);
|
||||
/* On IBMi PASE, qsecofr users can overwrite read-only files */
|
||||
# ifndef __PASE__
|
||||
ASSERT_EQ(req.result, UV_EACCES);
|
||||
ASSERT_EQ(r, UV_EACCES);
|
||||
if (0 == getuid()) { /* If root. */
|
||||
ASSERT_EQ(req.result, 0);
|
||||
ASSERT_EQ(r, 0);
|
||||
} else {
|
||||
ASSERT_EQ(req.result, UV_EACCES);
|
||||
ASSERT_EQ(r, UV_EACCES);
|
||||
}
|
||||
# endif
|
||||
uv_fs_req_cleanup(&req);
|
||||
#endif
|
||||
|
||||
Vendored
+8
@@ -66,17 +66,25 @@ void assert_removal(int fd) {
|
||||
/* Run a function for a set of values up to a very high number */
|
||||
#define RUN_HASH(function) \
|
||||
do { \
|
||||
uint64_t before = uv_hrtime(); \
|
||||
for (fd = 0; fd < HASH_MAX; fd += HASH_INC) { \
|
||||
function(fd); \
|
||||
} \
|
||||
uint64_t after = uv_hrtime(); \
|
||||
double seconds = (after - before) / 1e9; \
|
||||
printf("%.5f hash %s\n", seconds, #function); \
|
||||
} while (0)
|
||||
|
||||
/* Run a function for a set of values that will cause many collisions */
|
||||
#define RUN_COLLISIONS(function) \
|
||||
do { \
|
||||
uint64_t before = uv_hrtime(); \
|
||||
for (fd = 1; fd < BUCKET_MAX; fd += BUCKET_INC) { \
|
||||
function(fd); \
|
||||
} \
|
||||
uint64_t after = uv_hrtime(); \
|
||||
double seconds = (after - before) / 1e9; \
|
||||
printf("%.5f coll %s\n", seconds, #function); \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
Vendored
+5
-5
@@ -96,7 +96,7 @@ static void empty_opendir_cb(uv_fs_t* req) {
|
||||
* of the uv_fs_opendir() -> uv_fs_readdir() -> uv_fs_closedir() sequence work
|
||||
* as expected when processing an empty directory.
|
||||
*/
|
||||
TEST_IMPL(fs_readdir_empty_dir) {
|
||||
TEST_FS_IMPL(fs_readdir_empty_dir) {
|
||||
const char* path;
|
||||
uv_fs_t mkdir_req;
|
||||
uv_fs_t rmdir_req;
|
||||
@@ -178,7 +178,7 @@ static void non_existing_opendir_cb(uv_fs_t* req) {
|
||||
++non_existing_opendir_cb_count;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_readdir_non_existing_dir) {
|
||||
TEST_FS_IMPL(fs_readdir_non_existing_dir) {
|
||||
const char* path;
|
||||
int r;
|
||||
|
||||
@@ -230,7 +230,7 @@ static void file_opendir_cb(uv_fs_t* req) {
|
||||
++file_opendir_cb_count;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_readdir_file) {
|
||||
TEST_FS_IMPL(fs_readdir_file) {
|
||||
const char* path;
|
||||
int r;
|
||||
|
||||
@@ -342,7 +342,7 @@ static void non_empty_opendir_cb(uv_fs_t* req) {
|
||||
++non_empty_opendir_cb_count;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_readdir_non_empty_dir) {
|
||||
TEST_FS_IMPL(fs_readdir_non_empty_dir) {
|
||||
size_t entries_count;
|
||||
uv_fs_t mkdir_req;
|
||||
uv_fs_t rmdir_req;
|
||||
@@ -518,7 +518,7 @@ static void cleanup_symlink_test_files(void) {
|
||||
uv_fs_req_cleanup(&req);
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_readdir_symlink) {
|
||||
TEST_FS_IMPL(fs_readdir_symlink) {
|
||||
|
||||
uv_fs_t mkdir_req;
|
||||
uv_fs_t symlink_req;
|
||||
|
||||
Vendored
+210
-85
@@ -23,6 +23,7 @@
|
||||
#include "task.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stddef.h> /* offsetof */
|
||||
#include <string.h> /* memset */
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -37,6 +38,13 @@
|
||||
# ifndef ERROR_SYMLINK_NOT_SUPPORTED
|
||||
# define ERROR_SYMLINK_NOT_SUPPORTED 1464
|
||||
# endif
|
||||
# ifndef REPARSE_DATA_BUFFER_HEADER_SIZE
|
||||
# define REPARSE_DATA_BUFFER_HEADER_SIZE \
|
||||
offsetof(REPARSE_DATA_BUFFER, GenericReparseBuffer)
|
||||
# endif
|
||||
# ifndef IO_REPARSE_TAG_LX_SYMLINK
|
||||
# define IO_REPARSE_TAG_LX_SYMLINK (0xA000001DL)
|
||||
# endif
|
||||
# ifndef S_IFIFO
|
||||
# define S_IFIFO _S_IFIFO
|
||||
# endif
|
||||
@@ -65,18 +73,30 @@ static const int is_win32 = 1;
|
||||
static const int is_win32 = 0;
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) || defined(__SUNPRO_C)
|
||||
static const int is_apple_or_sunpro_c = 1;
|
||||
#else
|
||||
static const int is_apple_or_sunpro_c = 0;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
const char* path;
|
||||
double atime;
|
||||
double mtime;
|
||||
} utime_check_t;
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifndef REPARSE_DATA_BUFFER
|
||||
typedef struct _REPARSE_DATA_BUFFER {
|
||||
ULONG ReparseTag;
|
||||
USHORT ReparseDataLength;
|
||||
USHORT Reserved;
|
||||
union {
|
||||
struct {
|
||||
ULONG Version;
|
||||
UCHAR PathBuffer[1];
|
||||
} LinuxSymbolicLinkReparseBuffer;
|
||||
struct {
|
||||
UCHAR DataBuffer[1];
|
||||
} GenericReparseBuffer;
|
||||
} DUMMYUNIONNAME;
|
||||
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static int dummy_cb_count;
|
||||
static int close_cb_count;
|
||||
@@ -152,7 +172,7 @@ int uv_test_getiovmax(void) {
|
||||
int uv_test_getiovmax(void) {
|
||||
#if defined(IOV_MAX)
|
||||
return IOV_MAX;
|
||||
#elif defined(_SC_IOV_MAX)
|
||||
#elif defined(_SC_IOV_MAX) && !defined(__QNX__)
|
||||
static int iovmax = -1;
|
||||
if (iovmax == -1) {
|
||||
iovmax = sysconf(_SC_IOV_MAX);
|
||||
@@ -356,13 +376,14 @@ static void statfs_cb(uv_fs_t* req) {
|
||||
stats = req->ptr;
|
||||
|
||||
#if defined(_WIN32) || defined(__sun) || defined(_AIX) || defined(__MVS__) || \
|
||||
defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
defined(__OpenBSD__) || defined(__NetBSD__) || defined(__QNX__)
|
||||
ASSERT_OK(stats->f_type);
|
||||
#else
|
||||
ASSERT_UINT64_GT(stats->f_type, 0);
|
||||
#endif
|
||||
|
||||
ASSERT_GT(stats->f_bsize, 0);
|
||||
ASSERT_GT(stats->f_frsize, 0);
|
||||
ASSERT_GT(stats->f_blocks, 0);
|
||||
ASSERT_LE(stats->f_bfree, stats->f_blocks);
|
||||
ASSERT_LE(stats->f_bavail, stats->f_bfree);
|
||||
@@ -728,7 +749,7 @@ static void open_loop_cb(uv_fs_t* req) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_file_noent) {
|
||||
TEST_FS_IMPL(fs_file_noent) {
|
||||
uv_fs_t req;
|
||||
int r;
|
||||
|
||||
@@ -753,7 +774,7 @@ TEST_IMPL(fs_file_noent) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_file_nametoolong) {
|
||||
TEST_FS_IMPL(fs_file_nametoolong) {
|
||||
uv_fs_t req;
|
||||
int r;
|
||||
char name[TOO_LONG_NAME_LENGTH + 1];
|
||||
@@ -779,7 +800,7 @@ TEST_IMPL(fs_file_nametoolong) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_file_loop) {
|
||||
TEST_FS_IMPL(fs_file_loop) {
|
||||
uv_fs_t req;
|
||||
int r;
|
||||
|
||||
@@ -855,9 +876,10 @@ static void check_utime(const char* path,
|
||||
ASSERT_LE(s->st_atim.tv_sec, (long) atime);
|
||||
} else {
|
||||
double st_atim;
|
||||
#ifndef __APPLE__
|
||||
/* TODO(vtjnash): would it be better to normalize this? */
|
||||
if (!is_apple_or_sunpro_c)
|
||||
ASSERT_DOUBLE_GE(s->st_atim.tv_nsec, 0);
|
||||
ASSERT_DOUBLE_GE(s->st_atim.tv_nsec, 0);
|
||||
#endif
|
||||
st_atim = s->st_atim.tv_sec + s->st_atim.tv_nsec / 1e9;
|
||||
/* Linux does not allow reading reliably the atime of a symlink
|
||||
* since readlink() can update it
|
||||
@@ -890,9 +912,10 @@ static void check_utime(const char* path,
|
||||
ASSERT_LE(s->st_mtim.tv_sec, (long) mtime);
|
||||
} else {
|
||||
double st_mtim;
|
||||
#ifndef __APPLE__
|
||||
/* TODO(vtjnash): would it be better to normalize this? */
|
||||
if (!is_apple_or_sunpro_c)
|
||||
ASSERT_DOUBLE_GE(s->st_mtim.tv_nsec, 0);
|
||||
ASSERT_DOUBLE_GE(s->st_mtim.tv_nsec, 0);
|
||||
#endif
|
||||
st_mtim = s->st_mtim.tv_sec + s->st_mtim.tv_nsec / 1e9;
|
||||
ASSERT_DOUBLE_EQ(st_mtim, mtime);
|
||||
}
|
||||
@@ -953,7 +976,7 @@ static void lutime_cb(uv_fs_t* req) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_file_async) {
|
||||
TEST_FS_IMPL(fs_file_async) {
|
||||
int r;
|
||||
|
||||
/* Setup. */
|
||||
@@ -1099,7 +1122,7 @@ static void fs_file_sync(int add_flags) {
|
||||
unlink("test_file");
|
||||
unlink("test_file2");
|
||||
}
|
||||
TEST_IMPL(fs_file_sync) {
|
||||
TEST_FS_IMPL(fs_file_sync) {
|
||||
fs_file_sync(0);
|
||||
fs_file_sync(UV_FS_O_FILEMAP);
|
||||
|
||||
@@ -1107,7 +1130,7 @@ TEST_IMPL(fs_file_sync) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_posix_delete) {
|
||||
TEST_FS_IMPL(fs_posix_delete) {
|
||||
int r;
|
||||
|
||||
/* Setup. */
|
||||
@@ -1180,7 +1203,7 @@ static void fs_file_write_null_buffer(int add_flags) {
|
||||
|
||||
unlink("test_file");
|
||||
}
|
||||
TEST_IMPL(fs_file_write_null_buffer) {
|
||||
TEST_FS_IMPL(fs_file_write_null_buffer) {
|
||||
fs_file_write_null_buffer(0);
|
||||
fs_file_write_null_buffer(UV_FS_O_FILEMAP);
|
||||
|
||||
@@ -1189,7 +1212,7 @@ TEST_IMPL(fs_file_write_null_buffer) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_async_dir) {
|
||||
TEST_FS_IMPL(fs_async_dir) {
|
||||
int r;
|
||||
uv_dirent_t dent;
|
||||
|
||||
@@ -1373,17 +1396,17 @@ static void sendfile_setup(int f) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_async_sendfile) {
|
||||
TEST_FS_IMPL(fs_async_sendfile) {
|
||||
return test_sendfile(sendfile_setup, sendfile_cb, 65545);
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_async_sendfile_nodata) {
|
||||
TEST_FS_IMPL(fs_async_sendfile_nodata) {
|
||||
return test_sendfile(NULL, sendfile_nodata_cb, 0);
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_mkdtemp) {
|
||||
TEST_FS_IMPL(fs_mkdtemp) {
|
||||
int r;
|
||||
const char* path_template = "test_dir_XXXXXX";
|
||||
|
||||
@@ -1414,7 +1437,7 @@ TEST_IMPL(fs_mkdtemp) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_mkstemp) {
|
||||
TEST_FS_IMPL(fs_mkstemp) {
|
||||
int r;
|
||||
int fd;
|
||||
const char path_template[] = "test_file_XXXXXX";
|
||||
@@ -1482,7 +1505,7 @@ TEST_IMPL(fs_mkstemp) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_fstat) {
|
||||
TEST_FS_IMPL(fs_fstat) {
|
||||
int r;
|
||||
uv_fs_t req;
|
||||
uv_file file;
|
||||
@@ -1646,7 +1669,7 @@ TEST_IMPL(fs_fstat) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_fstat_st_dev) {
|
||||
TEST_FS_IMPL(fs_fstat_st_dev) {
|
||||
uv_fs_t req;
|
||||
uv_fs_t req_link;
|
||||
uv_loop_t* loop = uv_default_loop();
|
||||
@@ -1690,7 +1713,7 @@ TEST_IMPL(fs_fstat_st_dev) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_fstat_stdio) {
|
||||
TEST_FS_IMPL(fs_fstat_stdio) {
|
||||
int fd;
|
||||
int res;
|
||||
uv_fs_t req;
|
||||
@@ -1729,7 +1752,7 @@ TEST_IMPL(fs_fstat_stdio) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_access) {
|
||||
TEST_FS_IMPL(fs_access) {
|
||||
int r;
|
||||
uv_fs_t req;
|
||||
uv_file file;
|
||||
@@ -1805,7 +1828,7 @@ TEST_IMPL(fs_access) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_chmod) {
|
||||
TEST_FS_IMPL(fs_chmod) {
|
||||
int r;
|
||||
uv_fs_t req;
|
||||
uv_file file;
|
||||
@@ -1903,7 +1926,7 @@ TEST_IMPL(fs_chmod) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_unlink_readonly) {
|
||||
TEST_FS_IMPL(fs_unlink_readonly) {
|
||||
int r;
|
||||
uv_fs_t req;
|
||||
uv_file file;
|
||||
@@ -1960,7 +1983,7 @@ TEST_IMPL(fs_unlink_readonly) {
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
TEST_IMPL(fs_unlink_archive_readonly) {
|
||||
TEST_FS_IMPL(fs_unlink_archive_readonly) {
|
||||
int r;
|
||||
uv_fs_t req;
|
||||
uv_file file;
|
||||
@@ -2016,7 +2039,7 @@ TEST_IMPL(fs_unlink_archive_readonly) {
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_IMPL(fs_chown) {
|
||||
TEST_FS_IMPL(fs_chown) {
|
||||
int r;
|
||||
uv_fs_t req;
|
||||
uv_file file;
|
||||
@@ -2109,7 +2132,7 @@ TEST_IMPL(fs_chown) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_link) {
|
||||
TEST_FS_IMPL(fs_link) {
|
||||
int r;
|
||||
uv_fs_t req;
|
||||
uv_file file;
|
||||
@@ -2195,7 +2218,7 @@ TEST_IMPL(fs_link) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_readlink) {
|
||||
TEST_FS_IMPL(fs_readlink) {
|
||||
/* Must return UV_ENOENT on an inexistent file */
|
||||
{
|
||||
uv_fs_t req;
|
||||
@@ -2249,7 +2272,7 @@ TEST_IMPL(fs_readlink) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_realpath) {
|
||||
TEST_FS_IMPL(fs_realpath) {
|
||||
uv_fs_t req;
|
||||
|
||||
loop = uv_default_loop();
|
||||
@@ -2270,7 +2293,7 @@ TEST_IMPL(fs_realpath) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_symlink) {
|
||||
TEST_FS_IMPL(fs_symlink) {
|
||||
int r;
|
||||
uv_fs_t req;
|
||||
uv_file file;
|
||||
@@ -2584,16 +2607,16 @@ int test_symlink_dir_impl(int type) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_symlink_dir) {
|
||||
TEST_FS_IMPL(fs_symlink_dir) {
|
||||
return test_symlink_dir_impl(UV_FS_SYMLINK_DIR);
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_symlink_junction) {
|
||||
TEST_FS_IMPL(fs_symlink_junction) {
|
||||
return test_symlink_dir_impl(UV_FS_SYMLINK_JUNCTION);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
TEST_IMPL(fs_non_symlink_reparse_point) {
|
||||
TEST_FS_IMPL(fs_non_symlink_reparse_point) {
|
||||
uv_fs_t req;
|
||||
int r;
|
||||
HANDLE file_handle;
|
||||
@@ -2693,7 +2716,81 @@ TEST_IMPL(fs_non_symlink_reparse_point) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_lstat_windows_store_apps) {
|
||||
TEST_FS_IMPL(fs_readlink_lx_symlink) {
|
||||
uv_fs_t req;
|
||||
int r;
|
||||
HANDLE file_handle;
|
||||
REPARSE_DATA_BUFFER* reparse_buffer;
|
||||
DWORD bytes_returned;
|
||||
const char* target_path = "target_file";
|
||||
size_t target_len = strlen(target_path);
|
||||
size_t buffer_size;
|
||||
|
||||
/* set-up */
|
||||
unlink("test_dir/lx_symlink");
|
||||
rmdir("test_dir");
|
||||
|
||||
loop = uv_default_loop();
|
||||
|
||||
uv_fs_mkdir(NULL, &req, "test_dir", 0777, NULL);
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
file_handle = CreateFile("test_dir/lx_symlink",
|
||||
GENERIC_WRITE | FILE_WRITE_ATTRIBUTES,
|
||||
0,
|
||||
NULL,
|
||||
CREATE_ALWAYS,
|
||||
FILE_FLAG_OPEN_REPARSE_POINT |
|
||||
FILE_FLAG_BACKUP_SEMANTICS,
|
||||
NULL);
|
||||
ASSERT_PTR_NE(file_handle, INVALID_HANDLE_VALUE);
|
||||
|
||||
/* Allocate buffer for reparse data */
|
||||
buffer_size = REPARSE_DATA_BUFFER_HEADER_SIZE +
|
||||
sizeof(ULONG) + /* Version field */
|
||||
target_len;
|
||||
reparse_buffer = malloc(buffer_size);
|
||||
ASSERT_NOT_NULL(reparse_buffer);
|
||||
|
||||
/* Set up Linux symlink reparse buffer */
|
||||
memset(reparse_buffer, 0, buffer_size);
|
||||
reparse_buffer->ReparseTag = IO_REPARSE_TAG_LX_SYMLINK;
|
||||
reparse_buffer->ReparseDataLength = sizeof(ULONG) + target_len;
|
||||
reparse_buffer->Reserved = 0;
|
||||
reparse_buffer->LinuxSymbolicLinkReparseBuffer.Version = 2;
|
||||
memcpy(reparse_buffer->LinuxSymbolicLinkReparseBuffer.PathBuffer,
|
||||
target_path,
|
||||
target_len);
|
||||
|
||||
r = DeviceIoControl(file_handle,
|
||||
FSCTL_SET_REPARSE_POINT,
|
||||
reparse_buffer,
|
||||
buffer_size,
|
||||
NULL,
|
||||
0,
|
||||
&bytes_returned,
|
||||
NULL);
|
||||
ASSERT(r);
|
||||
|
||||
CloseHandle(file_handle);
|
||||
|
||||
/* Test that readlink works on the Linux symlink */
|
||||
r = uv_fs_readlink(NULL, &req, "test_dir/lx_symlink", NULL);
|
||||
ASSERT_OK(r);
|
||||
ASSERT_NOT_NULL(req.ptr);
|
||||
ASSERT_OK(strcmp(req.ptr, target_path));
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
/* clean-up */
|
||||
free(reparse_buffer);
|
||||
unlink("test_dir/lx_symlink");
|
||||
rmdir("test_dir");
|
||||
|
||||
MAKE_VALGRIND_HAPPY(loop);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_FS_IMPL(fs_lstat_windows_store_apps) {
|
||||
uv_loop_t* loop;
|
||||
char localappdata[MAX_PATH];
|
||||
char windowsapps_path[MAX_PATH];
|
||||
@@ -2746,7 +2843,7 @@ TEST_IMPL(fs_lstat_windows_store_apps) {
|
||||
#endif
|
||||
|
||||
|
||||
TEST_IMPL(fs_utime) {
|
||||
TEST_FS_IMPL(fs_utime) {
|
||||
utime_check_t checkme;
|
||||
const char* path = "test_file";
|
||||
double atime;
|
||||
@@ -2827,13 +2924,15 @@ TEST_IMPL(fs_utime) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_utime_round) {
|
||||
TEST_FS_IMPL(fs_utime_round) {
|
||||
const char path[] = "test_file";
|
||||
double atime;
|
||||
double mtime;
|
||||
uv_fs_t req;
|
||||
int r;
|
||||
|
||||
#if defined(__QNX__)
|
||||
RETURN_SKIP("Setting time to a negative value is unsupported on QNX");
|
||||
#endif
|
||||
loop = uv_default_loop();
|
||||
unlink(path);
|
||||
r = uv_fs_open(NULL, &req, path, UV_FS_O_RDWR | UV_FS_O_CREAT,
|
||||
@@ -2869,7 +2968,7 @@ TEST_IMPL(fs_utime_round) {
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
TEST_IMPL(fs_stat_root) {
|
||||
TEST_FS_IMPL(fs_stat_root) {
|
||||
int r;
|
||||
|
||||
r = uv_fs_stat(NULL, &stat_req, "\\", NULL);
|
||||
@@ -2900,7 +2999,7 @@ TEST_IMPL(fs_stat_root) {
|
||||
#endif
|
||||
|
||||
|
||||
TEST_IMPL(fs_futime) {
|
||||
TEST_FS_IMPL(fs_futime) {
|
||||
utime_check_t checkme;
|
||||
const char* path = "test_file";
|
||||
double atime;
|
||||
@@ -2998,7 +3097,7 @@ TEST_IMPL(fs_futime) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_lutime) {
|
||||
TEST_FS_IMPL(fs_lutime) {
|
||||
utime_check_t checkme;
|
||||
const char* path = "test_file";
|
||||
const char* symlink_path = "test_file_symlink";
|
||||
@@ -3105,7 +3204,7 @@ TEST_IMPL(fs_lutime) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_stat_missing_path) {
|
||||
TEST_FS_IMPL(fs_stat_missing_path) {
|
||||
uv_fs_t req;
|
||||
int r;
|
||||
|
||||
@@ -3121,7 +3220,7 @@ TEST_IMPL(fs_stat_missing_path) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_scandir_empty_dir) {
|
||||
TEST_FS_IMPL(fs_scandir_empty_dir) {
|
||||
const char* path;
|
||||
uv_fs_t req;
|
||||
uv_dirent_t dent;
|
||||
@@ -3158,7 +3257,7 @@ TEST_IMPL(fs_scandir_empty_dir) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_scandir_non_existent_dir) {
|
||||
TEST_FS_IMPL(fs_scandir_non_existent_dir) {
|
||||
const char* path;
|
||||
uv_fs_t req;
|
||||
uv_dirent_t dent;
|
||||
@@ -3191,7 +3290,7 @@ TEST_IMPL(fs_scandir_non_existent_dir) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_scandir_file) {
|
||||
TEST_FS_IMPL(fs_scandir_file) {
|
||||
const char* path;
|
||||
int r;
|
||||
|
||||
@@ -3215,7 +3314,7 @@ TEST_IMPL(fs_scandir_file) {
|
||||
|
||||
|
||||
/* Run in Valgrind. Should not leak when the iterator isn't exhausted. */
|
||||
TEST_IMPL(fs_scandir_early_exit) {
|
||||
TEST_FS_IMPL(fs_scandir_early_exit) {
|
||||
uv_dirent_t d;
|
||||
uv_fs_t req;
|
||||
|
||||
@@ -3232,7 +3331,7 @@ TEST_IMPL(fs_scandir_early_exit) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_open_dir) {
|
||||
TEST_FS_IMPL(fs_open_dir) {
|
||||
const char* path;
|
||||
uv_fs_t req;
|
||||
int r, file;
|
||||
@@ -3329,7 +3428,7 @@ static void fs_file_open_append(int add_flags) {
|
||||
/* Cleanup */
|
||||
unlink("test_file");
|
||||
}
|
||||
TEST_IMPL(fs_file_open_append) {
|
||||
TEST_FS_IMPL(fs_file_open_append) {
|
||||
fs_file_open_append(0);
|
||||
fs_file_open_append(UV_FS_O_FILEMAP);
|
||||
|
||||
@@ -3338,7 +3437,7 @@ TEST_IMPL(fs_file_open_append) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_rename_to_existing_file) {
|
||||
TEST_FS_IMPL(fs_rename_to_existing_file) {
|
||||
int r;
|
||||
|
||||
/* Setup. */
|
||||
@@ -3456,7 +3555,7 @@ static void fs_read_bufs(int add_flags) {
|
||||
ASSERT_OK(close_req.result);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
}
|
||||
TEST_IMPL(fs_read_bufs) {
|
||||
TEST_FS_IMPL(fs_read_bufs) {
|
||||
fs_read_bufs(0);
|
||||
fs_read_bufs(UV_FS_O_FILEMAP);
|
||||
|
||||
@@ -3523,7 +3622,7 @@ static void fs_read_file_eof(int add_flags) {
|
||||
/* Cleanup */
|
||||
unlink("test_file");
|
||||
}
|
||||
TEST_IMPL(fs_read_file_eof) {
|
||||
TEST_FS_IMPL(fs_read_file_eof) {
|
||||
fs_read_file_eof(0);
|
||||
fs_read_file_eof(UV_FS_O_FILEMAP);
|
||||
|
||||
@@ -3618,7 +3717,7 @@ static void fs_write_multiple_bufs(int add_flags) {
|
||||
/* Cleanup */
|
||||
unlink("test_file");
|
||||
}
|
||||
TEST_IMPL(fs_write_multiple_bufs) {
|
||||
TEST_FS_IMPL(fs_write_multiple_bufs) {
|
||||
fs_write_multiple_bufs(0);
|
||||
fs_write_multiple_bufs(UV_FS_O_FILEMAP);
|
||||
|
||||
@@ -3726,7 +3825,7 @@ static void fs_write_alotof_bufs(int add_flags) {
|
||||
unlink("test_file");
|
||||
free(iovs);
|
||||
}
|
||||
TEST_IMPL(fs_write_alotof_bufs) {
|
||||
TEST_FS_IMPL(fs_write_alotof_bufs) {
|
||||
fs_write_alotof_bufs(0);
|
||||
fs_write_alotof_bufs(UV_FS_O_FILEMAP);
|
||||
|
||||
@@ -3842,7 +3941,7 @@ static void fs_write_alotof_bufs_with_offset(int add_flags) {
|
||||
unlink("test_file");
|
||||
free(iovs);
|
||||
}
|
||||
TEST_IMPL(fs_write_alotof_bufs_with_offset) {
|
||||
TEST_FS_IMPL(fs_write_alotof_bufs_with_offset) {
|
||||
fs_write_alotof_bufs_with_offset(0);
|
||||
fs_write_alotof_bufs_with_offset(UV_FS_O_FILEMAP);
|
||||
|
||||
@@ -3850,7 +3949,7 @@ TEST_IMPL(fs_write_alotof_bufs_with_offset) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_read_dir) {
|
||||
TEST_FS_IMPL(fs_read_dir) {
|
||||
int r;
|
||||
char buf[2];
|
||||
loop = uv_default_loop();
|
||||
@@ -3889,6 +3988,12 @@ TEST_IMPL(fs_read_dir) {
|
||||
* created on. That is why this assertion is a bit lenient.
|
||||
*/
|
||||
ASSERT((r >= 0) || (r == UV_EISDIR));
|
||||
#elif defined(__QNX__)
|
||||
/*
|
||||
* If UV_FS_O_DIRECTORY is supplied, QNX returns ENOSYS. Otherwise
|
||||
* UV_EISDIR is returned. Here we are lenient and accept both.
|
||||
*/
|
||||
ASSERT((r == UV_ENOSYS) || (r == UV_EISDIR));
|
||||
#else
|
||||
ASSERT_EQ(r, UV_EISDIR);
|
||||
#endif
|
||||
@@ -3907,11 +4012,11 @@ TEST_IMPL(fs_read_dir) {
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
TEST_IMPL(fs_partial_read) {
|
||||
TEST_FS_IMPL(fs_partial_read) {
|
||||
RETURN_SKIP("Test not implemented on Windows.");
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_partial_write) {
|
||||
TEST_FS_IMPL(fs_partial_write) {
|
||||
RETURN_SKIP("Test not implemented on Windows.");
|
||||
}
|
||||
|
||||
@@ -4063,19 +4168,19 @@ static void test_fs_partial(int doread) {
|
||||
MAKE_VALGRIND_HAPPY(loop);
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_partial_read) {
|
||||
TEST_FS_IMPL(fs_partial_read) {
|
||||
test_fs_partial(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_partial_write) {
|
||||
TEST_FS_IMPL(fs_partial_write) {
|
||||
test_fs_partial(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif/* _WIN32 */
|
||||
|
||||
TEST_IMPL(fs_read_write_null_arguments) {
|
||||
TEST_FS_IMPL(fs_read_write_null_arguments) {
|
||||
int r;
|
||||
|
||||
r = uv_fs_read(NULL, &read_req, 0, NULL, 0, -1, NULL);
|
||||
@@ -4138,7 +4243,7 @@ TEST_IMPL(fs_read_write_null_arguments) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(get_osfhandle_valid_handle) {
|
||||
TEST_FS_IMPL(get_osfhandle_valid_handle) {
|
||||
int r;
|
||||
uv_os_fd_t fd;
|
||||
|
||||
@@ -4174,7 +4279,7 @@ TEST_IMPL(get_osfhandle_valid_handle) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_IMPL(open_osfhandle_valid_handle) {
|
||||
TEST_FS_IMPL(open_osfhandle_valid_handle) {
|
||||
int r;
|
||||
uv_os_fd_t handle;
|
||||
int fd;
|
||||
@@ -4220,7 +4325,7 @@ TEST_IMPL(open_osfhandle_valid_handle) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_file_pos_after_op_with_offset) {
|
||||
TEST_FS_IMPL(fs_file_pos_after_op_with_offset) {
|
||||
int r;
|
||||
|
||||
/* Setup. */
|
||||
@@ -4349,7 +4454,7 @@ static void fs_file_pos_write(int add_flags) {
|
||||
|
||||
fs_file_pos_close_check("aecd", 4);
|
||||
}
|
||||
TEST_IMPL(fs_file_pos_write) {
|
||||
TEST_FS_IMPL(fs_file_pos_write) {
|
||||
fs_file_pos_write(0);
|
||||
fs_file_pos_write(UV_FS_O_FILEMAP);
|
||||
|
||||
@@ -4389,7 +4494,7 @@ static void fs_file_pos_append(int add_flags) {
|
||||
|
||||
fs_file_pos_close_check("abcde", 5);
|
||||
}
|
||||
TEST_IMPL(fs_file_pos_append) {
|
||||
TEST_FS_IMPL(fs_file_pos_append) {
|
||||
fs_file_pos_append(0);
|
||||
fs_file_pos_append(UV_FS_O_FILEMAP);
|
||||
|
||||
@@ -4398,7 +4503,7 @@ TEST_IMPL(fs_file_pos_append) {
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_IMPL(fs_null_req) {
|
||||
TEST_FS_IMPL(fs_null_req) {
|
||||
/* Verify that all fs functions return UV_EINVAL when the request is NULL. */
|
||||
int r;
|
||||
|
||||
@@ -4502,7 +4607,7 @@ TEST_IMPL(fs_null_req) {
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
TEST_IMPL(fs_exclusive_sharing_mode) {
|
||||
TEST_FS_IMPL(fs_exclusive_sharing_mode) {
|
||||
int r;
|
||||
|
||||
/* Setup. */
|
||||
@@ -4557,7 +4662,7 @@ TEST_IMPL(fs_exclusive_sharing_mode) {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
TEST_IMPL(fs_file_flag_no_buffering) {
|
||||
TEST_FS_IMPL(fs_file_flag_no_buffering) {
|
||||
int r;
|
||||
|
||||
/* Setup. */
|
||||
@@ -4614,7 +4719,7 @@ int call_icacls(const char* command, ...) {
|
||||
return system(icacls_command);
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_open_readonly_acl) {
|
||||
TEST_FS_IMPL(fs_open_readonly_acl) {
|
||||
uv_passwd_t pwd;
|
||||
uv_fs_t req;
|
||||
int r;
|
||||
@@ -4689,7 +4794,7 @@ TEST_IMPL(fs_open_readonly_acl) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_stat_no_permission) {
|
||||
TEST_FS_IMPL(fs_stat_no_permission) {
|
||||
uv_passwd_t pwd;
|
||||
uv_fs_t req;
|
||||
int r;
|
||||
@@ -4745,7 +4850,7 @@ TEST_IMPL(fs_stat_no_permission) {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
TEST_IMPL(fs_fchmod_archive_readonly) {
|
||||
TEST_FS_IMPL(fs_fchmod_archive_readonly) {
|
||||
uv_fs_t req;
|
||||
uv_file file;
|
||||
int r;
|
||||
@@ -4790,7 +4895,7 @@ TEST_IMPL(fs_fchmod_archive_readonly) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_invalid_mkdir_name) {
|
||||
TEST_FS_IMPL(fs_invalid_mkdir_name) {
|
||||
uv_loop_t* loop;
|
||||
uv_fs_t req;
|
||||
int r;
|
||||
@@ -4804,29 +4909,49 @@ TEST_IMPL(fs_invalid_mkdir_name) {
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_IMPL(fs_statfs) {
|
||||
TEST_FS_IMPL(fs_statfs) {
|
||||
uv_fs_t req;
|
||||
uv_fs_t req1;
|
||||
int r;
|
||||
|
||||
/* Setup. */
|
||||
unlink("test_file");
|
||||
|
||||
r = uv_fs_open(NULL, &req, "test_file", UV_FS_O_WRONLY | UV_FS_O_CREAT,
|
||||
S_IRUSR | S_IWUSR, NULL);
|
||||
ASSERT_GT(r, 0);
|
||||
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
r = uv_fs_close(NULL, &req, req.result, NULL);
|
||||
ASSERT_OK(r);
|
||||
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
loop = uv_default_loop();
|
||||
|
||||
/* Test the synchronous version. */
|
||||
/* Test the synchronous version for both a directory and a file. */
|
||||
r = uv_fs_statfs(NULL, &req, ".", NULL);
|
||||
ASSERT_OK(r);
|
||||
statfs_cb(&req);
|
||||
ASSERT_EQ(1, statfs_cb_count);
|
||||
r = uv_fs_statfs(NULL, &req, "test_file", NULL);
|
||||
ASSERT_OK(r);
|
||||
statfs_cb(&req);
|
||||
ASSERT_EQ(2, statfs_cb_count);
|
||||
|
||||
/* Test the asynchronous version. */
|
||||
/* Test the asynchronous version too. */
|
||||
r = uv_fs_statfs(loop, &req, ".", statfs_cb);
|
||||
ASSERT_OK(r);
|
||||
r = uv_fs_statfs(loop, &req1, "test_file", statfs_cb);
|
||||
ASSERT_OK(r);
|
||||
uv_run(loop, UV_RUN_DEFAULT);
|
||||
ASSERT_EQ(2, statfs_cb_count);
|
||||
ASSERT_EQ(4, statfs_cb_count);
|
||||
|
||||
MAKE_VALGRIND_HAPPY(loop);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_get_system_error) {
|
||||
TEST_FS_IMPL(fs_get_system_error) {
|
||||
uv_fs_t req;
|
||||
int r;
|
||||
int system_error;
|
||||
@@ -4845,7 +4970,7 @@ TEST_IMPL(fs_get_system_error) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_stat_batch_multiple) {
|
||||
TEST_FS_IMPL(fs_stat_batch_multiple) {
|
||||
uv_fs_t req[300];
|
||||
int r;
|
||||
int i;
|
||||
@@ -4871,7 +4996,7 @@ TEST_IMPL(fs_stat_batch_multiple) {
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
TEST_IMPL(fs_wtf) {
|
||||
TEST_FS_IMPL(fs_wtf) {
|
||||
int r;
|
||||
HANDLE file_handle;
|
||||
uv_dirent_t dent;
|
||||
|
||||
Vendored
-3
@@ -35,9 +35,6 @@ TEST_IMPL(get_currentexe) {
|
||||
#if defined(__QEMU__)
|
||||
RETURN_SKIP("Test does not currently work in QEMU");
|
||||
#endif
|
||||
#if defined(__OpenBSD__)
|
||||
RETURN_SKIP("Test does not currently work in OpenBSD");
|
||||
#endif
|
||||
|
||||
char buffer[PATHMAX];
|
||||
char path[PATHMAX];
|
||||
|
||||
Vendored
+2
-4
@@ -119,7 +119,7 @@ TEST_IMPL(getaddrinfo_fail_sync) {
|
||||
uv_getaddrinfo_t req;
|
||||
|
||||
/* Use a FQDN by ending in a period */
|
||||
ASSERT_GT(0, uv_getaddrinfo(uv_default_loop(),
|
||||
ASSERT_GT(0, uv_getaddrinfo(NULL,
|
||||
&req,
|
||||
NULL,
|
||||
"example.invalid.",
|
||||
@@ -165,15 +165,13 @@ TEST_IMPL(getaddrinfo_basic_sync) {
|
||||
#endif
|
||||
uv_getaddrinfo_t req;
|
||||
|
||||
ASSERT_OK(uv_getaddrinfo(uv_default_loop(),
|
||||
ASSERT_OK(uv_getaddrinfo(NULL,
|
||||
&req,
|
||||
NULL,
|
||||
name,
|
||||
NULL,
|
||||
NULL));
|
||||
uv_freeaddrinfo(req.addrinfo);
|
||||
|
||||
MAKE_VALGRIND_HAPPY(uv_default_loop());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Vendored
+16
@@ -19,6 +19,14 @@
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* This blank UV_EXTERN squelches "‘uv_wtf8_to_utf16’ redeclared without
|
||||
* dllimport attribute: previous dllimport ignored" warnings. We neither want
|
||||
* or need dllimport or dllexport, we just include the source file verbatim.
|
||||
* It's kind of sloppy because we end up with duplicate symbols, one in
|
||||
* libuv.dll and one in this translation unit, but it works out fine in
|
||||
* the end.
|
||||
*/
|
||||
#define UV_EXTERN
|
||||
#include "task.h"
|
||||
#define uv__malloc malloc
|
||||
#include "../src/idna.c"
|
||||
@@ -228,5 +236,13 @@ TEST_IMPL(wtf8) {
|
||||
ASSERT_GT(len, 0);
|
||||
ASSERT_LT(len, ARRAY_SIZE(buf));
|
||||
uv_wtf8_to_utf16(input, buf, len);
|
||||
|
||||
/* Test 0x10FFFF, max unicode character */
|
||||
static const char input_max[] = "\xF4\x8F\xBF\xBF";
|
||||
|
||||
len = uv_wtf8_length_as_utf16(input_max);
|
||||
ASSERT_GT(len, 0);
|
||||
ASSERT_LT(len, ARRAY_SIZE(buf));
|
||||
uv_wtf8_to_utf16(input_max, buf, len);
|
||||
return 0;
|
||||
}
|
||||
Vendored
+158
-146
@@ -77,6 +77,7 @@ TEST_DECLARE (tty_escape_sequence_processing)
|
||||
#endif
|
||||
TEST_DECLARE (tty_file)
|
||||
TEST_DECLARE (tty_pty)
|
||||
TEST_DECLARE (tty_pty_partial)
|
||||
TEST_DECLARE (stdio_over_pipes)
|
||||
TEST_DECLARE (stdio_emulate_iocp)
|
||||
TEST_DECLARE (ip6_pton)
|
||||
@@ -175,6 +176,10 @@ TEST_DECLARE (udp_send_and_recv)
|
||||
TEST_DECLARE (udp_send_hang_loop)
|
||||
TEST_DECLARE (udp_send_immediate)
|
||||
TEST_DECLARE (udp_send_unreachable)
|
||||
TEST_DECLARE (udp_recv_cb_close_pollerr)
|
||||
TEST_DECLARE (udp_recvmsg_unreachable_error)
|
||||
TEST_DECLARE (udp_recvmsg_unreachable_error6)
|
||||
TEST_DECLARE (udp_send_pollerr_no_recv)
|
||||
TEST_DECLARE (udp_mmsg)
|
||||
TEST_DECLARE (udp_multicast_join)
|
||||
TEST_DECLARE (udp_multicast_join6)
|
||||
@@ -352,53 +357,54 @@ TEST_DECLARE (fs_poll_close_request_multi_stop_start)
|
||||
TEST_DECLARE (fs_poll_close_request_stop_when_active)
|
||||
TEST_DECLARE (kill)
|
||||
TEST_DECLARE (kill_invalid_signum)
|
||||
TEST_DECLARE (fs_file_noent)
|
||||
TEST_DECLARE (fs_file_nametoolong)
|
||||
TEST_DECLARE (fs_file_loop)
|
||||
TEST_DECLARE (fs_file_async)
|
||||
TEST_DECLARE (fs_file_sync)
|
||||
TEST_DECLARE (fs_posix_delete)
|
||||
TEST_DECLARE (fs_file_write_null_buffer)
|
||||
TEST_DECLARE (fs_async_dir)
|
||||
TEST_DECLARE (fs_async_sendfile)
|
||||
TEST_DECLARE (fs_async_sendfile_nodata)
|
||||
TEST_DECLARE (fs_mkdtemp)
|
||||
TEST_DECLARE (fs_mkstemp)
|
||||
TEST_DECLARE (fs_fstat)
|
||||
TEST_DECLARE (fs_fstat_stdio)
|
||||
TEST_DECLARE (fs_fstat_st_dev)
|
||||
TEST_DECLARE (fs_access)
|
||||
TEST_DECLARE (fs_chmod)
|
||||
TEST_DECLARE (fs_copyfile)
|
||||
TEST_DECLARE (fs_unlink_readonly)
|
||||
TEST_FS_DECLARE (fs_file_noent)
|
||||
TEST_FS_DECLARE (fs_file_nametoolong)
|
||||
TEST_FS_DECLARE (fs_file_loop)
|
||||
TEST_FS_DECLARE (fs_file_async)
|
||||
TEST_FS_DECLARE (fs_file_sync)
|
||||
TEST_FS_DECLARE (fs_posix_delete)
|
||||
TEST_FS_DECLARE (fs_file_write_null_buffer)
|
||||
TEST_FS_DECLARE (fs_async_dir)
|
||||
TEST_FS_DECLARE (fs_async_sendfile)
|
||||
TEST_FS_DECLARE (fs_async_sendfile_nodata)
|
||||
TEST_FS_DECLARE (fs_mkdtemp)
|
||||
TEST_FS_DECLARE (fs_mkstemp)
|
||||
TEST_FS_DECLARE (fs_fstat)
|
||||
TEST_FS_DECLARE (fs_fstat_stdio)
|
||||
TEST_FS_DECLARE (fs_fstat_st_dev)
|
||||
TEST_FS_DECLARE (fs_access)
|
||||
TEST_FS_DECLARE (fs_chmod)
|
||||
TEST_FS_DECLARE (fs_copyfile)
|
||||
TEST_FS_DECLARE (fs_unlink_readonly)
|
||||
#ifdef _WIN32
|
||||
TEST_DECLARE (fs_unlink_archive_readonly)
|
||||
TEST_FS_DECLARE (fs_unlink_archive_readonly)
|
||||
#endif
|
||||
TEST_DECLARE (fs_chown)
|
||||
TEST_DECLARE (fs_link)
|
||||
TEST_DECLARE (fs_readlink)
|
||||
TEST_DECLARE (fs_realpath)
|
||||
TEST_DECLARE (fs_symlink)
|
||||
TEST_DECLARE (fs_symlink_dir)
|
||||
TEST_FS_DECLARE (fs_chown)
|
||||
TEST_FS_DECLARE (fs_link)
|
||||
TEST_FS_DECLARE (fs_readlink)
|
||||
TEST_FS_DECLARE (fs_realpath)
|
||||
TEST_FS_DECLARE (fs_symlink)
|
||||
TEST_FS_DECLARE (fs_symlink_dir)
|
||||
#ifdef _WIN32
|
||||
TEST_DECLARE (fs_symlink_junction)
|
||||
TEST_DECLARE (fs_non_symlink_reparse_point)
|
||||
TEST_DECLARE (fs_lstat_windows_store_apps)
|
||||
TEST_DECLARE (fs_open_flags)
|
||||
TEST_FS_DECLARE (fs_symlink_junction)
|
||||
TEST_FS_DECLARE (fs_non_symlink_reparse_point)
|
||||
TEST_FS_DECLARE (fs_readlink_lx_symlink)
|
||||
TEST_FS_DECLARE (fs_lstat_windows_store_apps)
|
||||
TEST_FS_DECLARE (fs_open_flags)
|
||||
#endif
|
||||
#if defined(_WIN32) && !defined(USING_UV_SHARED)
|
||||
TEST_DECLARE (fs_fd_hash)
|
||||
TEST_FS_DECLARE (fs_fd_hash)
|
||||
#endif
|
||||
TEST_DECLARE (fs_utime)
|
||||
TEST_DECLARE (fs_utime_round)
|
||||
TEST_DECLARE (fs_futime)
|
||||
TEST_DECLARE (fs_lutime)
|
||||
TEST_DECLARE (fs_file_open_append)
|
||||
TEST_DECLARE (fs_statfs)
|
||||
TEST_DECLARE (fs_stat_batch_multiple)
|
||||
TEST_DECLARE (fs_stat_missing_path)
|
||||
TEST_DECLARE (fs_read_bufs)
|
||||
TEST_DECLARE (fs_read_file_eof)
|
||||
TEST_FS_DECLARE (fs_utime)
|
||||
TEST_FS_DECLARE (fs_utime_round)
|
||||
TEST_FS_DECLARE (fs_futime)
|
||||
TEST_FS_DECLARE (fs_lutime)
|
||||
TEST_FS_DECLARE (fs_file_open_append)
|
||||
TEST_FS_DECLARE (fs_statfs)
|
||||
TEST_FS_DECLARE (fs_stat_batch_multiple)
|
||||
TEST_FS_DECLARE (fs_stat_missing_path)
|
||||
TEST_FS_DECLARE (fs_read_bufs)
|
||||
TEST_FS_DECLARE (fs_read_file_eof)
|
||||
TEST_DECLARE (fs_event_watch_dir)
|
||||
TEST_DECLARE (fs_event_watch_delete_dir)
|
||||
TEST_DECLARE (fs_event_watch_dir_recursive)
|
||||
@@ -422,41 +428,41 @@ TEST_DECLARE (fs_event_close_in_callback)
|
||||
TEST_DECLARE (fs_event_start_and_close)
|
||||
TEST_DECLARE (fs_event_getpath)
|
||||
TEST_DECLARE (fs_event_stop_in_cb)
|
||||
TEST_DECLARE (fs_scandir_empty_dir)
|
||||
TEST_DECLARE (fs_scandir_non_existent_dir)
|
||||
TEST_DECLARE (fs_scandir_file)
|
||||
TEST_DECLARE (fs_scandir_early_exit)
|
||||
TEST_DECLARE (fs_open_dir)
|
||||
TEST_DECLARE (fs_readdir_empty_dir)
|
||||
TEST_DECLARE (fs_readdir_file)
|
||||
TEST_DECLARE (fs_readdir_non_empty_dir)
|
||||
TEST_DECLARE (fs_readdir_non_existing_dir)
|
||||
TEST_FS_DECLARE (fs_scandir_empty_dir)
|
||||
TEST_FS_DECLARE (fs_scandir_non_existent_dir)
|
||||
TEST_FS_DECLARE (fs_scandir_file)
|
||||
TEST_FS_DECLARE (fs_scandir_early_exit)
|
||||
TEST_FS_DECLARE (fs_open_dir)
|
||||
TEST_FS_DECLARE (fs_readdir_empty_dir)
|
||||
TEST_FS_DECLARE (fs_readdir_file)
|
||||
TEST_FS_DECLARE (fs_readdir_non_empty_dir)
|
||||
TEST_FS_DECLARE (fs_readdir_non_existing_dir)
|
||||
#ifdef _WIN32
|
||||
TEST_DECLARE (fs_readdir_symlink)
|
||||
TEST_FS_DECLARE (fs_readdir_symlink)
|
||||
#endif
|
||||
TEST_DECLARE (fs_rename_to_existing_file)
|
||||
TEST_DECLARE (fs_write_multiple_bufs)
|
||||
TEST_DECLARE (fs_read_write_null_arguments)
|
||||
TEST_FS_DECLARE (fs_rename_to_existing_file)
|
||||
TEST_FS_DECLARE (fs_write_multiple_bufs)
|
||||
TEST_FS_DECLARE (fs_read_write_null_arguments)
|
||||
TEST_DECLARE (get_osfhandle_valid_handle)
|
||||
TEST_DECLARE (open_osfhandle_valid_handle)
|
||||
TEST_DECLARE (fs_write_alotof_bufs)
|
||||
TEST_DECLARE (fs_write_alotof_bufs_with_offset)
|
||||
TEST_DECLARE (fs_partial_read)
|
||||
TEST_DECLARE (fs_partial_write)
|
||||
TEST_DECLARE (fs_file_pos_after_op_with_offset)
|
||||
TEST_DECLARE (fs_null_req)
|
||||
TEST_DECLARE (fs_read_dir)
|
||||
TEST_FS_DECLARE (fs_write_alotof_bufs)
|
||||
TEST_FS_DECLARE (fs_write_alotof_bufs_with_offset)
|
||||
TEST_FS_DECLARE (fs_partial_read)
|
||||
TEST_FS_DECLARE (fs_partial_write)
|
||||
TEST_FS_DECLARE (fs_file_pos_after_op_with_offset)
|
||||
TEST_FS_DECLARE (fs_null_req)
|
||||
TEST_FS_DECLARE (fs_read_dir)
|
||||
#ifdef _WIN32
|
||||
TEST_DECLARE (fs_file_pos_write)
|
||||
TEST_DECLARE (fs_file_pos_append)
|
||||
TEST_DECLARE (fs_exclusive_sharing_mode)
|
||||
TEST_DECLARE (fs_file_flag_no_buffering)
|
||||
TEST_DECLARE (fs_open_readonly_acl)
|
||||
TEST_DECLARE (fs_fchmod_archive_readonly)
|
||||
TEST_DECLARE (fs_invalid_mkdir_name)
|
||||
TEST_DECLARE (fs_wtf)
|
||||
TEST_FS_DECLARE (fs_file_pos_write)
|
||||
TEST_FS_DECLARE (fs_file_pos_append)
|
||||
TEST_FS_DECLARE (fs_exclusive_sharing_mode)
|
||||
TEST_FS_DECLARE (fs_file_flag_no_buffering)
|
||||
TEST_FS_DECLARE (fs_open_readonly_acl)
|
||||
TEST_FS_DECLARE (fs_fchmod_archive_readonly)
|
||||
TEST_FS_DECLARE (fs_invalid_mkdir_name)
|
||||
TEST_FS_DECLARE (fs_wtf)
|
||||
#endif
|
||||
TEST_DECLARE (fs_get_system_error)
|
||||
TEST_FS_DECLARE (fs_get_system_error)
|
||||
TEST_DECLARE (strscpy)
|
||||
TEST_DECLARE (strtok)
|
||||
TEST_DECLARE (threadpool_queue_work_simple)
|
||||
@@ -466,7 +472,7 @@ TEST_DECLARE (threadpool_cancel_getaddrinfo)
|
||||
TEST_DECLARE (threadpool_cancel_getnameinfo)
|
||||
TEST_DECLARE (threadpool_cancel_random)
|
||||
TEST_DECLARE (threadpool_cancel_work)
|
||||
TEST_DECLARE (threadpool_cancel_fs)
|
||||
TEST_FS_DECLARE (threadpool_cancel_fs)
|
||||
TEST_DECLARE (threadpool_cancel_single)
|
||||
TEST_DECLARE (threadpool_cancel_when_busy)
|
||||
TEST_DECLARE (thread_detach)
|
||||
@@ -517,8 +523,8 @@ TEST_DECLARE (environment_creation)
|
||||
#endif
|
||||
TEST_DECLARE (listen_with_simultaneous_accepts)
|
||||
TEST_DECLARE (listen_no_simultaneous_accepts)
|
||||
TEST_DECLARE (fs_stat_root)
|
||||
TEST_DECLARE (fs_stat_no_permission)
|
||||
TEST_FS_DECLARE (fs_stat_root)
|
||||
TEST_FS_DECLARE (fs_stat_no_permission)
|
||||
TEST_DECLARE (spawn_with_an_odd_path)
|
||||
TEST_DECLARE (spawn_no_path)
|
||||
TEST_DECLARE (spawn_no_ext)
|
||||
@@ -662,6 +668,7 @@ TASK_LIST_START
|
||||
#endif
|
||||
TEST_ENTRY (tty_file)
|
||||
TEST_ENTRY (tty_pty)
|
||||
TEST_ENTRY (tty_pty_partial)
|
||||
TEST_ENTRY (stdio_over_pipes)
|
||||
TEST_ENTRY (stdio_emulate_iocp)
|
||||
TEST_ENTRY (ip6_pton)
|
||||
@@ -805,6 +812,10 @@ TASK_LIST_START
|
||||
TEST_ENTRY (udp_send_hang_loop)
|
||||
TEST_ENTRY (udp_send_immediate)
|
||||
TEST_ENTRY (udp_send_unreachable)
|
||||
TEST_ENTRY (udp_recv_cb_close_pollerr)
|
||||
TEST_ENTRY (udp_recvmsg_unreachable_error)
|
||||
TEST_ENTRY (udp_recvmsg_unreachable_error6)
|
||||
TEST_ENTRY (udp_send_pollerr_no_recv)
|
||||
TEST_ENTRY (udp_dgram_too_big)
|
||||
TEST_ENTRY (udp_dual_stack)
|
||||
TEST_ENTRY (udp_ipv6_only)
|
||||
@@ -1049,8 +1060,8 @@ TASK_LIST_START
|
||||
# endif
|
||||
TEST_ENTRY (listen_with_simultaneous_accepts)
|
||||
TEST_ENTRY (listen_no_simultaneous_accepts)
|
||||
TEST_ENTRY (fs_stat_root)
|
||||
TEST_ENTRY (fs_stat_no_permission)
|
||||
TEST_FS_ENTRY (fs_stat_root)
|
||||
TEST_FS_ENTRY (fs_stat_no_permission)
|
||||
TEST_ENTRY (spawn_with_an_odd_path)
|
||||
TEST_ENTRY (spawn_no_path)
|
||||
TEST_ENTRY (spawn_no_ext)
|
||||
@@ -1074,53 +1085,54 @@ TASK_LIST_START
|
||||
TEST_ENTRY (osx_select_many_fds)
|
||||
#endif
|
||||
|
||||
TEST_ENTRY (fs_file_noent)
|
||||
TEST_ENTRY (fs_file_nametoolong)
|
||||
TEST_ENTRY (fs_file_loop)
|
||||
TEST_ENTRY (fs_file_async)
|
||||
TEST_ENTRY (fs_file_sync)
|
||||
TEST_ENTRY (fs_posix_delete)
|
||||
TEST_ENTRY (fs_file_write_null_buffer)
|
||||
TEST_ENTRY (fs_async_dir)
|
||||
TEST_ENTRY (fs_async_sendfile)
|
||||
TEST_ENTRY (fs_async_sendfile_nodata)
|
||||
TEST_ENTRY (fs_mkdtemp)
|
||||
TEST_ENTRY (fs_mkstemp)
|
||||
TEST_ENTRY (fs_fstat)
|
||||
TEST_ENTRY (fs_fstat_stdio)
|
||||
TEST_ENTRY (fs_fstat_st_dev)
|
||||
TEST_ENTRY (fs_access)
|
||||
TEST_ENTRY (fs_chmod)
|
||||
TEST_ENTRY (fs_copyfile)
|
||||
TEST_ENTRY (fs_unlink_readonly)
|
||||
TEST_FS_ENTRY (fs_file_noent)
|
||||
TEST_FS_ENTRY (fs_file_nametoolong)
|
||||
TEST_FS_ENTRY (fs_file_loop)
|
||||
TEST_FS_ENTRY(fs_file_async)
|
||||
TEST_FS_ENTRY (fs_file_sync)
|
||||
TEST_FS_ENTRY (fs_posix_delete)
|
||||
TEST_FS_ENTRY (fs_file_write_null_buffer)
|
||||
TEST_FS_ENTRY (fs_async_dir)
|
||||
TEST_FS_ENTRY (fs_async_sendfile)
|
||||
TEST_FS_ENTRY (fs_async_sendfile_nodata)
|
||||
TEST_FS_ENTRY (fs_mkdtemp)
|
||||
TEST_FS_ENTRY (fs_mkstemp)
|
||||
TEST_FS_ENTRY (fs_fstat)
|
||||
TEST_FS_ENTRY (fs_fstat_stdio)
|
||||
TEST_FS_ENTRY (fs_fstat_st_dev)
|
||||
TEST_FS_ENTRY (fs_access)
|
||||
TEST_FS_ENTRY (fs_chmod)
|
||||
TEST_FS_ENTRY (fs_copyfile)
|
||||
TEST_FS_ENTRY (fs_unlink_readonly)
|
||||
#ifdef _WIN32
|
||||
TEST_ENTRY (fs_unlink_archive_readonly)
|
||||
TEST_FS_ENTRY (fs_unlink_archive_readonly)
|
||||
#endif
|
||||
TEST_ENTRY (fs_chown)
|
||||
TEST_ENTRY (fs_link)
|
||||
TEST_ENTRY (fs_utime)
|
||||
TEST_ENTRY (fs_utime_round)
|
||||
TEST_ENTRY (fs_futime)
|
||||
TEST_ENTRY (fs_lutime)
|
||||
TEST_ENTRY (fs_readlink)
|
||||
TEST_ENTRY (fs_realpath)
|
||||
TEST_ENTRY (fs_symlink)
|
||||
TEST_ENTRY (fs_symlink_dir)
|
||||
TEST_FS_ENTRY (fs_chown)
|
||||
TEST_FS_ENTRY (fs_link)
|
||||
TEST_FS_ENTRY (fs_utime)
|
||||
TEST_FS_ENTRY (fs_utime_round)
|
||||
TEST_FS_ENTRY (fs_futime)
|
||||
TEST_FS_ENTRY (fs_lutime)
|
||||
TEST_FS_ENTRY (fs_readlink)
|
||||
TEST_FS_ENTRY (fs_realpath)
|
||||
TEST_FS_ENTRY (fs_symlink)
|
||||
TEST_FS_ENTRY (fs_symlink_dir)
|
||||
#ifdef _WIN32
|
||||
TEST_ENTRY (fs_symlink_junction)
|
||||
TEST_ENTRY (fs_non_symlink_reparse_point)
|
||||
TEST_ENTRY (fs_lstat_windows_store_apps)
|
||||
TEST_ENTRY (fs_open_flags)
|
||||
TEST_FS_ENTRY (fs_symlink_junction)
|
||||
TEST_FS_ENTRY (fs_non_symlink_reparse_point)
|
||||
TEST_FS_ENTRY (fs_readlink_lx_symlink)
|
||||
TEST_FS_ENTRY (fs_lstat_windows_store_apps)
|
||||
TEST_FS_ENTRY (fs_open_flags)
|
||||
#endif
|
||||
#if defined(_WIN32) && !defined(USING_UV_SHARED)
|
||||
TEST_ENTRY (fs_fd_hash)
|
||||
TEST_FS_ENTRY (fs_fd_hash)
|
||||
#endif
|
||||
TEST_ENTRY (fs_statfs)
|
||||
TEST_ENTRY (fs_stat_batch_multiple)
|
||||
TEST_ENTRY (fs_stat_missing_path)
|
||||
TEST_ENTRY (fs_read_bufs)
|
||||
TEST_ENTRY (fs_read_file_eof)
|
||||
TEST_ENTRY (fs_file_open_append)
|
||||
TEST_FS_ENTRY (fs_statfs)
|
||||
TEST_FS_ENTRY (fs_stat_batch_multiple)
|
||||
TEST_FS_ENTRY (fs_stat_missing_path)
|
||||
TEST_FS_ENTRY (fs_read_bufs)
|
||||
TEST_FS_ENTRY (fs_read_file_eof)
|
||||
TEST_FS_ENTRY (fs_file_open_append)
|
||||
TEST_ENTRY (fs_event_watch_dir)
|
||||
TEST_ENTRY (fs_event_watch_delete_dir)
|
||||
TEST_ENTRY (fs_event_watch_dir_recursive)
|
||||
@@ -1144,39 +1156,39 @@ TASK_LIST_START
|
||||
TEST_ENTRY (fs_event_start_and_close)
|
||||
TEST_ENTRY (fs_event_getpath)
|
||||
TEST_ENTRY (fs_event_stop_in_cb)
|
||||
TEST_ENTRY (fs_scandir_empty_dir)
|
||||
TEST_ENTRY (fs_scandir_non_existent_dir)
|
||||
TEST_ENTRY (fs_scandir_file)
|
||||
TEST_ENTRY (fs_scandir_early_exit)
|
||||
TEST_ENTRY (fs_open_dir)
|
||||
TEST_ENTRY (fs_readdir_empty_dir)
|
||||
TEST_ENTRY (fs_readdir_file)
|
||||
TEST_ENTRY (fs_readdir_non_empty_dir)
|
||||
TEST_ENTRY (fs_readdir_non_existing_dir)
|
||||
TEST_FS_ENTRY (fs_scandir_empty_dir)
|
||||
TEST_FS_ENTRY (fs_scandir_non_existent_dir)
|
||||
TEST_FS_ENTRY (fs_scandir_file)
|
||||
TEST_FS_ENTRY (fs_scandir_early_exit)
|
||||
TEST_FS_ENTRY (fs_open_dir)
|
||||
TEST_FS_ENTRY (fs_readdir_empty_dir)
|
||||
TEST_FS_ENTRY (fs_readdir_file)
|
||||
TEST_FS_ENTRY (fs_readdir_non_empty_dir)
|
||||
TEST_FS_ENTRY (fs_readdir_non_existing_dir)
|
||||
#ifdef _WIN32
|
||||
TEST_ENTRY (fs_readdir_symlink)
|
||||
TEST_FS_ENTRY (fs_readdir_symlink)
|
||||
#endif
|
||||
TEST_ENTRY (fs_rename_to_existing_file)
|
||||
TEST_ENTRY (fs_write_multiple_bufs)
|
||||
TEST_ENTRY (fs_write_alotof_bufs)
|
||||
TEST_ENTRY (fs_write_alotof_bufs_with_offset)
|
||||
TEST_ENTRY (fs_partial_read)
|
||||
TEST_ENTRY (fs_partial_write)
|
||||
TEST_ENTRY (fs_read_write_null_arguments)
|
||||
TEST_ENTRY (fs_file_pos_after_op_with_offset)
|
||||
TEST_ENTRY (fs_null_req)
|
||||
TEST_ENTRY (fs_read_dir)
|
||||
TEST_FS_ENTRY (fs_rename_to_existing_file)
|
||||
TEST_FS_ENTRY (fs_write_multiple_bufs)
|
||||
TEST_FS_ENTRY (fs_write_alotof_bufs)
|
||||
TEST_FS_ENTRY (fs_write_alotof_bufs_with_offset)
|
||||
TEST_FS_ENTRY (fs_partial_read)
|
||||
TEST_FS_ENTRY (fs_partial_write)
|
||||
TEST_FS_ENTRY (fs_read_write_null_arguments)
|
||||
TEST_FS_ENTRY (fs_file_pos_after_op_with_offset)
|
||||
TEST_FS_ENTRY (fs_null_req)
|
||||
TEST_FS_ENTRY (fs_read_dir)
|
||||
#ifdef _WIN32
|
||||
TEST_ENTRY (fs_file_pos_write)
|
||||
TEST_ENTRY (fs_file_pos_append)
|
||||
TEST_ENTRY (fs_exclusive_sharing_mode)
|
||||
TEST_ENTRY (fs_file_flag_no_buffering)
|
||||
TEST_ENTRY (fs_open_readonly_acl)
|
||||
TEST_ENTRY (fs_fchmod_archive_readonly)
|
||||
TEST_ENTRY (fs_invalid_mkdir_name)
|
||||
TEST_ENTRY (fs_wtf)
|
||||
TEST_FS_ENTRY (fs_file_pos_write)
|
||||
TEST_FS_ENTRY (fs_file_pos_append)
|
||||
TEST_FS_ENTRY (fs_exclusive_sharing_mode)
|
||||
TEST_FS_ENTRY (fs_file_flag_no_buffering)
|
||||
TEST_FS_ENTRY (fs_open_readonly_acl)
|
||||
TEST_FS_ENTRY (fs_fchmod_archive_readonly)
|
||||
TEST_FS_ENTRY (fs_invalid_mkdir_name)
|
||||
TEST_FS_ENTRY (fs_wtf)
|
||||
#endif
|
||||
TEST_ENTRY (fs_get_system_error)
|
||||
TEST_FS_ENTRY (fs_get_system_error)
|
||||
TEST_ENTRY (get_osfhandle_valid_handle)
|
||||
TEST_ENTRY (open_osfhandle_valid_handle)
|
||||
TEST_ENTRY (strscpy)
|
||||
@@ -1188,7 +1200,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (threadpool_cancel_getnameinfo)
|
||||
TEST_ENTRY (threadpool_cancel_random)
|
||||
TEST_ENTRY (threadpool_cancel_work)
|
||||
TEST_ENTRY (threadpool_cancel_fs)
|
||||
TEST_FS_ENTRY (threadpool_cancel_fs)
|
||||
TEST_ENTRY (threadpool_cancel_single)
|
||||
TEST_ENTRY (threadpool_cancel_when_busy)
|
||||
TEST_ENTRY (thread_detach)
|
||||
|
||||
Vendored
+1
-1
@@ -91,8 +91,8 @@ static void poll_cb(uv_poll_t* handle, int status, int events) {
|
||||
while (n == -1 && errno == EINTR);
|
||||
ASSERT(n >= 0 || errno != EINVAL);
|
||||
if (cli_rd_check == 1) {
|
||||
ASSERT_OK(strncmp(buffer, "world", n));
|
||||
ASSERT_EQ(5, n);
|
||||
ASSERT_OK(strncmp(buffer, "world", n));
|
||||
cli_rd_check = 2;
|
||||
}
|
||||
if (cli_rd_check == 0) {
|
||||
|
||||
Vendored
+8
-8
@@ -83,9 +83,9 @@ static int closed_connections = 0;
|
||||
static int valid_writable_wakeups = 0;
|
||||
static int spurious_writable_wakeups = 0;
|
||||
|
||||
#if !defined(__sun) && !defined(_AIX) && !defined(__MVS__)
|
||||
#if !defined(__sun) && !defined(_AIX) && !defined(__MVS__) && !defined(__QNX__)
|
||||
static int disconnects = 0;
|
||||
#endif /* !__sun && !_AIX && !__MVS__ */
|
||||
#endif /* !__sun && !_AIX && !__MVS__ && !__QNX__*/
|
||||
|
||||
static int got_eagain(void) {
|
||||
#ifdef _WIN32
|
||||
@@ -409,7 +409,7 @@ static void connection_poll_cb(uv_poll_t* handle, int status, int events) {
|
||||
new_events &= ~UV_WRITABLE;
|
||||
}
|
||||
}
|
||||
#if !defined(__sun) && !defined(_AIX) && !defined(__MVS__)
|
||||
#if !defined(__sun) && !defined(_AIX) && !defined(__MVS__) && !defined(__QNX__)
|
||||
if (events & UV_DISCONNECT) {
|
||||
context->got_disconnect = 1;
|
||||
++disconnects;
|
||||
@@ -417,9 +417,9 @@ static void connection_poll_cb(uv_poll_t* handle, int status, int events) {
|
||||
}
|
||||
|
||||
if (context->got_fin && context->sent_fin && context->got_disconnect) {
|
||||
#else /* __sun && _AIX && __MVS__ */
|
||||
#else /* __sun && _AIX && __MVS__ && __QNX__*/
|
||||
if (context->got_fin && context->sent_fin) {
|
||||
#endif /* !__sun && !_AIX && !__MVS__ */
|
||||
#endif /* !__sun && !_AIX && !__MVS__ && !__QNX__ */
|
||||
/* Sent and received FIN. Close and destroy context. */
|
||||
close_socket(context->sock);
|
||||
destroy_connection_context(context);
|
||||
@@ -587,7 +587,7 @@ static void start_poll_test(void) {
|
||||
spurious_writable_wakeups > 20, 0);
|
||||
|
||||
ASSERT_EQ(closed_connections, NUM_CLIENTS * 2);
|
||||
#if !defined(__sun) && !defined(_AIX) && !defined(__MVS__)
|
||||
#if !defined(__sun) && !defined(_AIX) && !defined(__MVS__) && !defined(__QNX__)
|
||||
ASSERT_EQ(disconnects, NUM_CLIENTS * 2);
|
||||
#endif
|
||||
MAKE_VALGRIND_HAPPY(uv_default_loop());
|
||||
@@ -633,12 +633,12 @@ TEST_IMPL(poll_unidirectional) {
|
||||
* In addition to regular files, we also disallow FIFOs on Darwin.
|
||||
*/
|
||||
#ifdef __APPLE__
|
||||
#define TEST_POLL_FIFO_PATH "/tmp/uv-test-poll-fifo"
|
||||
#define TEST_POLL_FIFO_PATH "uv-test-poll-fifo"
|
||||
#endif
|
||||
TEST_IMPL(poll_bad_fdtype) {
|
||||
#if !defined(__sun) && \
|
||||
!defined(_AIX) && !defined(__MVS__) && \
|
||||
!defined(__CYGWIN__) && !defined(__MSYS__)
|
||||
!defined(__CYGWIN__) && !defined(__MSYS__) && !defined(__QNX__)
|
||||
uv_poll_t poll_handle;
|
||||
int fd[2];
|
||||
|
||||
|
||||
Vendored
+2
-2
@@ -28,9 +28,9 @@ TEST_IMPL(process_priority) {
|
||||
int r;
|
||||
int i;
|
||||
|
||||
#if defined(__MVS__)
|
||||
#if defined(__MVS__) || defined(__QNX__)
|
||||
if (uv_os_setpriority(0, 0) == UV_ENOSYS)
|
||||
RETURN_SKIP("functionality not supported on zOS");
|
||||
RETURN_SKIP("functionality not supported on zOS and QNX");
|
||||
#endif
|
||||
|
||||
/* Verify that passing a NULL pointer returns UV_EINVAL. */
|
||||
|
||||
+9
-1
@@ -85,10 +85,18 @@ TEST_IMPL(process_title_threadsafe) {
|
||||
int i;
|
||||
|
||||
#if defined(__sun) || defined(__CYGWIN__) || defined(__MSYS__) || \
|
||||
defined(__MVS__) || defined(__PASE__)
|
||||
defined(__MVS__) || defined(__PASE__) || defined(__QNX__)
|
||||
RETURN_SKIP("uv_(get|set)_process_title is not implemented.");
|
||||
#endif
|
||||
|
||||
#if defined(__ASAN__) && defined(__APPLE__)
|
||||
/* uv_set_process_title loads and unloads a bunch of dynamic libraries,
|
||||
* and that's quite slow and prone to time out when running concurrently
|
||||
* under AddressSanitizer.
|
||||
*/
|
||||
RETURN_SKIP("too slow under ASAN");
|
||||
#endif
|
||||
|
||||
ASSERT_OK(uv_set_process_title(titles[0]));
|
||||
|
||||
ASSERT_OK(uv_sem_init(&getter_sem, 0));
|
||||
|
||||
Loaded 100 of 122 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user