mirror of
https://github.com/nodejs/node.git
synced 2025-04-28 13:40:37 +00:00
deps: upgrade to libuv 1.42.0
Notable changes: - win,tcp: make `uv_close()` work more like unix. - cleanup,win: Remove `_WIN32` guards on threadpool. - more errno mappings and fixes. - higher performance try-writes. - fix string encoding issue of `uv_os_gethostname()` (note: MINGW-W64 upstream is broken on i686 due to https://sourceforge.net/p/mingw-w64/bugs/899/). - zOS support. - Workarounds for a `copy_file_range()` kernel bug. - Better support for TSan. - darwin: use `RLIMIT_STACK` for fsevents pthread. - fix a bug that would cause libuv to hang if the user called `uv_shutdown()`. - darwin: fix `uv_barrier()` race condition. PR-URL: https://github.com/nodejs/node/pull/39525 Fixes: https://github.com/nodejs/node/issues/39502 Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
This commit is contained in:
parent
fe3c5a769d
commit
c61870c376
4
deps/uv/.mailmap
vendored
4
deps/uv/.mailmap
vendored
@ -2,6 +2,7 @@ A. Hauptmann <andreashauptmann@t-online.de>
|
||||
Aaron Bieber <qbit@deftly.net> <deftly@gmail.com>
|
||||
Alan Gutierrez <alan@prettyrobots.com> <alan@blogometer.com>
|
||||
Andrius Bentkus <andrius.bentkus@gmail.com> <toxedvirus@gmail.com>
|
||||
Andy Fiddaman <andy@omniosce.org> <omnios@citrus-it.co.uk>
|
||||
Bert Belder <bertbelder@gmail.com> <i@bertbelder.com>
|
||||
Bert Belder <bertbelder@gmail.com> <info@2bs.nl>
|
||||
Bert Belder <bertbelder@gmail.com> <user@ChrUbuntu.(none)>
|
||||
@ -10,6 +11,8 @@ Brian White <mscdex@mscdex.net>
|
||||
Brian White <mscdex@mscdex.net> <mscdex@gmail.com>
|
||||
Caleb James DeLisle <cjd@hyperboria.ca> <cjd@cjdns.fr>
|
||||
Christoph Iserlohn <christoph.iserlohn@innoq.com>
|
||||
Darshan Sen <raisinten@gmail.com>
|
||||
David Carlier <devnexen@gmail.com>
|
||||
Devchandra Meetei Leishangthem <dlmeetei@gmail.com>
|
||||
Fedor Indutny <fedor.indutny@gmail.com> <fedor@indutny.com>
|
||||
Frank Denis <github@pureftpd.org>
|
||||
@ -53,4 +56,5 @@ gengjiawen <technicalcute@gmail.com>
|
||||
jBarz <jBarz@users.noreply.github.com> <jbarboza@ca.ibm.com>
|
||||
jBarz <jBarz@users.noreply.github.com> <jbarz@users.noreply.github.com>
|
||||
ptlomholt <pt@lomholt.com>
|
||||
tjarlama <59913901+tjarlama@users.noreply.github.com> <tjarlama@gmail.com>
|
||||
zlargon <zlargon1988@gmail.com>
|
||||
|
11
deps/uv/.readthedocs.yaml
vendored
Normal file
11
deps/uv/.readthedocs.yaml
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
version: 2
|
||||
|
||||
sphinx:
|
||||
builder: html
|
||||
configuration: null
|
||||
fail_on_warning: false
|
||||
|
||||
python:
|
||||
version: 3.8
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
24
deps/uv/AUTHORS
vendored
24
deps/uv/AUTHORS
vendored
@ -114,7 +114,6 @@ Dylan Cali <calid1984@gmail.com>
|
||||
Austin Foxley <austinf@cetoncorp.com>
|
||||
Benjamin Saunders <ben.e.saunders@gmail.com>
|
||||
Geoffry Song <goffrie@gmail.com>
|
||||
Rasmus Christian Pedersen <ruysch@outlook.com>
|
||||
William Light <wrl@illest.net>
|
||||
Oleg Efimov <o.efimov@corp.badoo.com>
|
||||
Lars Gierth <larsg@systemli.org>
|
||||
@ -123,7 +122,6 @@ Justin Venus <justin.venus@gmail.com>
|
||||
Kristian Evensen <kristian.evensen@gmail.com>
|
||||
Linus Mårtensson <linus.martensson@sonymobile.com>
|
||||
Navaneeth Kedaram Nambiathan <navaneethkn@gmail.com>
|
||||
Yorkie <yorkiefixer@gmail.com>
|
||||
StarWing <weasley.wx@gmail.com>
|
||||
thierry-FreeBSD <thierry@FreeBSD.org>
|
||||
Isaiah Norton <isaiah.norton@gmail.com>
|
||||
@ -459,3 +457,25 @@ schamberg97 <50446906+schamberg97@users.noreply.github.com>
|
||||
Bob Weinand <bobwei9@hotmail.com>
|
||||
Issam E. Maghni <issam.e.maghni@mailbox.org>
|
||||
Juan Pablo Canepa <jpcanepa@gmail.com>
|
||||
Shuowang (Wayne) Zhang <shuowang.zhang@ibm.com>
|
||||
Ondřej Surý <ondrej@sury.org>
|
||||
Juan José Arboleda <soyjuanarbol@gmail.com>
|
||||
Zhao Zhili <zhilizhao@tencent.com>
|
||||
Brandon Cheng <brandon.cheng@protonmail.com>
|
||||
Matvii Hodovaniuk <matvii@hodovani.uk>
|
||||
Hayden <me@diatr.us>
|
||||
yiyuaner <yguoaz@gmail.com>
|
||||
bbara <bbara93@gmail.com>
|
||||
SeverinLeonhardt <Severin.Leonhardt@teamviewer.com>
|
||||
Andy Fiddaman <andy@omniosce.org>
|
||||
Romain Roffé <rofferom@gmail.com>
|
||||
Eagle Liang <eagleliang@gmail.com>
|
||||
Ricky Zhou <ives199511@gmail.com>
|
||||
Simon Kissane <skissane@gmail.com>
|
||||
James M Snell <jasnell@gmail.com>
|
||||
Ali Mohammad Pur <Ali.mpfard@gmail.com>
|
||||
Erkhes N <71805796+rexes-ND@users.noreply.github.com>
|
||||
Joshua M. Clulow <josh@sysmgr.org>
|
||||
Guilherme Íscaro <cabelitostos@gmail.com>
|
||||
Martin Storsjö <martin@martin.st>
|
||||
Claes Nästén <pekdon@gmail.com>
|
||||
|
63
deps/uv/CMakeLists.txt
vendored
63
deps/uv/CMakeLists.txt
vendored
@ -34,7 +34,8 @@ option(ASAN "Enable AddressSanitizer (ASan)" OFF)
|
||||
if(ASAN AND CMAKE_C_COMPILER_ID MATCHES "AppleClang|GNU|Clang")
|
||||
add_definitions(-D__ASAN__=1)
|
||||
set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
|
||||
set (CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
|
||||
set (CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
|
||||
endif()
|
||||
|
||||
# Compiler check
|
||||
@ -209,10 +210,11 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
src/unix/pthread-fixes.c
|
||||
src/unix/random-getentropy.c
|
||||
src/unix/random-getrandom.c
|
||||
src/unix/random-sysctl-linux.c)
|
||||
src/unix/random-sysctl-linux.c
|
||||
src/unix/epoll.c)
|
||||
endif()
|
||||
|
||||
if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "Android|Linux|OS390")
|
||||
if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "Android|Linux")
|
||||
list(APPEND uv_sources src/unix/proctitle.c)
|
||||
endif()
|
||||
|
||||
@ -253,7 +255,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
src/unix/linux-syscalls.c
|
||||
src/unix/procfs-exepath.c
|
||||
src/unix/random-getrandom.c
|
||||
src/unix/random-sysctl-linux.c)
|
||||
src/unix/random-sysctl-linux.c
|
||||
src/unix/epoll.c)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
|
||||
@ -266,9 +269,11 @@ if(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "OS390")
|
||||
list(APPEND uv_defines PATH_MAX=255)
|
||||
enable_language(CXX)
|
||||
list(APPEND uv_defines PATH_MAX=1024)
|
||||
list(APPEND uv_defines _AE_BIMODAL)
|
||||
list(APPEND uv_defines _ALL_SOURCE)
|
||||
list(APPEND uv_defines _ENHANCED_ASCII_EXT=0xFFFFFFFF)
|
||||
list(APPEND uv_defines _ISOC99_SOURCE)
|
||||
list(APPEND uv_defines _LARGE_TIME_API)
|
||||
list(APPEND uv_defines _OPEN_MSGQ_EXT)
|
||||
@ -279,14 +284,31 @@ if(CMAKE_SYSTEM_NAME STREQUAL "OS390")
|
||||
list(APPEND uv_defines _UNIX03_SOURCE)
|
||||
list(APPEND uv_defines _UNIX03_THREADS)
|
||||
list(APPEND uv_defines _UNIX03_WITHDRAWN)
|
||||
list(APPEND uv_defines _XOPEN_SOURCE=600)
|
||||
list(APPEND uv_defines _XOPEN_SOURCE_EXTENDED)
|
||||
list(APPEND uv_sources
|
||||
src/unix/pthread-fixes.c
|
||||
src/unix/os390.c
|
||||
src/unix/os390-syscalls.c)
|
||||
list(APPEND uv_cflags -Wc,DLL -Wc,exportall -Wc,xplink)
|
||||
list(APPEND uv_libraries -Wl,xplink)
|
||||
list(APPEND uv_test_libraries -Wl,xplink)
|
||||
src/unix/os390-syscalls.c
|
||||
src/unix/os390-proctitle.c)
|
||||
list(APPEND uv_cflags
|
||||
-q64
|
||||
-qascii
|
||||
-qexportall
|
||||
-qgonumber
|
||||
-qlongname
|
||||
-qlibansi
|
||||
-qfloat=IEEE
|
||||
-qtune=10
|
||||
-qarch=10
|
||||
-qasm
|
||||
-qasmlib=sys1.maclib:sys1.modgen)
|
||||
find_library(ZOSLIB
|
||||
NAMES zoslib
|
||||
PATHS ${ZOSLIB_DIR}
|
||||
PATH_SUFFIXES lib
|
||||
)
|
||||
list(APPEND uv_libraries ${ZOSLIB})
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "OS400")
|
||||
@ -303,9 +325,11 @@ if(CMAKE_SYSTEM_NAME STREQUAL "OS400")
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
|
||||
list(APPEND uv_defines __EXTENSIONS__ _XOPEN_SOURCE=500)
|
||||
list(APPEND uv_defines __EXTENSIONS__ _XOPEN_SOURCE=500 _REENTRANT)
|
||||
list(APPEND uv_libraries kstat nsl sendfile socket)
|
||||
list(APPEND uv_sources src/unix/no-proctitle.c src/unix/sunos.c)
|
||||
list(APPEND uv_sources
|
||||
src/unix/no-proctitle.c
|
||||
src/unix/sunos.c)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Haiku")
|
||||
@ -349,6 +373,10 @@ target_include_directories(uv
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
PRIVATE
|
||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "OS390")
|
||||
target_include_directories(uv PUBLIC $<BUILD_INTERFACE:${ZOSLIB_DIR}/include>)
|
||||
set_target_properties(uv PROPERTIES LINKER_LANGUAGE CXX)
|
||||
endif()
|
||||
target_link_libraries(uv ${uv_libraries})
|
||||
|
||||
add_library(uv_a STATIC ${uv_sources})
|
||||
@ -360,6 +388,10 @@ target_include_directories(uv_a
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
PRIVATE
|
||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "OS390")
|
||||
target_include_directories(uv_a PUBLIC $<BUILD_INTERFACE:${ZOSLIB_DIR}/include>)
|
||||
set_target_properties(uv_a PROPERTIES LINKER_LANGUAGE CXX)
|
||||
endif()
|
||||
target_link_libraries(uv_a ${uv_libraries})
|
||||
|
||||
if(LIBUV_BUILD_TESTS)
|
||||
@ -457,6 +489,9 @@ if(LIBUV_BUILD_TESTS)
|
||||
test/test-metrics.c
|
||||
test/test-multiple-listen.c
|
||||
test/test-mutexes.c
|
||||
test/test-not-readable-nor-writable-on-read-error.c
|
||||
test/test-not-readable-on-eof.c
|
||||
test/test-not-writable-after-shutdown.c
|
||||
test/test-osx-select.c
|
||||
test/test-pass-always.c
|
||||
test/test-ping-pong.c
|
||||
@ -489,6 +524,7 @@ if(LIBUV_BUILD_TESTS)
|
||||
test/test-semaphore.c
|
||||
test/test-shutdown-close.c
|
||||
test/test-shutdown-eof.c
|
||||
test/test-shutdown-simultaneous.c
|
||||
test/test-shutdown-twice.c
|
||||
test/test-signal-multiple-loops.c
|
||||
test/test-signal-pending-on-close.c
|
||||
@ -582,6 +618,11 @@ if(LIBUV_BUILD_TESTS)
|
||||
add_test(NAME uv_test_a
|
||||
COMMAND uv_run_tests_a
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "OS390")
|
||||
set_target_properties(uv_run_benchmarks_a PROPERTIES LINKER_LANGUAGE CXX)
|
||||
set_target_properties(uv_run_tests PROPERTIES LINKER_LANGUAGE CXX)
|
||||
set_target_properties(uv_run_tests_a PROPERTIES LINKER_LANGUAGE CXX)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(UNIX OR MINGW)
|
||||
|
10
deps/uv/CONTRIBUTING.md
vendored
10
deps/uv/CONTRIBUTING.md
vendored
@ -23,11 +23,11 @@ The stable branch is effectively frozen; patches that change the libuv
|
||||
API/ABI or affect the run-time behavior of applications get rejected.
|
||||
|
||||
In case of doubt, open an issue in the [issue tracker][], post your question
|
||||
to the [libuv mailing list], or contact one of [project maintainers][] on [IRC][].
|
||||
to the [libuv discussions forum], or message the [libuv mailing list].
|
||||
|
||||
Especially do so if you plan to work on something big. Nothing is more
|
||||
frustrating than seeing your hard work go to waste because your vision
|
||||
does not align with that of a project maintainers.
|
||||
Especially do so if you plan to work on something big. Nothing is more
|
||||
frustrating than seeing your hard work go to waste because your vision does not
|
||||
align with that of the [project maintainers].
|
||||
|
||||
|
||||
### BRANCH
|
||||
@ -166,6 +166,6 @@ not send out notifications when you add commits.
|
||||
|
||||
[issue tracker]: https://github.com/libuv/libuv/issues
|
||||
[libuv mailing list]: http://groups.google.com/group/libuv
|
||||
[IRC]: http://webchat.freenode.net/?channels=libuv
|
||||
[libuv discussions forum]: https://github.com/libuv/libuv/discussions
|
||||
[Google C/C++ style guide]: https://google.github.io/styleguide/cppguide.html
|
||||
[project maintainers]: https://github.com/libuv/libuv/blob/master/MAINTAINERS.md
|
||||
|
155
deps/uv/ChangeLog
vendored
155
deps/uv/ChangeLog
vendored
@ -1,3 +1,158 @@
|
||||
2021.07.21, Version 1.42.0 (Stable)
|
||||
|
||||
Changes since version 1.41.0:
|
||||
|
||||
* doc: fix code highlighting (Darshan Sen)
|
||||
|
||||
* test: move to ASSERT_NULL and ASSERT_NOT_NULL test macros (tjarlama)
|
||||
|
||||
* zos: build in ascii code page (Shuowang (Wayne) Zhang)
|
||||
|
||||
* zos: don't use nanosecond timestamp fields (Shuowang (Wayne) Zhang)
|
||||
|
||||
* zos: introduce zoslib (Shuowang (Wayne) Zhang)
|
||||
|
||||
* zos: use strnlen() from zoslib (Shuowang (Wayne) Zhang)
|
||||
|
||||
* zos: use nanosleep() from zoslib (Shuowang (Wayne) Zhang)
|
||||
|
||||
* zos: use __getargv() from zoslib to get exe path (Shuowang (Wayne) Zhang)
|
||||
|
||||
* zos: treat __rfim_utok as binary (Shuowang (Wayne) Zhang)
|
||||
|
||||
* zos: use execvpe() to set environ explictly (Shuowang (Wayne) Zhang)
|
||||
|
||||
* zos: use custom proctitle implementation (Shuowang (Wayne) Zhang)
|
||||
|
||||
* doc: add instructions for building on z/OS (Shuowang (Wayne) Zhang)
|
||||
|
||||
* linux,udp: enable full ICMP error reporting (Ondřej Surý)
|
||||
|
||||
* test: fix test-udp-send-unreachable (Ondřej Surý)
|
||||
|
||||
* include: fix typo in documentation (Tobias Nießen)
|
||||
|
||||
* chore: use for(;;) instead of while (Yash Ladha)
|
||||
|
||||
* test: remove string + int warning on udp-pummel (Juan José Arboleda)
|
||||
|
||||
* cmake: fix linker flags (Zhao Zhili)
|
||||
|
||||
* test: fix stack-use-after-scope (Zhao Zhili)
|
||||
|
||||
* unix: expose thread_stack_size() internally (Brandon Cheng)
|
||||
|
||||
* darwin: use RLIMIT_STACK for fsevents pthread (Brandon Cheng)
|
||||
|
||||
* darwin: abort on pthread_attr_init fail (Brandon Cheng)
|
||||
|
||||
* benchmark: remove unreachable code (Matvii Hodovaniuk)
|
||||
|
||||
* macos: fix memleaks in uv__get_cpu_speed (George Zhao)
|
||||
|
||||
* Make Thread Sanitizer aware of file descriptor close in uv__close() (Ondřej
|
||||
Surý)
|
||||
|
||||
* darwin: fix iOS compilation and functionality (Hayden)
|
||||
|
||||
* linux: work around copy_file_range() cephfs bug (Ben Noordhuis)
|
||||
|
||||
* zos: implement uv_get_constrained_memory() (Shuowang (Wayne) Zhang)
|
||||
|
||||
* zos: fix uv_get_free_memory() (Shuowang (Wayne) Zhang)
|
||||
|
||||
* zos: use CVTRLSTG to get total memory accurately (Shuowang (Wayne) Zhang)
|
||||
|
||||
* ibmi: Handle interface names longer than 10 chars (Kevin Adler)
|
||||
|
||||
* docs: update read-the-docs version of sphinx (Jameson Nash)
|
||||
|
||||
* unix: refactor uv_try_write (twosee)
|
||||
|
||||
* linux-core: add proper divide by zero assert (yiyuaner)
|
||||
|
||||
* misc: remove unnecessary _GNU_SOURCE macros (Darshan Sen)
|
||||
|
||||
* test: log to stdout to conform TAP spec (bbara)
|
||||
|
||||
* win,fs: fix C4090 warning with MSVC (SeverinLeonhardt)
|
||||
|
||||
* build: some systems provide dlopen() in libc (Andy Fiddaman)
|
||||
|
||||
* include: add EOVERFLOW status code mapping (Darshan Sen)
|
||||
|
||||
* unix,fs: use uv__load_relaxed and uv__store_relaxed (Darshan Sen)
|
||||
|
||||
* win: fix string encoding issue of uv_os_gethostname (Eagle Liang)
|
||||
|
||||
* unix,process: add uv__write_errno helper function (Ricky Zhou)
|
||||
|
||||
* Re-merge "unix,stream: clear read/write states on close/eof" (Jameson Nash)
|
||||
|
||||
* unix,core: fix errno handling in uv__getpwuid_r (Darshan Sen)
|
||||
|
||||
* errors: map ESOCKTNOSUPPORT errno (Ryan Liptak)
|
||||
|
||||
* doc: uv_read_stop always succeeds (Simon Kissane)
|
||||
|
||||
* inet: fix inconsistent return value of inet_ntop6 (twosee)
|
||||
|
||||
* darwin: fix -Wsometimes-uninitialized warning (twosee)
|
||||
|
||||
* stream: introduce uv_try_write2 function (twosee)
|
||||
|
||||
* poll,win: UV_PRIORITIZED option should not assert (twosee)
|
||||
|
||||
* src: DragonFlyBSD has mmsghdr struct too (David Carlier)
|
||||
|
||||
* cleanup,win: Remove _WIN32 guards on threadpool (James M Snell)
|
||||
|
||||
* freebsd: fix an incompatible pointer type warning (Darshan Sen)
|
||||
|
||||
* core: Correct the conditionals for {cloexec,nonblock}_ioctl (Ali Mohammad
|
||||
Pur)
|
||||
|
||||
* win,tcp: make uv_close work more like unix (Jameson Nash)
|
||||
|
||||
* doc: more accurate list of valid send_handle's (twosee)
|
||||
|
||||
* win,tcp: translate system errors correctly (twosee)
|
||||
|
||||
* unix: implement cpu_relax() on ppc64 (Ben Noordhuis)
|
||||
|
||||
* docs: move list of project links under PR control (Jameson Nash)
|
||||
|
||||
* test: wrong pointer arithmetic multiplier (Erkhes N)
|
||||
|
||||
* doc: switch discussion forum to github (Jameson Nash)
|
||||
|
||||
* idna: fix OOB read in punycode decoder (Ben Noordhuis)
|
||||
|
||||
* build: make sure -fvisibility=hidden is set (Santiago Gimeno)
|
||||
|
||||
* illumos: event ports to epoll (tjarlama)
|
||||
|
||||
* illumos,tty: UV_TTY_MODE_IO waits for 4 bytes (Joshua M. Clulow)
|
||||
|
||||
* doc: add vtjnash GPG ID (Jameson Nash)
|
||||
|
||||
* linux: read CPU model information on ppc (Richard Lau)
|
||||
|
||||
* darwin: fix uv_barrier race condition (Guilherme Íscaro)
|
||||
|
||||
* unix,stream: fix loop hang after uv_shutdown (Jameson Nash)
|
||||
|
||||
* doc,udp: note that suggested_size is 1 max-sized dgram (Ryan Liptak)
|
||||
|
||||
* mingw: fix building for ARM/AArch64 (Martin Storsjö)
|
||||
|
||||
* unix: strnlen is not available on Solaris 10 (Claes Nästén)
|
||||
|
||||
* sunos: restore use of event ports (Andy Fiddaman)
|
||||
|
||||
* sunos,cmake: use thread-safe errno (Andy Fiddaman)
|
||||
|
||||
|
||||
2021.02.14, Version 1.41.0 (Stable), 1dff88e5161cba5c59276d2070d2e304e4dcb242
|
||||
|
||||
Changes since version 1.40.0:
|
||||
|
101
deps/uv/LINKS.md
vendored
Normal file
101
deps/uv/LINKS.md
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
### Apps / VM
|
||||
* [BIND 9](https://bind.isc.org/): DNS software system including an authoritative server, a recursive resolver and related utilities.
|
||||
* [cjdns](https://github.com/cjdelisle/cjdns): Encrypted self-configuring network/VPN routing engine
|
||||
* [clearskies_core](https://github.com/larroy/clearskies_core): Clearskies file synchronization program. (C++11)
|
||||
* [CMake](https://cmake.org) open-source, cross-platform family of tools designed to build, test and package software
|
||||
* [Coherence](https://github.com/liesware/coherence/): Cryptographic server for modern web apps.
|
||||
* [DPS-For-IoT](https://github.com/intel/dps-for-iot/wiki): Fully distributed publish/subscribe protocol.
|
||||
* [HashLink](https://github.com/HaxeFoundation/hashlink): Haxe run-time with libuv support included.
|
||||
* [Haywire](https://github.com/kellabyte/Haywire): Asynchronous HTTP server.
|
||||
* [H2O](https://github.com/h2o/h2o): An optimized HTTP server with support for HTTP/1.x and HTTP/2.
|
||||
* [Igropyr](https://github.com/guenchi/Igropyr): a async Scheme http server base on libuv.
|
||||
* [Julia](http://julialang.org/): Scientific computing programming language
|
||||
* [Kestrel](https://github.com/aspnet/AspNetCore/tree/master/src/Servers/Kestrel): web server (C# + libuv + [ASP.NET Core](http://github.com/aspnet))
|
||||
* [Knot DNS Resolver](https://www.knot-resolver.cz/): A minimalistic DNS caching resolver
|
||||
* [Lever](http://leverlanguage.com): runtime, libuv at the 0.9.0 release
|
||||
* [libnode](https://github.com/plenluno/libnode): C++ implementation of Node.js
|
||||
* [libstorj](https://github.com/Storj/libstorj): Library for interacting with Storj network
|
||||
* [libuv_message_framing](https://github.com/litesync/libuv_message_framing) Message-based communication for libuv
|
||||
* [luaw](https://github.com/raksoras/luaw): Lua web server backed by libuv
|
||||
* [Luvit](http://luvit.io): Node.JS for the Lua Inventor
|
||||
* [mo](https://github.com/wehu/mo): Scheme (guile) + libuv runtime
|
||||
* [MoarVM](https://github.com/MoarVM/MoarVM): a VM for [Rakudo](http://rakudo.org/) [Raku](http://raku.org)
|
||||
* [Mysocks](https://github.com/zhou0/mysocks): a cross-platform [Shadowsocks](https://shadowsocks.org) client
|
||||
* [mediasoup](http://mediasoup.org): Powerful WebRTC SFU for Node.js
|
||||
* [Neovim](https://neovim.io/): A major refactor of Vim.
|
||||
* [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
|
||||
* [potion](https://github.com/perl11/potion)/[p2](https://github.com/perl11/p2): runtime
|
||||
* [racer](https://libraries.io/rubygems/racer): Ruby web server written as an C extension
|
||||
* [spider-gazelle](https://github.com/cotag/spider-gazelle): Ruby web server using libuv bindings
|
||||
* [Suave](http://suave.io/): A simple web development F# library providing a lightweight web server and a set of combinators to manipulate route flow and task composition
|
||||
* [Swish](https://github.com/becls/swish/): Concurrency engine with Erlang-like concepts. Includes a web server.
|
||||
* [Trevi](https://github.com/Yoseob/Trevi): A powerful Swift Web Application Server Framework Project
|
||||
* [Urbit](http://urbit.org): runtime
|
||||
* [uv_callback](https://github.com/litesync/uv_callback) libuv thread communication
|
||||
* [uvloop](https://github.com/MagicStack/uvloop): Ultra fast implementation of python's asyncio event loop on top of libuv
|
||||
* [Wren CLI](https://github.com/wren-lang/wren-cli): For io, process, scheduler and timer modules
|
||||
|
||||
### Other
|
||||
* [libtuv](https://github.com/Samsung/libtuv): libuv fork for IoT and embedded systems
|
||||
|
||||
### Bindings
|
||||
* [Ring](http://ring-lang.net)
|
||||
* [RingLibuv](http://ring-lang.sourceforge.net/doc1.7/libuv.html)
|
||||
* Ruby
|
||||
* [libuv](https://github.com/cotag/libuv)
|
||||
* [uvrb](https://github.com/avalanche123/uvrb)
|
||||
* [ruv](https://github.com/aq1018/ruv)
|
||||
* [rbuv](https://github.com/rbuv/rbuv)
|
||||
* [mruby-uv](https://github.com/mattn/mruby-uv): mruby binding
|
||||
* Lua
|
||||
* [luv](https://github.com/creationix/luv)
|
||||
* [lev](https://github.com/connectFree/lev)
|
||||
* [lluv](https://github.com/moteus/lua-lluv)
|
||||
* C++11
|
||||
* [uvpp](https://github.com/larroy/uvpp) - Not complete, exposes very few aspects of `libuv`
|
||||
* C++17
|
||||
* [uvw](https://github.com/skypjack/uvw) - Header-only, event based, tiny and easy to use *libuv* wrapper in modern C++.
|
||||
* Python
|
||||
* [Pyuv](https://github.com/saghul/pyuv)
|
||||
* [uvloop](https://github.com/MagicStack/uvloop) - Ultra fast asyncio event loop.
|
||||
* [gevent](http://www.gevent.org) - Coroutine-based concurrency library for Python
|
||||
* C#
|
||||
* [NetUV](http://github.com/StormHub/NetUV)
|
||||
* [LibuvSharp](http://github.com/txdv/LibuvSharp)
|
||||
* Perl 5
|
||||
* [UV](https://metacpan.org/pod/UV)
|
||||
* [Raku](https://raku.org/)
|
||||
* [MoarVM](https://github.com/MoarVM/MoarVM) [uses](http://6guts.wordpress.com/2013/05/31/moarvm-a-virtual-machine-for-nqp-and-rakudo/) libuv
|
||||
* PHP
|
||||
* [php-uv](https://github.com/bwoebi/php-uv)
|
||||
* Go
|
||||
* [go-uv](https://github.com/mattn/go-uv)
|
||||
* OCaml
|
||||
* [luv](https://github.com/aantron/luv)
|
||||
* [uwt](https://github.com/fdopen/uwt)
|
||||
* ooc
|
||||
* [ooc-uv](https://github.com/nddrylliog/ooc-uv)
|
||||
* dylan
|
||||
* [uv-dylan](https://github.com/waywardmonkeys/uv-dylan)
|
||||
* R
|
||||
* [httpuv](https://github.com/rstudio/httpuv): HTTP and WebSocket server library for R
|
||||
* [fs](https://fs.r-lib.org/): Cross-platform file system operations
|
||||
* Java
|
||||
* [libuv-java](https://java.net/projects/avatar-js/sources/libuv-java/show): Java bindings
|
||||
* Nim
|
||||
* [nimuv](https://github.com/2vg/nimuv): Nim bindings
|
||||
* Lisp
|
||||
* [cl-libuv](https://github.com/orthecreedence/cl-libuv) Common Lisp bindings
|
||||
* [cl-async](https://github.com/orthecreedence/cl-async) Common Lisp async abstraction on top of cl-libuv
|
||||
* [Céu](http://www.ceu-lang.org)
|
||||
* [Céu-libuv](https://github.com/fsantanna/ceu-libuv)
|
||||
* Delphi
|
||||
* [node.pas](https://github.com/vovach777/node.pas) NodeJS-like ecosystem
|
||||
* Haskell
|
||||
* [Z.Haskell](https://z.haskell.world)
|
1
deps/uv/MAINTAINERS.md
vendored
1
deps/uv/MAINTAINERS.md
vendored
@ -16,6 +16,7 @@ libuv is currently managed by the following individuals:
|
||||
* **Imran Iqbal** ([@imran-iq](https://github.com/imran-iq))
|
||||
- GPG key: 9DFE AA5F 481B BF77 2D90 03CE D592 4925 2F8E C41A (pubkey-iwuzhere)
|
||||
* **Jameson Nash** ([@vtjnash](https://github.com/vtjnash))
|
||||
- GPG key: AEAD 0A4B 6867 6775 1A0E 4AEF 34A2 5FB1 2824 6514 (pubkey-vtjnash)
|
||||
* **John Barboza** ([@jbarz](https://github.com/jbarz))
|
||||
* **Kaoru Takanashi** ([@erw7](https://github.com/erw7))
|
||||
- GPG Key: 5804 F999 8A92 2AFB A398 47A0 7183 5090 6134 887F (pubkey-erw7)
|
||||
|
10
deps/uv/Makefile.am
vendored
10
deps/uv/Makefile.am
vendored
@ -206,6 +206,9 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
||||
test/test-metrics.c \
|
||||
test/test-multiple-listen.c \
|
||||
test/test-mutexes.c \
|
||||
test/test-not-readable-nor-writable-on-read-error.c \
|
||||
test/test-not-readable-on-eof.c \
|
||||
test/test-not-writable-after-shutdown.c \
|
||||
test/test-osx-select.c \
|
||||
test/test-pass-always.c \
|
||||
test/test-ping-pong.c \
|
||||
@ -238,6 +241,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
||||
test/test-semaphore.c \
|
||||
test/test-shutdown-close.c \
|
||||
test/test-shutdown-eof.c \
|
||||
test/test-shutdown-simultaneous.c \
|
||||
test/test-shutdown-twice.c \
|
||||
test/test-signal-multiple-loops.c \
|
||||
test/test-signal-pending-on-close.c \
|
||||
@ -388,7 +392,8 @@ libuv_la_CFLAGS += -D_GNU_SOURCE
|
||||
libuv_la_SOURCES += src/unix/android-ifaddrs.c \
|
||||
src/unix/pthread-fixes.c \
|
||||
src/unix/random-getrandom.c \
|
||||
src/unix/random-sysctl-linux.c
|
||||
src/unix/random-sysctl-linux.c \
|
||||
src/unix/epoll.c
|
||||
endif
|
||||
|
||||
if CYGWIN
|
||||
@ -469,7 +474,8 @@ libuv_la_SOURCES += src/unix/linux-core.c \
|
||||
src/unix/procfs-exepath.c \
|
||||
src/unix/proctitle.c \
|
||||
src/unix/random-getrandom.c \
|
||||
src/unix/random-sysctl-linux.c
|
||||
src/unix/random-sysctl-linux.c \
|
||||
src/unix/epoll.c
|
||||
test_run_tests_LDFLAGS += -lutil
|
||||
endif
|
||||
|
||||
|
12
deps/uv/README.md
vendored
12
deps/uv/README.md
vendored
@ -5,7 +5,7 @@
|
||||
libuv is a multi-platform support library with a focus on asynchronous I/O. It
|
||||
was primarily developed for use by [Node.js][], but it's also
|
||||
used by [Luvit](http://luvit.io/), [Julia](http://julialang.org/),
|
||||
[pyuv](https://github.com/saghul/pyuv), and [others](https://github.com/libuv/libuv/wiki/Projects-that-use-libuv).
|
||||
[pyuv](https://github.com/saghul/pyuv), and [others](https://github.com/libuv/libuv/blob/v1.x/LINKS.md).
|
||||
|
||||
## Feature highlights
|
||||
|
||||
@ -48,9 +48,8 @@ The documentation is licensed under the CC BY 4.0 license. Check the [LICENSE-do
|
||||
|
||||
## Community
|
||||
|
||||
* [Support](https://github.com/libuv/help)
|
||||
* [Support](https://github.com/libuv/libuv/discussions)
|
||||
* [Mailing list](http://groups.google.com/group/libuv)
|
||||
* [IRC chatroom (#libuv@irc.freenode.org)](http://webchat.freenode.net?channels=libuv&uio=d4)
|
||||
|
||||
## Documentation
|
||||
|
||||
@ -308,6 +307,13 @@ describes the package in more detail.
|
||||
|
||||
### z/OS Notes
|
||||
|
||||
z/OS compilation requires [ZOSLIB](https://github.com/ibmruntimes/zoslib) to be installed. When building with [CMake][], use the flag `-DZOSLIB_DIR` to specify the path to [ZOSLIB](https://github.com/ibmruntimes/zoslib):
|
||||
|
||||
```bash
|
||||
$ (cd build && cmake .. -DBUILD_TESTING=ON -DZOSLIB_DIR=/path/to/zoslib)
|
||||
$ cmake --build build
|
||||
```
|
||||
|
||||
z/OS creates System V semaphores and message queues. These persist on the system
|
||||
after the process terminates unless the event loop is closed.
|
||||
|
||||
|
9
deps/uv/configure.ac
vendored
9
deps/uv/configure.ac
vendored
@ -13,7 +13,7 @@
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT([libuv], [1.41.0], [https://github.com/libuv/libuv/issues])
|
||||
AC_INIT([libuv], [1.42.0], [https://github.com/libuv/libuv/issues])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
m4_include([m4/libuv-extra-automake-flags.m4])
|
||||
m4_include([m4/as_case.m4])
|
||||
@ -24,7 +24,10 @@ AC_ENABLE_SHARED
|
||||
AC_ENABLE_STATIC
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
CC_FLAG_VISIBILITY #[-fvisibility=hidden]
|
||||
|
||||
CC_ATTRIBUTE_VISIBILITY([default], [
|
||||
CC_FLAG_VISIBILITY([CFLAGS="${CFLAGS} -fvisibility=hidden"])
|
||||
])
|
||||
CC_CHECK_CFLAGS_APPEND([-fno-strict-aliasing])
|
||||
CC_CHECK_CFLAGS_APPEND([-g])
|
||||
CC_CHECK_CFLAGS_APPEND([-std=gnu89])
|
||||
@ -43,7 +46,7 @@ AX_PTHREAD([
|
||||
LIBS="$LIBS $PTHREAD_LIBS"
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
])
|
||||
AC_CHECK_LIB([dl], [dlopen])
|
||||
AC_SEARCH_LIBS([dlopen], [dl])
|
||||
AC_SEARCH_LIBS([kstat_lookup], [kstat])
|
||||
AC_SEARCH_LIBS([gethostbyname], [nsl])
|
||||
AC_SEARCH_LIBS([perfstat_cpu], [perfstat])
|
||||
|
42
deps/uv/docs/requirements.txt
vendored
Normal file
42
deps/uv/docs/requirements.txt
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
# primary
|
||||
Sphinx==3.5.4
|
||||
|
||||
# dependencies
|
||||
alabaster==0.7.12
|
||||
appdirs==1.4.3
|
||||
Babel==2.9.0
|
||||
CacheControl==0.12.6
|
||||
certifi==2019.11.28
|
||||
chardet==3.0.4
|
||||
colorama==0.4.3
|
||||
contextlib2==0.6.0
|
||||
distlib==0.3.0
|
||||
distro==1.4.0
|
||||
docutils==0.16
|
||||
html5lib==1.0.1
|
||||
idna==2.8
|
||||
imagesize==1.2.0
|
||||
ipaddr==2.2.0
|
||||
Jinja2==2.11.3
|
||||
lockfile==0.12.2
|
||||
MarkupSafe==1.1.1
|
||||
msgpack==0.6.2
|
||||
packaging==20.3
|
||||
pep517==0.8.2
|
||||
progress==1.5
|
||||
Pygments==2.8.1
|
||||
pyparsing==2.4.6
|
||||
pytoml==0.1.21
|
||||
pytz==2021.1
|
||||
requests==2.22.0
|
||||
retrying==1.3.3
|
||||
six==1.14.0
|
||||
snowballstemmer==2.1.0
|
||||
sphinxcontrib-applehelp==1.0.2
|
||||
sphinxcontrib-devhelp==1.0.2
|
||||
sphinxcontrib-htmlhelp==1.0.3
|
||||
sphinxcontrib-jsmath==1.0.1
|
||||
sphinxcontrib-qthelp==1.0.3
|
||||
sphinxcontrib-serializinghtml==1.1.4
|
||||
urllib3==1.25.8
|
||||
webencodings==0.5.1
|
8
deps/uv/docs/src/errors.rst
vendored
8
deps/uv/docs/src/errors.rst
vendored
@ -251,6 +251,10 @@ Error constants
|
||||
|
||||
operation not supported on socket
|
||||
|
||||
.. c:macro:: UV_EOVERFLOW
|
||||
|
||||
value too large for defined data type
|
||||
|
||||
.. c:macro:: UV_EPERM
|
||||
|
||||
operation not permitted
|
||||
@ -331,6 +335,10 @@ Error constants
|
||||
|
||||
illegal byte sequence
|
||||
|
||||
.. c:macro:: UV_ESOCKTNOSUPPORT
|
||||
|
||||
socket type not supported
|
||||
|
||||
|
||||
API
|
||||
---
|
||||
|
2
deps/uv/docs/src/index.rst
vendored
2
deps/uv/docs/src/index.rst
vendored
@ -17,7 +17,7 @@ was primarily developed for use by `Node.js`_, but it's also used by `Luvit`_,
|
||||
.. _Luvit: https://luvit.io
|
||||
.. _Julia: https://julialang.org
|
||||
.. _pyuv: https://github.com/saghul/pyuv
|
||||
.. _others: https://github.com/libuv/libuv/wiki/Projects-that-use-libuv
|
||||
.. _others: https://github.com/libuv/libuv/blob/v1.x/LINKS.md
|
||||
|
||||
|
||||
Features
|
||||
|
2
deps/uv/docs/src/misc.rst
vendored
2
deps/uv/docs/src/misc.rst
vendored
@ -533,7 +533,7 @@ API
|
||||
|
||||
.. note::
|
||||
This function currently only returns a non-zero value on Linux, based
|
||||
on cgroups if it is present.
|
||||
on cgroups if it is present, and on z/OS based on RLIMIT_MEMLIMIT.
|
||||
|
||||
.. versionadded:: 1.29.0
|
||||
|
||||
|
20
deps/uv/docs/src/stream.rst
vendored
20
deps/uv/docs/src/stream.rst
vendored
@ -151,6 +151,11 @@ API
|
||||
|
||||
This function is idempotent and may be safely called on a stopped stream.
|
||||
|
||||
This function will always succeed; hence, checking its return value is
|
||||
unnecessary. A non-zero return indicates that finishing releasing resources
|
||||
may be pending on the next input event on that TTY on Windows, and does not
|
||||
indicate failure.
|
||||
|
||||
.. c:function:: int uv_write(uv_write_t* req, uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb)
|
||||
|
||||
Write data to stream. Buffers are written in order. Example:
|
||||
@ -188,8 +193,9 @@ API
|
||||
initialized with `ipc` == 1.
|
||||
|
||||
.. note::
|
||||
`send_handle` must be a TCP socket or pipe, which is a server or a connection (listening
|
||||
or connected state). Bound sockets or pipes will be assumed to be servers.
|
||||
`send_handle` must be a TCP, pipe and UDP handle on Unix, or a TCP
|
||||
handle on Windows, which is a server or a connection (listening or
|
||||
connected state). Bound sockets or pipes will be assumed to be servers.
|
||||
|
||||
.. c:function:: int uv_try_write(uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs)
|
||||
|
||||
@ -202,6 +208,16 @@ API
|
||||
* < 0: negative error code (``UV_EAGAIN`` is returned if no data can be sent
|
||||
immediately).
|
||||
|
||||
.. c:function:: int uv_try_write2(uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle)
|
||||
|
||||
Same as :c:func:`uv_try_write` and extended write function for sending
|
||||
handles over a pipe like c:func:`uv_write2`.
|
||||
|
||||
Try to send a handle is not supported on Windows,
|
||||
where it returns ``UV_EAGAIN``.
|
||||
|
||||
.. versionadded:: 1.42.0
|
||||
|
||||
.. c:function:: int uv_is_readable(const uv_stream_t* handle)
|
||||
|
||||
Returns 1 if the stream is readable, 0 otherwise.
|
||||
|
16
deps/uv/docs/src/udp.rst
vendored
16
deps/uv/docs/src/udp.rst
vendored
@ -53,6 +53,14 @@ Data types
|
||||
* in uv_udp_recv_cb, nread will always be 0 and addr will always be NULL.
|
||||
*/
|
||||
UV_UDP_MMSG_FREE = 16,
|
||||
/*
|
||||
* Indicates if IP_RECVERR/IPV6_RECVERR will be set when binding the handle.
|
||||
* This sets IP_RECVERR for IPv4 and IPV6_RECVERR for IPv6 UDP sockets on
|
||||
* Linux. This stops the Linux kernel from supressing some ICMP error messages
|
||||
* and enables full ICMP error reporting for faster failover.
|
||||
* This flag is no-op on platforms other than Linux.
|
||||
*/
|
||||
UV_UDP_LINUX_RECVERR = 32,
|
||||
/*
|
||||
* Indicates that recvmmsg should be used, if available.
|
||||
*/
|
||||
@ -178,7 +186,8 @@ API
|
||||
with the address and port to bind to.
|
||||
|
||||
:param flags: Indicate how the socket will be bound,
|
||||
``UV_UDP_IPV6ONLY`` and ``UV_UDP_REUSEADDR`` are supported.
|
||||
``UV_UDP_IPV6ONLY``, ``UV_UDP_REUSEADDR``, and ``UV_UDP_RECVERR``
|
||||
are supported.
|
||||
|
||||
:returns: 0 on success, or an error code < 0 on failure.
|
||||
|
||||
@ -395,6 +404,11 @@ API
|
||||
|
||||
:returns: 0 on success, or an error code < 0 on failure.
|
||||
|
||||
.. note::
|
||||
When using :man:`recvmmsg(2)`, the number of messages received at a time is limited
|
||||
by the number of max size dgrams that will fit into the buffer allocated in `alloc_cb`, and
|
||||
`suggested_size` in `alloc_cb` for udp_recv is always set to the size of 1 max size dgram.
|
||||
|
||||
.. versionchanged:: 1.35.0 added support for :man:`recvmmsg(2)` on supported platforms).
|
||||
The use of this feature requires a buffer larger than
|
||||
2 * 64KB to be passed to `alloc_cb`.
|
||||
|
15
deps/uv/include/uv.h
vendored
15
deps/uv/include/uv.h
vendored
@ -126,6 +126,7 @@ extern "C" {
|
||||
XX(ENOTEMPTY, "directory not empty") \
|
||||
XX(ENOTSOCK, "socket operation on non-socket") \
|
||||
XX(ENOTSUP, "operation not supported on socket") \
|
||||
XX(EOVERFLOW, "value too large for defined data type") \
|
||||
XX(EPERM, "operation not permitted") \
|
||||
XX(EPIPE, "broken pipe") \
|
||||
XX(EPROTO, "protocol error") \
|
||||
@ -148,6 +149,7 @@ extern "C" {
|
||||
XX(ENOTTY, "inappropriate ioctl for device") \
|
||||
XX(EFTYPE, "inappropriate file type or format") \
|
||||
XX(EILSEQ, "illegal byte sequence") \
|
||||
XX(ESOCKTNOSUPPORT, "socket type not supported") \
|
||||
|
||||
#define UV_HANDLE_TYPE_MAP(XX) \
|
||||
XX(ASYNC, async) \
|
||||
@ -526,6 +528,10 @@ UV_EXTERN int uv_write2(uv_write_t* req,
|
||||
UV_EXTERN int uv_try_write(uv_stream_t* handle,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs);
|
||||
UV_EXTERN int uv_try_write2(uv_stream_t* handle,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs,
|
||||
uv_stream_t* send_handle);
|
||||
|
||||
/* uv_write_t is a subclass of uv_req_t. */
|
||||
struct uv_write_s {
|
||||
@ -626,7 +632,14 @@ enum uv_udp_flags {
|
||||
* in uv_udp_recv_cb, nread will always be 0 and addr will always be NULL.
|
||||
*/
|
||||
UV_UDP_MMSG_FREE = 16,
|
||||
|
||||
/*
|
||||
* Indicates if IP_RECVERR/IPV6_RECVERR will be set when binding the handle.
|
||||
* This sets IP_RECVERR for IPv4 and IPV6_RECVERR for IPv6 UDP sockets on
|
||||
* Linux. This stops the Linux kernel from suppressing some ICMP error
|
||||
* messages and enables full ICMP error reporting for faster failover.
|
||||
* This flag is no-op on platforms other than Linux.
|
||||
*/
|
||||
UV_UDP_LINUX_RECVERR = 32,
|
||||
/*
|
||||
* Indicates that recvmmsg should be used, if available.
|
||||
*/
|
||||
|
12
deps/uv/include/uv/errno.h
vendored
12
deps/uv/include/uv/errno.h
vendored
@ -445,4 +445,16 @@
|
||||
# define UV__EILSEQ (-4027)
|
||||
#endif
|
||||
|
||||
#if defined(EOVERFLOW) && !defined(_WIN32)
|
||||
# define UV__EOVERFLOW UV__ERR(EOVERFLOW)
|
||||
#else
|
||||
# define UV__EOVERFLOW (-4026)
|
||||
#endif
|
||||
|
||||
#if defined(ESOCKTNOSUPPORT) && !defined(_WIN32)
|
||||
# define UV__ESOCKTNOSUPPORT UV__ERR(ESOCKTNOSUPPORT)
|
||||
#else
|
||||
# define UV__ESOCKTNOSUPPORT (-4025)
|
||||
#endif
|
||||
|
||||
#endif /* UV_ERRNO_H_ */
|
||||
|
2
deps/uv/include/uv/tree.h
vendored
2
deps/uv/include/uv/tree.h
vendored
@ -251,7 +251,7 @@ void name##_SPLAY_MINMAX(struct name *head, int __comp) \
|
||||
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \
|
||||
__left = __right = &__node; \
|
||||
\
|
||||
while (1) { \
|
||||
for (;;) { \
|
||||
if (__comp < 0) { \
|
||||
__tmp = SPLAY_LEFT((head)->sph_root, field); \
|
||||
if (__tmp == NULL) \
|
||||
|
2
deps/uv/include/uv/version.h
vendored
2
deps/uv/include/uv/version.h
vendored
@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
#define UV_VERSION_MAJOR 1
|
||||
#define UV_VERSION_MINOR 41
|
||||
#define UV_VERSION_MINOR 42
|
||||
#define UV_VERSION_PATCH 0
|
||||
#define UV_VERSION_IS_RELEASE 1
|
||||
#define UV_VERSION_SUFFIX ""
|
||||
|
3
deps/uv/src/inet.c
vendored
3
deps/uv/src/inet.c
vendored
@ -141,8 +141,9 @@ static int inet_ntop6(const unsigned char *src, char *dst, size_t size) {
|
||||
if (best.base != -1 && (best.base + best.len) == ARRAY_SIZE(words))
|
||||
*tp++ = ':';
|
||||
*tp++ = '\0';
|
||||
if (UV_E2BIG == uv__strscpy(dst, tmp, size))
|
||||
if ((size_t) (tp - tmp) > size)
|
||||
return UV_ENOSPC;
|
||||
uv__strscpy(dst, tmp, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
2
deps/uv/src/threadpool.c
vendored
2
deps/uv/src/threadpool.c
vendored
@ -161,7 +161,6 @@ static void post(QUEUE* q, enum uv__work_kind kind) {
|
||||
|
||||
|
||||
void uv__threadpool_cleanup(void) {
|
||||
#ifndef _WIN32
|
||||
unsigned int i;
|
||||
|
||||
if (nthreads == 0)
|
||||
@ -181,7 +180,6 @@ void uv__threadpool_cleanup(void) {
|
||||
|
||||
threads = NULL;
|
||||
nthreads = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
6
deps/uv/src/unix/atomic-ops.h
vendored
6
deps/uv/src/unix/atomic-ops.h
vendored
@ -52,9 +52,11 @@ UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) {
|
||||
|
||||
UV_UNUSED(static void cpu_relax(void)) {
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
__asm__ __volatile__ ("rep; nop"); /* a.k.a. PAUSE */
|
||||
__asm__ __volatile__ ("rep; nop" ::: "memory"); /* a.k.a. PAUSE */
|
||||
#elif (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__)
|
||||
__asm__ volatile("yield");
|
||||
__asm__ __volatile__ ("yield" ::: "memory");
|
||||
#elif defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__)
|
||||
__asm__ __volatile__ ("or 1,1,1; or 2,2,2" ::: "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
23
deps/uv/src/unix/core.c
vendored
23
deps/uv/src/unix/core.c
vendored
@ -88,6 +88,10 @@ extern char** environ;
|
||||
# define uv__accept4 accept4
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) && defined(__SANITIZE_THREAD__) && defined(__clang__)
|
||||
# include <sanitizer/linux_syscall_hooks.h>
|
||||
#endif
|
||||
|
||||
static int uv__run_pending(uv_loop_t* loop);
|
||||
|
||||
/* Verify that uv_buf_t is ABI-compatible with struct iovec. */
|
||||
@ -539,7 +543,13 @@ int uv__close_nocancel(int fd) {
|
||||
return close$NOCANCEL$UNIX2003(fd);
|
||||
#endif
|
||||
#pragma GCC diagnostic pop
|
||||
#elif defined(__linux__)
|
||||
#elif defined(__linux__) && defined(__SANITIZE_THREAD__) && defined(__clang__)
|
||||
long rc;
|
||||
__sanitizer_syscall_pre_close(fd);
|
||||
rc = syscall(SYS_close, fd);
|
||||
__sanitizer_syscall_post_close(rc, fd);
|
||||
return rc;
|
||||
#elif defined(__linux__) && !defined(__SANITIZE_THREAD__)
|
||||
return syscall(SYS_close, fd);
|
||||
#else
|
||||
return close(fd);
|
||||
@ -574,7 +584,7 @@ int uv__close(int fd) {
|
||||
return uv__close_nocheckstdio(fd);
|
||||
}
|
||||
|
||||
|
||||
#if UV__NONBLOCK_IS_IOCTL
|
||||
int uv__nonblock_ioctl(int fd, int set) {
|
||||
int r;
|
||||
|
||||
@ -589,7 +599,6 @@ int uv__nonblock_ioctl(int fd, int set) {
|
||||
}
|
||||
|
||||
|
||||
#if !defined(__CYGWIN__) && !defined(__MSYS__) && !defined(__HAIKU__)
|
||||
int uv__cloexec_ioctl(int fd, int set) {
|
||||
int r;
|
||||
|
||||
@ -1174,7 +1183,9 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
|
||||
if (buf == NULL)
|
||||
return UV_ENOMEM;
|
||||
|
||||
r = getpwuid_r(uid, &pw, buf, bufsize, &result);
|
||||
do
|
||||
r = getpwuid_r(uid, &pw, buf, bufsize, &result);
|
||||
while (r == EINTR);
|
||||
|
||||
if (r != ERANGE)
|
||||
break;
|
||||
@ -1184,7 +1195,7 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
|
||||
|
||||
if (r != 0) {
|
||||
uv__free(buf);
|
||||
return -r;
|
||||
return UV__ERR(r);
|
||||
}
|
||||
|
||||
if (result == NULL) {
|
||||
@ -1570,7 +1581,7 @@ int uv__search_path(const char* prog, char* buf, size_t* buflen) {
|
||||
buf[*buflen] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Case iii). Search PATH environment variable */
|
||||
cloned_path = NULL;
|
||||
|
12
deps/uv/src/unix/darwin.c
vendored
12
deps/uv/src/unix/darwin.c
vendored
@ -33,9 +33,7 @@
|
||||
#include <sys/sysctl.h>
|
||||
#include <unistd.h> /* sysconf */
|
||||
|
||||
#if !TARGET_OS_IPHONE
|
||||
#include "darwin-stub.h"
|
||||
#endif
|
||||
|
||||
static uv_once_t once = UV_ONCE_INIT;
|
||||
static uint64_t (*time_func)(void);
|
||||
@ -223,10 +221,10 @@ static int uv__get_cpu_speed(uint64_t* speed) {
|
||||
err = UV_ENOENT;
|
||||
core_foundation_handle = dlopen("/System/Library/Frameworks/"
|
||||
"CoreFoundation.framework/"
|
||||
"Versions/A/CoreFoundation",
|
||||
"CoreFoundation",
|
||||
RTLD_LAZY | RTLD_LOCAL);
|
||||
iokit_handle = dlopen("/System/Library/Frameworks/IOKit.framework/"
|
||||
"Versions/A/IOKit",
|
||||
"IOKit",
|
||||
RTLD_LAZY | RTLD_LOCAL);
|
||||
|
||||
if (core_foundation_handle == NULL || iokit_handle == NULL)
|
||||
@ -304,6 +302,12 @@ static int uv__get_cpu_speed(uint64_t* speed) {
|
||||
pIOObjectRelease(it);
|
||||
|
||||
err = 0;
|
||||
|
||||
if (device_type_str != NULL)
|
||||
pCFRelease(device_type_str);
|
||||
if (clock_frequency_str != NULL)
|
||||
pCFRelease(clock_frequency_str);
|
||||
|
||||
out:
|
||||
if (core_foundation_handle != NULL)
|
||||
dlclose(core_foundation_handle);
|
||||
|
422
deps/uv/src/unix/epoll.c
vendored
Normal file
422
deps/uv/src/unix/epoll.c
vendored
Normal file
@ -0,0 +1,422 @@
|
||||
/* Copyright libuv contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "internal.h"
|
||||
#include <errno.h>
|
||||
#include <sys/epoll.h>
|
||||
|
||||
int uv__epoll_init(uv_loop_t* loop) {
|
||||
int fd;
|
||||
fd = epoll_create1(O_CLOEXEC);
|
||||
|
||||
/* epoll_create1() can fail either because it's not implemented (old kernel)
|
||||
* or because it doesn't understand the O_CLOEXEC flag.
|
||||
*/
|
||||
if (fd == -1 && (errno == ENOSYS || errno == EINVAL)) {
|
||||
fd = epoll_create(256);
|
||||
|
||||
if (fd != -1)
|
||||
uv__cloexec(fd, 1);
|
||||
}
|
||||
|
||||
loop->backend_fd = fd;
|
||||
if (fd == -1)
|
||||
return UV__ERR(errno);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
|
||||
struct epoll_event* events;
|
||||
struct epoll_event dummy;
|
||||
uintptr_t i;
|
||||
uintptr_t nfds;
|
||||
|
||||
assert(loop->watchers != NULL);
|
||||
assert(fd >= 0);
|
||||
|
||||
events = (struct epoll_event*) loop->watchers[loop->nwatchers];
|
||||
nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
|
||||
if (events != NULL)
|
||||
/* Invalidate events with same file descriptor */
|
||||
for (i = 0; i < nfds; i++)
|
||||
if (events[i].data.fd == fd)
|
||||
events[i].data.fd = -1;
|
||||
|
||||
/* Remove the file descriptor from the epoll.
|
||||
* This avoids a problem where the same file description remains open
|
||||
* in another process, causing repeated junk epoll events.
|
||||
*
|
||||
* We pass in a dummy epoll_event, to work around a bug in old kernels.
|
||||
*/
|
||||
if (loop->backend_fd >= 0) {
|
||||
/* Work around a bug in kernels 3.10 to 3.19 where passing a struct that
|
||||
* has the EPOLLWAKEUP flag set generates spurious audit syslog warnings.
|
||||
*/
|
||||
memset(&dummy, 0, sizeof(dummy));
|
||||
epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, &dummy);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int uv__io_check_fd(uv_loop_t* loop, int fd) {
|
||||
struct epoll_event e;
|
||||
int rc;
|
||||
|
||||
memset(&e, 0, sizeof(e));
|
||||
e.events = POLLIN;
|
||||
e.data.fd = -1;
|
||||
|
||||
rc = 0;
|
||||
if (epoll_ctl(loop->backend_fd, EPOLL_CTL_ADD, fd, &e))
|
||||
if (errno != EEXIST)
|
||||
rc = UV__ERR(errno);
|
||||
|
||||
if (rc == 0)
|
||||
if (epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, &e))
|
||||
abort();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
/* A bug in kernels < 2.6.37 makes timeouts larger than ~30 minutes
|
||||
* effectively infinite on 32 bits architectures. To avoid blocking
|
||||
* indefinitely, we cap the timeout and poll again if necessary.
|
||||
*
|
||||
* Note that "30 minutes" is a simplification because it depends on
|
||||
* the value of CONFIG_HZ. The magic constant assumes CONFIG_HZ=1200,
|
||||
* that being the largest value I have seen in the wild (and only once.)
|
||||
*/
|
||||
static const int max_safe_timeout = 1789569;
|
||||
static int no_epoll_pwait_cached;
|
||||
static int no_epoll_wait_cached;
|
||||
int no_epoll_pwait;
|
||||
int no_epoll_wait;
|
||||
struct epoll_event events[1024];
|
||||
struct epoll_event* pe;
|
||||
struct epoll_event e;
|
||||
int real_timeout;
|
||||
QUEUE* q;
|
||||
uv__io_t* w;
|
||||
sigset_t sigset;
|
||||
uint64_t sigmask;
|
||||
uint64_t base;
|
||||
int have_signals;
|
||||
int nevents;
|
||||
int count;
|
||||
int nfds;
|
||||
int fd;
|
||||
int op;
|
||||
int i;
|
||||
int user_timeout;
|
||||
int reset_timeout;
|
||||
|
||||
if (loop->nfds == 0) {
|
||||
assert(QUEUE_EMPTY(&loop->watcher_queue));
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&e, 0, sizeof(e));
|
||||
|
||||
while (!QUEUE_EMPTY(&loop->watcher_queue)) {
|
||||
q = QUEUE_HEAD(&loop->watcher_queue);
|
||||
QUEUE_REMOVE(q);
|
||||
QUEUE_INIT(q);
|
||||
|
||||
w = QUEUE_DATA(q, uv__io_t, watcher_queue);
|
||||
assert(w->pevents != 0);
|
||||
assert(w->fd >= 0);
|
||||
assert(w->fd < (int) loop->nwatchers);
|
||||
|
||||
e.events = w->pevents;
|
||||
e.data.fd = w->fd;
|
||||
|
||||
if (w->events == 0)
|
||||
op = EPOLL_CTL_ADD;
|
||||
else
|
||||
op = EPOLL_CTL_MOD;
|
||||
|
||||
/* XXX Future optimization: do EPOLL_CTL_MOD lazily if we stop watching
|
||||
* events, skip the syscall and squelch the events after epoll_wait().
|
||||
*/
|
||||
if (epoll_ctl(loop->backend_fd, op, w->fd, &e)) {
|
||||
if (errno != EEXIST)
|
||||
abort();
|
||||
|
||||
assert(op == EPOLL_CTL_ADD);
|
||||
|
||||
/* We've reactivated a file descriptor that's been watched before. */
|
||||
if (epoll_ctl(loop->backend_fd, EPOLL_CTL_MOD, w->fd, &e))
|
||||
abort();
|
||||
}
|
||||
|
||||
w->events = w->pevents;
|
||||
}
|
||||
|
||||
sigmask = 0;
|
||||
if (loop->flags & UV_LOOP_BLOCK_SIGPROF) {
|
||||
sigemptyset(&sigset);
|
||||
sigaddset(&sigset, SIGPROF);
|
||||
sigmask |= 1 << (SIGPROF - 1);
|
||||
}
|
||||
|
||||
assert(timeout >= -1);
|
||||
base = loop->time;
|
||||
count = 48; /* Benchmarks suggest this gives the best throughput. */
|
||||
real_timeout = timeout;
|
||||
|
||||
if (uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME) {
|
||||
reset_timeout = 1;
|
||||
user_timeout = timeout;
|
||||
timeout = 0;
|
||||
} else {
|
||||
reset_timeout = 0;
|
||||
user_timeout = 0;
|
||||
}
|
||||
|
||||
/* You could argue there is a dependency between these two but
|
||||
* ultimately we don't care about their ordering with respect
|
||||
* to one another. Worst case, we make a few system calls that
|
||||
* could have been avoided because another thread already knows
|
||||
* they fail with ENOSYS. Hardly the end of the world.
|
||||
*/
|
||||
no_epoll_pwait = uv__load_relaxed(&no_epoll_pwait_cached);
|
||||
no_epoll_wait = uv__load_relaxed(&no_epoll_wait_cached);
|
||||
|
||||
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);
|
||||
|
||||
/* See the comment for max_safe_timeout for an explanation of why
|
||||
* this is necessary. Executive summary: kernel bug workaround.
|
||||
*/
|
||||
if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout)
|
||||
timeout = max_safe_timeout;
|
||||
|
||||
if (sigmask != 0 && no_epoll_pwait != 0)
|
||||
if (pthread_sigmask(SIG_BLOCK, &sigset, NULL))
|
||||
abort();
|
||||
|
||||
if (no_epoll_wait != 0 || (sigmask != 0 && no_epoll_pwait == 0)) {
|
||||
nfds = epoll_pwait(loop->backend_fd,
|
||||
events,
|
||||
ARRAY_SIZE(events),
|
||||
timeout,
|
||||
&sigset);
|
||||
if (nfds == -1 && errno == ENOSYS) {
|
||||
uv__store_relaxed(&no_epoll_pwait_cached, 1);
|
||||
no_epoll_pwait = 1;
|
||||
}
|
||||
} else {
|
||||
nfds = epoll_wait(loop->backend_fd,
|
||||
events,
|
||||
ARRAY_SIZE(events),
|
||||
timeout);
|
||||
if (nfds == -1 && errno == ENOSYS) {
|
||||
uv__store_relaxed(&no_epoll_wait_cached, 1);
|
||||
no_epoll_wait = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (sigmask != 0 && no_epoll_pwait != 0)
|
||||
if (pthread_sigmask(SIG_UNBLOCK, &sigset, 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));
|
||||
|
||||
if (nfds == 0) {
|
||||
assert(timeout != -1);
|
||||
|
||||
if (reset_timeout != 0) {
|
||||
timeout = user_timeout;
|
||||
reset_timeout = 0;
|
||||
}
|
||||
|
||||
if (timeout == -1)
|
||||
continue;
|
||||
|
||||
if (timeout == 0)
|
||||
return;
|
||||
|
||||
/* We may have been inside the system call for longer than |timeout|
|
||||
* milliseconds so we need to update the timestamp to avoid drift.
|
||||
*/
|
||||
goto update_timeout;
|
||||
}
|
||||
|
||||
if (nfds == -1) {
|
||||
if (errno == ENOSYS) {
|
||||
/* epoll_wait() or epoll_pwait() failed, try the other system call. */
|
||||
assert(no_epoll_wait == 0 || no_epoll_pwait == 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (errno != EINTR)
|
||||
abort();
|
||||
|
||||
if (reset_timeout != 0) {
|
||||
timeout = user_timeout;
|
||||
reset_timeout = 0;
|
||||
}
|
||||
|
||||
if (timeout == -1)
|
||||
continue;
|
||||
|
||||
if (timeout == 0)
|
||||
return;
|
||||
|
||||
/* Interrupted by a signal. Update timeout and poll again. */
|
||||
goto update_timeout;
|
||||
}
|
||||
|
||||
have_signals = 0;
|
||||
nevents = 0;
|
||||
|
||||
{
|
||||
/* Squelch a -Waddress-of-packed-member warning with gcc >= 9. */
|
||||
union {
|
||||
struct epoll_event* events;
|
||||
uv__io_t* watchers;
|
||||
} x;
|
||||
|
||||
x.events = events;
|
||||
assert(loop->watchers != NULL);
|
||||
loop->watchers[loop->nwatchers] = x.watchers;
|
||||
loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
|
||||
}
|
||||
|
||||
for (i = 0; i < nfds; i++) {
|
||||
pe = events + i;
|
||||
fd = pe->data.fd;
|
||||
|
||||
/* Skip invalidated events, see uv__platform_invalidate_fd */
|
||||
if (fd == -1)
|
||||
continue;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert((unsigned) fd < loop->nwatchers);
|
||||
|
||||
w = loop->watchers[fd];
|
||||
|
||||
if (w == NULL) {
|
||||
/* File descriptor that we've stopped watching, disarm it.
|
||||
*
|
||||
* Ignore all errors because we may be racing with another thread
|
||||
* when the file descriptor is closed.
|
||||
*/
|
||||
epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, pe);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Give users only events they're interested in. Prevents spurious
|
||||
* callbacks when previous callback invocation in this loop has stopped
|
||||
* the current watcher. Also, filters out events that users has not
|
||||
* requested us to watch.
|
||||
*/
|
||||
pe->events &= w->pevents | POLLERR | POLLHUP;
|
||||
|
||||
/* Work around an epoll quirk where it sometimes reports just the
|
||||
* EPOLLERR or EPOLLHUP event. In order to force the event loop to
|
||||
* move forward, we merge in the read/write events that the watcher
|
||||
* is interested in; uv__read() and uv__write() will then deal with
|
||||
* the error or hangup in the usual fashion.
|
||||
*
|
||||
* Note to self: happens when epoll reports EPOLLIN|EPOLLHUP, the user
|
||||
* reads the available data, calls uv_read_stop(), then sometime later
|
||||
* calls uv_read_start() again. By then, libuv has forgotten about the
|
||||
* hangup and the kernel won't report EPOLLIN again because there's
|
||||
* nothing left to read. If anything, libuv is to blame here. The
|
||||
* current hack is just a quick bandaid; to properly fix it, libuv
|
||||
* needs to remember the error/hangup event. We should get that for
|
||||
* free when we switch over to edge-triggered I/O.
|
||||
*/
|
||||
if (pe->events == POLLERR || pe->events == POLLHUP)
|
||||
pe->events |=
|
||||
w->pevents & (POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI);
|
||||
|
||||
if (pe->events != 0) {
|
||||
/* Run signal watchers last. This also affects child process watchers
|
||||
* because those are implemented in terms of signal watchers.
|
||||
*/
|
||||
if (w == &loop->signal_io_watcher) {
|
||||
have_signals = 1;
|
||||
} else {
|
||||
uv__metrics_update_idle_time(loop);
|
||||
w->cb(loop, w, pe->events);
|
||||
}
|
||||
|
||||
nevents++;
|
||||
}
|
||||
}
|
||||
|
||||
if (reset_timeout != 0) {
|
||||
timeout = user_timeout;
|
||||
reset_timeout = 0;
|
||||
}
|
||||
|
||||
if (have_signals != 0) {
|
||||
uv__metrics_update_idle_time(loop);
|
||||
loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
|
||||
}
|
||||
|
||||
loop->watchers[loop->nwatchers] = NULL;
|
||||
loop->watchers[loop->nwatchers + 1] = NULL;
|
||||
|
||||
if (have_signals != 0)
|
||||
return; /* Event loop should cycle now so don't poll again. */
|
||||
|
||||
if (nevents != 0) {
|
||||
if (nfds == ARRAY_SIZE(events) && --count != 0) {
|
||||
/* Poll for more events but don't block this time. */
|
||||
timeout = 0;
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (timeout == 0)
|
||||
return;
|
||||
|
||||
if (timeout == -1)
|
||||
continue;
|
||||
|
||||
update_timeout:
|
||||
assert(timeout > 0);
|
||||
|
||||
real_timeout -= (loop->time - base);
|
||||
if (real_timeout <= 0)
|
||||
return;
|
||||
|
||||
timeout = real_timeout;
|
||||
}
|
||||
}
|
||||
|
15
deps/uv/src/unix/freebsd.c
vendored
15
deps/uv/src/unix/freebsd.c
vendored
@ -265,8 +265,11 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
|
||||
|
||||
|
||||
int uv__sendmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) {
|
||||
#if __FreeBSD__ >= 11
|
||||
return sendmmsg(fd, mmsg, vlen, /* flags */ 0);
|
||||
#if __FreeBSD__ >= 11 && !defined(__DragonFly__)
|
||||
return sendmmsg(fd,
|
||||
(struct mmsghdr*) mmsg,
|
||||
vlen,
|
||||
0 /* flags */);
|
||||
#else
|
||||
return errno = ENOSYS, -1;
|
||||
#endif
|
||||
@ -274,8 +277,12 @@ int uv__sendmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) {
|
||||
|
||||
|
||||
int uv__recvmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) {
|
||||
#if __FreeBSD__ >= 11
|
||||
return recvmmsg(fd, mmsg, vlen, 0 /* flags */, NULL /* timeout */);
|
||||
#if __FreeBSD__ >= 11 && !defined(__DragonFly__)
|
||||
return recvmmsg(fd,
|
||||
(struct mmsghdr*) mmsg,
|
||||
vlen,
|
||||
0 /* flags */,
|
||||
NULL /* timeout */);
|
||||
#else
|
||||
return errno = ENOSYS, -1;
|
||||
#endif
|
||||
|
62
deps/uv/src/unix/fs.c
vendored
62
deps/uv/src/unix/fs.c
vendored
@ -56,6 +56,10 @@
|
||||
# define HAVE_PREADV 0
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
# include "sys/utsname.h"
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(__sun)
|
||||
# include <sys/sendfile.h>
|
||||
# include <sys/sysmacros.h>
|
||||
@ -901,6 +905,50 @@ out:
|
||||
}
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
static unsigned uv__kernel_version(void) {
|
||||
static unsigned cached_version;
|
||||
struct utsname u;
|
||||
unsigned version;
|
||||
unsigned major;
|
||||
unsigned minor;
|
||||
unsigned patch;
|
||||
|
||||
version = uv__load_relaxed(&cached_version);
|
||||
if (version != 0)
|
||||
return version;
|
||||
|
||||
if (-1 == uname(&u))
|
||||
return 0;
|
||||
|
||||
if (3 != sscanf(u.release, "%u.%u.%u", &major, &minor, &patch))
|
||||
return 0;
|
||||
|
||||
version = major * 65536 + minor * 256 + patch;
|
||||
uv__store_relaxed(&cached_version, version);
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
|
||||
/* Pre-4.20 kernels have a bug where CephFS uses the RADOS copy-from command
|
||||
* in copy_file_range() when it shouldn't. There is no workaround except to
|
||||
* fall back to a regular copy.
|
||||
*/
|
||||
static int uv__is_buggy_cephfs(int fd) {
|
||||
struct statfs s;
|
||||
|
||||
if (-1 == fstatfs(fd, &s))
|
||||
return 0;
|
||||
|
||||
if (s.f_type != /* CephFS */ 0xC36400)
|
||||
return 0;
|
||||
|
||||
return uv__kernel_version() < /* 4.20.0 */ 0x041400;
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
|
||||
|
||||
static ssize_t uv__fs_sendfile(uv_fs_t* req) {
|
||||
int in_fd;
|
||||
int out_fd;
|
||||
@ -917,15 +965,20 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
|
||||
|
||||
#ifdef __linux__
|
||||
{
|
||||
static int copy_file_range_support = 1;
|
||||
static int no_copy_file_range_support;
|
||||
|
||||
if (copy_file_range_support) {
|
||||
if (uv__load_relaxed(&no_copy_file_range_support) == 0) {
|
||||
r = uv__fs_copy_file_range(in_fd, &off, out_fd, NULL, req->bufsml[0].len, 0);
|
||||
|
||||
if (r == -1 && errno == ENOSYS) {
|
||||
/* ENOSYS - it will never work */
|
||||
errno = 0;
|
||||
copy_file_range_support = 0;
|
||||
uv__store_relaxed(&no_copy_file_range_support, 1);
|
||||
} else if (r == -1 && errno == EACCES && uv__is_buggy_cephfs(in_fd)) {
|
||||
/* EACCES - pre-4.20 kernels have a bug where CephFS uses the RADOS
|
||||
copy-from command when it shouldn't */
|
||||
errno = 0;
|
||||
uv__store_relaxed(&no_copy_file_range_support, 1);
|
||||
} else if (r == -1 && (errno == ENOTSUP || errno == EXDEV)) {
|
||||
/* ENOTSUP - it could work on another file system type */
|
||||
/* EXDEV - it will not work when in_fd and out_fd are not on the same
|
||||
@ -1357,7 +1410,8 @@ static void uv__to_stat(struct stat* src, uv_stat_t* dst) {
|
||||
dst->st_birthtim.tv_nsec = src->st_ctimensec;
|
||||
dst->st_flags = 0;
|
||||
dst->st_gen = 0;
|
||||
#elif !defined(_AIX) && ( \
|
||||
#elif !defined(_AIX) && \
|
||||
!defined(__MVS__) && ( \
|
||||
defined(__DragonFly__) || \
|
||||
defined(__FreeBSD__) || \
|
||||
defined(__OpenBSD__) || \
|
||||
|
23
deps/uv/src/unix/fsevents.c
vendored
23
deps/uv/src/unix/fsevents.c
vendored
@ -595,8 +595,7 @@ out:
|
||||
static int uv__fsevents_loop_init(uv_loop_t* loop) {
|
||||
CFRunLoopSourceContext ctx;
|
||||
uv__cf_loop_state_t* state;
|
||||
pthread_attr_t attr_storage;
|
||||
pthread_attr_t* attr;
|
||||
pthread_attr_t attr;
|
||||
int err;
|
||||
|
||||
if (loop->cf_state != NULL)
|
||||
@ -641,25 +640,19 @@ static int uv__fsevents_loop_init(uv_loop_t* loop) {
|
||||
goto fail_signal_source_create;
|
||||
}
|
||||
|
||||
/* In the unlikely event that pthread_attr_init() fails, create the thread
|
||||
* with the default stack size. We'll use a little more address space but
|
||||
* that in itself is not a fatal error.
|
||||
*/
|
||||
attr = &attr_storage;
|
||||
if (pthread_attr_init(attr))
|
||||
attr = NULL;
|
||||
if (pthread_attr_init(&attr))
|
||||
abort();
|
||||
|
||||
if (attr != NULL)
|
||||
if (pthread_attr_setstacksize(attr, 4 * PTHREAD_STACK_MIN))
|
||||
abort();
|
||||
if (pthread_attr_setstacksize(&attr, uv__thread_stack_size()))
|
||||
abort();
|
||||
|
||||
loop->cf_state = state;
|
||||
|
||||
/* uv_thread_t is an alias for pthread_t. */
|
||||
err = UV__ERR(pthread_create(&loop->cf_thread, attr, uv__cf_loop_runner, loop));
|
||||
err = UV__ERR(pthread_create(&loop->cf_thread, &attr, uv__cf_loop_runner, loop));
|
||||
|
||||
if (attr != NULL)
|
||||
pthread_attr_destroy(attr);
|
||||
if (pthread_attr_destroy(&attr))
|
||||
abort();
|
||||
|
||||
if (err)
|
||||
goto fail_thread_create;
|
||||
|
3
deps/uv/src/unix/getaddrinfo.c
vendored
3
deps/uv/src/unix/getaddrinfo.c
vendored
@ -21,9 +21,6 @@
|
||||
/* Expose glibc-specific EAI_* error codes. Needs to be defined before we
|
||||
* include any headers.
|
||||
*/
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include "uv.h"
|
||||
#include "internal.h"
|
||||
|
48
deps/uv/src/unix/ibmi.c
vendored
48
deps/uv/src/unix/ibmi.c
vendored
@ -26,7 +26,6 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -166,7 +165,7 @@ static void iconv_a2e(const char* src, unsigned char dst[], size_t length) {
|
||||
|
||||
srclen = strlen(src);
|
||||
if (srclen > length)
|
||||
abort();
|
||||
srclen = length;
|
||||
for (i = 0; i < srclen; i++)
|
||||
dst[i] = a2e[src[i]];
|
||||
/* padding the remaining part with spaces */
|
||||
@ -360,6 +359,10 @@ static int get_ibmi_physical_address(const char* line, char (*phys_addr)[6]) {
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
if (err.bytes_available > 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* convert ebcdic loca_adapter_address to ascii first */
|
||||
iconv_e2a(rcvr.loca_adapter_address, mac_addr,
|
||||
sizeof(rcvr.loca_adapter_address));
|
||||
@ -443,9 +446,42 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
||||
}
|
||||
address->is_internal = cur->ifa_flags & IFF_LOOPBACK ? 1 : 0;
|
||||
if (!address->is_internal) {
|
||||
int rc = get_ibmi_physical_address(address->name, &address->phys_addr);
|
||||
if (rc != 0)
|
||||
r = rc;
|
||||
int rc = -1;
|
||||
size_t name_len = strlen(address->name);
|
||||
/* To get the associated MAC address, we must convert the address to a
|
||||
* line description. Normally, the name field contains the line
|
||||
* description name, but for VLANs it has the VLAN appended with a
|
||||
* period. Since object names can also contain periods and numbers, there
|
||||
* is no way to know if a returned name is for a VLAN or not. eg.
|
||||
* *LIND ETH1.1 and *LIND ETH1, VLAN 1 both have the same name: ETH1.1
|
||||
*
|
||||
* Instead, we apply the same heuristic used by some of the XPF ioctls:
|
||||
* - names > 10 *must* contain a VLAN
|
||||
* - assume names <= 10 do not contain a VLAN and try directly
|
||||
* - if >10 or QDCRLIND returned an error, try to strip off a VLAN
|
||||
* and try again
|
||||
* - if we still get an error or couldn't find a period, leave the MAC as
|
||||
* 00:00:00:00:00:00
|
||||
*/
|
||||
if (name_len <= 10) {
|
||||
/* Assume name does not contain a VLAN ID */
|
||||
rc = get_ibmi_physical_address(address->name, &address->phys_addr);
|
||||
}
|
||||
|
||||
if (name_len > 10 || rc != 0) {
|
||||
/* The interface name must contain a VLAN ID suffix. Attempt to strip
|
||||
* it off so we can get the line description to pass to QDCRLIND.
|
||||
*/
|
||||
char* temp_name = uv__strdup(address->name);
|
||||
char* dot = strrchr(temp_name, '.');
|
||||
if (dot != NULL) {
|
||||
*dot = '\0';
|
||||
if (strlen(temp_name) <= 10) {
|
||||
rc = get_ibmi_physical_address(temp_name, &address->phys_addr);
|
||||
}
|
||||
}
|
||||
uv__free(temp_name);
|
||||
}
|
||||
}
|
||||
|
||||
address++;
|
||||
@ -498,4 +534,4 @@ int uv_get_process_title(char* buffer, size_t size) {
|
||||
}
|
||||
|
||||
void uv__process_title_cleanup(void) {
|
||||
}
|
||||
}
|
||||
|
24
deps/uv/src/unix/internal.h
vendored
24
deps/uv/src/unix/internal.h
vendored
@ -62,6 +62,17 @@
|
||||
# include <AvailabilityMacros.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define common detection for active Thread Sanitizer
|
||||
* - clang uses __has_feature(thread_sanitizer)
|
||||
* - gcc-7+ uses __SANITIZE_THREAD__
|
||||
*/
|
||||
#if defined(__has_feature)
|
||||
# if __has_feature(thread_sanitizer)
|
||||
# define __SANITIZE_THREAD__ 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(PATH_MAX)
|
||||
# define UV__PATH_MAX PATH_MAX
|
||||
#else
|
||||
@ -165,9 +176,11 @@ struct uv__stream_queued_fds_s {
|
||||
defined(__NetBSD__)
|
||||
#define uv__cloexec uv__cloexec_ioctl
|
||||
#define uv__nonblock uv__nonblock_ioctl
|
||||
#define UV__NONBLOCK_IS_IOCTL 1
|
||||
#else
|
||||
#define uv__cloexec uv__cloexec_fcntl
|
||||
#define uv__nonblock uv__nonblock_fcntl
|
||||
#define UV__NONBLOCK_IS_IOCTL 0
|
||||
#endif
|
||||
|
||||
/* On Linux, uv__nonblock_fcntl() and uv__nonblock_ioctl() do not commute
|
||||
@ -246,6 +259,7 @@ int uv__signal_loop_fork(uv_loop_t* loop);
|
||||
/* platform specific */
|
||||
uint64_t uv__hrtime(uv_clocktype_t type);
|
||||
int uv__kqueue_init(uv_loop_t* loop);
|
||||
int uv__epoll_init(uv_loop_t* loop);
|
||||
int uv__platform_loop_init(uv_loop_t* loop);
|
||||
void uv__platform_loop_delete(uv_loop_t* loop);
|
||||
void uv__platform_invalidate_fd(uv_loop_t* loop, int fd);
|
||||
@ -261,6 +275,7 @@ void uv__prepare_close(uv_prepare_t* handle);
|
||||
void uv__process_close(uv_process_t* handle);
|
||||
void uv__stream_close(uv_stream_t* handle);
|
||||
void uv__tcp_close(uv_tcp_t* handle);
|
||||
size_t uv__thread_stack_size(void);
|
||||
void uv__udp_close(uv_udp_t* handle);
|
||||
void uv__udp_finish_close(uv_udp_t* handle);
|
||||
uv_handle_type uv__handle_type(int fd);
|
||||
@ -321,7 +336,8 @@ int uv__getsockpeername(const uv_handle_t* handle,
|
||||
|
||||
#if defined(__linux__) || \
|
||||
defined(__FreeBSD__) || \
|
||||
defined(__FreeBSD_kernel__)
|
||||
defined(__FreeBSD_kernel__) || \
|
||||
defined(__DragonFly__)
|
||||
#define HAVE_MMSG 1
|
||||
struct uv__mmsghdr {
|
||||
struct msghdr msg_hdr;
|
||||
@ -334,5 +350,11 @@ int uv__sendmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen);
|
||||
#define HAVE_MMSG 0
|
||||
#endif
|
||||
|
||||
#if defined(__sun)
|
||||
#if !defined(_POSIX_VERSION) || _POSIX_VERSION < 200809L
|
||||
size_t strnlen(const char* s, size_t maxlen);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* UV_UNIX_INTERNAL_H_ */
|
||||
|
409
deps/uv/src/unix/linux-core.c
vendored
409
deps/uv/src/unix/linux-core.c
vendored
@ -82,29 +82,12 @@ static int read_times(FILE* statfile_fp,
|
||||
static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci);
|
||||
static uint64_t read_cpufreq(unsigned int cpunum);
|
||||
|
||||
|
||||
int uv__platform_loop_init(uv_loop_t* loop) {
|
||||
int fd;
|
||||
fd = epoll_create1(O_CLOEXEC);
|
||||
|
||||
/* epoll_create1() can fail either because it's not implemented (old kernel)
|
||||
* or because it doesn't understand the O_CLOEXEC flag.
|
||||
*/
|
||||
if (fd == -1 && (errno == ENOSYS || errno == EINVAL)) {
|
||||
fd = epoll_create(256);
|
||||
|
||||
if (fd != -1)
|
||||
uv__cloexec(fd, 1);
|
||||
}
|
||||
|
||||
loop->backend_fd = fd;
|
||||
|
||||
loop->inotify_fd = -1;
|
||||
loop->inotify_watchers = NULL;
|
||||
|
||||
if (fd == -1)
|
||||
return UV__ERR(errno);
|
||||
|
||||
return 0;
|
||||
return uv__epoll_init(loop);
|
||||
}
|
||||
|
||||
|
||||
@ -134,380 +117,6 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
|
||||
struct epoll_event* events;
|
||||
struct epoll_event dummy;
|
||||
uintptr_t i;
|
||||
uintptr_t nfds;
|
||||
|
||||
assert(loop->watchers != NULL);
|
||||
assert(fd >= 0);
|
||||
|
||||
events = (struct epoll_event*) loop->watchers[loop->nwatchers];
|
||||
nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
|
||||
if (events != NULL)
|
||||
/* Invalidate events with same file descriptor */
|
||||
for (i = 0; i < nfds; i++)
|
||||
if (events[i].data.fd == fd)
|
||||
events[i].data.fd = -1;
|
||||
|
||||
/* Remove the file descriptor from the epoll.
|
||||
* This avoids a problem where the same file description remains open
|
||||
* in another process, causing repeated junk epoll events.
|
||||
*
|
||||
* We pass in a dummy epoll_event, to work around a bug in old kernels.
|
||||
*/
|
||||
if (loop->backend_fd >= 0) {
|
||||
/* Work around a bug in kernels 3.10 to 3.19 where passing a struct that
|
||||
* has the EPOLLWAKEUP flag set generates spurious audit syslog warnings.
|
||||
*/
|
||||
memset(&dummy, 0, sizeof(dummy));
|
||||
epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, &dummy);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int uv__io_check_fd(uv_loop_t* loop, int fd) {
|
||||
struct epoll_event e;
|
||||
int rc;
|
||||
|
||||
memset(&e, 0, sizeof(e));
|
||||
e.events = POLLIN;
|
||||
e.data.fd = -1;
|
||||
|
||||
rc = 0;
|
||||
if (epoll_ctl(loop->backend_fd, EPOLL_CTL_ADD, fd, &e))
|
||||
if (errno != EEXIST)
|
||||
rc = UV__ERR(errno);
|
||||
|
||||
if (rc == 0)
|
||||
if (epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, &e))
|
||||
abort();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
/* A bug in kernels < 2.6.37 makes timeouts larger than ~30 minutes
|
||||
* effectively infinite on 32 bits architectures. To avoid blocking
|
||||
* indefinitely, we cap the timeout and poll again if necessary.
|
||||
*
|
||||
* Note that "30 minutes" is a simplification because it depends on
|
||||
* the value of CONFIG_HZ. The magic constant assumes CONFIG_HZ=1200,
|
||||
* that being the largest value I have seen in the wild (and only once.)
|
||||
*/
|
||||
static const int max_safe_timeout = 1789569;
|
||||
static int no_epoll_pwait_cached;
|
||||
static int no_epoll_wait_cached;
|
||||
int no_epoll_pwait;
|
||||
int no_epoll_wait;
|
||||
struct epoll_event events[1024];
|
||||
struct epoll_event* pe;
|
||||
struct epoll_event e;
|
||||
int real_timeout;
|
||||
QUEUE* q;
|
||||
uv__io_t* w;
|
||||
sigset_t sigset;
|
||||
uint64_t sigmask;
|
||||
uint64_t base;
|
||||
int have_signals;
|
||||
int nevents;
|
||||
int count;
|
||||
int nfds;
|
||||
int fd;
|
||||
int op;
|
||||
int i;
|
||||
int user_timeout;
|
||||
int reset_timeout;
|
||||
|
||||
if (loop->nfds == 0) {
|
||||
assert(QUEUE_EMPTY(&loop->watcher_queue));
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&e, 0, sizeof(e));
|
||||
|
||||
while (!QUEUE_EMPTY(&loop->watcher_queue)) {
|
||||
q = QUEUE_HEAD(&loop->watcher_queue);
|
||||
QUEUE_REMOVE(q);
|
||||
QUEUE_INIT(q);
|
||||
|
||||
w = QUEUE_DATA(q, uv__io_t, watcher_queue);
|
||||
assert(w->pevents != 0);
|
||||
assert(w->fd >= 0);
|
||||
assert(w->fd < (int) loop->nwatchers);
|
||||
|
||||
e.events = w->pevents;
|
||||
e.data.fd = w->fd;
|
||||
|
||||
if (w->events == 0)
|
||||
op = EPOLL_CTL_ADD;
|
||||
else
|
||||
op = EPOLL_CTL_MOD;
|
||||
|
||||
/* XXX Future optimization: do EPOLL_CTL_MOD lazily if we stop watching
|
||||
* events, skip the syscall and squelch the events after epoll_wait().
|
||||
*/
|
||||
if (epoll_ctl(loop->backend_fd, op, w->fd, &e)) {
|
||||
if (errno != EEXIST)
|
||||
abort();
|
||||
|
||||
assert(op == EPOLL_CTL_ADD);
|
||||
|
||||
/* We've reactivated a file descriptor that's been watched before. */
|
||||
if (epoll_ctl(loop->backend_fd, EPOLL_CTL_MOD, w->fd, &e))
|
||||
abort();
|
||||
}
|
||||
|
||||
w->events = w->pevents;
|
||||
}
|
||||
|
||||
sigmask = 0;
|
||||
if (loop->flags & UV_LOOP_BLOCK_SIGPROF) {
|
||||
sigemptyset(&sigset);
|
||||
sigaddset(&sigset, SIGPROF);
|
||||
sigmask |= 1 << (SIGPROF - 1);
|
||||
}
|
||||
|
||||
assert(timeout >= -1);
|
||||
base = loop->time;
|
||||
count = 48; /* Benchmarks suggest this gives the best throughput. */
|
||||
real_timeout = timeout;
|
||||
|
||||
if (uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME) {
|
||||
reset_timeout = 1;
|
||||
user_timeout = timeout;
|
||||
timeout = 0;
|
||||
} else {
|
||||
reset_timeout = 0;
|
||||
user_timeout = 0;
|
||||
}
|
||||
|
||||
/* You could argue there is a dependency between these two but
|
||||
* ultimately we don't care about their ordering with respect
|
||||
* to one another. Worst case, we make a few system calls that
|
||||
* could have been avoided because another thread already knows
|
||||
* they fail with ENOSYS. Hardly the end of the world.
|
||||
*/
|
||||
no_epoll_pwait = uv__load_relaxed(&no_epoll_pwait_cached);
|
||||
no_epoll_wait = uv__load_relaxed(&no_epoll_wait_cached);
|
||||
|
||||
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);
|
||||
|
||||
/* See the comment for max_safe_timeout for an explanation of why
|
||||
* this is necessary. Executive summary: kernel bug workaround.
|
||||
*/
|
||||
if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout)
|
||||
timeout = max_safe_timeout;
|
||||
|
||||
if (sigmask != 0 && no_epoll_pwait != 0)
|
||||
if (pthread_sigmask(SIG_BLOCK, &sigset, NULL))
|
||||
abort();
|
||||
|
||||
if (no_epoll_wait != 0 || (sigmask != 0 && no_epoll_pwait == 0)) {
|
||||
nfds = epoll_pwait(loop->backend_fd,
|
||||
events,
|
||||
ARRAY_SIZE(events),
|
||||
timeout,
|
||||
&sigset);
|
||||
if (nfds == -1 && errno == ENOSYS) {
|
||||
uv__store_relaxed(&no_epoll_pwait_cached, 1);
|
||||
no_epoll_pwait = 1;
|
||||
}
|
||||
} else {
|
||||
nfds = epoll_wait(loop->backend_fd,
|
||||
events,
|
||||
ARRAY_SIZE(events),
|
||||
timeout);
|
||||
if (nfds == -1 && errno == ENOSYS) {
|
||||
uv__store_relaxed(&no_epoll_wait_cached, 1);
|
||||
no_epoll_wait = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (sigmask != 0 && no_epoll_pwait != 0)
|
||||
if (pthread_sigmask(SIG_UNBLOCK, &sigset, 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));
|
||||
|
||||
if (nfds == 0) {
|
||||
assert(timeout != -1);
|
||||
|
||||
if (reset_timeout != 0) {
|
||||
timeout = user_timeout;
|
||||
reset_timeout = 0;
|
||||
}
|
||||
|
||||
if (timeout == -1)
|
||||
continue;
|
||||
|
||||
if (timeout == 0)
|
||||
return;
|
||||
|
||||
/* We may have been inside the system call for longer than |timeout|
|
||||
* milliseconds so we need to update the timestamp to avoid drift.
|
||||
*/
|
||||
goto update_timeout;
|
||||
}
|
||||
|
||||
if (nfds == -1) {
|
||||
if (errno == ENOSYS) {
|
||||
/* epoll_wait() or epoll_pwait() failed, try the other system call. */
|
||||
assert(no_epoll_wait == 0 || no_epoll_pwait == 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (errno != EINTR)
|
||||
abort();
|
||||
|
||||
if (reset_timeout != 0) {
|
||||
timeout = user_timeout;
|
||||
reset_timeout = 0;
|
||||
}
|
||||
|
||||
if (timeout == -1)
|
||||
continue;
|
||||
|
||||
if (timeout == 0)
|
||||
return;
|
||||
|
||||
/* Interrupted by a signal. Update timeout and poll again. */
|
||||
goto update_timeout;
|
||||
}
|
||||
|
||||
have_signals = 0;
|
||||
nevents = 0;
|
||||
|
||||
{
|
||||
/* Squelch a -Waddress-of-packed-member warning with gcc >= 9. */
|
||||
union {
|
||||
struct epoll_event* events;
|
||||
uv__io_t* watchers;
|
||||
} x;
|
||||
|
||||
x.events = events;
|
||||
assert(loop->watchers != NULL);
|
||||
loop->watchers[loop->nwatchers] = x.watchers;
|
||||
loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
|
||||
}
|
||||
|
||||
for (i = 0; i < nfds; i++) {
|
||||
pe = events + i;
|
||||
fd = pe->data.fd;
|
||||
|
||||
/* Skip invalidated events, see uv__platform_invalidate_fd */
|
||||
if (fd == -1)
|
||||
continue;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert((unsigned) fd < loop->nwatchers);
|
||||
|
||||
w = loop->watchers[fd];
|
||||
|
||||
if (w == NULL) {
|
||||
/* File descriptor that we've stopped watching, disarm it.
|
||||
*
|
||||
* Ignore all errors because we may be racing with another thread
|
||||
* when the file descriptor is closed.
|
||||
*/
|
||||
epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, pe);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Give users only events they're interested in. Prevents spurious
|
||||
* callbacks when previous callback invocation in this loop has stopped
|
||||
* the current watcher. Also, filters out events that users has not
|
||||
* requested us to watch.
|
||||
*/
|
||||
pe->events &= w->pevents | POLLERR | POLLHUP;
|
||||
|
||||
/* Work around an epoll quirk where it sometimes reports just the
|
||||
* EPOLLERR or EPOLLHUP event. In order to force the event loop to
|
||||
* move forward, we merge in the read/write events that the watcher
|
||||
* is interested in; uv__read() and uv__write() will then deal with
|
||||
* the error or hangup in the usual fashion.
|
||||
*
|
||||
* Note to self: happens when epoll reports EPOLLIN|EPOLLHUP, the user
|
||||
* reads the available data, calls uv_read_stop(), then sometime later
|
||||
* calls uv_read_start() again. By then, libuv has forgotten about the
|
||||
* hangup and the kernel won't report EPOLLIN again because there's
|
||||
* nothing left to read. If anything, libuv is to blame here. The
|
||||
* current hack is just a quick bandaid; to properly fix it, libuv
|
||||
* needs to remember the error/hangup event. We should get that for
|
||||
* free when we switch over to edge-triggered I/O.
|
||||
*/
|
||||
if (pe->events == POLLERR || pe->events == POLLHUP)
|
||||
pe->events |=
|
||||
w->pevents & (POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI);
|
||||
|
||||
if (pe->events != 0) {
|
||||
/* Run signal watchers last. This also affects child process watchers
|
||||
* because those are implemented in terms of signal watchers.
|
||||
*/
|
||||
if (w == &loop->signal_io_watcher) {
|
||||
have_signals = 1;
|
||||
} else {
|
||||
uv__metrics_update_idle_time(loop);
|
||||
w->cb(loop, w, pe->events);
|
||||
}
|
||||
|
||||
nevents++;
|
||||
}
|
||||
}
|
||||
|
||||
if (reset_timeout != 0) {
|
||||
timeout = user_timeout;
|
||||
reset_timeout = 0;
|
||||
}
|
||||
|
||||
if (have_signals != 0) {
|
||||
uv__metrics_update_idle_time(loop);
|
||||
loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
|
||||
}
|
||||
|
||||
loop->watchers[loop->nwatchers] = NULL;
|
||||
loop->watchers[loop->nwatchers + 1] = NULL;
|
||||
|
||||
if (have_signals != 0)
|
||||
return; /* Event loop should cycle now so don't poll again. */
|
||||
|
||||
if (nevents != 0) {
|
||||
if (nfds == ARRAY_SIZE(events) && --count != 0) {
|
||||
/* Poll for more events but don't block this time. */
|
||||
timeout = 0;
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (timeout == 0)
|
||||
return;
|
||||
|
||||
if (timeout == -1)
|
||||
continue;
|
||||
|
||||
update_timeout:
|
||||
assert(timeout > 0);
|
||||
|
||||
real_timeout -= (loop->time - base);
|
||||
if (real_timeout <= 0)
|
||||
return;
|
||||
|
||||
timeout = real_timeout;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv__hrtime(uv_clocktype_t type) {
|
||||
static clock_t fast_clock_id = -1;
|
||||
@ -740,14 +349,19 @@ static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci) {
|
||||
}
|
||||
|
||||
|
||||
/* Also reads the CPU frequency on x86. The other architectures only have
|
||||
* a BogoMIPS field, which may not be very accurate.
|
||||
/* Also reads the CPU frequency on ppc and x86. The other architectures only
|
||||
* have a BogoMIPS field, which may not be very accurate.
|
||||
*
|
||||
* Note: Simply returns on error, uv_cpu_info() takes care of the cleanup.
|
||||
*/
|
||||
static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
|
||||
#if defined(__PPC__)
|
||||
static const char model_marker[] = "cpu\t\t: ";
|
||||
static const char speed_marker[] = "clock\t\t: ";
|
||||
#else
|
||||
static const char model_marker[] = "model name\t: ";
|
||||
static const char speed_marker[] = "cpu MHz\t\t: ";
|
||||
#endif
|
||||
const char* inferred_model;
|
||||
unsigned int model_idx;
|
||||
unsigned int speed_idx;
|
||||
@ -769,6 +383,7 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
|
||||
#if defined(__arm__) || \
|
||||
defined(__i386__) || \
|
||||
defined(__mips__) || \
|
||||
defined(__PPC__) || \
|
||||
defined(__x86_64__)
|
||||
fp = uv__open_file("/proc/cpuinfo");
|
||||
if (fp == NULL)
|
||||
@ -817,7 +432,7 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
#endif /* __arm__ || __i386__ || __mips__ || __x86_64__ */
|
||||
#endif /* __arm__ || __i386__ || __mips__ || __PPC__ || __x86_64__ */
|
||||
|
||||
/* Now we want to make sure that all the models contain *something* because
|
||||
* it's not safe to leave them as null. Copy the last entry unless there
|
||||
@ -855,9 +470,9 @@ static int read_times(FILE* statfile_fp,
|
||||
char buf[1024];
|
||||
|
||||
ticks = (unsigned int)sysconf(_SC_CLK_TCK);
|
||||
multiplier = ((uint64_t)1000L / ticks);
|
||||
assert(ticks != (unsigned int) -1);
|
||||
assert(ticks != 0);
|
||||
multiplier = ((uint64_t)1000L / ticks);
|
||||
|
||||
rewind(statfile_fp);
|
||||
|
||||
|
2
deps/uv/src/unix/linux-inotify.c
vendored
2
deps/uv/src/unix/linux-inotify.c
vendored
@ -178,7 +178,7 @@ static void uv__inotify_read(uv_loop_t* loop,
|
||||
/* needs to be large enough for sizeof(inotify_event) + strlen(path) */
|
||||
char buf[4096];
|
||||
|
||||
while (1) {
|
||||
for (;;) {
|
||||
do
|
||||
size = read(loop->inotify_fd, buf, sizeof(buf));
|
||||
while (size == -1 && errno == EINTR);
|
||||
|
3
deps/uv/src/unix/linux-syscalls.h
vendored
3
deps/uv/src/unix/linux-syscalls.h
vendored
@ -22,9 +22,6 @@
|
||||
#ifndef UV_LINUX_SYSCALL_H_
|
||||
#define UV_LINUX_SYSCALL_H_
|
||||
|
||||
#undef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdint.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
|
136
deps/uv/src/unix/os390-proctitle.c
vendored
Normal file
136
deps/uv/src/unix/os390-proctitle.c
vendored
Normal file
@ -0,0 +1,136 @@
|
||||
/* Copyright libuv project contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static uv_mutex_t process_title_mutex;
|
||||
static uv_once_t process_title_mutex_once = UV_ONCE_INIT;
|
||||
static char* process_title = NULL;
|
||||
static void* args_mem = NULL;
|
||||
|
||||
|
||||
static void init_process_title_mutex_once(void) {
|
||||
uv_mutex_init(&process_title_mutex);
|
||||
}
|
||||
|
||||
|
||||
char** uv_setup_args(int argc, char** argv) {
|
||||
char** new_argv;
|
||||
size_t size;
|
||||
char* s;
|
||||
int i;
|
||||
|
||||
if (argc <= 0)
|
||||
return argv;
|
||||
|
||||
/* Calculate how much memory we need for the argv strings. */
|
||||
size = 0;
|
||||
for (i = 0; i < argc; i++)
|
||||
size += strlen(argv[i]) + 1;
|
||||
|
||||
/* Add space for the argv pointers. */
|
||||
size += (argc + 1) * sizeof(char*);
|
||||
|
||||
new_argv = uv__malloc(size);
|
||||
if (new_argv == NULL)
|
||||
return argv;
|
||||
|
||||
/* Copy over the strings and set up the pointer table. */
|
||||
s = (char*) &new_argv[argc + 1];
|
||||
for (i = 0; i < argc; i++) {
|
||||
size = strlen(argv[i]) + 1;
|
||||
memcpy(s, argv[i], size);
|
||||
new_argv[i] = s;
|
||||
s += size;
|
||||
}
|
||||
new_argv[i] = NULL;
|
||||
|
||||
args_mem = new_argv;
|
||||
process_title = uv__strdup(argv[0]);
|
||||
|
||||
return new_argv;
|
||||
}
|
||||
|
||||
|
||||
int uv_set_process_title(const char* title) {
|
||||
char* new_title;
|
||||
|
||||
/* If uv_setup_args wasn't called or failed, we can't continue. */
|
||||
if (args_mem == NULL)
|
||||
return UV_ENOBUFS;
|
||||
|
||||
/* We cannot free this pointer when libuv shuts down,
|
||||
* the process may still be using it.
|
||||
*/
|
||||
new_title = uv__strdup(title);
|
||||
if (new_title == NULL)
|
||||
return UV_ENOMEM;
|
||||
|
||||
uv_once(&process_title_mutex_once, init_process_title_mutex_once);
|
||||
uv_mutex_lock(&process_title_mutex);
|
||||
|
||||
if (process_title != NULL)
|
||||
uv__free(process_title);
|
||||
|
||||
process_title = new_title;
|
||||
|
||||
uv_mutex_unlock(&process_title_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_get_process_title(char* buffer, size_t size) {
|
||||
size_t len;
|
||||
|
||||
if (buffer == NULL || size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
/* If uv_setup_args wasn't called or failed, we can't continue. */
|
||||
if (args_mem == NULL || process_title == NULL)
|
||||
return UV_ENOBUFS;
|
||||
|
||||
uv_once(&process_title_mutex_once, init_process_title_mutex_once);
|
||||
uv_mutex_lock(&process_title_mutex);
|
||||
|
||||
len = strlen(process_title);
|
||||
|
||||
if (size <= len) {
|
||||
uv_mutex_unlock(&process_title_mutex);
|
||||
return UV_ENOBUFS;
|
||||
}
|
||||
|
||||
strcpy(buffer, process_title);
|
||||
|
||||
uv_mutex_unlock(&process_title_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv__process_title_cleanup(void) {
|
||||
uv__free(args_mem); /* Keep valgrind happy. */
|
||||
args_mem = NULL;
|
||||
}
|
57
deps/uv/src/unix/os390-syscalls.c
vendored
57
deps/uv/src/unix/os390-syscalls.c
vendored
@ -27,12 +27,6 @@
|
||||
#include <termios.h>
|
||||
#include <sys/msg.h>
|
||||
|
||||
#define CW_INTRPT 1
|
||||
#define CW_CONDVAR 32
|
||||
|
||||
#pragma linkage(BPX4CTW, OS)
|
||||
#pragma linkage(BPX1CTW, OS)
|
||||
|
||||
static QUEUE global_epoll_queue;
|
||||
static uv_mutex_t global_epoll_lock;
|
||||
static uv_once_t once = UV_ONCE_INIT;
|
||||
@ -55,7 +49,7 @@ int scandir(const char* maindir, struct dirent*** namelist,
|
||||
if (!mdir)
|
||||
return -1;
|
||||
|
||||
while (1) {
|
||||
for (;;) {
|
||||
dirent = readdir(mdir);
|
||||
if (!dirent)
|
||||
break;
|
||||
@ -381,46 +375,6 @@ void epoll_queue_close(uv__os390_epoll* lst) {
|
||||
}
|
||||
|
||||
|
||||
int nanosleep(const struct timespec* req, struct timespec* rem) {
|
||||
unsigned nano;
|
||||
unsigned seconds;
|
||||
unsigned events;
|
||||
unsigned secrem;
|
||||
unsigned nanorem;
|
||||
int rv;
|
||||
int err;
|
||||
int rsn;
|
||||
|
||||
nano = (int)req->tv_nsec;
|
||||
seconds = req->tv_sec;
|
||||
events = CW_CONDVAR | CW_INTRPT;
|
||||
secrem = 0;
|
||||
nanorem = 0;
|
||||
|
||||
#if defined(_LP64)
|
||||
BPX4CTW(&seconds, &nano, &events, &secrem, &nanorem, &rv, &err, &rsn);
|
||||
#else
|
||||
BPX1CTW(&seconds, &nano, &events, &secrem, &nanorem, &rv, &err, &rsn);
|
||||
#endif
|
||||
|
||||
/* Don't clobber errno unless BPX1CTW/BPX4CTW errored.
|
||||
* Don't leak EAGAIN, that just means the timeout expired.
|
||||
*/
|
||||
if (rv == -1)
|
||||
if (err == EAGAIN)
|
||||
rv = 0;
|
||||
else
|
||||
errno = err;
|
||||
|
||||
if (rem != NULL && (rv == 0 || err == EINTR)) {
|
||||
rem->tv_nsec = nanorem;
|
||||
rem->tv_sec = secrem;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
char* mkdtemp(char* path) {
|
||||
static const char* tempchars =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
@ -550,15 +504,6 @@ ssize_t os390_readlink(const char* path, char* buf, size_t len) {
|
||||
}
|
||||
|
||||
|
||||
size_t strnlen(const char* str, size_t maxlen) {
|
||||
char* p = memchr(str, 0, maxlen);
|
||||
if (p == NULL)
|
||||
return maxlen;
|
||||
else
|
||||
return p - str;
|
||||
}
|
||||
|
||||
|
||||
int sem_init(UV_PLATFORM_SEM_T* semid, int pshared, unsigned int value) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
2
deps/uv/src/unix/os390-syscalls.h
vendored
2
deps/uv/src/unix/os390-syscalls.h
vendored
@ -28,6 +28,7 @@
|
||||
#include <dirent.h>
|
||||
#include <poll.h>
|
||||
#include <pthread.h>
|
||||
#include "zos-base.h"
|
||||
|
||||
#define EPOLL_CTL_ADD 1
|
||||
#define EPOLL_CTL_DEL 2
|
||||
@ -57,7 +58,6 @@ int epoll_wait(uv__os390_epoll* ep, struct epoll_event *events, int maxevents, i
|
||||
int epoll_file_close(int fd);
|
||||
|
||||
/* utility functions */
|
||||
int nanosleep(const struct timespec* req, struct timespec* rem);
|
||||
int scandir(const char* maindir, struct dirent*** namelist,
|
||||
int (*filter)(const struct dirent *),
|
||||
int (*compar)(const struct dirent **,
|
||||
|
136
deps/uv/src/unix/os390.c
vendored
136
deps/uv/src/unix/os390.c
vendored
@ -28,6 +28,8 @@
|
||||
#include <builtins.h>
|
||||
#include <termios.h>
|
||||
#include <sys/msg.h>
|
||||
#include <sys/resource.h>
|
||||
#include "zos-base.h"
|
||||
#if defined(__clang__)
|
||||
#include "csrsic.h"
|
||||
#else
|
||||
@ -61,12 +63,6 @@
|
||||
/* Address of the rsm control and enumeration area. */
|
||||
#define CVTRCEP_OFFSET 0x490
|
||||
|
||||
/*
|
||||
Number of frames currently available to system.
|
||||
Excluded are frames backing perm storage, frames offline, and bad frames.
|
||||
*/
|
||||
#define RCEPOOL_OFFSET 0x004
|
||||
|
||||
/* Total number of frames currently on all available frame queues. */
|
||||
#define RCEAFC_OFFSET 0x088
|
||||
|
||||
@ -144,102 +140,8 @@ uint64_t uv__hrtime(uv_clocktype_t type) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Get the exe path using the thread entry information
|
||||
in the address space.
|
||||
*/
|
||||
static int getexe(const int pid, char* buf, size_t len) {
|
||||
struct {
|
||||
int pid;
|
||||
int thid[2];
|
||||
char accesspid;
|
||||
char accessthid;
|
||||
char asid[2];
|
||||
char loginname[8];
|
||||
char flag;
|
||||
char len;
|
||||
} Input_data;
|
||||
|
||||
union {
|
||||
struct {
|
||||
char gthb[4];
|
||||
int pid;
|
||||
int thid[2];
|
||||
char accesspid;
|
||||
char accessthid[3];
|
||||
int lenused;
|
||||
int offsetProcess;
|
||||
int offsetConTTY;
|
||||
int offsetPath;
|
||||
int offsetCommand;
|
||||
int offsetFileData;
|
||||
int offsetThread;
|
||||
} Output_data;
|
||||
char buf[2048];
|
||||
} Output_buf;
|
||||
|
||||
struct Output_path_type {
|
||||
char gthe[4];
|
||||
short int len;
|
||||
char path[1024];
|
||||
};
|
||||
|
||||
int Input_length;
|
||||
int Output_length;
|
||||
void* Input_address;
|
||||
void* Output_address;
|
||||
struct Output_path_type* Output_path;
|
||||
int rv;
|
||||
int rc;
|
||||
int rsn;
|
||||
|
||||
Input_length = PGTH_LEN;
|
||||
Output_length = sizeof(Output_buf);
|
||||
Output_address = &Output_buf;
|
||||
Input_address = &Input_data;
|
||||
memset(&Input_data, 0, sizeof Input_data);
|
||||
Input_data.flag |= PGTHAPATH;
|
||||
Input_data.pid = pid;
|
||||
Input_data.accesspid = PGTH_CURRENT;
|
||||
|
||||
#ifdef _LP64
|
||||
BPX4GTH(&Input_length,
|
||||
&Input_address,
|
||||
&Output_length,
|
||||
&Output_address,
|
||||
&rv,
|
||||
&rc,
|
||||
&rsn);
|
||||
#else
|
||||
BPX1GTH(&Input_length,
|
||||
&Input_address,
|
||||
&Output_length,
|
||||
&Output_address,
|
||||
&rv,
|
||||
&rc,
|
||||
&rsn);
|
||||
#endif
|
||||
|
||||
if (rv == -1) {
|
||||
errno = rc;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check highest byte to ensure data availability */
|
||||
assert(((Output_buf.Output_data.offsetPath >>24) & 0xFF) == 'A');
|
||||
|
||||
/* Get the offset from the lowest 3 bytes */
|
||||
Output_path = (struct Output_path_type*) ((char*) (&Output_buf) +
|
||||
(Output_buf.Output_data.offsetPath & 0x00FFFFFF));
|
||||
|
||||
if (Output_path->len >= len) {
|
||||
errno = ENOBUFS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uv__strscpy(buf, Output_path->path, len);
|
||||
|
||||
return 0;
|
||||
static int getexe(char* buf, size_t len) {
|
||||
return uv__strscpy(buf, __getargv()[0], len);
|
||||
}
|
||||
|
||||
|
||||
@ -259,8 +161,7 @@ int uv_exepath(char* buffer, size_t* size) {
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
pid = getpid();
|
||||
res = getexe(pid, args, sizeof(args));
|
||||
res = getexe(args, sizeof(args));
|
||||
if (res < 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
@ -275,25 +176,25 @@ uint64_t uv_get_free_memory(void) {
|
||||
data_area_ptr rcep = {0};
|
||||
cvt.assign = *(data_area_ptr_assign_type*)(CVT_PTR);
|
||||
rcep.assign = *(data_area_ptr_assign_type*)(cvt.deref + CVTRCEP_OFFSET);
|
||||
freeram = *((uint64_t*)(rcep.deref + RCEAFC_OFFSET)) * 4;
|
||||
freeram = (uint64_t)*((uint32_t*)(rcep.deref + RCEAFC_OFFSET)) * 4096;
|
||||
return freeram;
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv_get_total_memory(void) {
|
||||
uint64_t totalram;
|
||||
|
||||
data_area_ptr cvt = {0};
|
||||
data_area_ptr rcep = {0};
|
||||
cvt.assign = *(data_area_ptr_assign_type*)(CVT_PTR);
|
||||
rcep.assign = *(data_area_ptr_assign_type*)(cvt.deref + CVTRCEP_OFFSET);
|
||||
totalram = *((uint64_t*)(rcep.deref + RCEPOOL_OFFSET)) * 4;
|
||||
return totalram;
|
||||
/* Use CVTRLSTG to get the size of actual real storage online at IPL in K. */
|
||||
return (uint64_t)((int)((char *__ptr32 *__ptr32 *)0)[4][214]) * 1024;
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0; /* Memory constraints are unknown. */
|
||||
struct rlimit rl;
|
||||
|
||||
/* RLIMIT_MEMLIMIT return value is in megabytes rather than bytes. */
|
||||
if (getrlimit(RLIMIT_MEMLIMIT, &rl) == 0)
|
||||
return rl.rlim_cur * 1024 * 1024;
|
||||
|
||||
return 0; /* There is no memory limit set. */
|
||||
}
|
||||
|
||||
|
||||
@ -733,6 +634,10 @@ static int os390_message_queue_handler(uv__os390_epoll* ep) {
|
||||
/* Some event that we are not interested in. */
|
||||
return 0;
|
||||
|
||||
/* `__rfim_utok` is treated as text when it should be treated as binary while
|
||||
* running in ASCII mode, resulting in an unwanted autoconversion.
|
||||
*/
|
||||
__a2e_l(msg.__rfim_utok, sizeof(msg.__rfim_utok));
|
||||
handle = *(uv_fs_event_t**)(msg.__rfim_utok);
|
||||
handle->cb(handle, uv__basename_r(handle->path), events, 0);
|
||||
return 1;
|
||||
@ -959,9 +864,6 @@ update_timeout:
|
||||
}
|
||||
}
|
||||
|
||||
void uv__set_process_title(const char* title) {
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
int uv__io_fork(uv_loop_t* loop) {
|
||||
/*
|
||||
|
5
deps/uv/src/unix/poll.c
vendored
5
deps/uv/src/unix/poll.c
vendored
@ -79,9 +79,10 @@ int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
|
||||
* Workaround for e.g. kqueue fds not supporting ioctls.
|
||||
*/
|
||||
err = uv__nonblock(fd, 1);
|
||||
#if UV__NONBLOCK_IS_IOCTL
|
||||
if (err == UV_ENOTTY)
|
||||
if (uv__nonblock == uv__nonblock_ioctl)
|
||||
err = uv__nonblock_fcntl(fd, 1);
|
||||
err = uv__nonblock_fcntl(fd, 1);
|
||||
#endif
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
63
deps/uv/src/unix/process.c
vendored
63
deps/uv/src/unix/process.c
vendored
@ -44,6 +44,10 @@ extern char **environ;
|
||||
# include <grp.h>
|
||||
#endif
|
||||
|
||||
#if defined(__MVS__)
|
||||
# include "zos-base.h"
|
||||
#endif
|
||||
|
||||
|
||||
static void uv__chld(uv_signal_t* handle, int signum) {
|
||||
uv_process_t* process;
|
||||
@ -197,6 +201,12 @@ static void uv__write_int(int fd, int val) {
|
||||
}
|
||||
|
||||
|
||||
static void uv__write_errno(int error_fd) {
|
||||
uv__write_int(error_fd, UV__ERR(errno));
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
|
||||
#if !(defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH))
|
||||
/* execvp is marked __WATCHOS_PROHIBITED __TVOS_PROHIBITED, so must be
|
||||
* avoided. Since this isn't called on those targets, the function
|
||||
@ -225,10 +235,8 @@ static void uv__process_child_init(const uv_process_options_t* options,
|
||||
if (use_fd < 0 || use_fd >= fd)
|
||||
continue;
|
||||
pipes[fd][1] = fcntl(use_fd, F_DUPFD, stdio_count);
|
||||
if (pipes[fd][1] == -1) {
|
||||
uv__write_int(error_fd, UV__ERR(errno));
|
||||
_exit(127);
|
||||
}
|
||||
if (pipes[fd][1] == -1)
|
||||
uv__write_errno(error_fd);
|
||||
}
|
||||
|
||||
for (fd = 0; fd < stdio_count; fd++) {
|
||||
@ -245,10 +253,8 @@ static void uv__process_child_init(const uv_process_options_t* options,
|
||||
use_fd = open("/dev/null", fd == 0 ? O_RDONLY : O_RDWR);
|
||||
close_fd = use_fd;
|
||||
|
||||
if (use_fd < 0) {
|
||||
uv__write_int(error_fd, UV__ERR(errno));
|
||||
_exit(127);
|
||||
}
|
||||
if (use_fd < 0)
|
||||
uv__write_errno(error_fd);
|
||||
}
|
||||
}
|
||||
|
||||
@ -257,10 +263,8 @@ static void uv__process_child_init(const uv_process_options_t* options,
|
||||
else
|
||||
fd = dup2(use_fd, fd);
|
||||
|
||||
if (fd == -1) {
|
||||
uv__write_int(error_fd, UV__ERR(errno));
|
||||
_exit(127);
|
||||
}
|
||||
if (fd == -1)
|
||||
uv__write_errno(error_fd);
|
||||
|
||||
if (fd <= 2)
|
||||
uv__nonblock_fcntl(fd, 0);
|
||||
@ -276,10 +280,8 @@ static void uv__process_child_init(const uv_process_options_t* options,
|
||||
uv__close(use_fd);
|
||||
}
|
||||
|
||||
if (options->cwd != NULL && chdir(options->cwd)) {
|
||||
uv__write_int(error_fd, UV__ERR(errno));
|
||||
_exit(127);
|
||||
}
|
||||
if (options->cwd != NULL && chdir(options->cwd))
|
||||
uv__write_errno(error_fd);
|
||||
|
||||
if (options->flags & (UV_PROCESS_SETUID | UV_PROCESS_SETGID)) {
|
||||
/* When dropping privileges from root, the `setgroups` call will
|
||||
@ -292,15 +294,11 @@ static void uv__process_child_init(const uv_process_options_t* options,
|
||||
SAVE_ERRNO(setgroups(0, NULL));
|
||||
}
|
||||
|
||||
if ((options->flags & UV_PROCESS_SETGID) && setgid(options->gid)) {
|
||||
uv__write_int(error_fd, UV__ERR(errno));
|
||||
_exit(127);
|
||||
}
|
||||
if ((options->flags & UV_PROCESS_SETGID) && setgid(options->gid))
|
||||
uv__write_errno(error_fd);
|
||||
|
||||
if ((options->flags & UV_PROCESS_SETUID) && setuid(options->uid)) {
|
||||
uv__write_int(error_fd, UV__ERR(errno));
|
||||
_exit(127);
|
||||
}
|
||||
if ((options->flags & UV_PROCESS_SETUID) && setuid(options->uid))
|
||||
uv__write_errno(error_fd);
|
||||
|
||||
if (options->env != NULL) {
|
||||
environ = options->env;
|
||||
@ -323,22 +321,23 @@ static void uv__process_child_init(const uv_process_options_t* options,
|
||||
if (SIG_ERR != signal(n, SIG_DFL))
|
||||
continue;
|
||||
|
||||
uv__write_int(error_fd, UV__ERR(errno));
|
||||
_exit(127);
|
||||
uv__write_errno(error_fd);
|
||||
}
|
||||
|
||||
/* Reset signal mask. */
|
||||
sigemptyset(&set);
|
||||
err = pthread_sigmask(SIG_SETMASK, &set, NULL);
|
||||
|
||||
if (err != 0) {
|
||||
uv__write_int(error_fd, UV__ERR(err));
|
||||
_exit(127);
|
||||
}
|
||||
if (err != 0)
|
||||
uv__write_errno(error_fd);
|
||||
|
||||
#ifdef __MVS__
|
||||
execvpe(options->file, options->args, environ);
|
||||
#else
|
||||
execvp(options->file, options->args);
|
||||
uv__write_int(error_fd, UV__ERR(errno));
|
||||
_exit(127);
|
||||
#endif
|
||||
|
||||
uv__write_errno(error_fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
3
deps/uv/src/unix/proctitle.c
vendored
3
deps/uv/src/unix/proctitle.c
vendored
@ -84,10 +84,7 @@ char** uv_setup_args(int argc, char** argv) {
|
||||
}
|
||||
new_argv[i] = NULL;
|
||||
|
||||
/* argv is not adjacent on z/os, we use just argv[0] on that platform. */
|
||||
#ifndef __MVS__
|
||||
pt.cap = argv[i - 1] + size - argv[0];
|
||||
#endif
|
||||
|
||||
args_mem = new_argv;
|
||||
process_title = pt;
|
||||
|
215
deps/uv/src/unix/stream.c
vendored
215
deps/uv/src/unix/stream.c
vendored
@ -164,7 +164,7 @@ static void uv__stream_osx_select(void* arg) {
|
||||
else
|
||||
max_fd = s->int_fd;
|
||||
|
||||
while (1) {
|
||||
for (;;) {
|
||||
/* Terminate on semaphore */
|
||||
if (uv_sem_trywait(&s->close_sem) == 0)
|
||||
break;
|
||||
@ -195,7 +195,7 @@ static void uv__stream_osx_select(void* arg) {
|
||||
|
||||
/* Empty socketpair's buffer in case of interruption */
|
||||
if (FD_ISSET(s->int_fd, s->sread))
|
||||
while (1) {
|
||||
for (;;) {
|
||||
r = read(s->int_fd, buf, sizeof(buf));
|
||||
|
||||
if (r == sizeof(buf))
|
||||
@ -799,33 +799,21 @@ static int uv__handle_fd(uv_handle_t* handle) {
|
||||
}
|
||||
}
|
||||
|
||||
static void uv__write(uv_stream_t* stream) {
|
||||
static int uv__try_write(uv_stream_t* stream,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs,
|
||||
uv_stream_t* send_handle) {
|
||||
struct iovec* iov;
|
||||
QUEUE* q;
|
||||
uv_write_t* req;
|
||||
int iovmax;
|
||||
int iovcnt;
|
||||
ssize_t n;
|
||||
int err;
|
||||
|
||||
start:
|
||||
|
||||
assert(uv__stream_fd(stream) >= 0);
|
||||
|
||||
if (QUEUE_EMPTY(&stream->write_queue))
|
||||
return;
|
||||
|
||||
q = QUEUE_HEAD(&stream->write_queue);
|
||||
req = QUEUE_DATA(q, uv_write_t, queue);
|
||||
assert(req->handle == stream);
|
||||
|
||||
/*
|
||||
* Cast to iovec. We had to have our own uv_buf_t instead of iovec
|
||||
* because Windows's WSABUF is not an iovec.
|
||||
*/
|
||||
assert(sizeof(uv_buf_t) == sizeof(struct iovec));
|
||||
iov = (struct iovec*) &(req->bufs[req->write_index]);
|
||||
iovcnt = req->nbufs - req->write_index;
|
||||
iov = (struct iovec*) bufs;
|
||||
iovcnt = nbufs;
|
||||
|
||||
iovmax = uv__getiovmax();
|
||||
|
||||
@ -837,8 +825,7 @@ start:
|
||||
* Now do the actual writev. Note that we've been updating the pointers
|
||||
* inside the iov each time we write. So there is no need to offset it.
|
||||
*/
|
||||
|
||||
if (req->send_handle) {
|
||||
if (send_handle != NULL) {
|
||||
int fd_to_send;
|
||||
struct msghdr msg;
|
||||
struct cmsghdr *cmsg;
|
||||
@ -847,12 +834,10 @@ start:
|
||||
struct cmsghdr alias;
|
||||
} scratch;
|
||||
|
||||
if (uv__is_closing(req->send_handle)) {
|
||||
err = UV_EBADF;
|
||||
goto error;
|
||||
}
|
||||
if (uv__is_closing(send_handle))
|
||||
return UV_EBADF;
|
||||
|
||||
fd_to_send = uv__handle_fd((uv_handle_t*) req->send_handle);
|
||||
fd_to_send = uv__handle_fd((uv_handle_t*) send_handle);
|
||||
|
||||
memset(&scratch, 0, sizeof(scratch));
|
||||
|
||||
@ -882,44 +867,68 @@ start:
|
||||
do
|
||||
n = sendmsg(uv__stream_fd(stream), &msg, 0);
|
||||
while (n == -1 && RETRY_ON_WRITE_ERROR(errno));
|
||||
|
||||
/* Ensure the handle isn't sent again in case this is a partial write. */
|
||||
if (n >= 0)
|
||||
req->send_handle = NULL;
|
||||
} else {
|
||||
do
|
||||
n = uv__writev(uv__stream_fd(stream), iov, iovcnt);
|
||||
while (n == -1 && RETRY_ON_WRITE_ERROR(errno));
|
||||
}
|
||||
|
||||
if (n == -1 && !IS_TRANSIENT_WRITE_ERROR(errno, req->send_handle)) {
|
||||
err = UV__ERR(errno);
|
||||
goto error;
|
||||
if (n >= 0)
|
||||
return n;
|
||||
|
||||
if (IS_TRANSIENT_WRITE_ERROR(errno, send_handle))
|
||||
return UV_EAGAIN;
|
||||
|
||||
return UV__ERR(errno);
|
||||
}
|
||||
|
||||
static void uv__write(uv_stream_t* stream) {
|
||||
QUEUE* q;
|
||||
uv_write_t* req;
|
||||
ssize_t n;
|
||||
|
||||
assert(uv__stream_fd(stream) >= 0);
|
||||
|
||||
for (;;) {
|
||||
if (QUEUE_EMPTY(&stream->write_queue))
|
||||
return;
|
||||
|
||||
q = QUEUE_HEAD(&stream->write_queue);
|
||||
req = QUEUE_DATA(q, uv_write_t, queue);
|
||||
assert(req->handle == stream);
|
||||
|
||||
n = uv__try_write(stream,
|
||||
&(req->bufs[req->write_index]),
|
||||
req->nbufs - req->write_index,
|
||||
req->send_handle);
|
||||
|
||||
/* Ensure the handle isn't sent again in case this is a partial write. */
|
||||
if (n >= 0) {
|
||||
req->send_handle = NULL;
|
||||
if (uv__write_req_update(stream, req, n)) {
|
||||
uv__write_req_finish(req);
|
||||
return; /* TODO(bnoordhuis) Start trying to write the next request. */
|
||||
}
|
||||
} else if (n != UV_EAGAIN)
|
||||
break;
|
||||
|
||||
/* If this is a blocking stream, try again. */
|
||||
if (stream->flags & UV_HANDLE_BLOCKING_WRITES)
|
||||
continue;
|
||||
|
||||
/* We're not done. */
|
||||
uv__io_start(stream->loop, &stream->io_watcher, POLLOUT);
|
||||
|
||||
/* Notify select() thread about state change */
|
||||
uv__stream_osx_interrupt_select(stream);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (n >= 0 && uv__write_req_update(stream, req, n)) {
|
||||
uv__write_req_finish(req);
|
||||
return; /* TODO(bnoordhuis) Start trying to write the next request. */
|
||||
}
|
||||
|
||||
/* If this is a blocking stream, try again. */
|
||||
if (stream->flags & UV_HANDLE_BLOCKING_WRITES)
|
||||
goto start;
|
||||
|
||||
/* We're not done. */
|
||||
uv__io_start(stream->loop, &stream->io_watcher, POLLOUT);
|
||||
|
||||
/* Notify select() thread about state change */
|
||||
uv__stream_osx_interrupt_select(stream);
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
req->error = err;
|
||||
req->error = n;
|
||||
// XXX(jwn): this must call uv__stream_flush_write_queue(stream, n) here, since we won't generate any more events
|
||||
uv__write_req_finish(req);
|
||||
uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT);
|
||||
if (!uv__io_active(&stream->io_watcher, POLLIN))
|
||||
uv__handle_stop(stream);
|
||||
uv__stream_osx_interrupt_select(stream);
|
||||
}
|
||||
|
||||
@ -1001,9 +1010,9 @@ uv_handle_type uv__handle_type(int fd) {
|
||||
static void uv__stream_eof(uv_stream_t* stream, const uv_buf_t* buf) {
|
||||
stream->flags |= UV_HANDLE_READ_EOF;
|
||||
stream->flags &= ~UV_HANDLE_READING;
|
||||
stream->flags &= ~UV_HANDLE_READABLE;
|
||||
uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
|
||||
if (!uv__io_active(&stream->io_watcher, POLLOUT))
|
||||
uv__handle_stop(stream);
|
||||
uv__handle_stop(stream);
|
||||
uv__stream_osx_interrupt_select(stream);
|
||||
stream->read_cb(stream, UV_EOF, buf);
|
||||
}
|
||||
@ -1188,12 +1197,12 @@ static void uv__read(uv_stream_t* stream) {
|
||||
#endif
|
||||
} else {
|
||||
/* Error. User should call uv_close(). */
|
||||
stream->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
|
||||
stream->read_cb(stream, UV__ERR(errno), &buf);
|
||||
if (stream->flags & UV_HANDLE_READING) {
|
||||
stream->flags &= ~UV_HANDLE_READING;
|
||||
uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
|
||||
if (!uv__io_active(&stream->io_watcher, POLLOUT))
|
||||
uv__handle_stop(stream);
|
||||
uv__handle_stop(stream);
|
||||
uv__stream_osx_interrupt_select(stream);
|
||||
}
|
||||
}
|
||||
@ -1276,6 +1285,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) {
|
||||
req->cb = cb;
|
||||
stream->shutdown_req = req;
|
||||
stream->flags |= UV_HANDLE_SHUTTING;
|
||||
stream->flags &= ~UV_HANDLE_WRITABLE;
|
||||
|
||||
uv__io_start(stream->loop, &stream->io_watcher, POLLOUT);
|
||||
uv__stream_osx_interrupt_select(stream);
|
||||
@ -1390,14 +1400,9 @@ static void uv__stream_connect(uv_stream_t* stream) {
|
||||
}
|
||||
|
||||
|
||||
int uv_write2(uv_write_t* req,
|
||||
uv_stream_t* stream,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs,
|
||||
uv_stream_t* send_handle,
|
||||
uv_write_cb cb) {
|
||||
int empty_queue;
|
||||
|
||||
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 ||
|
||||
@ -1410,7 +1415,7 @@ int uv_write2(uv_write_t* req,
|
||||
if (!(stream->flags & UV_HANDLE_WRITABLE))
|
||||
return UV_EPIPE;
|
||||
|
||||
if (send_handle) {
|
||||
if (send_handle != NULL) {
|
||||
if (stream->type != UV_NAMED_PIPE || !((uv_pipe_t*)stream)->ipc)
|
||||
return UV_EINVAL;
|
||||
|
||||
@ -1430,6 +1435,22 @@ int uv_write2(uv_write_t* req,
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uv_write2(uv_write_t* req,
|
||||
uv_stream_t* stream,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs,
|
||||
uv_stream_t* send_handle,
|
||||
uv_write_cb cb) {
|
||||
int empty_queue;
|
||||
int err;
|
||||
|
||||
err = uv__check_before_write(stream, nbufs, send_handle);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* It's legal for write_queue_size > 0 even when the write_queue is empty;
|
||||
* it means there are error-state requests in the write_completed_queue that
|
||||
* will touch up write_queue_size later, see also uv__write_req_finish().
|
||||
@ -1498,57 +1519,28 @@ int uv_write(uv_write_t* req,
|
||||
}
|
||||
|
||||
|
||||
void uv_try_write_cb(uv_write_t* req, int status) {
|
||||
/* Should not be called */
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
int uv_try_write(uv_stream_t* stream,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs) {
|
||||
int r;
|
||||
int has_pollout;
|
||||
size_t written;
|
||||
size_t req_size;
|
||||
uv_write_t req;
|
||||
return uv_try_write2(stream, bufs, nbufs, NULL);
|
||||
}
|
||||
|
||||
|
||||
int uv_try_write2(uv_stream_t* stream,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs,
|
||||
uv_stream_t* send_handle) {
|
||||
int err;
|
||||
|
||||
/* Connecting or already writing some data */
|
||||
if (stream->connect_req != NULL || stream->write_queue_size != 0)
|
||||
return UV_EAGAIN;
|
||||
|
||||
has_pollout = uv__io_active(&stream->io_watcher, POLLOUT);
|
||||
err = uv__check_before_write(stream, nbufs, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
r = uv_write(&req, stream, bufs, nbufs, uv_try_write_cb);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
/* Remove not written bytes from write queue size */
|
||||
written = uv__count_bufs(bufs, nbufs);
|
||||
if (req.bufs != NULL)
|
||||
req_size = uv__write_req_size(&req);
|
||||
else
|
||||
req_size = 0;
|
||||
written -= req_size;
|
||||
stream->write_queue_size -= req_size;
|
||||
|
||||
/* Unqueue request, regardless of immediateness */
|
||||
QUEUE_REMOVE(&req.queue);
|
||||
uv__req_unregister(stream->loop, &req);
|
||||
if (req.bufs != req.bufsml)
|
||||
uv__free(req.bufs);
|
||||
req.bufs = NULL;
|
||||
|
||||
/* Do not poll for writable, if we wasn't before calling this */
|
||||
if (!has_pollout) {
|
||||
uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT);
|
||||
uv__stream_osx_interrupt_select(stream);
|
||||
}
|
||||
|
||||
if (written == 0 && req_size != 0)
|
||||
return req.error < 0 ? req.error : UV_EAGAIN;
|
||||
else
|
||||
return written;
|
||||
return uv__try_write(stream, bufs, nbufs, send_handle);
|
||||
}
|
||||
|
||||
|
||||
@ -1587,8 +1579,7 @@ int uv_read_stop(uv_stream_t* stream) {
|
||||
|
||||
stream->flags &= ~UV_HANDLE_READING;
|
||||
uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
|
||||
if (!uv__io_active(&stream->io_watcher, POLLOUT))
|
||||
uv__handle_stop(stream);
|
||||
uv__handle_stop(stream);
|
||||
uv__stream_osx_interrupt_select(stream);
|
||||
|
||||
stream->read_cb = NULL;
|
||||
|
11
deps/uv/src/unix/sunos.c
vendored
11
deps/uv/src/unix/sunos.c
vendored
@ -865,3 +865,14 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
||||
|
||||
uv__free(addresses);
|
||||
}
|
||||
|
||||
|
||||
#if !defined(_POSIX_VERSION) || _POSIX_VERSION < 200809L
|
||||
size_t strnlen(const char* s, size_t maxlen) {
|
||||
const char* end;
|
||||
end = memchr(s, '\0', maxlen);
|
||||
if (end == NULL)
|
||||
return maxlen;
|
||||
return end - s;
|
||||
}
|
||||
#endif
|
||||
|
12
deps/uv/src/unix/thread.c
vendored
12
deps/uv/src/unix/thread.c
vendored
@ -107,8 +107,7 @@ int uv_barrier_wait(uv_barrier_t* barrier) {
|
||||
}
|
||||
|
||||
last = (--b->out == 0);
|
||||
if (!last)
|
||||
uv_cond_signal(&b->cond); /* Not needed for last thread. */
|
||||
uv_cond_signal(&b->cond);
|
||||
|
||||
uv_mutex_unlock(&b->mutex);
|
||||
return last;
|
||||
@ -122,9 +121,10 @@ void uv_barrier_destroy(uv_barrier_t* barrier) {
|
||||
uv_mutex_lock(&b->mutex);
|
||||
|
||||
assert(b->in == 0);
|
||||
assert(b->out == 0);
|
||||
while (b->out != 0)
|
||||
uv_cond_wait(&b->cond, &b->mutex);
|
||||
|
||||
if (b->in != 0 || b->out != 0)
|
||||
if (b->in != 0)
|
||||
abort();
|
||||
|
||||
uv_mutex_unlock(&b->mutex);
|
||||
@ -168,7 +168,7 @@ void uv_barrier_destroy(uv_barrier_t* barrier) {
|
||||
* On Linux, threads created by musl have a much smaller stack than threads
|
||||
* created by glibc (80 vs. 2048 or 4096 kB.) Follow glibc for consistency.
|
||||
*/
|
||||
static size_t thread_stack_size(void) {
|
||||
size_t uv__thread_stack_size(void) {
|
||||
#if defined(__APPLE__) || defined(__linux__)
|
||||
struct rlimit lim;
|
||||
|
||||
@ -234,7 +234,7 @@ int uv_thread_create_ex(uv_thread_t* tid,
|
||||
|
||||
attr = NULL;
|
||||
if (stack_size == 0) {
|
||||
stack_size = thread_stack_size();
|
||||
stack_size = uv__thread_stack_size();
|
||||
} else {
|
||||
pagesize = (size_t)getpagesize();
|
||||
/* Round up to the nearest page boundary. */
|
||||
|
18
deps/uv/src/unix/tty.c
vendored
18
deps/uv/src/unix/tty.c
vendored
@ -242,6 +242,24 @@ static void uv__tty_make_raw(struct termios* tio) {
|
||||
tio->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
|
||||
tio->c_cflag &= ~(CSIZE | PARENB);
|
||||
tio->c_cflag |= CS8;
|
||||
|
||||
/*
|
||||
* By default, most software expects a pending read to block until at
|
||||
* least one byte becomes available. As per termio(7I), this requires
|
||||
* setting the MIN and TIME parameters appropriately.
|
||||
*
|
||||
* As a somewhat unfortunate artifact of history, the MIN and TIME slots
|
||||
* in the control character array overlap with the EOF and EOL slots used
|
||||
* for canonical mode processing. Because the EOF character needs to be
|
||||
* the ASCII EOT value (aka Control-D), it has the byte value 4. When
|
||||
* switching to raw mode, this is interpreted as a MIN value of 4; i.e.,
|
||||
* reads will block until at least four bytes have been input.
|
||||
*
|
||||
* Other platforms with a distinct MIN slot like Linux and FreeBSD appear
|
||||
* to default to a MIN value of 1, so we'll force that value here:
|
||||
*/
|
||||
tio->c_cc[VMIN] = 1;
|
||||
tio->c_cc[VTIME] = 0;
|
||||
#else
|
||||
cfmakeraw(tio);
|
||||
#endif /* #ifdef __sun */
|
||||
|
32
deps/uv/src/unix/udp.c
vendored
32
deps/uv/src/unix/udp.c
vendored
@ -32,8 +32,6 @@
|
||||
#endif
|
||||
#include <sys/un.h>
|
||||
|
||||
#define UV__UDP_DGRAM_MAXSIZE (64 * 1024)
|
||||
|
||||
#if defined(IPV6_JOIN_GROUP) && !defined(IPV6_ADD_MEMBERSHIP)
|
||||
# define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
|
||||
#endif
|
||||
@ -504,6 +502,28 @@ static int uv__set_reuse(int fd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The Linux kernel suppresses some ICMP error messages by default for UDP
|
||||
* sockets. Setting IP_RECVERR/IPV6_RECVERR on the socket enables full ICMP
|
||||
* error reporting, hopefully resulting in faster failover to working name
|
||||
* servers.
|
||||
*/
|
||||
static int uv__set_recverr(int fd, sa_family_t ss_family) {
|
||||
#if defined(__linux__)
|
||||
int yes;
|
||||
|
||||
yes = 1;
|
||||
if (ss_family == AF_INET) {
|
||||
if (setsockopt(fd, IPPROTO_IP, IP_RECVERR, &yes, sizeof(yes)))
|
||||
return UV__ERR(errno);
|
||||
} else if (ss_family == AF_INET6) {
|
||||
if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVERR, &yes, sizeof(yes)))
|
||||
return UV__ERR(errno);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv__udp_bind(uv_udp_t* handle,
|
||||
const struct sockaddr* addr,
|
||||
@ -514,7 +534,7 @@ int uv__udp_bind(uv_udp_t* handle,
|
||||
int fd;
|
||||
|
||||
/* Check for bad flags. */
|
||||
if (flags & ~(UV_UDP_IPV6ONLY | UV_UDP_REUSEADDR))
|
||||
if (flags & ~(UV_UDP_IPV6ONLY | UV_UDP_REUSEADDR | UV_UDP_LINUX_RECVERR))
|
||||
return UV_EINVAL;
|
||||
|
||||
/* Cannot set IPv6-only mode on non-IPv6 socket. */
|
||||
@ -530,6 +550,12 @@ int uv__udp_bind(uv_udp_t* handle,
|
||||
handle->io_watcher.fd = fd;
|
||||
}
|
||||
|
||||
if (flags & UV_UDP_LINUX_RECVERR) {
|
||||
err = uv__set_recverr(fd, addr->sa_family);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (flags & UV_UDP_REUSEADDR) {
|
||||
err = uv__set_reuse(fd);
|
||||
if (err)
|
||||
|
6
deps/uv/src/uv-common.c
vendored
6
deps/uv/src/uv-common.c
vendored
@ -872,7 +872,11 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
|
||||
}
|
||||
|
||||
|
||||
#ifdef __GNUC__ /* Also covers __clang__ and __INTEL_COMPILER. */
|
||||
/* Also covers __clang__ and __INTEL_COMPILER. Disabled on Windows because
|
||||
* threads have already been forcibly terminated by the operating system
|
||||
* by the time destructors run, ergo, it's not safe to try to clean them up.
|
||||
*/
|
||||
#if defined(__GNUC__) && !defined(_WIN32)
|
||||
__attribute__((destructor))
|
||||
#endif
|
||||
void uv_library_shutdown(void) {
|
||||
|
5
deps/uv/src/uv-common.h
vendored
5
deps/uv/src/uv-common.h
vendored
@ -68,6 +68,8 @@ extern int snprintf(char*, size_t, const char*, ...);
|
||||
#define uv__store_relaxed(p, v) do *p = v; while (0)
|
||||
#endif
|
||||
|
||||
#define UV__UDP_DGRAM_MAXSIZE (64 * 1024)
|
||||
|
||||
/* Handle flags. Some flags are specific to Windows or UNIX. */
|
||||
enum {
|
||||
/* Used by all handles. */
|
||||
@ -106,8 +108,7 @@ enum {
|
||||
UV_HANDLE_TCP_KEEPALIVE = 0x02000000,
|
||||
UV_HANDLE_TCP_SINGLE_ACCEPT = 0x04000000,
|
||||
UV_HANDLE_TCP_ACCEPT_STATE_CHANGING = 0x08000000,
|
||||
UV_HANDLE_TCP_SOCKET_CLOSED = 0x10000000,
|
||||
UV_HANDLE_SHARED_TCP_SOCKET = 0x20000000,
|
||||
UV_HANDLE_SHARED_TCP_SOCKET = 0x10000000,
|
||||
|
||||
/* Only used by uv_udp_t handles. */
|
||||
UV_HANDLE_UDP_PROCESSING = 0x01000000,
|
||||
|
8
deps/uv/src/win/atomicops-inl.h
vendored
8
deps/uv/src/win/atomicops-inl.h
vendored
@ -39,10 +39,11 @@ static char INLINE uv__atomic_exchange_set(char volatile* target) {
|
||||
return _InterlockedOr8(target, 1);
|
||||
}
|
||||
|
||||
#else /* GCC */
|
||||
#else /* GCC, Clang in mingw mode */
|
||||
|
||||
/* Mingw-32 version, hopefully this works for 64-bit gcc as well. */
|
||||
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"
|
||||
@ -50,6 +51,9 @@ static inline char uv__atomic_exchange_set(char volatile* target) {
|
||||
: "0"(one), "m"(*target)
|
||||
: "memory");
|
||||
return old_value;
|
||||
#else
|
||||
return __sync_fetch_and_or(target, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
2
deps/uv/src/win/error.c
vendored
2
deps/uv/src/win/error.c
vendored
@ -105,7 +105,6 @@ int uv_translate_sys_error(int sys_errno) {
|
||||
case ERROR_SYMLINK_NOT_SUPPORTED: return UV_EINVAL;
|
||||
case WSAEINVAL: return UV_EINVAL;
|
||||
case WSAEPFNOSUPPORT: return UV_EINVAL;
|
||||
case WSAESOCKTNOSUPPORT: return UV_EINVAL;
|
||||
case ERROR_BEGINNING_OF_MEDIA: return UV_EIO;
|
||||
case ERROR_BUS_RESET: return UV_EIO;
|
||||
case ERROR_CRC: return UV_EIO;
|
||||
@ -168,6 +167,7 @@ int uv_translate_sys_error(int sys_errno) {
|
||||
case ERROR_NOT_SAME_DEVICE: return UV_EXDEV;
|
||||
case ERROR_INVALID_FUNCTION: return UV_EISDIR;
|
||||
case ERROR_META_EXPANSION_TOO_LONG: return UV_E2BIG;
|
||||
case WSAESOCKTNOSUPPORT: return UV_ESOCKTNOSUPPORT;
|
||||
default: return UV_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
2
deps/uv/src/win/fs.c
vendored
2
deps/uv/src/win/fs.c
vendored
@ -1238,7 +1238,7 @@ void fs__mktemp(uv_fs_t* req, uv__fs_mktemp_func func) {
|
||||
uint64_t v;
|
||||
char* path;
|
||||
|
||||
path = req->path;
|
||||
path = (char*)req->path;
|
||||
len = wcslen(req->file.pathw);
|
||||
ep = req->file.pathw + len;
|
||||
if (len < num_x || wcsncmp(ep - num_x, L"XXXXXX", num_x)) {
|
||||
|
3
deps/uv/src/win/poll.c
vendored
3
deps/uv/src/win/poll.c
vendored
@ -488,7 +488,8 @@ static int uv__poll_set(uv_poll_t* handle, int events, uv_poll_cb cb) {
|
||||
|
||||
assert(handle->type == UV_POLL);
|
||||
assert(!(handle->flags & UV_HANDLE_CLOSING));
|
||||
assert((events & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT)) == 0);
|
||||
assert((events & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT |
|
||||
UV_PRIORITIZED)) == 0);
|
||||
|
||||
handle->events = events;
|
||||
handle->poll_cb = cb;
|
||||
|
2
deps/uv/src/win/process.c
vendored
2
deps/uv/src/win/process.c
vendored
@ -642,7 +642,7 @@ int env_strncmp(const wchar_t* a, int na, const wchar_t* b) {
|
||||
assert(r==nb);
|
||||
B[nb] = L'\0';
|
||||
|
||||
while (1) {
|
||||
for (;;) {
|
||||
wchar_t AA = *A++;
|
||||
wchar_t BB = *B++;
|
||||
if (AA < BB) {
|
||||
|
10
deps/uv/src/win/stream.c
vendored
10
deps/uv/src/win/stream.c
vendored
@ -188,6 +188,16 @@ int uv_try_write(uv_stream_t* stream,
|
||||
}
|
||||
|
||||
|
||||
int uv_try_write2(uv_stream_t* stream,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs,
|
||||
uv_stream_t* send_handle) {
|
||||
if (send_handle != NULL)
|
||||
return UV_EAGAIN;
|
||||
return uv_try_write(stream, bufs, nbufs);
|
||||
}
|
||||
|
||||
|
||||
int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
|
||||
uv_loop_t* loop = handle->loop;
|
||||
|
||||
|
117
deps/uv/src/win/tcp.c
vendored
117
deps/uv/src/win/tcp.c
vendored
@ -236,12 +236,7 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
|
||||
if (handle->flags & UV_HANDLE_CLOSING &&
|
||||
handle->reqs_pending == 0) {
|
||||
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
||||
|
||||
if (!(handle->flags & UV_HANDLE_TCP_SOCKET_CLOSED)) {
|
||||
closesocket(handle->socket);
|
||||
handle->socket = INVALID_SOCKET;
|
||||
handle->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
|
||||
}
|
||||
assert(handle->socket == INVALID_SOCKET);
|
||||
|
||||
if (!(handle->flags & UV_HANDLE_CONNECTION) && handle->tcp.serv.accept_reqs) {
|
||||
if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
|
||||
@ -599,6 +594,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
|
||||
}
|
||||
}
|
||||
|
||||
/* If this flag is set, we already made this listen call in xfer. */
|
||||
if (!(handle->flags & UV_HANDLE_SHARED_TCP_SOCKET) &&
|
||||
listen(handle->socket, backlog) == SOCKET_ERROR) {
|
||||
return WSAGetLastError();
|
||||
@ -769,7 +765,7 @@ static int uv__is_loopback(const struct sockaddr_storage* storage) {
|
||||
}
|
||||
|
||||
// Check if Windows version is 10.0.16299 or later
|
||||
static int uv__is_fast_loopback_fail_supported() {
|
||||
static int uv__is_fast_loopback_fail_supported(void) {
|
||||
OSVERSIONINFOW os_info;
|
||||
if (!pRtlGetVersion)
|
||||
return 0;
|
||||
@ -1024,6 +1020,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
|
||||
*/
|
||||
err = WSAECONNRESET;
|
||||
}
|
||||
handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
|
||||
|
||||
handle->read_cb((uv_stream_t*)handle,
|
||||
uv_translate_sys_error(err),
|
||||
@ -1105,6 +1102,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
|
||||
* Unix. */
|
||||
err = WSAECONNRESET;
|
||||
}
|
||||
handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
|
||||
|
||||
handle->read_cb((uv_stream_t*)handle,
|
||||
uv_translate_sys_error(err),
|
||||
@ -1158,9 +1156,14 @@ void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
|
||||
}
|
||||
|
||||
handle->stream.conn.write_reqs_pending--;
|
||||
if (handle->stream.conn.shutdown_req != NULL &&
|
||||
handle->stream.conn.write_reqs_pending == 0) {
|
||||
uv_want_endgame(loop, (uv_handle_t*)handle);
|
||||
if (handle->stream.conn.write_reqs_pending == 0) {
|
||||
if (handle->flags & UV_HANDLE_CLOSING) {
|
||||
closesocket(handle->socket);
|
||||
handle->socket = INVALID_SOCKET;
|
||||
}
|
||||
if (handle->stream.conn.shutdown_req != NULL) {
|
||||
uv_want_endgame(loop, (uv_handle_t*)handle);
|
||||
}
|
||||
}
|
||||
|
||||
DECREASE_PENDING_REQ_COUNT(handle);
|
||||
@ -1336,7 +1339,7 @@ int uv_tcp_nodelay(uv_tcp_t* handle, int enable) {
|
||||
if (handle->socket != INVALID_SOCKET) {
|
||||
err = uv__tcp_nodelay(handle, handle->socket, enable);
|
||||
if (err)
|
||||
return err;
|
||||
return uv_translate_sys_error(err);
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
@ -1355,7 +1358,7 @@ int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
|
||||
if (handle->socket != INVALID_SOCKET) {
|
||||
err = uv__tcp_keepalive(handle, handle->socket, enable, delay);
|
||||
if (err)
|
||||
return err;
|
||||
return uv_translate_sys_error(err);
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
@ -1402,9 +1405,24 @@ int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
|
||||
}
|
||||
|
||||
|
||||
static int uv_tcp_try_cancel_io(uv_tcp_t* tcp) {
|
||||
SOCKET socket = tcp->socket;
|
||||
static void uv_tcp_try_cancel_reqs(uv_tcp_t* tcp) {
|
||||
SOCKET socket;
|
||||
int non_ifs_lsp;
|
||||
int reading;
|
||||
int writing;
|
||||
|
||||
socket = tcp->socket;
|
||||
reading = tcp->flags & UV_HANDLE_READING;
|
||||
writing = tcp->stream.conn.write_reqs_pending > 0;
|
||||
if (!reading && !writing)
|
||||
return;
|
||||
|
||||
/* TODO: in libuv v2, keep explicit track of write_reqs, so we can cancel
|
||||
* them each explicitly with CancelIoEx (like unix). */
|
||||
if (reading)
|
||||
CancelIoEx((HANDLE) socket, &tcp->read_req.u.io.overlapped);
|
||||
if (writing)
|
||||
CancelIo((HANDLE) socket);
|
||||
|
||||
/* Check if we have any non-IFS LSPs stacked on top of TCP */
|
||||
non_ifs_lsp = (tcp->flags & UV_HANDLE_IPV6) ? uv_tcp_non_ifs_lsp_ipv6 :
|
||||
@ -1424,71 +1442,41 @@ static int uv_tcp_try_cancel_io(uv_tcp_t* tcp) {
|
||||
NULL,
|
||||
NULL) != 0) {
|
||||
/* Failed. We can't do CancelIo. */
|
||||
return -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
assert(socket != 0 && socket != INVALID_SOCKET);
|
||||
|
||||
if (!CancelIo((HANDLE) socket)) {
|
||||
return GetLastError();
|
||||
if (socket != tcp->socket) {
|
||||
if (reading)
|
||||
CancelIoEx((HANDLE) socket, &tcp->read_req.u.io.overlapped);
|
||||
if (writing)
|
||||
CancelIo((HANDLE) socket);
|
||||
}
|
||||
|
||||
/* It worked. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
|
||||
int close_socket = 1;
|
||||
|
||||
if (tcp->flags & UV_HANDLE_READ_PENDING) {
|
||||
/* In order for winsock to do a graceful close there must not be any any
|
||||
* pending reads, or the socket must be shut down for writing */
|
||||
if (!(tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET)) {
|
||||
/* Just do shutdown on non-shared sockets, which ensures graceful close. */
|
||||
shutdown(tcp->socket, SD_SEND);
|
||||
|
||||
} else if (uv_tcp_try_cancel_io(tcp) == 0) {
|
||||
/* In case of a shared socket, we try to cancel all outstanding I/O,. If
|
||||
* that works, don't close the socket yet - wait for the read req to
|
||||
* return and close the socket in uv_tcp_endgame. */
|
||||
close_socket = 0;
|
||||
|
||||
} else {
|
||||
/* When cancelling isn't possible - which could happen when an LSP is
|
||||
* present on an old Windows version, we will have to close the socket
|
||||
* with a read pending. That is not nice because trailing sent bytes may
|
||||
* not make it to the other side. */
|
||||
if (tcp->flags & UV_HANDLE_CONNECTION) {
|
||||
uv_tcp_try_cancel_reqs(tcp);
|
||||
if (tcp->flags & UV_HANDLE_READING) {
|
||||
uv_read_stop((uv_stream_t*) tcp);
|
||||
}
|
||||
|
||||
} else if ((tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET) &&
|
||||
tcp->tcp.serv.accept_reqs != NULL) {
|
||||
/* Under normal circumstances closesocket() will ensure that all pending
|
||||
* accept reqs are canceled. However, when the socket is shared the
|
||||
* presence of another reference to the socket in another process will keep
|
||||
* the accept reqs going, so we have to ensure that these are canceled. */
|
||||
if (uv_tcp_try_cancel_io(tcp) != 0) {
|
||||
/* When cancellation is not possible, there is another option: we can
|
||||
* close the incoming sockets, which will also cancel the accept
|
||||
* operations. However this is not cool because we might inadvertently
|
||||
* close a socket that just accepted a new connection, which will cause
|
||||
* the connection to be aborted. */
|
||||
} else {
|
||||
if (tcp->tcp.serv.accept_reqs != NULL) {
|
||||
/* First close the incoming sockets to cancel the accept operations before
|
||||
* we free their resources. */
|
||||
unsigned int i;
|
||||
for (i = 0; i < uv_simultaneous_server_accepts; i++) {
|
||||
uv_tcp_accept_t* req = &tcp->tcp.serv.accept_reqs[i];
|
||||
if (req->accept_socket != INVALID_SOCKET &&
|
||||
!HasOverlappedIoCompleted(&req->u.io.overlapped)) {
|
||||
if (req->accept_socket != INVALID_SOCKET) {
|
||||
closesocket(req->accept_socket);
|
||||
req->accept_socket = INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tcp->flags & UV_HANDLE_READING) {
|
||||
tcp->flags &= ~UV_HANDLE_READING;
|
||||
DECREASE_ACTIVE_COUNT(loop, tcp);
|
||||
assert(!(tcp->flags & UV_HANDLE_READING));
|
||||
}
|
||||
|
||||
if (tcp->flags & UV_HANDLE_LISTENING) {
|
||||
@ -1496,10 +1484,15 @@ void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
|
||||
DECREASE_ACTIVE_COUNT(loop, tcp);
|
||||
}
|
||||
|
||||
if (close_socket) {
|
||||
/* If any overlapped req failed to cancel, calling `closesocket` now would
|
||||
* cause Win32 to send an RST packet. Try to avoid that for writes, if
|
||||
* possibly applicable, by waiting to process the completion notifications
|
||||
* first (which typically should be cancellations). There's not much we can
|
||||
* do about canceled reads, which also will generate an RST packet. */
|
||||
if (!(tcp->flags & UV_HANDLE_CONNECTION) ||
|
||||
tcp->stream.conn.write_reqs_pending == 0) {
|
||||
closesocket(tcp->socket);
|
||||
tcp->socket = INVALID_SOCKET;
|
||||
tcp->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
|
||||
}
|
||||
|
||||
tcp->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
|
||||
|
4
deps/uv/src/win/udp.c
vendored
4
deps/uv/src/win/udp.c
vendored
@ -284,7 +284,7 @@ static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) {
|
||||
handle->flags &= ~UV_HANDLE_ZERO_READ;
|
||||
|
||||
handle->recv_buffer = uv_buf_init(NULL, 0);
|
||||
handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->recv_buffer);
|
||||
handle->alloc_cb((uv_handle_t*) handle, UV__UDP_DGRAM_MAXSIZE, &handle->recv_buffer);
|
||||
if (handle->recv_buffer.base == NULL || handle->recv_buffer.len == 0) {
|
||||
handle->recv_cb(handle, UV_ENOBUFS, &handle->recv_buffer, NULL, 0);
|
||||
return;
|
||||
@ -501,7 +501,7 @@ void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle,
|
||||
/* Do a nonblocking receive.
|
||||
* TODO: try to read multiple datagrams at once. FIONREAD maybe? */
|
||||
buf = uv_buf_init(NULL, 0);
|
||||
handle->alloc_cb((uv_handle_t*) handle, 65536, &buf);
|
||||
handle->alloc_cb((uv_handle_t*) handle, UV__UDP_DGRAM_MAXSIZE, &buf);
|
||||
if (buf.base == NULL || buf.len == 0) {
|
||||
handle->recv_cb(handle, UV_ENOBUFS, &buf, NULL, 0);
|
||||
goto done;
|
||||
|
17
deps/uv/src/win/util.c
vendored
17
deps/uv/src/win/util.c
vendored
@ -1664,26 +1664,33 @@ int uv_os_unsetenv(const char* name) {
|
||||
|
||||
|
||||
int uv_os_gethostname(char* buffer, size_t* size) {
|
||||
char buf[UV_MAXHOSTNAMESIZE];
|
||||
WCHAR buf[UV_MAXHOSTNAMESIZE];
|
||||
size_t len;
|
||||
char* utf8_str;
|
||||
int convert_result;
|
||||
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
uv__once_init(); /* Initialize winsock */
|
||||
|
||||
if (gethostname(buf, sizeof(buf)) != 0)
|
||||
if (GetHostNameW(buf, UV_MAXHOSTNAMESIZE) != 0)
|
||||
return uv_translate_sys_error(WSAGetLastError());
|
||||
|
||||
buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */
|
||||
len = strlen(buf);
|
||||
convert_result = uv__convert_utf16_to_utf8(buf, -1, &utf8_str);
|
||||
|
||||
if (convert_result != 0)
|
||||
return convert_result;
|
||||
|
||||
len = strlen(utf8_str);
|
||||
if (len >= *size) {
|
||||
*size = len + 1;
|
||||
uv__free(utf8_str);
|
||||
return UV_ENOBUFS;
|
||||
}
|
||||
|
||||
memcpy(buffer, buf, len + 1);
|
||||
memcpy(buffer, utf8_str, len + 1);
|
||||
uv__free(utf8_str);
|
||||
*size = len;
|
||||
return 0;
|
||||
}
|
||||
|
2
deps/uv/test/benchmark-async-pummel.c
vendored
2
deps/uv/test/benchmark-async-pummel.c
vendored
@ -68,7 +68,7 @@ static int test_async_pummel(int nthreads) {
|
||||
int i;
|
||||
|
||||
tids = calloc(nthreads, sizeof(tids[0]));
|
||||
ASSERT(tids != NULL);
|
||||
ASSERT_NOT_NULL(tids);
|
||||
|
||||
ASSERT(0 == uv_async_init(uv_default_loop(), &handle, async_cb));
|
||||
ACCESS_ONCE(const char*, handle.data) = running;
|
||||
|
2
deps/uv/test/benchmark-async.c
vendored
2
deps/uv/test/benchmark-async.c
vendored
@ -79,7 +79,7 @@ static int test_async(int nthreads) {
|
||||
int i;
|
||||
|
||||
threads = calloc(nthreads, sizeof(threads[0]));
|
||||
ASSERT(threads != NULL);
|
||||
ASSERT_NOT_NULL(threads);
|
||||
|
||||
for (i = 0; i < nthreads; i++) {
|
||||
ctx = threads + i;
|
||||
|
2
deps/uv/test/benchmark-million-async.c
vendored
2
deps/uv/test/benchmark-million-async.c
vendored
@ -86,7 +86,7 @@ BENCHMARK_IMPL(million_async) {
|
||||
timeout = 5000;
|
||||
|
||||
container = malloc(sizeof(*container));
|
||||
ASSERT(container != NULL);
|
||||
ASSERT_NOT_NULL(container);
|
||||
container->async_events = 0;
|
||||
container->handles_seen = 0;
|
||||
|
||||
|
2
deps/uv/test/benchmark-million-timers.c
vendored
2
deps/uv/test/benchmark-million-timers.c
vendored
@ -49,7 +49,7 @@ BENCHMARK_IMPL(million_timers) {
|
||||
int i;
|
||||
|
||||
timers = malloc(NUM_TIMERS * sizeof(timers[0]));
|
||||
ASSERT(timers != NULL);
|
||||
ASSERT_NOT_NULL(timers);
|
||||
|
||||
loop = uv_default_loop();
|
||||
timeout = 0;
|
||||
|
8
deps/uv/test/benchmark-multi-accept.c
vendored
8
deps/uv/test/benchmark-multi-accept.c
vendored
@ -114,7 +114,7 @@ static void ipc_connection_cb(uv_stream_t* ipc_pipe, int status) {
|
||||
buf = uv_buf_init("PING", 4);
|
||||
sc = container_of(ipc_pipe, struct ipc_server_ctx, ipc_pipe);
|
||||
pc = calloc(1, sizeof(*pc));
|
||||
ASSERT(pc != NULL);
|
||||
ASSERT_NOT_NULL(pc);
|
||||
|
||||
if (ipc_pipe->type == UV_TCP)
|
||||
ASSERT(0 == uv_tcp_init(loop, (uv_tcp_t*) &pc->peer_handle));
|
||||
@ -295,7 +295,7 @@ static void sv_connection_cb(uv_stream_t* server_handle, int status) {
|
||||
ASSERT(status == 0);
|
||||
|
||||
storage = malloc(sizeof(*storage));
|
||||
ASSERT(storage != NULL);
|
||||
ASSERT_NOT_NULL(storage);
|
||||
|
||||
if (server_handle->type == UV_TCP)
|
||||
ASSERT(0 == uv_tcp_init(server_handle->loop, (uv_tcp_t*) storage));
|
||||
@ -372,8 +372,8 @@ static int test_tcp(unsigned int num_servers, unsigned int num_clients) {
|
||||
|
||||
servers = calloc(num_servers, sizeof(servers[0]));
|
||||
clients = calloc(num_clients, sizeof(clients[0]));
|
||||
ASSERT(servers != NULL);
|
||||
ASSERT(clients != NULL);
|
||||
ASSERT_NOT_NULL(servers);
|
||||
ASSERT_NOT_NULL(clients);
|
||||
|
||||
/* We're making the assumption here that from the perspective of the
|
||||
* OS scheduler, threads are functionally equivalent to and interchangeable
|
||||
|
8
deps/uv/test/benchmark-pound.c
vendored
8
deps/uv/test/benchmark-pound.c
vendored
@ -114,11 +114,11 @@ static void connect_cb(uv_connect_t* req, int status) {
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(req != NULL);
|
||||
ASSERT_NOT_NULL(req);
|
||||
ASSERT(status == 0);
|
||||
|
||||
conn = (conn_rec*)req->data;
|
||||
ASSERT(conn != NULL);
|
||||
ASSERT_NOT_NULL(conn);
|
||||
|
||||
#if DEBUG
|
||||
printf("connect_cb %d\n", conn->i);
|
||||
@ -137,7 +137,7 @@ static void connect_cb(uv_connect_t* req, int status) {
|
||||
|
||||
static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
|
||||
|
||||
ASSERT(stream != NULL);
|
||||
ASSERT_NOT_NULL(stream);
|
||||
|
||||
#if DEBUG
|
||||
printf("read_cb %d\n", p->i);
|
||||
@ -161,7 +161,7 @@ static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
conn_rec* p = (conn_rec*)handle->data;
|
||||
|
||||
ASSERT(handle != NULL);
|
||||
ASSERT_NOT_NULL(handle);
|
||||
closed_streams++;
|
||||
|
||||
#if DEBUG
|
||||
|
4
deps/uv/test/benchmark-tcp-write-batch.c
vendored
4
deps/uv/test/benchmark-tcp-write-batch.c
vendored
@ -71,7 +71,7 @@ static void connect_cb(uv_connect_t* req, int status) {
|
||||
|
||||
|
||||
static void write_cb(uv_write_t* req, int status) {
|
||||
ASSERT(req != NULL);
|
||||
ASSERT_NOT_NULL(req);
|
||||
ASSERT(status == 0);
|
||||
write_cb_called++;
|
||||
}
|
||||
@ -103,7 +103,7 @@ BENCHMARK_IMPL(tcp_write_batch) {
|
||||
int r;
|
||||
|
||||
write_reqs = malloc(sizeof(*write_reqs) * NUM_WRITE_REQS);
|
||||
ASSERT(write_reqs != NULL);
|
||||
ASSERT_NOT_NULL(write_reqs);
|
||||
|
||||
/* Prepare the data to write out. */
|
||||
for (i = 0; i < NUM_WRITE_REQS; i++) {
|
||||
|
14
deps/uv/test/benchmark-udp-pummel.c
vendored
14
deps/uv/test/benchmark-udp-pummel.c
vendored
@ -72,7 +72,7 @@ static void alloc_cb(uv_handle_t* handle,
|
||||
static void send_cb(uv_udp_send_t* req, int status) {
|
||||
struct sender_state* s;
|
||||
|
||||
ASSERT(req != NULL);
|
||||
ASSERT_NOT_NULL(req);
|
||||
|
||||
if (status != 0) {
|
||||
ASSERT(status == UV_ECANCELED);
|
||||
@ -127,7 +127,7 @@ static void recv_cb(uv_udp_t* handle,
|
||||
|
||||
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
ASSERT(handle != NULL);
|
||||
ASSERT_NOT_NULL(handle);
|
||||
close_cb_called++;
|
||||
}
|
||||
|
||||
@ -179,11 +179,11 @@ static int pummel(unsigned int n_senders,
|
||||
uv_unref((uv_handle_t*)&s->udp_handle);
|
||||
}
|
||||
|
||||
bufs[0] = uv_buf_init(EXPECTED + 0, 10);
|
||||
bufs[1] = uv_buf_init(EXPECTED + 10, 10);
|
||||
bufs[2] = uv_buf_init(EXPECTED + 20, 10);
|
||||
bufs[3] = uv_buf_init(EXPECTED + 30, 10);
|
||||
bufs[4] = uv_buf_init(EXPECTED + 40, 5);
|
||||
bufs[0] = uv_buf_init(&EXPECTED[0], 10);
|
||||
bufs[1] = uv_buf_init(&EXPECTED[10], 10);
|
||||
bufs[2] = uv_buf_init(&EXPECTED[20], 10);
|
||||
bufs[3] = uv_buf_init(&EXPECTED[30], 10);
|
||||
bufs[4] = uv_buf_init(&EXPECTED[40], 5);
|
||||
|
||||
for (i = 0; i < n_senders; i++) {
|
||||
struct sender_state* s = senders + i;
|
||||
|
2
deps/uv/test/blackhole-server.c
vendored
2
deps/uv/test/blackhole-server.c
vendored
@ -47,7 +47,7 @@ static void connection_cb(uv_stream_t* stream, int status) {
|
||||
ASSERT(stream == (uv_stream_t*)&tcp_server);
|
||||
|
||||
conn = malloc(sizeof *conn);
|
||||
ASSERT(conn != NULL);
|
||||
ASSERT_NOT_NULL(conn);
|
||||
|
||||
r = uv_tcp_init(stream->loop, &conn->handle);
|
||||
ASSERT(r == 0);
|
||||
|
2
deps/uv/test/dns-server.c
vendored
2
deps/uv/test/dns-server.c
vendored
@ -280,7 +280,7 @@ static void on_connection(uv_stream_t* server, int status) {
|
||||
ASSERT(status == 0);
|
||||
|
||||
handle = (dnshandle*) malloc(sizeof *handle);
|
||||
ASSERT(handle != NULL);
|
||||
ASSERT_NOT_NULL(handle);
|
||||
|
||||
/* initialize read buffer state */
|
||||
handle->state.prevbuf_ptr = 0;
|
||||
|
59
deps/uv/test/echo-server.c
vendored
59
deps/uv/test/echo-server.c
vendored
@ -65,25 +65,35 @@ static void after_write(uv_write_t* req, int status) {
|
||||
|
||||
|
||||
static void after_shutdown(uv_shutdown_t* req, int status) {
|
||||
ASSERT_EQ(status, 0);
|
||||
uv_close((uv_handle_t*) req->handle, on_close);
|
||||
free(req);
|
||||
}
|
||||
|
||||
|
||||
static void on_shutdown(uv_shutdown_t* req, int status) {
|
||||
ASSERT_EQ(status, 0);
|
||||
free(req);
|
||||
}
|
||||
|
||||
|
||||
static void after_read(uv_stream_t* handle,
|
||||
ssize_t nread,
|
||||
const uv_buf_t* buf) {
|
||||
int i;
|
||||
write_req_t *wr;
|
||||
uv_shutdown_t* sreq;
|
||||
int shutdown = 0;
|
||||
|
||||
if (nread < 0) {
|
||||
/* Error or EOF */
|
||||
ASSERT(nread == UV_EOF);
|
||||
ASSERT_EQ(nread, UV_EOF);
|
||||
|
||||
free(buf->base);
|
||||
sreq = malloc(sizeof* sreq);
|
||||
ASSERT(0 == uv_shutdown(sreq, handle, after_shutdown));
|
||||
if (uv_is_writable(handle)) {
|
||||
ASSERT_EQ(0, uv_shutdown(sreq, handle, after_shutdown));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -96,29 +106,42 @@ static void after_read(uv_stream_t* handle,
|
||||
/*
|
||||
* Scan for the letter Q which signals that we should quit the server.
|
||||
* If we get QS it means close the stream.
|
||||
* If we get QSS it means shutdown the stream.
|
||||
* If we get QSH it means disable linger before close the socket.
|
||||
*/
|
||||
if (!server_closed) {
|
||||
for (i = 0; i < nread; i++) {
|
||||
if (buf->base[i] == 'Q') {
|
||||
if (i + 1 < nread && buf->base[i + 1] == 'S') {
|
||||
free(buf->base);
|
||||
uv_close((uv_handle_t*)handle, on_close);
|
||||
return;
|
||||
} else {
|
||||
uv_close(server, on_server_close);
|
||||
server_closed = 1;
|
||||
}
|
||||
for (i = 0; i < nread; i++) {
|
||||
if (buf->base[i] == 'Q') {
|
||||
if (i + 1 < nread && buf->base[i + 1] == 'S') {
|
||||
int reset = 0;
|
||||
if (i + 2 < nread && buf->base[i + 2] == 'S')
|
||||
shutdown = 1;
|
||||
if (i + 2 < nread && buf->base[i + 2] == 'H')
|
||||
reset = 1;
|
||||
if (reset && handle->type == UV_TCP)
|
||||
ASSERT_EQ(0, uv_tcp_close_reset((uv_tcp_t*) handle, on_close));
|
||||
else if (shutdown)
|
||||
break;
|
||||
else
|
||||
uv_close((uv_handle_t*) handle, on_close);
|
||||
free(buf->base);
|
||||
return;
|
||||
} else if (!server_closed) {
|
||||
uv_close(server, on_server_close);
|
||||
server_closed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wr = (write_req_t*) malloc(sizeof *wr);
|
||||
ASSERT(wr != NULL);
|
||||
ASSERT_NOT_NULL(wr);
|
||||
wr->buf = uv_buf_init(buf->base, nread);
|
||||
|
||||
if (uv_write(&wr->req, handle, &wr->buf, 1, after_write)) {
|
||||
FATAL("uv_write failed");
|
||||
}
|
||||
|
||||
if (shutdown)
|
||||
ASSERT_EQ(0, uv_shutdown(malloc(sizeof* sreq), handle, on_shutdown));
|
||||
}
|
||||
|
||||
|
||||
@ -155,14 +178,14 @@ static void on_connection(uv_stream_t* server, int status) {
|
||||
switch (serverType) {
|
||||
case TCP:
|
||||
stream = malloc(sizeof(uv_tcp_t));
|
||||
ASSERT(stream != NULL);
|
||||
ASSERT_NOT_NULL(stream);
|
||||
r = uv_tcp_init(loop, (uv_tcp_t*)stream);
|
||||
ASSERT(r == 0);
|
||||
break;
|
||||
|
||||
case PIPE:
|
||||
stream = malloc(sizeof(uv_pipe_t));
|
||||
ASSERT(stream != NULL);
|
||||
ASSERT_NOT_NULL(stream);
|
||||
r = uv_pipe_init(loop, (uv_pipe_t*)stream, 0);
|
||||
ASSERT(r == 0);
|
||||
break;
|
||||
@ -197,7 +220,7 @@ static uv_udp_send_t* send_alloc(void) {
|
||||
}
|
||||
|
||||
static void on_send(uv_udp_send_t* req, int status) {
|
||||
ASSERT(req != NULL);
|
||||
ASSERT_NOT_NULL(req);
|
||||
ASSERT(status == 0);
|
||||
req->data = send_freelist;
|
||||
send_freelist = req;
|
||||
@ -220,7 +243,7 @@ static void on_recv(uv_udp_t* handle,
|
||||
ASSERT(addr->sa_family == AF_INET);
|
||||
|
||||
req = send_alloc();
|
||||
ASSERT(req != NULL);
|
||||
ASSERT_NOT_NULL(req);
|
||||
sndbuf = uv_buf_init(rcvbuf->base, nread);
|
||||
ASSERT(0 <= uv_udp_send(req, handle, &sndbuf, 1, addr, on_send));
|
||||
}
|
||||
|
12
deps/uv/test/run-benchmarks.c
vendored
12
deps/uv/test/run-benchmarks.c
vendored
@ -28,6 +28,16 @@
|
||||
/* Actual benchmarks and helpers are defined in benchmark-list.h */
|
||||
#include "benchmark-list.h"
|
||||
|
||||
#ifdef __MVS__
|
||||
#include "zos-base.h"
|
||||
/* Initialize environment and zoslib */
|
||||
__attribute__((constructor)) void init() {
|
||||
zoslib_config_t config;
|
||||
init_zoslib_config(&config);
|
||||
init_zoslib(config);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int maybe_run_test(int argc, char **argv);
|
||||
|
||||
@ -44,8 +54,6 @@ int main(int argc, char **argv) {
|
||||
fflush(stderr);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
14
deps/uv/test/run-tests.c
vendored
14
deps/uv/test/run-tests.c
vendored
@ -36,6 +36,16 @@
|
||||
/* Actual tests and helpers are defined in test-list.h */
|
||||
#include "test-list.h"
|
||||
|
||||
#ifdef __MVS__
|
||||
#include "zos-base.h"
|
||||
/* Initialize environment and zoslib */
|
||||
__attribute__((constructor)) void init() {
|
||||
zoslib_config_t config;
|
||||
init_zoslib_config(&config);
|
||||
init_zoslib(config);
|
||||
}
|
||||
#endif
|
||||
|
||||
int ipc_helper(int listen_after_write);
|
||||
int ipc_helper_heavy_traffic_deadlock_bug(void);
|
||||
int ipc_helper_tcp_connection(void);
|
||||
@ -153,7 +163,7 @@ static int maybe_run_test(int argc, char **argv) {
|
||||
if (strcmp(argv[1], "spawn_helper4") == 0) {
|
||||
notify_parent_process();
|
||||
/* Never surrender, never return! */
|
||||
while (1) uv_sleep(10000);
|
||||
for (;;) uv_sleep(10000);
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "spawn_helper5") == 0) {
|
||||
@ -198,7 +208,7 @@ static int maybe_run_test(int argc, char **argv) {
|
||||
|
||||
/* Test if the test value from the parent is still set */
|
||||
test = getenv("ENV_TEST");
|
||||
ASSERT(test != NULL);
|
||||
ASSERT_NOT_NULL(test);
|
||||
|
||||
r = fprintf(stdout, "%s", test);
|
||||
ASSERT(r > 0);
|
||||
|
4
deps/uv/test/runner-unix.c
vendored
4
deps/uv/test/runner-unix.c
vendored
@ -197,7 +197,7 @@ static void* dowait(void* data) {
|
||||
process_info_t* p;
|
||||
|
||||
for (i = 0; i < args->n; i++) {
|
||||
p = (process_info_t*)(args->vec + i * sizeof(process_info_t));
|
||||
p = &args->vec[i];
|
||||
if (p->terminated) continue;
|
||||
r = waitpid(p->pid, &p->status, 0);
|
||||
if (r < 0) {
|
||||
@ -323,7 +323,7 @@ int process_wait(process_info_t* vec, int n, int timeout) {
|
||||
} else {
|
||||
/* Timeout. Kill all the children. */
|
||||
for (i = 0; i < n; i++) {
|
||||
p = (process_info_t*)(vec + i * sizeof(process_info_t));
|
||||
p = &vec[i];
|
||||
kill(p->pid, SIGTERM);
|
||||
}
|
||||
retval = -2;
|
||||
|
42
deps/uv/test/runner.c
vendored
42
deps/uv/test/runner.c
vendored
@ -98,8 +98,8 @@ int run_tests(int benchmark_output) {
|
||||
skip = (actual > 0 && 0 == strcmp(TASKS[0].task_name, "platform_output"));
|
||||
qsort(TASKS + skip, actual - skip, sizeof(TASKS[0]), compare_task);
|
||||
|
||||
fprintf(stderr, "1..%d\n", total);
|
||||
fflush(stderr);
|
||||
fprintf(stdout, "1..%d\n", total);
|
||||
fflush(stdout);
|
||||
|
||||
/* Run all tests. */
|
||||
passed = 0;
|
||||
@ -156,8 +156,8 @@ void log_tap_result(int test_count,
|
||||
reason[0] = '\0';
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s %d - %s%s%s\n", result, test_count, test, directive, reason);
|
||||
fflush(stderr);
|
||||
fprintf(stdout, "%s %d - %s%s%s\n", result, test_count, test, directive, reason);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
@ -307,28 +307,28 @@ out:
|
||||
/* Show error and output from processes if the test failed. */
|
||||
if ((status != TEST_OK && status != TEST_SKIP) || task->show_output) {
|
||||
if (strlen(errmsg) > 0)
|
||||
fprintf(stderr, "# %s\n", errmsg);
|
||||
fprintf(stderr, "# ");
|
||||
fflush(stderr);
|
||||
fprintf(stdout, "# %s\n", errmsg);
|
||||
fprintf(stdout, "# ");
|
||||
fflush(stdout);
|
||||
|
||||
for (i = 0; i < process_count; i++) {
|
||||
switch (process_output_size(&processes[i])) {
|
||||
case -1:
|
||||
fprintf(stderr, "Output from process `%s`: (unavailable)\n",
|
||||
fprintf(stdout, "Output from process `%s`: (unavailable)\n",
|
||||
process_get_name(&processes[i]));
|
||||
fflush(stderr);
|
||||
fflush(stdout);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
fprintf(stderr, "Output from process `%s`: (no output)\n",
|
||||
fprintf(stdout, "Output from process `%s`: (no output)\n",
|
||||
process_get_name(&processes[i]));
|
||||
fflush(stderr);
|
||||
fflush(stdout);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Output from process `%s`:\n", process_get_name(&processes[i]));
|
||||
fflush(stderr);
|
||||
process_copy_output(&processes[i], stderr);
|
||||
fprintf(stdout, "Output from process `%s`:\n", process_get_name(&processes[i]));
|
||||
fflush(stdout);
|
||||
process_copy_output(&processes[i], stdout);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -337,18 +337,18 @@ out:
|
||||
} else if (benchmark_output) {
|
||||
switch (process_output_size(main_proc)) {
|
||||
case -1:
|
||||
fprintf(stderr, "%s: (unavailable)\n", test);
|
||||
fflush(stderr);
|
||||
fprintf(stdout, "%s: (unavailable)\n", test);
|
||||
fflush(stdout);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
fprintf(stderr, "%s: (no output)\n", test);
|
||||
fflush(stderr);
|
||||
fprintf(stdout, "%s: (no output)\n", test);
|
||||
fflush(stdout);
|
||||
break;
|
||||
|
||||
default:
|
||||
for (i = 0; i < process_count; i++) {
|
||||
process_copy_output(&processes[i], stderr);
|
||||
process_copy_output(&processes[i], stdout);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -378,8 +378,8 @@ int run_test_part(const char* test, const char* part) {
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "No test part with that name: %s:%s\n", test, part);
|
||||
fflush(stderr);
|
||||
fprintf(stdout, "No test part with that name: %s:%s\n", test, part);
|
||||
fflush(stdout);
|
||||
return 255;
|
||||
}
|
||||
|
||||
|
1
deps/uv/test/task.h
vendored
1
deps/uv/test/task.h
vendored
@ -52,6 +52,7 @@
|
||||
|
||||
#define TEST_PORT 9123
|
||||
#define TEST_PORT_2 9124
|
||||
#define TEST_PORT_3 9125
|
||||
|
||||
#ifdef _WIN32
|
||||
# define TEST_PIPENAME "\\\\?\\pipe\\uv-test"
|
||||
|
2
deps/uv/test/test-active.c
vendored
2
deps/uv/test/test-active.c
vendored
@ -30,7 +30,7 @@ static int close_cb_called = 0;
|
||||
|
||||
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
ASSERT(handle != NULL);
|
||||
ASSERT_NOT_NULL(handle);
|
||||
close_cb_called++;
|
||||
}
|
||||
|
||||
|
2
deps/uv/test/test-async.c
vendored
2
deps/uv/test/test-async.c
vendored
@ -70,7 +70,7 @@ static void thread_cb(void *arg) {
|
||||
|
||||
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
ASSERT(handle != NULL);
|
||||
ASSERT_NOT_NULL(handle);
|
||||
close_cb_called++;
|
||||
}
|
||||
|
||||
|
2
deps/uv/test/test-callback-stack.c
vendored
2
deps/uv/test/test-callback-stack.c
vendored
@ -48,7 +48,7 @@ static int shutdown_cb_called = 0;
|
||||
static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
|
||||
buf->len = size;
|
||||
buf->base = malloc(size);
|
||||
ASSERT(buf->base != NULL);
|
||||
ASSERT_NOT_NULL(buf->base);
|
||||
}
|
||||
|
||||
|
||||
|
2
deps/uv/test/test-close-order.c
vendored
2
deps/uv/test/test-close-order.c
vendored
@ -32,7 +32,7 @@ static uv_timer_t timer_handle2;
|
||||
|
||||
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
ASSERT(handle != NULL);
|
||||
ASSERT_NOT_NULL(handle);
|
||||
close_cb_called++;
|
||||
}
|
||||
|
||||
|
4
deps/uv/test/test-default-loop-close.c
vendored
4
deps/uv/test/test-default-loop-close.c
vendored
@ -37,7 +37,7 @@ TEST_IMPL(default_loop_close) {
|
||||
uv_timer_t timer_handle;
|
||||
|
||||
loop = uv_default_loop();
|
||||
ASSERT(loop != NULL);
|
||||
ASSERT_NOT_NULL(loop);
|
||||
|
||||
ASSERT(0 == uv_timer_init(loop, &timer_handle));
|
||||
ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0));
|
||||
@ -46,7 +46,7 @@ TEST_IMPL(default_loop_close) {
|
||||
ASSERT(0 == uv_loop_close(loop));
|
||||
|
||||
loop = uv_default_loop();
|
||||
ASSERT(loop != NULL);
|
||||
ASSERT_NOT_NULL(loop);
|
||||
|
||||
ASSERT(0 == uv_timer_init(loop, &timer_handle));
|
||||
ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0));
|
||||
|
18
deps/uv/test/test-delayed-accept.c
vendored
18
deps/uv/test/test-delayed-accept.c
vendored
@ -37,7 +37,7 @@ static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
|
||||
|
||||
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
ASSERT(handle != NULL);
|
||||
ASSERT_NOT_NULL(handle);
|
||||
|
||||
free(handle);
|
||||
|
||||
@ -50,8 +50,8 @@ static void do_accept(uv_timer_t* timer_handle) {
|
||||
uv_tcp_t* accepted_handle = (uv_tcp_t*)malloc(sizeof *accepted_handle);
|
||||
int r;
|
||||
|
||||
ASSERT(timer_handle != NULL);
|
||||
ASSERT(accepted_handle != NULL);
|
||||
ASSERT_NOT_NULL(timer_handle);
|
||||
ASSERT_NOT_NULL(accepted_handle);
|
||||
|
||||
r = uv_tcp_init(uv_default_loop(), accepted_handle);
|
||||
ASSERT(r == 0);
|
||||
@ -82,7 +82,7 @@ static void connection_cb(uv_stream_t* tcp, int status) {
|
||||
ASSERT(status == 0);
|
||||
|
||||
timer_handle = (uv_timer_t*)malloc(sizeof *timer_handle);
|
||||
ASSERT(timer_handle != NULL);
|
||||
ASSERT_NOT_NULL(timer_handle);
|
||||
|
||||
/* Accept the client after 1 second */
|
||||
r = uv_timer_init(uv_default_loop(), timer_handle);
|
||||
@ -103,7 +103,7 @@ static void start_server(void) {
|
||||
int r;
|
||||
|
||||
ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
|
||||
ASSERT(server != NULL);
|
||||
ASSERT_NOT_NULL(server);
|
||||
|
||||
r = uv_tcp_init(uv_default_loop(), server);
|
||||
ASSERT(r == 0);
|
||||
@ -125,7 +125,7 @@ static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
|
||||
if (nread >= 0) {
|
||||
ASSERT(nread == 0);
|
||||
} else {
|
||||
ASSERT(tcp != NULL);
|
||||
ASSERT_NOT_NULL(tcp);
|
||||
ASSERT(nread == UV_EOF);
|
||||
uv_close((uv_handle_t*)tcp, close_cb);
|
||||
}
|
||||
@ -135,7 +135,7 @@ static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
|
||||
static void connect_cb(uv_connect_t* req, int status) {
|
||||
int r;
|
||||
|
||||
ASSERT(req != NULL);
|
||||
ASSERT_NOT_NULL(req);
|
||||
ASSERT(status == 0);
|
||||
|
||||
/* Not that the server will send anything, but otherwise we'll never know
|
||||
@ -156,8 +156,8 @@ static void client_connect(void) {
|
||||
int r;
|
||||
|
||||
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
|
||||
ASSERT(client != NULL);
|
||||
ASSERT(connect_req != NULL);
|
||||
ASSERT_NOT_NULL(client);
|
||||
ASSERT_NOT_NULL(connect_req);
|
||||
|
||||
r = uv_tcp_init(uv_default_loop(), client);
|
||||
ASSERT(r == 0);
|
||||
|
16
deps/uv/test/test-dlerror.c
vendored
16
deps/uv/test/test-dlerror.c
vendored
@ -34,26 +34,26 @@ TEST_IMPL(dlerror) {
|
||||
lib.errmsg = NULL;
|
||||
lib.handle = NULL;
|
||||
msg = uv_dlerror(&lib);
|
||||
ASSERT(msg != NULL);
|
||||
ASSERT(strstr(msg, dlerror_no_error) != NULL);
|
||||
ASSERT_NOT_NULL(msg);
|
||||
ASSERT_NOT_NULL(strstr(msg, dlerror_no_error));
|
||||
|
||||
r = uv_dlopen(path, &lib);
|
||||
ASSERT(r == -1);
|
||||
|
||||
msg = uv_dlerror(&lib);
|
||||
ASSERT(msg != NULL);
|
||||
ASSERT_NOT_NULL(msg);
|
||||
#if !defined(__OpenBSD__) && !defined(__QNX__)
|
||||
ASSERT(strstr(msg, path) != NULL);
|
||||
ASSERT_NOT_NULL(strstr(msg, path));
|
||||
#endif
|
||||
ASSERT(strstr(msg, dlerror_no_error) == NULL);
|
||||
ASSERT_NULL(strstr(msg, dlerror_no_error));
|
||||
|
||||
/* Should return the same error twice in a row. */
|
||||
msg = uv_dlerror(&lib);
|
||||
ASSERT(msg != NULL);
|
||||
ASSERT_NOT_NULL(msg);
|
||||
#if !defined(__OpenBSD__) && !defined(__QNX__)
|
||||
ASSERT(strstr(msg, path) != NULL);
|
||||
ASSERT_NOT_NULL(strstr(msg, path));
|
||||
#endif
|
||||
ASSERT(strstr(msg, dlerror_no_error) == NULL);
|
||||
ASSERT_NULL(strstr(msg, dlerror_no_error));
|
||||
|
||||
uv_dlclose(&lib);
|
||||
|
||||
|
8
deps/uv/test/test-error.c
vendored
8
deps/uv/test/test-error.c
vendored
@ -50,13 +50,13 @@ TEST_IMPL(error_message) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ASSERT(strstr(uv_strerror(UV_EINVAL), "Success") == NULL);
|
||||
ASSERT_NULL(strstr(uv_strerror(UV_EINVAL), "Success"));
|
||||
ASSERT(strcmp(uv_strerror(1337), "Unknown error") == 0);
|
||||
ASSERT(strcmp(uv_strerror(-1337), "Unknown error") == 0);
|
||||
|
||||
ASSERT(strstr(uv_strerror_r(UV_EINVAL, buf, sizeof(buf)), "Success") == NULL);
|
||||
ASSERT(strstr(uv_strerror_r(1337, buf, sizeof(buf)), "1337") != NULL);
|
||||
ASSERT(strstr(uv_strerror_r(-1337, buf, sizeof(buf)), "-1337") != NULL);
|
||||
ASSERT_NULL(strstr(uv_strerror_r(UV_EINVAL, buf, sizeof(buf)), "Success"));
|
||||
ASSERT_NOT_NULL(strstr(uv_strerror_r(1337, buf, sizeof(buf)), "1337"));
|
||||
ASSERT_NOT_NULL(strstr(uv_strerror_r(-1337, buf, sizeof(buf)), "-1337"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
8
deps/uv/test/test-fs-event.c
vendored
8
deps/uv/test/test-fs-event.c
vendored
@ -118,7 +118,7 @@ static void touch_file(const char* name) {
|
||||
}
|
||||
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
ASSERT(handle != NULL);
|
||||
ASSERT_NOT_NULL(handle);
|
||||
close_cb_called++;
|
||||
}
|
||||
|
||||
@ -337,7 +337,7 @@ static void fs_event_cb_file(uv_fs_event_t* handle, const char* filename,
|
||||
static void timer_cb_close_handle(uv_timer_t* timer) {
|
||||
uv_handle_t* handle;
|
||||
|
||||
ASSERT(timer != NULL);
|
||||
ASSERT_NOT_NULL(timer);
|
||||
handle = timer->data;
|
||||
|
||||
uv_close((uv_handle_t*)timer, NULL);
|
||||
@ -758,7 +758,7 @@ TEST_IMPL(fs_event_watch_file_root_dir) {
|
||||
const char* sys_drive = getenv("SystemDrive");
|
||||
char path[] = "\\\\?\\X:\\bootsect.bak";
|
||||
|
||||
ASSERT(sys_drive != NULL);
|
||||
ASSERT_NOT_NULL(sys_drive);
|
||||
strncpy(path + sizeof("\\\\?\\") - 1, sys_drive, 1);
|
||||
|
||||
loop = uv_default_loop();
|
||||
@ -1072,7 +1072,7 @@ static void timer_cb_nop(uv_timer_t* handle) {
|
||||
}
|
||||
|
||||
static void fs_event_error_report_close_cb(uv_handle_t* handle) {
|
||||
ASSERT(handle != NULL);
|
||||
ASSERT_NOT_NULL(handle);
|
||||
close_cb_called++;
|
||||
|
||||
/* handle is allocated on-stack, no need to free it */
|
||||
|
4
deps/uv/test/test-fs-poll.c
vendored
4
deps/uv/test/test-fs-poll.c
vendored
@ -105,8 +105,8 @@ static void poll_cb(uv_fs_poll_t* handle,
|
||||
|
||||
ASSERT(handle == &poll_handle);
|
||||
ASSERT(1 == uv_is_active((uv_handle_t*) handle));
|
||||
ASSERT(prev != NULL);
|
||||
ASSERT(curr != NULL);
|
||||
ASSERT_NOT_NULL(prev);
|
||||
ASSERT_NOT_NULL(curr);
|
||||
|
||||
switch (poll_cb_called++) {
|
||||
case 0:
|
||||
|
16
deps/uv/test/test-fs-readdir.c
vendored
16
deps/uv/test/test-fs-readdir.c
vendored
@ -77,7 +77,7 @@ static void empty_opendir_cb(uv_fs_t* req) {
|
||||
ASSERT(req == &opendir_req);
|
||||
ASSERT(req->fs_type == UV_FS_OPENDIR);
|
||||
ASSERT(req->result == 0);
|
||||
ASSERT(req->ptr != NULL);
|
||||
ASSERT_NOT_NULL(req->ptr);
|
||||
dir = req->ptr;
|
||||
dir->dirents = dirents;
|
||||
dir->nentries = ARRAY_SIZE(dirents);
|
||||
@ -118,7 +118,7 @@ TEST_IMPL(fs_readdir_empty_dir) {
|
||||
ASSERT(r == 0);
|
||||
ASSERT(opendir_req.fs_type == UV_FS_OPENDIR);
|
||||
ASSERT(opendir_req.result == 0);
|
||||
ASSERT(opendir_req.ptr != NULL);
|
||||
ASSERT_NOT_NULL(opendir_req.ptr);
|
||||
dir = opendir_req.ptr;
|
||||
uv_fs_req_cleanup(&opendir_req);
|
||||
|
||||
@ -171,7 +171,7 @@ static void non_existing_opendir_cb(uv_fs_t* req) {
|
||||
ASSERT(req == &opendir_req);
|
||||
ASSERT(req->fs_type == UV_FS_OPENDIR);
|
||||
ASSERT(req->result == UV_ENOENT);
|
||||
ASSERT(req->ptr == NULL);
|
||||
ASSERT_NULL(req->ptr);
|
||||
|
||||
uv_fs_req_cleanup(req);
|
||||
++non_existing_opendir_cb_count;
|
||||
@ -191,7 +191,7 @@ TEST_IMPL(fs_readdir_non_existing_dir) {
|
||||
ASSERT(r == UV_ENOENT);
|
||||
ASSERT(opendir_req.fs_type == UV_FS_OPENDIR);
|
||||
ASSERT(opendir_req.result == UV_ENOENT);
|
||||
ASSERT(opendir_req.ptr == NULL);
|
||||
ASSERT_NULL(opendir_req.ptr);
|
||||
uv_fs_req_cleanup(&opendir_req);
|
||||
|
||||
/* Fill the req to ensure that required fields are cleaned up. */
|
||||
@ -223,7 +223,7 @@ static void file_opendir_cb(uv_fs_t* req) {
|
||||
ASSERT(req == &opendir_req);
|
||||
ASSERT(req->fs_type == UV_FS_OPENDIR);
|
||||
ASSERT(req->result == UV_ENOTDIR);
|
||||
ASSERT(req->ptr == NULL);
|
||||
ASSERT_NULL(req->ptr);
|
||||
|
||||
uv_fs_req_cleanup(req);
|
||||
++file_opendir_cb_count;
|
||||
@ -247,7 +247,7 @@ TEST_IMPL(fs_readdir_file) {
|
||||
ASSERT(r == UV_ENOTDIR);
|
||||
ASSERT(opendir_req.fs_type == UV_FS_OPENDIR);
|
||||
ASSERT(opendir_req.result == UV_ENOTDIR);
|
||||
ASSERT(opendir_req.ptr == NULL);
|
||||
ASSERT_NULL(opendir_req.ptr);
|
||||
|
||||
uv_fs_req_cleanup(&opendir_req);
|
||||
|
||||
@ -329,7 +329,7 @@ static void non_empty_opendir_cb(uv_fs_t* req) {
|
||||
ASSERT(req == &opendir_req);
|
||||
ASSERT(req->fs_type == UV_FS_OPENDIR);
|
||||
ASSERT(req->result == 0);
|
||||
ASSERT(req->ptr != NULL);
|
||||
ASSERT_NOT_NULL(req->ptr);
|
||||
|
||||
dir = req->ptr;
|
||||
dir->dirents = dirents;
|
||||
@ -403,7 +403,7 @@ TEST_IMPL(fs_readdir_non_empty_dir) {
|
||||
ASSERT(r == 0);
|
||||
ASSERT(opendir_req.fs_type == UV_FS_OPENDIR);
|
||||
ASSERT(opendir_req.result == 0);
|
||||
ASSERT(opendir_req.ptr != NULL);
|
||||
ASSERT_NOT_NULL(opendir_req.ptr);
|
||||
|
||||
entries_count = 0;
|
||||
dir = opendir_req.ptr;
|
||||
|
55
deps/uv/test/test-fs.c
vendored
55
deps/uv/test/test-fs.c
vendored
@ -343,7 +343,7 @@ static void statfs_cb(uv_fs_t* req) {
|
||||
|
||||
ASSERT(req->fs_type == UV_FS_STATFS);
|
||||
ASSERT(req->result == 0);
|
||||
ASSERT(req->ptr != NULL);
|
||||
ASSERT_NOT_NULL(req->ptr);
|
||||
stats = req->ptr;
|
||||
|
||||
#if defined(_WIN32) || defined(__sun) || defined(_AIX) || defined(__MVS__) || \
|
||||
@ -366,7 +366,7 @@ static void statfs_cb(uv_fs_t* req) {
|
||||
ASSERT(stats->f_ffree <= stats->f_files);
|
||||
#endif
|
||||
uv_fs_req_cleanup(req);
|
||||
ASSERT(req->ptr == NULL);
|
||||
ASSERT_NULL(req->ptr);
|
||||
statfs_cb_count++;
|
||||
}
|
||||
|
||||
@ -630,7 +630,7 @@ static void empty_scandir_cb(uv_fs_t* req) {
|
||||
ASSERT(req == &scandir_req);
|
||||
ASSERT(req->fs_type == UV_FS_SCANDIR);
|
||||
ASSERT(req->result == 0);
|
||||
ASSERT(req->ptr == NULL);
|
||||
ASSERT_NULL(req->ptr);
|
||||
ASSERT(UV_EOF == uv_fs_scandir_next(req, &dent));
|
||||
uv_fs_req_cleanup(req);
|
||||
scandir_cb_count++;
|
||||
@ -642,7 +642,7 @@ static void non_existent_scandir_cb(uv_fs_t* req) {
|
||||
ASSERT(req == &scandir_req);
|
||||
ASSERT(req->fs_type == UV_FS_SCANDIR);
|
||||
ASSERT(req->result == UV_ENOENT);
|
||||
ASSERT(req->ptr == NULL);
|
||||
ASSERT_NULL(req->ptr);
|
||||
ASSERT(UV_ENOENT == uv_fs_scandir_next(req, &dent));
|
||||
uv_fs_req_cleanup(req);
|
||||
scandir_cb_count++;
|
||||
@ -653,7 +653,7 @@ static void file_scandir_cb(uv_fs_t* req) {
|
||||
ASSERT(req == &scandir_req);
|
||||
ASSERT(req->fs_type == UV_FS_SCANDIR);
|
||||
ASSERT(req->result == UV_ENOTDIR);
|
||||
ASSERT(req->ptr == NULL);
|
||||
ASSERT_NULL(req->ptr);
|
||||
uv_fs_req_cleanup(req);
|
||||
scandir_cb_count++;
|
||||
}
|
||||
@ -1453,7 +1453,8 @@ TEST_IMPL(fs_fstat) {
|
||||
ASSERT(s->st_mtim.tv_nsec == t.st_mtimespec.tv_nsec);
|
||||
ASSERT(s->st_ctim.tv_sec == t.st_ctimespec.tv_sec);
|
||||
ASSERT(s->st_ctim.tv_nsec == t.st_ctimespec.tv_nsec);
|
||||
#elif defined(_AIX)
|
||||
#elif defined(_AIX) || \
|
||||
defined(__MVS__)
|
||||
ASSERT(s->st_atim.tv_sec == t.st_atime);
|
||||
ASSERT(s->st_atim.tv_nsec == 0);
|
||||
ASSERT(s->st_mtim.tv_sec == t.st_mtime);
|
||||
@ -2011,12 +2012,12 @@ TEST_IMPL(fs_readlink) {
|
||||
ASSERT(0 == uv_fs_readlink(loop, &req, "no_such_file", dummy_cb));
|
||||
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
|
||||
ASSERT(dummy_cb_count == 1);
|
||||
ASSERT(req.ptr == NULL);
|
||||
ASSERT_NULL(req.ptr);
|
||||
ASSERT(req.result == UV_ENOENT);
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
ASSERT(UV_ENOENT == uv_fs_readlink(NULL, &req, "no_such_file", NULL));
|
||||
ASSERT(req.ptr == NULL);
|
||||
ASSERT_NULL(req.ptr);
|
||||
ASSERT(req.result == UV_ENOENT);
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
@ -2032,7 +2033,7 @@ TEST_IMPL(fs_realpath) {
|
||||
ASSERT(0 == uv_fs_realpath(loop, &req, "no_such_file", dummy_cb));
|
||||
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
|
||||
ASSERT(dummy_cb_count == 1);
|
||||
ASSERT(req.ptr == NULL);
|
||||
ASSERT_NULL(req.ptr);
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* Windows XP and Server 2003 don't support GetFinalPathNameByHandleW()
|
||||
@ -2046,7 +2047,7 @@ TEST_IMPL(fs_realpath) {
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
ASSERT(UV_ENOENT == uv_fs_realpath(NULL, &req, "no_such_file", NULL));
|
||||
ASSERT(req.ptr == NULL);
|
||||
ASSERT_NULL(req.ptr);
|
||||
ASSERT(req.result == UV_ENOENT);
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
@ -2843,7 +2844,7 @@ TEST_IMPL(fs_scandir_empty_dir) {
|
||||
r = uv_fs_scandir(NULL, &req, path, 0, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(req.result == 0);
|
||||
ASSERT(req.ptr == NULL);
|
||||
ASSERT_NULL(req.ptr);
|
||||
ASSERT(UV_EOF == uv_fs_scandir_next(&req, &dent));
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
@ -2880,7 +2881,7 @@ TEST_IMPL(fs_scandir_non_existent_dir) {
|
||||
r = uv_fs_scandir(NULL, &req, path, 0, NULL);
|
||||
ASSERT(r == UV_ENOENT);
|
||||
ASSERT(req.result == UV_ENOENT);
|
||||
ASSERT(req.ptr == NULL);
|
||||
ASSERT_NULL(req.ptr);
|
||||
ASSERT(UV_ENOENT == uv_fs_scandir_next(&req, &dent));
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
@ -2932,7 +2933,7 @@ TEST_IMPL(fs_open_dir) {
|
||||
r = uv_fs_open(NULL, &req, path, O_RDONLY, 0, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(req.result >= 0);
|
||||
ASSERT(req.ptr == NULL);
|
||||
ASSERT_NULL(req.ptr);
|
||||
file = r;
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
@ -3332,7 +3333,7 @@ static void fs_write_alotof_bufs(int add_flags) {
|
||||
loop = uv_default_loop();
|
||||
|
||||
iovs = malloc(sizeof(*iovs) * iovcount);
|
||||
ASSERT(iovs != NULL);
|
||||
ASSERT_NOT_NULL(iovs);
|
||||
iovmax = uv_test_getiovmax();
|
||||
|
||||
r = uv_fs_open(NULL,
|
||||
@ -3361,7 +3362,7 @@ static void fs_write_alotof_bufs(int add_flags) {
|
||||
|
||||
/* Read the strings back to separate buffers. */
|
||||
buffer = malloc(sizeof(test_buf) * iovcount);
|
||||
ASSERT(buffer != NULL);
|
||||
ASSERT_NOT_NULL(buffer);
|
||||
|
||||
for (index = 0; index < iovcount; ++index)
|
||||
iovs[index] = uv_buf_init(buffer + index * sizeof(test_buf),
|
||||
@ -3444,7 +3445,7 @@ static void fs_write_alotof_bufs_with_offset(int add_flags) {
|
||||
loop = uv_default_loop();
|
||||
|
||||
iovs = malloc(sizeof(*iovs) * iovcount);
|
||||
ASSERT(iovs != NULL);
|
||||
ASSERT_NOT_NULL(iovs);
|
||||
iovmax = uv_test_getiovmax();
|
||||
|
||||
r = uv_fs_open(NULL,
|
||||
@ -3480,7 +3481,7 @@ static void fs_write_alotof_bufs_with_offset(int add_flags) {
|
||||
|
||||
/* Read the strings back to separate buffers. */
|
||||
buffer = malloc(sizeof(test_buf) * iovcount);
|
||||
ASSERT(buffer != NULL);
|
||||
ASSERT_NOT_NULL(buffer);
|
||||
|
||||
for (index = 0; index < iovcount; ++index)
|
||||
iovs[index] = uv_buf_init(buffer + index * sizeof(test_buf),
|
||||
@ -3676,16 +3677,16 @@ static void test_fs_partial(int doread) {
|
||||
iovcount = 54321;
|
||||
|
||||
iovs = malloc(sizeof(*iovs) * iovcount);
|
||||
ASSERT(iovs != NULL);
|
||||
ASSERT_NOT_NULL(iovs);
|
||||
|
||||
ctx.pid = pthread_self();
|
||||
ctx.doread = doread;
|
||||
ctx.interval = 1000;
|
||||
ctx.size = sizeof(test_buf) * iovcount;
|
||||
ctx.data = malloc(ctx.size);
|
||||
ASSERT(ctx.data != NULL);
|
||||
ASSERT_NOT_NULL(ctx.data);
|
||||
buffer = malloc(ctx.size);
|
||||
ASSERT(buffer != NULL);
|
||||
ASSERT_NOT_NULL(buffer);
|
||||
|
||||
for (index = 0; index < iovcount; ++index)
|
||||
iovs[index] = uv_buf_init(buffer + index * sizeof(test_buf), sizeof(test_buf));
|
||||
@ -3773,15 +3774,15 @@ TEST_IMPL(fs_read_write_null_arguments) {
|
||||
/* Validate some memory management on failed input validation before sending
|
||||
fs work to the thread pool. */
|
||||
ASSERT(r == UV_EINVAL);
|
||||
ASSERT(write_req.path == NULL);
|
||||
ASSERT(write_req.ptr == NULL);
|
||||
ASSERT_NULL(write_req.path);
|
||||
ASSERT_NULL(write_req.ptr);
|
||||
#ifdef _WIN32
|
||||
ASSERT(write_req.file.pathw == NULL);
|
||||
ASSERT(write_req.fs.info.new_pathw == NULL);
|
||||
ASSERT(write_req.fs.info.bufs == NULL);
|
||||
ASSERT_NULL(write_req.file.pathw);
|
||||
ASSERT_NULL(write_req.fs.info.new_pathw);
|
||||
ASSERT_NULL(write_req.fs.info.bufs);
|
||||
#else
|
||||
ASSERT(write_req.new_path == NULL);
|
||||
ASSERT(write_req.bufs == NULL);
|
||||
ASSERT_NULL(write_req.new_path);
|
||||
ASSERT_NULL(write_req.bufs);
|
||||
#endif
|
||||
uv_fs_req_cleanup(&write_req);
|
||||
|
||||
|
2
deps/uv/test/test-get-currentexe.c
vendored
2
deps/uv/test/test-get-currentexe.c
vendored
@ -49,7 +49,7 @@ TEST_IMPL(get_currentexe) {
|
||||
#ifdef _WIN32
|
||||
snprintf(path, sizeof(path), "%s", executable_path);
|
||||
#else
|
||||
ASSERT(NULL != realpath(executable_path, path));
|
||||
ASSERT_NOT_NULL(realpath(executable_path, path));
|
||||
#endif
|
||||
|
||||
match = strstr(buffer, path);
|
||||
|
14
deps/uv/test/test-get-passwd.c
vendored
14
deps/uv/test/test-get-passwd.c
vendored
@ -40,7 +40,7 @@ TEST_IMPL(get_passwd) {
|
||||
ASSERT(len > 0);
|
||||
|
||||
#ifdef _WIN32
|
||||
ASSERT(pwd.shell == NULL);
|
||||
ASSERT_NULL(pwd.shell);
|
||||
#else
|
||||
len = strlen(pwd.shell);
|
||||
# ifndef __PASE__
|
||||
@ -74,16 +74,16 @@ TEST_IMPL(get_passwd) {
|
||||
/* Test uv_os_free_passwd() */
|
||||
uv_os_free_passwd(&pwd);
|
||||
|
||||
ASSERT(pwd.username == NULL);
|
||||
ASSERT(pwd.shell == NULL);
|
||||
ASSERT(pwd.homedir == NULL);
|
||||
ASSERT_NULL(pwd.username);
|
||||
ASSERT_NULL(pwd.shell);
|
||||
ASSERT_NULL(pwd.homedir);
|
||||
|
||||
/* Test a double free */
|
||||
uv_os_free_passwd(&pwd);
|
||||
|
||||
ASSERT(pwd.username == NULL);
|
||||
ASSERT(pwd.shell == NULL);
|
||||
ASSERT(pwd.homedir == NULL);
|
||||
ASSERT_NULL(pwd.username);
|
||||
ASSERT_NULL(pwd.shell);
|
||||
ASSERT_NULL(pwd.homedir);
|
||||
|
||||
/* Test invalid input */
|
||||
r = uv_os_get_passwd(NULL);
|
||||
|
4
deps/uv/test/test-getaddrinfo.c
vendored
4
deps/uv/test/test-getaddrinfo.c
vendored
@ -42,7 +42,7 @@ static void getaddrinfo_fail_cb(uv_getaddrinfo_t* req,
|
||||
|
||||
ASSERT(fail_cb_called == 0);
|
||||
ASSERT(status < 0);
|
||||
ASSERT(res == NULL);
|
||||
ASSERT_NULL(res);
|
||||
uv_freeaddrinfo(res); /* Should not crash. */
|
||||
fail_cb_called++;
|
||||
}
|
||||
@ -191,7 +191,7 @@ TEST_IMPL(getaddrinfo_concurrent) {
|
||||
callback_counts[i] = 0;
|
||||
|
||||
data = (int*)malloc(sizeof(int));
|
||||
ASSERT(data != NULL);
|
||||
ASSERT_NOT_NULL(data);
|
||||
*data = i;
|
||||
getaddrinfo_handles[i].data = data;
|
||||
|
||||
|
6
deps/uv/test/test-getnameinfo.c
vendored
6
deps/uv/test/test-getnameinfo.c
vendored
@ -38,10 +38,10 @@ static void getnameinfo_req(uv_getnameinfo_t* handle,
|
||||
int status,
|
||||
const char* hostname,
|
||||
const char* service) {
|
||||
ASSERT(handle != NULL);
|
||||
ASSERT_NOT_NULL(handle);
|
||||
ASSERT(status == 0);
|
||||
ASSERT(hostname != NULL);
|
||||
ASSERT(service != NULL);
|
||||
ASSERT_NOT_NULL(hostname);
|
||||
ASSERT_NOT_NULL(service);
|
||||
}
|
||||
|
||||
|
||||
|
2
deps/uv/test/test-getsockname.c
vendored
2
deps/uv/test/test-getsockname.c
vendored
@ -116,7 +116,7 @@ static void on_connection(uv_stream_t* server, int status) {
|
||||
ASSERT(status == 0);
|
||||
|
||||
handle = malloc(sizeof(*handle));
|
||||
ASSERT(handle != NULL);
|
||||
ASSERT_NOT_NULL(handle);
|
||||
|
||||
r = uv_tcp_init(loop, handle);
|
||||
ASSERT(r == 0);
|
||||
|
14
deps/uv/test/test-getters-setters.c
vendored
14
deps/uv/test/test-getters-setters.c
vendored
@ -33,9 +33,9 @@ TEST_IMPL(handle_type_name) {
|
||||
ASSERT(strcmp(uv_handle_type_name(UV_NAMED_PIPE), "pipe") == 0);
|
||||
ASSERT(strcmp(uv_handle_type_name(UV_UDP), "udp") == 0);
|
||||
ASSERT(strcmp(uv_handle_type_name(UV_FILE), "file") == 0);
|
||||
ASSERT(uv_handle_type_name(UV_HANDLE_TYPE_MAX) == NULL);
|
||||
ASSERT(uv_handle_type_name(UV_HANDLE_TYPE_MAX + 1) == NULL);
|
||||
ASSERT(uv_handle_type_name(UV_UNKNOWN_HANDLE) == NULL);
|
||||
ASSERT_NULL(uv_handle_type_name(UV_HANDLE_TYPE_MAX));
|
||||
ASSERT_NULL(uv_handle_type_name(UV_HANDLE_TYPE_MAX + 1));
|
||||
ASSERT_NULL(uv_handle_type_name(UV_UNKNOWN_HANDLE));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -44,9 +44,9 @@ TEST_IMPL(req_type_name) {
|
||||
ASSERT(strcmp(uv_req_type_name(UV_REQ), "req") == 0);
|
||||
ASSERT(strcmp(uv_req_type_name(UV_UDP_SEND), "udp_send") == 0);
|
||||
ASSERT(strcmp(uv_req_type_name(UV_WORK), "work") == 0);
|
||||
ASSERT(uv_req_type_name(UV_REQ_TYPE_MAX) == NULL);
|
||||
ASSERT(uv_req_type_name(UV_REQ_TYPE_MAX + 1) == NULL);
|
||||
ASSERT(uv_req_type_name(UV_UNKNOWN_REQ) == NULL);
|
||||
ASSERT_NULL(uv_req_type_name(UV_REQ_TYPE_MAX));
|
||||
ASSERT_NULL(uv_req_type_name(UV_REQ_TYPE_MAX + 1));
|
||||
ASSERT_NULL(uv_req_type_name(UV_UNKNOWN_REQ));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ TEST_IMPL(getters_setters) {
|
||||
int r;
|
||||
|
||||
loop = malloc(uv_loop_size());
|
||||
ASSERT(loop != NULL);
|
||||
ASSERT_NOT_NULL(loop);
|
||||
r = uv_loop_init(loop);
|
||||
ASSERT(r == 0);
|
||||
|
||||
|
@ -66,7 +66,7 @@ static void do_write(uv_stream_t* handle) {
|
||||
int r;
|
||||
|
||||
write_info = malloc(sizeof *write_info);
|
||||
ASSERT(write_info != NULL);
|
||||
ASSERT_NOT_NULL(write_info);
|
||||
|
||||
for (i = 0; i < BUFFERS_PER_WRITE; i++) {
|
||||
memset(&write_info->buffers[i], BUFFER_CONTENT, BUFFER_SIZE);
|
||||
|
2
deps/uv/test/test-ipc.c
vendored
2
deps/uv/test/test-ipc.c
vendored
@ -203,7 +203,7 @@ static void on_read(uv_stream_t* handle,
|
||||
/* Make sure that the expected data is correctly multiplexed. */
|
||||
ASSERT_MEM_EQ("hello\n", buf->base, nread);
|
||||
|
||||
outbuf = uv_buf_init("world\n", 6);
|
||||
outbuf = uv_buf_init("foobar\n", 7);
|
||||
r = uv_write(&write_req, (uv_stream_t*)pipe, &outbuf, 1, NULL);
|
||||
ASSERT_EQ(r, 0);
|
||||
|
||||
|
15
deps/uv/test/test-list.h
vendored
15
deps/uv/test/test-list.h
vendored
@ -206,6 +206,7 @@ TEST_DECLARE (connection_fail_doesnt_auto_close)
|
||||
TEST_DECLARE (shutdown_close_tcp)
|
||||
TEST_DECLARE (shutdown_close_pipe)
|
||||
TEST_DECLARE (shutdown_eof)
|
||||
TEST_DECLARE (shutdown_simultaneous)
|
||||
TEST_DECLARE (shutdown_twice)
|
||||
TEST_DECLARE (callback_stack)
|
||||
TEST_DECLARE (env_vars)
|
||||
@ -504,6 +505,10 @@ TEST_DECLARE (handle_type_name)
|
||||
TEST_DECLARE (req_type_name)
|
||||
TEST_DECLARE (getters_setters)
|
||||
|
||||
TEST_DECLARE (not_writable_after_shutdown)
|
||||
TEST_DECLARE (not_readable_nor_writable_on_read_error)
|
||||
TEST_DECLARE (not_readable_on_eof)
|
||||
|
||||
#ifndef _WIN32
|
||||
TEST_DECLARE (fork_timer)
|
||||
TEST_DECLARE (fork_socketpair)
|
||||
@ -780,6 +785,9 @@ TASK_LIST_START
|
||||
TEST_ENTRY (shutdown_eof)
|
||||
TEST_HELPER (shutdown_eof, tcp4_echo_server)
|
||||
|
||||
TEST_ENTRY (shutdown_simultaneous)
|
||||
TEST_HELPER (shutdown_simultaneous, tcp4_echo_server)
|
||||
|
||||
TEST_ENTRY (shutdown_twice)
|
||||
TEST_HELPER (shutdown_twice, tcp4_echo_server)
|
||||
|
||||
@ -1129,6 +1137,13 @@ TASK_LIST_START
|
||||
TEST_ENTRY (idna_toascii)
|
||||
#endif
|
||||
|
||||
TEST_ENTRY (not_writable_after_shutdown)
|
||||
TEST_HELPER (not_writable_after_shutdown, tcp4_echo_server)
|
||||
TEST_ENTRY (not_readable_nor_writable_on_read_error)
|
||||
TEST_HELPER (not_readable_nor_writable_on_read_error, tcp4_echo_server)
|
||||
TEST_ENTRY (not_readable_on_eof)
|
||||
TEST_HELPER (not_readable_on_eof, tcp4_echo_server)
|
||||
|
||||
TEST_ENTRY (metrics_idle_time)
|
||||
TEST_ENTRY (metrics_idle_time_thread)
|
||||
TEST_ENTRY (metrics_idle_time_zero)
|
||||
|
4
deps/uv/test/test-loop-handles.c
vendored
4
deps/uv/test/test-loop-handles.c
vendored
@ -143,7 +143,7 @@ static void idle_1_cb(uv_idle_t* handle) {
|
||||
fprintf(stderr, "%s", "IDLE_1_CB\n");
|
||||
fflush(stderr);
|
||||
|
||||
ASSERT(handle != NULL);
|
||||
ASSERT_NOT_NULL(handle);
|
||||
ASSERT(idles_1_active > 0);
|
||||
|
||||
/* Init idle_2 and make it active */
|
||||
@ -170,7 +170,7 @@ static void idle_1_close_cb(uv_handle_t* handle) {
|
||||
fprintf(stderr, "%s", "IDLE_1_CLOSE_CB\n");
|
||||
fflush(stderr);
|
||||
|
||||
ASSERT(handle != NULL);
|
||||
ASSERT_NOT_NULL(handle);
|
||||
|
||||
idle_1_close_cb_called++;
|
||||
}
|
||||
|
6
deps/uv/test/test-multiple-listen.c
vendored
6
deps/uv/test/test-multiple-listen.c
vendored
@ -32,7 +32,7 @@ static uv_tcp_t client;
|
||||
|
||||
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
ASSERT(handle != NULL);
|
||||
ASSERT_NOT_NULL(handle);
|
||||
close_cb_called++;
|
||||
}
|
||||
|
||||
@ -65,7 +65,7 @@ static void start_server(void) {
|
||||
|
||||
|
||||
static void connect_cb(uv_connect_t* req, int status) {
|
||||
ASSERT(req != NULL);
|
||||
ASSERT_NOT_NULL(req);
|
||||
ASSERT(status == 0);
|
||||
free(req);
|
||||
uv_close((uv_handle_t*)&client, close_cb);
|
||||
@ -79,7 +79,7 @@ static void client_connect(void) {
|
||||
int r;
|
||||
|
||||
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
|
||||
ASSERT(connect_req != NULL);
|
||||
ASSERT_NOT_NULL(connect_req);
|
||||
|
||||
r = uv_tcp_init(uv_default_loop(), &client);
|
||||
ASSERT(r == 0);
|
||||
|
104
deps/uv/test/test-not-readable-nor-writable-on-read-error.c
vendored
Normal file
104
deps/uv/test/test-not-readable-nor-writable-on-read-error.c
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
/* Copyright the libuv project contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "task.h"
|
||||
|
||||
static uv_loop_t loop;
|
||||
static uv_tcp_t tcp_client;
|
||||
static uv_connect_t connect_req;
|
||||
static uv_write_t write_req;
|
||||
static char reset_me_cmd[] = {'Q', 'S', 'H'};
|
||||
|
||||
static int connect_cb_called;
|
||||
static int read_cb_called;
|
||||
static int write_cb_called;
|
||||
static int close_cb_called;
|
||||
|
||||
static void write_cb(uv_write_t* req, int status) {
|
||||
write_cb_called++;
|
||||
ASSERT(status == 0);
|
||||
}
|
||||
|
||||
static void alloc_cb(uv_handle_t* handle,
|
||||
size_t suggested_size,
|
||||
uv_buf_t* buf) {
|
||||
static char slab[64];
|
||||
buf->base = slab;
|
||||
buf->len = sizeof(slab);
|
||||
}
|
||||
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
close_cb_called++;
|
||||
}
|
||||
|
||||
static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) {
|
||||
read_cb_called++;
|
||||
|
||||
ASSERT((nread < 0) && (nread != UV_EOF));
|
||||
ASSERT(0 == uv_is_writable(handle));
|
||||
ASSERT(0 == uv_is_readable(handle));
|
||||
|
||||
uv_close((uv_handle_t*) handle, close_cb);
|
||||
}
|
||||
|
||||
static void connect_cb(uv_connect_t* req, int status) {
|
||||
int r;
|
||||
uv_buf_t reset_me;
|
||||
|
||||
connect_cb_called++;
|
||||
ASSERT(status == 0);
|
||||
|
||||
r = uv_read_start((uv_stream_t*) &tcp_client, alloc_cb, read_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
reset_me = uv_buf_init(reset_me_cmd, sizeof(reset_me_cmd));
|
||||
|
||||
r = uv_write(&write_req,
|
||||
(uv_stream_t*) &tcp_client,
|
||||
&reset_me,
|
||||
1,
|
||||
write_cb);
|
||||
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
TEST_IMPL(not_readable_nor_writable_on_read_error) {
|
||||
struct sockaddr_in sa;
|
||||
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &sa));
|
||||
ASSERT(0 == uv_loop_init(&loop));
|
||||
ASSERT(0 == uv_tcp_init(&loop, &tcp_client));
|
||||
|
||||
ASSERT(0 == uv_tcp_connect(&connect_req,
|
||||
&tcp_client,
|
||||
(const struct sockaddr*) &sa,
|
||||
connect_cb));
|
||||
|
||||
ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT));
|
||||
|
||||
ASSERT(connect_cb_called == 1);
|
||||
ASSERT(read_cb_called == 1);
|
||||
ASSERT(write_cb_called == 1);
|
||||
ASSERT(close_cb_called == 1);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
103
deps/uv/test/test-not-readable-on-eof.c
vendored
Normal file
103
deps/uv/test/test-not-readable-on-eof.c
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
/* Copyright the libuv project contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "task.h"
|
||||
|
||||
static uv_loop_t loop;
|
||||
static uv_tcp_t tcp_client;
|
||||
static uv_connect_t connect_req;
|
||||
static uv_write_t write_req;
|
||||
static char close_me_cmd[] = {'Q', 'S'};
|
||||
|
||||
static int connect_cb_called;
|
||||
static int read_cb_called;
|
||||
static int write_cb_called;
|
||||
static int close_cb_called;
|
||||
|
||||
static void write_cb(uv_write_t* req, int status) {
|
||||
write_cb_called++;
|
||||
ASSERT(status == 0);
|
||||
}
|
||||
|
||||
static void alloc_cb(uv_handle_t* handle,
|
||||
size_t suggested_size,
|
||||
uv_buf_t* buf) {
|
||||
static char slab[64];
|
||||
buf->base = slab;
|
||||
buf->len = sizeof(slab);
|
||||
}
|
||||
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
close_cb_called++;
|
||||
}
|
||||
|
||||
static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) {
|
||||
read_cb_called++;
|
||||
|
||||
ASSERT(nread == UV_EOF);
|
||||
ASSERT(0 == uv_is_readable(handle));
|
||||
|
||||
uv_close((uv_handle_t*) handle, close_cb);
|
||||
}
|
||||
|
||||
static void connect_cb(uv_connect_t* req, int status) {
|
||||
int r;
|
||||
uv_buf_t close_me;
|
||||
|
||||
connect_cb_called++;
|
||||
ASSERT(status == 0);
|
||||
|
||||
r = uv_read_start((uv_stream_t*) &tcp_client, alloc_cb, read_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
close_me = uv_buf_init(close_me_cmd, sizeof(close_me_cmd));
|
||||
|
||||
r = uv_write(&write_req,
|
||||
(uv_stream_t*) &tcp_client,
|
||||
&close_me,
|
||||
1,
|
||||
write_cb);
|
||||
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
TEST_IMPL(not_readable_on_eof) {
|
||||
struct sockaddr_in sa;
|
||||
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &sa));
|
||||
ASSERT(0 == uv_loop_init(&loop));
|
||||
ASSERT(0 == uv_tcp_init(&loop, &tcp_client));
|
||||
|
||||
ASSERT(0 == uv_tcp_connect(&connect_req,
|
||||
&tcp_client,
|
||||
(const struct sockaddr*) &sa,
|
||||
connect_cb));
|
||||
|
||||
ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT));
|
||||
|
||||
ASSERT(connect_cb_called == 1);
|
||||
ASSERT(read_cb_called == 1);
|
||||
ASSERT(write_cb_called == 1);
|
||||
ASSERT(close_cb_called == 1);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user