deps: update uv to v1.0.0-rc1
6
deps/uv/.gitignore
vendored
@ -61,3 +61,9 @@ UpgradeLog*.XML
|
|||||||
Debug
|
Debug
|
||||||
Release
|
Release
|
||||||
ipch
|
ipch
|
||||||
|
|
||||||
|
# sphinx generated files
|
||||||
|
/docs/build/
|
||||||
|
|
||||||
|
*.xcodeproj
|
||||||
|
*.xcworkspace
|
||||||
|
2
deps/uv/.mailmap
vendored
@ -14,11 +14,13 @@ Isaac Z. Schlueter <i@izs.me>
|
|||||||
Justin Venus <justin.venus@gmail.com> <justin.venus@orbitz.com>
|
Justin Venus <justin.venus@gmail.com> <justin.venus@orbitz.com>
|
||||||
Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu>
|
Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu>
|
||||||
Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu>
|
Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu>
|
||||||
|
Leonard Hecker <leonard.hecker91@gmail.com> <leonard@hecker.io>
|
||||||
Maciej Małecki <maciej.malecki@notimplemented.org> <me@mmalecki.com>
|
Maciej Małecki <maciej.malecki@notimplemented.org> <me@mmalecki.com>
|
||||||
Marc Schlaich <marc.schlaich@googlemail.com> <marc.schlaich@gmail.com>
|
Marc Schlaich <marc.schlaich@googlemail.com> <marc.schlaich@gmail.com>
|
||||||
Rasmus Christian Pedersen <ruysch@outlook.com>
|
Rasmus Christian Pedersen <ruysch@outlook.com>
|
||||||
Rasmus Christian Pedersen <ruysch@outlook.com>
|
Rasmus Christian Pedersen <ruysch@outlook.com>
|
||||||
Rasmus Christian Pedersen <ruysch@outlook.com>
|
Rasmus Christian Pedersen <ruysch@outlook.com>
|
||||||
|
Rasmus Christian Pedersen <ruysch@outlook.com>
|
||||||
Rasmus Christian Pedersen <zerhacken@yahoo.com> <ruysch@outlook.com>
|
Rasmus Christian Pedersen <zerhacken@yahoo.com> <ruysch@outlook.com>
|
||||||
Rasmus Pedersen <ruysch@outlook.com> <zerhacken@yahoo.com>
|
Rasmus Pedersen <ruysch@outlook.com> <zerhacken@yahoo.com>
|
||||||
Robert Mustacchi <rm@joyent.com> <rm@fingolfin.org>
|
Robert Mustacchi <rm@joyent.com> <rm@fingolfin.org>
|
||||||
|
2
deps/uv/AUTHORS
vendored
@ -155,3 +155,5 @@ Pavel Platto <hinidu@gmail.com>
|
|||||||
Tony Kelman <tony@kelman.net>
|
Tony Kelman <tony@kelman.net>
|
||||||
John Firebaugh <john.firebaugh@gmail.com>
|
John Firebaugh <john.firebaugh@gmail.com>
|
||||||
lilohuang <lilohuang@hotmail.com>
|
lilohuang <lilohuang@hotmail.com>
|
||||||
|
Paul Goldsmith <paul.goldsmith@aplink.net>
|
||||||
|
Julien Gilli <julien.gilli@joyent.com>
|
||||||
|
99
deps/uv/ChangeLog
vendored
@ -1,4 +1,101 @@
|
|||||||
2014.08.08, Version 0.11.28 (Unstable)
|
2014.09.18, Version 1.0.0-rc1 (Unstable), 0c28bbf7b42882853d1799ab96ff68b07f7f8d49
|
||||||
|
|
||||||
|
* windows: improve timer precision (Alexis Campailla)
|
||||||
|
|
||||||
|
* build, gyp: set xcode flags (Recep ASLANTAS)
|
||||||
|
|
||||||
|
* ignore: include m4 files which are created manually (Recep ASLANTAS)
|
||||||
|
|
||||||
|
* build: add m4 for feature/flag-testing (Recep ASLANTAS)
|
||||||
|
|
||||||
|
* ignore: ignore Xcode project and workspace files (Recep ASLANTAS)
|
||||||
|
|
||||||
|
* unix: fix warnings about dollar symbol usage in identifiers (Recep ASLANTAS)
|
||||||
|
|
||||||
|
* unix: fix warnings when loading functions with dlsym (Recep ASLANTAS)
|
||||||
|
|
||||||
|
* linux: try epoll_pwait if epoll_wait is missing (Michael Hudson-Doyle)
|
||||||
|
|
||||||
|
* test: add test for closing and recreating default loop (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* windows: properly close the default loop (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* version: add ability to specify a version suffix (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* doc: add API documentation (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* test: don't close connection on write error (Trevor Norris)
|
||||||
|
|
||||||
|
* windows: further simplify the code for timers (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* gyp: remove UNLIMITED_SELECT from dependent define (Fedor Indutny)
|
||||||
|
|
||||||
|
* darwin: allocate enough space for select() hack (Fedor Indutny)
|
||||||
|
|
||||||
|
* unix, windows: don't allow a NULL callback on timers (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* windows: simplify code in uv_timer_again (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* test: use less requests on tcp-write-queue-order (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* unix: stop child process watcher after last one exits (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* unix: simplify how process handle queue is managed (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* windows: remove duplicated field (mattn)
|
||||||
|
|
||||||
|
* core: add a reserved field to uv_handle_t and uv_req_t (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* windows: fix buffer leak after failed udp send (Bert Belder)
|
||||||
|
|
||||||
|
* windows: make sure sockets and handles are reset on close (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* unix, windows: add uv_fileno (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* build: use same CFLAGS in autotools build as in gyp (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* build: remove unneeded define in uv.gyp (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* test: fix watcher_cross_stop on Windows (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* unix, windows: move includes for EAI constants (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* unix: fix exposing EAI_* glibc-isms (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* unix: fix tcp write after bad connect freezing (Andrius Bentkus)
|
||||||
|
|
||||||
|
|
||||||
|
2014.08.20, Version 0.11.29 (Unstable), 35451fed830807095bbae8ef981af004a4b9259e
|
||||||
|
|
||||||
|
Changes since version 0.11.28:
|
||||||
|
|
||||||
|
* windows: make uv_read_stop immediately stop reading (Jameson Nash)
|
||||||
|
|
||||||
|
* windows: fix uv__getaddrinfo_translate_error (Alexis Campailla)
|
||||||
|
|
||||||
|
* netbsd: fix build (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* unix, windows: add uv_recv_buffer_size and uv_send_buffer_size (Andrius
|
||||||
|
Bentkus)
|
||||||
|
|
||||||
|
* windows: add support for UNC paths on uv_spawn (Paul Goldsmith)
|
||||||
|
|
||||||
|
* windows: replace use of inet_addr with uv_inet_pton (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* unix: replace some asserts with returning errors (Andrius Bentkus)
|
||||||
|
|
||||||
|
* windows: use OpenBSD implementation for uv_fs_mkdtemp (Pavel Platto)
|
||||||
|
|
||||||
|
* windows: fix GetNameInfoW error handling (Alexis Campailla)
|
||||||
|
|
||||||
|
* fs: introduce uv_readdir_next() and report types (Fedor Indutny)
|
||||||
|
|
||||||
|
* fs: extend reported types in uv_fs_readdir_next (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* unix: read on stream even when UV__POLLHUP set. (Julien Gilli)
|
||||||
|
|
||||||
|
|
||||||
|
2014.08.08, Version 0.11.28 (Unstable), fc9e2a0bc487b299c0cd3b2c9a23aeb554b5d8d1
|
||||||
|
|
||||||
Changes since version 0.11.27:
|
Changes since version 0.11.27:
|
||||||
|
|
||||||
|
10
deps/uv/Makefile.am
vendored
@ -23,7 +23,7 @@ CLEANFILES =
|
|||||||
|
|
||||||
lib_LTLIBRARIES = libuv.la
|
lib_LTLIBRARIES = libuv.la
|
||||||
libuv_la_CFLAGS = @CFLAGS@
|
libuv_la_CFLAGS = @CFLAGS@
|
||||||
libuv_la_LDFLAGS = -no-undefined -version-info 11:0:0
|
libuv_la_LDFLAGS = -no-undefined -version-info 1:0:0
|
||||||
libuv_la_SOURCES = src/fs-poll.c \
|
libuv_la_SOURCES = src/fs-poll.c \
|
||||||
src/heap-inl.h \
|
src/heap-inl.h \
|
||||||
src/inet.c \
|
src/inet.c \
|
||||||
@ -81,6 +81,7 @@ else # WINNT
|
|||||||
|
|
||||||
include_HEADERS += include/uv-unix.h
|
include_HEADERS += include/uv-unix.h
|
||||||
AM_CPPFLAGS += -I$(top_srcdir)/src/unix
|
AM_CPPFLAGS += -I$(top_srcdir)/src/unix
|
||||||
|
libuv_la_CFLAGS += -g --std=gnu89 -pedantic -Wall -Wextra -Wno-unused-parameter
|
||||||
libuv_la_SOURCES += src/unix/async.c \
|
libuv_la_SOURCES += src/unix/async.c \
|
||||||
src/unix/atomic-ops.h \
|
src/unix/atomic-ops.h \
|
||||||
src/unix/core.c \
|
src/unix/core.c \
|
||||||
@ -126,6 +127,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
|||||||
test/test-condvar.c \
|
test/test-condvar.c \
|
||||||
test/test-connection-fail.c \
|
test/test-connection-fail.c \
|
||||||
test/test-cwd-and-chdir.c \
|
test/test-cwd-and-chdir.c \
|
||||||
|
test/test-default-loop-close.c \
|
||||||
test/test-delayed-accept.c \
|
test/test-delayed-accept.c \
|
||||||
test/test-dlerror.c \
|
test/test-dlerror.c \
|
||||||
test/test-embed.c \
|
test/test-embed.c \
|
||||||
@ -141,6 +143,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
|||||||
test/test-getaddrinfo.c \
|
test/test-getaddrinfo.c \
|
||||||
test/test-getnameinfo.c \
|
test/test-getnameinfo.c \
|
||||||
test/test-getsockname.c \
|
test/test-getsockname.c \
|
||||||
|
test/test-handle-fileno.c \
|
||||||
test/test-hrtime.c \
|
test/test-hrtime.c \
|
||||||
test/test-idle.c \
|
test/test-idle.c \
|
||||||
test/test-ip4-addr.c \
|
test/test-ip4-addr.c \
|
||||||
@ -163,6 +166,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
|||||||
test/test-pipe-getsockname.c \
|
test/test-pipe-getsockname.c \
|
||||||
test/test-pipe-sendmsg.c \
|
test/test-pipe-sendmsg.c \
|
||||||
test/test-pipe-server-close.c \
|
test/test-pipe-server-close.c \
|
||||||
|
test/test-pipe-close-stdout-read-stdin.c \
|
||||||
test/test-platform-output.c \
|
test/test-platform-output.c \
|
||||||
test/test-poll-close.c \
|
test/test-poll-close.c \
|
||||||
test/test-poll-closesocket.c \
|
test/test-poll-closesocket.c \
|
||||||
@ -177,6 +181,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
|||||||
test/test-shutdown-twice.c \
|
test/test-shutdown-twice.c \
|
||||||
test/test-signal-multiple-loops.c \
|
test/test-signal-multiple-loops.c \
|
||||||
test/test-signal.c \
|
test/test-signal.c \
|
||||||
|
test/test-socket-buffer-size.c \
|
||||||
test/test-spawn.c \
|
test/test-spawn.c \
|
||||||
test/test-stdio-over-pipes.c \
|
test/test-stdio-over-pipes.c \
|
||||||
test/test-tcp-bind-error.c \
|
test/test-tcp-bind-error.c \
|
||||||
@ -194,6 +199,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
|||||||
test/test-tcp-shutdown-after-write.c \
|
test/test-tcp-shutdown-after-write.c \
|
||||||
test/test-tcp-unexpected-read.c \
|
test/test-tcp-unexpected-read.c \
|
||||||
test/test-tcp-write-to-half-open-connection.c \
|
test/test-tcp-write-to-half-open-connection.c \
|
||||||
|
test/test-tcp-write-after-connect.c \
|
||||||
test/test-tcp-writealot.c \
|
test/test-tcp-writealot.c \
|
||||||
test/test-tcp-try-write.c \
|
test/test-tcp-try-write.c \
|
||||||
test/test-tcp-write-queue-order.c \
|
test/test-tcp-write-queue-order.c \
|
||||||
@ -216,6 +222,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
|||||||
test/test-udp-options.c \
|
test/test-udp-options.c \
|
||||||
test/test-udp-send-and-recv.c \
|
test/test-udp-send-and-recv.c \
|
||||||
test/test-udp-send-immediate.c \
|
test/test-udp-send-immediate.c \
|
||||||
|
test/test-udp-send-unreachable.c \
|
||||||
test/test-udp-try-send.c \
|
test/test-udp-try-send.c \
|
||||||
test/test-walk-handles.c \
|
test/test-walk-handles.c \
|
||||||
test/test-watcher-cross-stop.c
|
test/test-watcher-cross-stop.c
|
||||||
@ -253,6 +260,7 @@ endif
|
|||||||
if DARWIN
|
if DARWIN
|
||||||
include_HEADERS += include/uv-darwin.h
|
include_HEADERS += include/uv-darwin.h
|
||||||
libuv_la_CFLAGS += -D_DARWIN_USE_64_BIT_INODE=1
|
libuv_la_CFLAGS += -D_DARWIN_USE_64_BIT_INODE=1
|
||||||
|
libuv_la_CFLAGS += -D_DARWIN_UNLIMITED_SELECT=1
|
||||||
libuv_la_SOURCES += src/unix/darwin.c \
|
libuv_la_SOURCES += src/unix/darwin.c \
|
||||||
src/unix/darwin-proctitle.c \
|
src/unix/darwin-proctitle.c \
|
||||||
src/unix/fsevents.c \
|
src/unix/fsevents.c \
|
||||||
|
35
deps/uv/README.md
vendored
@ -34,6 +34,11 @@ used by Mozilla's [Rust language](http://www.rust-lang.org/),
|
|||||||
|
|
||||||
* Threading and synchronization primitives
|
* Threading and synchronization primitives
|
||||||
|
|
||||||
|
## Versioning
|
||||||
|
|
||||||
|
Starting with version 1.0.0 libuv follows the [semantic versioning](http://semver.org/)
|
||||||
|
scheme. The API change and backwards compatiblity rules are those indicated by
|
||||||
|
SemVer. libuv will keep a stable ABI across major releases.
|
||||||
|
|
||||||
## Community
|
## Community
|
||||||
|
|
||||||
@ -41,8 +46,34 @@ used by Mozilla's [Rust language](http://www.rust-lang.org/),
|
|||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
* [include/uv.h](https://github.com/joyent/libuv/blob/master/include/uv.h)
|
### Official API documentation
|
||||||
— API documentation in the form of detailed header comments.
|
|
||||||
|
Located in the docs/ subdirectory. It uses the [Sphinx](http://sphinx-doc.org/)
|
||||||
|
framework, which makes it possible to build the documentation in multiple
|
||||||
|
formats.
|
||||||
|
|
||||||
|
Show different supported building options:
|
||||||
|
|
||||||
|
$ make help
|
||||||
|
|
||||||
|
Build documentation as HTML:
|
||||||
|
|
||||||
|
$ make html
|
||||||
|
|
||||||
|
Build documentation as man pages:
|
||||||
|
|
||||||
|
$ make man
|
||||||
|
|
||||||
|
Build documentation as ePub:
|
||||||
|
|
||||||
|
$ make epub
|
||||||
|
|
||||||
|
NOTE: Windows users need to use make.bat instead of plain 'make'.
|
||||||
|
|
||||||
|
Documentation can be browsed online [here](http://docs.libuv.org).
|
||||||
|
|
||||||
|
### Other resources
|
||||||
|
|
||||||
* [An Introduction to libuv](http://nikhilm.github.com/uvbook/)
|
* [An Introduction to libuv](http://nikhilm.github.com/uvbook/)
|
||||||
— An overview of libuv with tutorials.
|
— An overview of libuv with tutorials.
|
||||||
* [LXJS 2012 talk](http://www.youtube.com/watch?v=nGn60vDSxQ4)
|
* [LXJS 2012 talk](http://www.youtube.com/watch?v=nGn60vDSxQ4)
|
||||||
|
4
deps/uv/configure.ac
vendored
@ -13,16 +13,18 @@
|
|||||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
AC_PREREQ(2.57)
|
AC_PREREQ(2.57)
|
||||||
AC_INIT([libuv], [0.11.28], [https://github.com/joyent/libuv/issues])
|
AC_INIT([libuv], [1.0.0], [https://github.com/joyent/libuv/issues])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
m4_include([m4/libuv-extra-automake-flags.m4])
|
m4_include([m4/libuv-extra-automake-flags.m4])
|
||||||
m4_include([m4/as_case.m4])
|
m4_include([m4/as_case.m4])
|
||||||
|
m4_include([m4/libuv-check-flags.m4])
|
||||||
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects] UV_EXTRA_AUTOMAKE_FLAGS)
|
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects] UV_EXTRA_AUTOMAKE_FLAGS)
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
AC_ENABLE_SHARED
|
AC_ENABLE_SHARED
|
||||||
AC_ENABLE_STATIC
|
AC_ENABLE_STATIC
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
AM_PROG_CC_C_O
|
AM_PROG_CC_C_O
|
||||||
|
CC_CHECK_CFLAGS_APPEND([-Wno-dollar-in-identifier-extension])
|
||||||
# AM_PROG_AR is not available in automake v0.11 but it's essential in v0.12.
|
# AM_PROG_AR is not available in automake v0.11 but it's essential in v0.12.
|
||||||
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
|
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
|
||||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||||
|
243
deps/uv/docs/make.bat
vendored
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
@ECHO OFF
|
||||||
|
|
||||||
|
REM Command file for Sphinx documentation
|
||||||
|
|
||||||
|
if "%SPHINXBUILD%" == "" (
|
||||||
|
set SPHINXBUILD=sphinx-build
|
||||||
|
)
|
||||||
|
set BUILDDIR=build
|
||||||
|
set SRCDIR=src
|
||||||
|
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% %SRCDIR%
|
||||||
|
set I18NSPHINXOPTS=%SPHINXOPTS% %SRCDIR%
|
||||||
|
if NOT "%PAPER%" == "" (
|
||||||
|
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
|
||||||
|
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "" goto help
|
||||||
|
|
||||||
|
if "%1" == "help" (
|
||||||
|
:help
|
||||||
|
echo.Please use `make ^<target^>` where ^<target^> is one of
|
||||||
|
echo. html to make standalone HTML files
|
||||||
|
echo. dirhtml to make HTML files named index.html in directories
|
||||||
|
echo. singlehtml to make a single large HTML file
|
||||||
|
echo. pickle to make pickle files
|
||||||
|
echo. json to make JSON files
|
||||||
|
echo. htmlhelp to make HTML files and a HTML help project
|
||||||
|
echo. qthelp to make HTML files and a qthelp project
|
||||||
|
echo. devhelp to make HTML files and a Devhelp project
|
||||||
|
echo. epub to make an epub
|
||||||
|
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
||||||
|
echo. text to make text files
|
||||||
|
echo. man to make manual pages
|
||||||
|
echo. texinfo to make Texinfo files
|
||||||
|
echo. gettext to make PO message catalogs
|
||||||
|
echo. changes to make an overview over all changed/added/deprecated items
|
||||||
|
echo. xml to make Docutils-native XML files
|
||||||
|
echo. pseudoxml to make pseudoxml-XML files for display purposes
|
||||||
|
echo. linkcheck to check all external links for integrity
|
||||||
|
echo. doctest to run all doctests embedded in the documentation if enabled
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "clean" (
|
||||||
|
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
|
||||||
|
del /q /s %BUILDDIR%\*
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
%SPHINXBUILD% 2> nul
|
||||||
|
if errorlevel 9009 (
|
||||||
|
echo.
|
||||||
|
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||||
|
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||||
|
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||||
|
echo.may add the Sphinx directory to PATH.
|
||||||
|
echo.
|
||||||
|
echo.If you don't have Sphinx installed, grab it from
|
||||||
|
echo.http://sphinx-doc.org/
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "html" (
|
||||||
|
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
|
||||||
|
if errorlevel 1 exit /b 1
|
||||||
|
echo.
|
||||||
|
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "dirhtml" (
|
||||||
|
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
|
||||||
|
if errorlevel 1 exit /b 1
|
||||||
|
echo.
|
||||||
|
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "singlehtml" (
|
||||||
|
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
|
||||||
|
if errorlevel 1 exit /b 1
|
||||||
|
echo.
|
||||||
|
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "pickle" (
|
||||||
|
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
|
||||||
|
if errorlevel 1 exit /b 1
|
||||||
|
echo.
|
||||||
|
echo.Build finished; now you can process the pickle files.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "json" (
|
||||||
|
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
|
||||||
|
if errorlevel 1 exit /b 1
|
||||||
|
echo.
|
||||||
|
echo.Build finished; now you can process the JSON files.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "htmlhelp" (
|
||||||
|
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
|
||||||
|
if errorlevel 1 exit /b 1
|
||||||
|
echo.
|
||||||
|
echo.Build finished; now you can run HTML Help Workshop with the ^
|
||||||
|
.hhp project file in %BUILDDIR%/htmlhelp.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "qthelp" (
|
||||||
|
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
|
||||||
|
if errorlevel 1 exit /b 1
|
||||||
|
echo.
|
||||||
|
echo.Build finished; now you can run "qcollectiongenerator" with the ^
|
||||||
|
.qhcp project file in %BUILDDIR%/qthelp, like this:
|
||||||
|
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\libuv.qhcp
|
||||||
|
echo.To view the help file:
|
||||||
|
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\libuv.ghc
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "devhelp" (
|
||||||
|
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
|
||||||
|
if errorlevel 1 exit /b 1
|
||||||
|
echo.
|
||||||
|
echo.Build finished.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "epub" (
|
||||||
|
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
|
||||||
|
if errorlevel 1 exit /b 1
|
||||||
|
echo.
|
||||||
|
echo.Build finished. The epub file is in %BUILDDIR%/epub.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "latex" (
|
||||||
|
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||||
|
if errorlevel 1 exit /b 1
|
||||||
|
echo.
|
||||||
|
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "latexpdf" (
|
||||||
|
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||||
|
cd %BUILDDIR%/latex
|
||||||
|
make all-pdf
|
||||||
|
cd %BUILDDIR%/..
|
||||||
|
echo.
|
||||||
|
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "latexpdfja" (
|
||||||
|
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||||
|
cd %BUILDDIR%/latex
|
||||||
|
make all-pdf-ja
|
||||||
|
cd %BUILDDIR%/..
|
||||||
|
echo.
|
||||||
|
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "text" (
|
||||||
|
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
|
||||||
|
if errorlevel 1 exit /b 1
|
||||||
|
echo.
|
||||||
|
echo.Build finished. The text files are in %BUILDDIR%/text.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "man" (
|
||||||
|
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
|
||||||
|
if errorlevel 1 exit /b 1
|
||||||
|
echo.
|
||||||
|
echo.Build finished. The manual pages are in %BUILDDIR%/man.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "texinfo" (
|
||||||
|
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
|
||||||
|
if errorlevel 1 exit /b 1
|
||||||
|
echo.
|
||||||
|
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "gettext" (
|
||||||
|
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
|
||||||
|
if errorlevel 1 exit /b 1
|
||||||
|
echo.
|
||||||
|
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "changes" (
|
||||||
|
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
|
||||||
|
if errorlevel 1 exit /b 1
|
||||||
|
echo.
|
||||||
|
echo.The overview file is in %BUILDDIR%/changes.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "linkcheck" (
|
||||||
|
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
|
||||||
|
if errorlevel 1 exit /b 1
|
||||||
|
echo.
|
||||||
|
echo.Link check complete; look for any errors in the above output ^
|
||||||
|
or in %BUILDDIR%/linkcheck/output.txt.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "doctest" (
|
||||||
|
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
|
||||||
|
if errorlevel 1 exit /b 1
|
||||||
|
echo.
|
||||||
|
echo.Testing of doctests in the sources finished, look at the ^
|
||||||
|
results in %BUILDDIR%/doctest/output.txt.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "xml" (
|
||||||
|
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
|
||||||
|
if errorlevel 1 exit /b 1
|
||||||
|
echo.
|
||||||
|
echo.Build finished. The XML files are in %BUILDDIR%/xml.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "pseudoxml" (
|
||||||
|
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
|
||||||
|
if errorlevel 1 exit /b 1
|
||||||
|
echo.
|
||||||
|
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
:end
|
56
deps/uv/docs/src/async.rst
vendored
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
|
||||||
|
.. _async:
|
||||||
|
|
||||||
|
:c:type:`uv_async_t` --- Async handle
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Async handles allow the user to "wakeup" the event loop and get a callback
|
||||||
|
called from another thread.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_async_t
|
||||||
|
|
||||||
|
Async handle type.
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_async_cb)(uv_async_t* handle)
|
||||||
|
|
||||||
|
Type definition for callback passed to :c:func:`uv_async_init`.
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
N/A
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: int uv_async_init(uv_loop_t* loop, uv_async_t* async, uv_async_cb async_cb)
|
||||||
|
|
||||||
|
Initialize the handle. A NULL callback is allowed.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Unlike other handle initialization functions, it immediately starts the handle.
|
||||||
|
|
||||||
|
.. c:function:: int uv_async_send(uv_async_t* async)
|
||||||
|
|
||||||
|
Wakeup the event loop and call the async handle's callback.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
It's safe to call this function from any thread. The callback will be called on the
|
||||||
|
loop thread.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
libuv will coalesce calls to :c:func:`uv_async_send`, that is, not every call to it will
|
||||||
|
yield an execution of the callback, the only guarantee is that it will be called at least
|
||||||
|
once. Thus, calling this function may not wakeup the event loop if it was already called
|
||||||
|
previously within a short period of time.
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
The :c:type:`uv_handle_t` API functions also apply.
|
46
deps/uv/docs/src/check.rst
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
|
||||||
|
.. _check:
|
||||||
|
|
||||||
|
:c:type:`uv_check_t` --- Check handle
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Check handles will run the given callback once per loop iteration, right
|
||||||
|
after polling for i/o.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_check_t
|
||||||
|
|
||||||
|
Check handle type.
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_check_cb)(uv_check_t* handle)
|
||||||
|
|
||||||
|
Type definition for callback passed to :c:func:`uv_check_start`.
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
N/A
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: int uv_check_init(uv_loop_t*, uv_check_t* check)
|
||||||
|
|
||||||
|
Initialize the handle.
|
||||||
|
|
||||||
|
.. c:function:: int uv_check_start(uv_check_t* check, uv_check_cb cb)
|
||||||
|
|
||||||
|
Start the handle with the given callback.
|
||||||
|
|
||||||
|
.. c:function:: int uv_check_stop(uv_check_t* check)
|
||||||
|
|
||||||
|
Stop the handle, the callback will no longer be called.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
348
deps/uv/docs/src/conf.py
vendored
Normal file
@ -0,0 +1,348 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# libuv API documentation documentation build configuration file, created by
|
||||||
|
# sphinx-quickstart on Sun Jul 27 11:47:51 2014.
|
||||||
|
#
|
||||||
|
# This file is execfile()d with the current directory set to its
|
||||||
|
# containing dir.
|
||||||
|
#
|
||||||
|
# Note that not all possible configuration values are present in this
|
||||||
|
# autogenerated file.
|
||||||
|
#
|
||||||
|
# All configuration values have a default; values that are commented out
|
||||||
|
# serve to show the default.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def get_libuv_version():
|
||||||
|
with open('../../include/uv-version.h') as f:
|
||||||
|
data = f.read()
|
||||||
|
try:
|
||||||
|
m = re.search(r"""^#define UV_VERSION_MAJOR (\d)$""", data, re.MULTILINE)
|
||||||
|
major = int(m.group(1))
|
||||||
|
m = re.search(r"""^#define UV_VERSION_MINOR (\d)$""", data, re.MULTILINE)
|
||||||
|
minor = int(m.group(1))
|
||||||
|
m = re.search(r"""^#define UV_VERSION_PATCH (\d)$""", data, re.MULTILINE)
|
||||||
|
patch = int(m.group(1))
|
||||||
|
m = re.search(r"""^#define UV_VERSION_IS_RELEASE (\d)$""", data, re.MULTILINE)
|
||||||
|
is_release = int(m.group(1))
|
||||||
|
m = re.search(r"""^#define UV_VERSION_SUFFIX \"(\w*)\"$""", data, re.MULTILINE)
|
||||||
|
suffix = m.group(1)
|
||||||
|
return '%d.%d.%d%s' % (major, minor, patch, '-%s' % suffix if not is_release else '')
|
||||||
|
except Exception:
|
||||||
|
return 'unknown'
|
||||||
|
|
||||||
|
# If extensions (or modules to document with autodoc) are in another directory,
|
||||||
|
# add these directories to sys.path here. If the directory is relative to the
|
||||||
|
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||||
|
#sys.path.insert(0, os.path.abspath('.'))
|
||||||
|
|
||||||
|
# -- General configuration ------------------------------------------------
|
||||||
|
|
||||||
|
# If your documentation needs a minimal Sphinx version, state it here.
|
||||||
|
#needs_sphinx = '1.0'
|
||||||
|
|
||||||
|
# Add any Sphinx extension module names here, as strings. They can be
|
||||||
|
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||||
|
# ones.
|
||||||
|
extensions = []
|
||||||
|
|
||||||
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
|
templates_path = ['templates']
|
||||||
|
|
||||||
|
# The suffix of source filenames.
|
||||||
|
source_suffix = '.rst'
|
||||||
|
|
||||||
|
# The encoding of source files.
|
||||||
|
#source_encoding = 'utf-8-sig'
|
||||||
|
|
||||||
|
# The master toctree document.
|
||||||
|
master_doc = 'index'
|
||||||
|
|
||||||
|
# General information about the project.
|
||||||
|
project = u'libuv API documentation'
|
||||||
|
copyright = u'libuv contributors'
|
||||||
|
|
||||||
|
# The version info for the project you're documenting, acts as replacement for
|
||||||
|
# |version| and |release|, also used in various other places throughout the
|
||||||
|
# built documents.
|
||||||
|
#
|
||||||
|
# The short X.Y version.
|
||||||
|
version = get_libuv_version()
|
||||||
|
# The full version, including alpha/beta/rc tags.
|
||||||
|
release = version
|
||||||
|
|
||||||
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
|
# for a list of supported languages.
|
||||||
|
#language = None
|
||||||
|
|
||||||
|
# There are two options for replacing |today|: either, you set today to some
|
||||||
|
# non-false value, then it is used:
|
||||||
|
#today = ''
|
||||||
|
# Else, today_fmt is used as the format for a strftime call.
|
||||||
|
#today_fmt = '%B %d, %Y'
|
||||||
|
|
||||||
|
# List of patterns, relative to source directory, that match files and
|
||||||
|
# directories to ignore when looking for source files.
|
||||||
|
exclude_patterns = []
|
||||||
|
|
||||||
|
# The reST default role (used for this markup: `text`) to use for all
|
||||||
|
# documents.
|
||||||
|
#default_role = None
|
||||||
|
|
||||||
|
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||||
|
#add_function_parentheses = True
|
||||||
|
|
||||||
|
# If true, the current module name will be prepended to all description
|
||||||
|
# unit titles (such as .. function::).
|
||||||
|
#add_module_names = True
|
||||||
|
|
||||||
|
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||||
|
# output. They are ignored by default.
|
||||||
|
#show_authors = False
|
||||||
|
|
||||||
|
# The name of the Pygments (syntax highlighting) style to use.
|
||||||
|
pygments_style = 'sphinx'
|
||||||
|
|
||||||
|
# A list of ignored prefixes for module index sorting.
|
||||||
|
#modindex_common_prefix = []
|
||||||
|
|
||||||
|
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||||
|
#keep_warnings = False
|
||||||
|
|
||||||
|
|
||||||
|
# -- Options for HTML output ----------------------------------------------
|
||||||
|
|
||||||
|
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||||
|
# a list of builtin themes.
|
||||||
|
html_theme = 'nature'
|
||||||
|
|
||||||
|
# Theme options are theme-specific and customize the look and feel of a theme
|
||||||
|
# further. For a list of options available for each theme, see the
|
||||||
|
# documentation.
|
||||||
|
#html_theme_options = {}
|
||||||
|
|
||||||
|
# Add any paths that contain custom themes here, relative to this directory.
|
||||||
|
#html_theme_path = []
|
||||||
|
|
||||||
|
# The name for this set of Sphinx documents. If None, it defaults to
|
||||||
|
# "<project> v<release> documentation".
|
||||||
|
html_title = 'libuv API documentation'
|
||||||
|
|
||||||
|
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||||
|
html_short_title = 'libuv %s API documentation' % version
|
||||||
|
|
||||||
|
# The name of an image file (relative to this directory) to place at the top
|
||||||
|
# of the sidebar.
|
||||||
|
html_logo = 'static/logo.png'
|
||||||
|
|
||||||
|
# The name of an image file (within the static path) to use as favicon of the
|
||||||
|
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||||
|
# pixels large.
|
||||||
|
html_favicon = 'static/favicon.ico'
|
||||||
|
|
||||||
|
# Add any paths that contain custom static files (such as style sheets) here,
|
||||||
|
# relative to this directory. They are copied after the builtin static files,
|
||||||
|
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||||
|
html_static_path = ['static']
|
||||||
|
|
||||||
|
# Add any extra paths that contain custom files (such as robots.txt or
|
||||||
|
# .htaccess) here, relative to this directory. These files are copied
|
||||||
|
# directly to the root of the documentation.
|
||||||
|
#html_extra_path = []
|
||||||
|
|
||||||
|
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||||
|
# using the given strftime format.
|
||||||
|
#html_last_updated_fmt = '%b %d, %Y'
|
||||||
|
|
||||||
|
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||||
|
# typographically correct entities.
|
||||||
|
#html_use_smartypants = True
|
||||||
|
|
||||||
|
# Custom sidebar templates, maps document names to template names.
|
||||||
|
#html_sidebars = {}
|
||||||
|
|
||||||
|
# Additional templates that should be rendered to pages, maps page names to
|
||||||
|
# template names.
|
||||||
|
#html_additional_pages = {}
|
||||||
|
|
||||||
|
# If false, no module index is generated.
|
||||||
|
#html_domain_indices = True
|
||||||
|
|
||||||
|
# If false, no index is generated.
|
||||||
|
#html_use_index = True
|
||||||
|
|
||||||
|
# If true, the index is split into individual pages for each letter.
|
||||||
|
#html_split_index = False
|
||||||
|
|
||||||
|
# If true, links to the reST sources are added to the pages.
|
||||||
|
#html_show_sourcelink = True
|
||||||
|
|
||||||
|
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||||
|
#html_show_sphinx = True
|
||||||
|
|
||||||
|
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||||
|
#html_show_copyright = True
|
||||||
|
|
||||||
|
# If true, an OpenSearch description file will be output, and all pages will
|
||||||
|
# contain a <link> tag referring to it. The value of this option must be the
|
||||||
|
# base URL from which the finished HTML is served.
|
||||||
|
#html_use_opensearch = ''
|
||||||
|
|
||||||
|
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||||
|
#html_file_suffix = None
|
||||||
|
|
||||||
|
# Output file base name for HTML help builder.
|
||||||
|
htmlhelp_basename = 'libuv'
|
||||||
|
|
||||||
|
|
||||||
|
# -- Options for LaTeX output ---------------------------------------------
|
||||||
|
|
||||||
|
latex_elements = {
|
||||||
|
# The paper size ('letterpaper' or 'a4paper').
|
||||||
|
#'papersize': 'letterpaper',
|
||||||
|
|
||||||
|
# The font size ('10pt', '11pt' or '12pt').
|
||||||
|
#'pointsize': '10pt',
|
||||||
|
|
||||||
|
# Additional stuff for the LaTeX preamble.
|
||||||
|
#'preamble': '',
|
||||||
|
}
|
||||||
|
|
||||||
|
# Grouping the document tree into LaTeX files. List of tuples
|
||||||
|
# (source start file, target name, title,
|
||||||
|
# author, documentclass [howto, manual, or own class]).
|
||||||
|
latex_documents = [
|
||||||
|
('index', 'libuv.tex', u'libuv API documentation',
|
||||||
|
u'libuv contributors', 'manual'),
|
||||||
|
]
|
||||||
|
|
||||||
|
# The name of an image file (relative to this directory) to place at the top of
|
||||||
|
# the title page.
|
||||||
|
#latex_logo = None
|
||||||
|
|
||||||
|
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||||
|
# not chapters.
|
||||||
|
#latex_use_parts = False
|
||||||
|
|
||||||
|
# If true, show page references after internal links.
|
||||||
|
#latex_show_pagerefs = False
|
||||||
|
|
||||||
|
# If true, show URL addresses after external links.
|
||||||
|
#latex_show_urls = False
|
||||||
|
|
||||||
|
# Documents to append as an appendix to all manuals.
|
||||||
|
#latex_appendices = []
|
||||||
|
|
||||||
|
# If false, no module index is generated.
|
||||||
|
#latex_domain_indices = True
|
||||||
|
|
||||||
|
|
||||||
|
# -- Options for manual page output ---------------------------------------
|
||||||
|
|
||||||
|
# One entry per manual page. List of tuples
|
||||||
|
# (source start file, name, description, authors, manual section).
|
||||||
|
man_pages = [
|
||||||
|
('index', 'libuv', u'libuv API documentation',
|
||||||
|
[u'libuv contributors'], 1)
|
||||||
|
]
|
||||||
|
|
||||||
|
# If true, show URL addresses after external links.
|
||||||
|
#man_show_urls = False
|
||||||
|
|
||||||
|
|
||||||
|
# -- Options for Texinfo output -------------------------------------------
|
||||||
|
|
||||||
|
# Grouping the document tree into Texinfo files. List of tuples
|
||||||
|
# (source start file, target name, title, author,
|
||||||
|
# dir menu entry, description, category)
|
||||||
|
texinfo_documents = [
|
||||||
|
('index', 'libuv', u'libuv API documentation',
|
||||||
|
u'libuv contributors', 'libuv', 'Cross-platform asychronous I/O',
|
||||||
|
'Miscellaneous'),
|
||||||
|
]
|
||||||
|
|
||||||
|
# Documents to append as an appendix to all manuals.
|
||||||
|
#texinfo_appendices = []
|
||||||
|
|
||||||
|
# If false, no module index is generated.
|
||||||
|
#texinfo_domain_indices = True
|
||||||
|
|
||||||
|
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||||
|
#texinfo_show_urls = 'footnote'
|
||||||
|
|
||||||
|
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||||
|
#texinfo_no_detailmenu = False
|
||||||
|
|
||||||
|
|
||||||
|
# -- Options for Epub output ----------------------------------------------
|
||||||
|
|
||||||
|
# Bibliographic Dublin Core info.
|
||||||
|
epub_title = u'libuv API documentation'
|
||||||
|
epub_author = u'libuv contributors'
|
||||||
|
epub_publisher = u'libuv contributors'
|
||||||
|
epub_copyright = u'2014, libuv contributors'
|
||||||
|
|
||||||
|
# The basename for the epub file. It defaults to the project name.
|
||||||
|
epub_basename = u'libuv'
|
||||||
|
|
||||||
|
# The HTML theme for the epub output. Since the default themes are not optimized
|
||||||
|
# for small screen space, using the same theme for HTML and epub output is
|
||||||
|
# usually not wise. This defaults to 'epub', a theme designed to save visual
|
||||||
|
# space.
|
||||||
|
#epub_theme = 'epub'
|
||||||
|
|
||||||
|
# The language of the text. It defaults to the language option
|
||||||
|
# or en if the language is not set.
|
||||||
|
#epub_language = ''
|
||||||
|
|
||||||
|
# The scheme of the identifier. Typical schemes are ISBN or URL.
|
||||||
|
#epub_scheme = ''
|
||||||
|
|
||||||
|
# The unique identifier of the text. This can be a ISBN number
|
||||||
|
# or the project homepage.
|
||||||
|
#epub_identifier = ''
|
||||||
|
|
||||||
|
# A unique identification for the text.
|
||||||
|
#epub_uid = ''
|
||||||
|
|
||||||
|
# A tuple containing the cover image and cover page html template filenames.
|
||||||
|
#epub_cover = ()
|
||||||
|
|
||||||
|
# A sequence of (type, uri, title) tuples for the guide element of content.opf.
|
||||||
|
#epub_guide = ()
|
||||||
|
|
||||||
|
# HTML files that should be inserted before the pages created by sphinx.
|
||||||
|
# The format is a list of tuples containing the path and title.
|
||||||
|
#epub_pre_files = []
|
||||||
|
|
||||||
|
# HTML files shat should be inserted after the pages created by sphinx.
|
||||||
|
# The format is a list of tuples containing the path and title.
|
||||||
|
#epub_post_files = []
|
||||||
|
|
||||||
|
# A list of files that should not be packed into the epub file.
|
||||||
|
epub_exclude_files = ['search.html']
|
||||||
|
|
||||||
|
# The depth of the table of contents in toc.ncx.
|
||||||
|
#epub_tocdepth = 3
|
||||||
|
|
||||||
|
# Allow duplicate toc entries.
|
||||||
|
#epub_tocdup = True
|
||||||
|
|
||||||
|
# Choose between 'default' and 'includehidden'.
|
||||||
|
#epub_tocscope = 'default'
|
||||||
|
|
||||||
|
# Fix unsupported image types using the PIL.
|
||||||
|
#epub_fix_images = False
|
||||||
|
|
||||||
|
# Scale large images.
|
||||||
|
#epub_max_image_width = 0
|
||||||
|
|
||||||
|
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||||
|
#epub_show_urls = 'inline'
|
||||||
|
|
||||||
|
# If false, no index is generated.
|
||||||
|
#epub_use_index = True
|
137
deps/uv/docs/src/design.rst
vendored
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
|
||||||
|
.. _design:
|
||||||
|
|
||||||
|
Design overview
|
||||||
|
===============
|
||||||
|
|
||||||
|
libuv is cross-platform support library which was originally written for NodeJS. It's designed
|
||||||
|
around the event-driven asynchronous I/O model.
|
||||||
|
|
||||||
|
The library provides much more than simply abstraction over different I/O polling mechanisms:
|
||||||
|
'handles' and 'streams' provde a high level abstraction for sockets and other entities;
|
||||||
|
cross-platform file I/O and threading functionality is also provided, amongst other things.
|
||||||
|
|
||||||
|
Here is a diagram illustrating the different parts that compose libuv and what subsystem they
|
||||||
|
relate to:
|
||||||
|
|
||||||
|
.. image:: static/architecture.png
|
||||||
|
:scale: 75%
|
||||||
|
:align: center
|
||||||
|
|
||||||
|
|
||||||
|
Handles and requests
|
||||||
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
libuv provides users with 2 abstractions to work with, in combination with the event loop:
|
||||||
|
handles and requests.
|
||||||
|
|
||||||
|
Handles represent long-lived objects capable of performing certain operations while active. Some
|
||||||
|
examples: a prepare handle gets its callback called once every loop iteration when active, and
|
||||||
|
a TCP server handle get its connection callback called every time there is a new connection.
|
||||||
|
|
||||||
|
Requests represent (typically) short-lived operations. These operations can be performed over a
|
||||||
|
handle: write requests are used to write data on a handle; or standalone: getaddrinfo requests
|
||||||
|
don't need a handle they run directly on the loop.
|
||||||
|
|
||||||
|
|
||||||
|
The I/O loop
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
|
The I/O (or event) loop is the central part of libuv. It establishes the content for all I/O
|
||||||
|
operations, and it's meant to be tied to a single thread. One can run multiple event loops
|
||||||
|
as long as each runs in a different thread. The libuv event loop (or any other API involving
|
||||||
|
the loop or handles, for that matter) **is not thread-safe** except stated otherwise.
|
||||||
|
|
||||||
|
The event loop follows the rather usual single threaded asynchronous I/O approah: all (network)
|
||||||
|
I/O is performed on non-blocking sockets which are polled using the best mechanism available
|
||||||
|
on the given platform: epoll on Linux, kqueue on OSX and other BSDs, event ports on SunOS and IOCP
|
||||||
|
on Windows. As part of a loop iteration the loop will block waiting for I/O activity on sockets
|
||||||
|
which have been added to the poller and callbacks will be fired indicating socket conditions
|
||||||
|
(readable, writable hangup) so handles can read, write or perform the desired I/O operation.
|
||||||
|
|
||||||
|
In order to better understand how the event loop operates, the following diagram illustrates all
|
||||||
|
stages of a loop iteration:
|
||||||
|
|
||||||
|
.. image:: static/loop_iteration.png
|
||||||
|
:scale: 75%
|
||||||
|
:align: center
|
||||||
|
|
||||||
|
|
||||||
|
#. The loop concept of 'now' is updated. The event loop caches the current time at the start of
|
||||||
|
the event loop tick in order to reduce the number of time-related system calls.
|
||||||
|
|
||||||
|
#. If the loop is *alive* an iteration is started, otherwise the loop will exit immediately. So,
|
||||||
|
when is a loop considered to be *alive*? If a loop has active and ref'd handles, active
|
||||||
|
requests or closing handles it's considered to be *alive*.
|
||||||
|
|
||||||
|
#. Due timers are run. All active timers scheduled for a time before the loop's concept of *now*
|
||||||
|
get their callbacks called.
|
||||||
|
|
||||||
|
#. Pending callbacks are called. All I/O callbacks are called right after polling for I/O, for the
|
||||||
|
most part. There are cases, however, in which calling such a callback is deferred for the next
|
||||||
|
loop iteration. If the previous iteration deferred any I/O callback it will be run at this point.
|
||||||
|
|
||||||
|
#. Idle handle callbacks are called. Despite the unfortunate name, idle handles are run on every
|
||||||
|
loop iteration, if they are active.
|
||||||
|
|
||||||
|
#. Prepare handle callbacks are called. Prepare handles get their callbacks called right before
|
||||||
|
the loop will block for I/O.
|
||||||
|
|
||||||
|
#. Poll timeout is calculated. Before blocking for I/O the loop calculates for how long it should
|
||||||
|
block. These are the rules when calculating the timeout:
|
||||||
|
|
||||||
|
* If the loop was run with the ``UV_RUN_NOWAIT`` flag, the timeout is 0.
|
||||||
|
* If the loop is going to be stopped (:c:func:`uv_stop` was called), the timeout is 0.
|
||||||
|
* If there are no active handles or requests, the timeout is 0.
|
||||||
|
* If there are any idle handles active, the timeout is 0.
|
||||||
|
* If there are any handles pending to be closed, the timeout is 0.
|
||||||
|
* If none of the above cases was matched, the timeout of the closest timer is taken, or
|
||||||
|
if there are no active timers, infinity.
|
||||||
|
|
||||||
|
#. The loop blocks for I/O. At this point the loop will block for I/O for the timeout calculated
|
||||||
|
on the previous step. All I/O related handles that were monitoring a given file descriptor
|
||||||
|
for a read or write operation get their callbacks called at this point.
|
||||||
|
|
||||||
|
#. Check handle callbacks are called. Check handles get their callbacks called right after the
|
||||||
|
loop has blocked for I/O. Check handles are essentially the counterpart of prepare handles.
|
||||||
|
|
||||||
|
#. Close callbacks are called. If a handle was closed by calling :c:func:`uv_close` it will
|
||||||
|
get the close callback called.
|
||||||
|
|
||||||
|
#. Special case in case the loop was run with ``UV_RUN_ONCE``, as it implies forward progress.
|
||||||
|
It's possible that no I/O callbacks were fired after blocking for I/O, but some time has passed
|
||||||
|
so there might be timers which are due, those timers get their callbacks called.
|
||||||
|
|
||||||
|
#. Iteration ends. If the loop was run with ``UV_RUN_NOWAIT`` or ``UV_RUN_ONCE`` modes the
|
||||||
|
iteration is ended and :c:func:`uv_run` will return. If the loop was run with ``UV_RUN_DEFAULT``
|
||||||
|
it will contionue from the start if it's asill *alive*, otherwise it will also end.
|
||||||
|
|
||||||
|
|
||||||
|
.. important::
|
||||||
|
libuv uses a thread pool to make asynchronous file I/O operations possible, but
|
||||||
|
network I/O is **always** performed in a single thread, each loop's thread.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
While the polling mechanism is different, libuv makes the execution model consistent
|
||||||
|
Unix systems and Windows.
|
||||||
|
|
||||||
|
|
||||||
|
File I/O
|
||||||
|
^^^^^^^^
|
||||||
|
|
||||||
|
Unlike network I/O, there are no platform-specific file I/O primitives libuv could rely on,
|
||||||
|
so the current approach is to run blocking file I/O operations in a thread pool.
|
||||||
|
|
||||||
|
For a thorough explanation of the cross-platform file I/O landscape, checkout
|
||||||
|
`this post <http://blog.libtorrent.org/2012/10/asynchronous-disk-io/>`_.
|
||||||
|
|
||||||
|
libuv currently uses a global thread pool on which all loops can queue work on. 3 types of
|
||||||
|
operations are currently run on this pool:
|
||||||
|
|
||||||
|
* Filesystem operations
|
||||||
|
* DNS functions (getaddrinfo and getnameinfo)
|
||||||
|
* User specified code via :c:func:`uv_queue_work`
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
See the :c:ref:`threadpool` section for more details, but keep in mind the thread pool size
|
||||||
|
is quite limited.
|
44
deps/uv/docs/src/dll.rst
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
|
||||||
|
.. _dll:
|
||||||
|
|
||||||
|
Shared library handling
|
||||||
|
=======================
|
||||||
|
|
||||||
|
libuv prodives cross platform utilities for loading shared libraries and
|
||||||
|
retrieving symbols from them, using the following API.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_lib_t
|
||||||
|
|
||||||
|
Shared library data type.
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
N/A
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: int uv_dlopen(const char* filename, uv_lib_t* lib)
|
||||||
|
|
||||||
|
Opens a shared library. The filename is in utf-8. Returns 0 on success and
|
||||||
|
-1 on error. Call :c:func:`uv_dlerror` to get the error message.
|
||||||
|
|
||||||
|
.. c:function:: void uv_dlclose(uv_lib_t* lib)
|
||||||
|
|
||||||
|
Close the shared library.
|
||||||
|
|
||||||
|
.. c:function:: uv_dlsym(uv_lib_t* lib, const char* name, void** ptr)
|
||||||
|
|
||||||
|
Retrieves a data pointer from a dynamic library. It is legal for a symbol
|
||||||
|
to map to NULL. Returns 0 on success and -1 if the symbol was not found.
|
||||||
|
|
||||||
|
.. c:function:: const char* uv_dlerror(const uv_lib_t* lib)
|
||||||
|
|
||||||
|
Returns the last uv_dlopen() or uv_dlsym() error message.
|
83
deps/uv/docs/src/dns.rst
vendored
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
|
||||||
|
.. _dns:
|
||||||
|
|
||||||
|
DNS utility functions
|
||||||
|
=====================
|
||||||
|
|
||||||
|
libuv provides asynchronous variants of `getaddrinfo` and `getnameinfo`.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_getaddrinfo_t
|
||||||
|
|
||||||
|
`getaddrinfo` request type.
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* req, int status, struct addrinfo* res)
|
||||||
|
|
||||||
|
Callback which will be called with the getaddrinfo request result once
|
||||||
|
complete. In case it was cancelled, `status` will have a value of
|
||||||
|
``UV_ECANCELED``.
|
||||||
|
|
||||||
|
.. c:type:: uv_getnameinfo_t
|
||||||
|
|
||||||
|
`getnameinfo` request type.
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_getnameinfo_cb)(uv_getnameinfo_t* req, int status, const char* hostname, const char* service)
|
||||||
|
|
||||||
|
Callback which will be called with the getnameinfo request result once
|
||||||
|
complete. In case it was cancelled, `status` will have a value of
|
||||||
|
``UV_ECANCELED``.
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. c:member:: uv_loop_t* uv_getaddrinfo_t.loop
|
||||||
|
|
||||||
|
Loop that started this getaddrinfo request and where completion will be
|
||||||
|
reported. Readonly.
|
||||||
|
|
||||||
|
.. c:member:: uv_loop_t* uv_getnameinfo_t.loop
|
||||||
|
|
||||||
|
Loop that started this getnameinfo request and where completion will be
|
||||||
|
reported. Readonly.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_req_t` members also apply.
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: int uv_getaddrinfo(uv_loop_t* loop, uv_getaddrinfo_t* req, uv_getaddrinfo_cb getaddrinfo_cb, const char* node, const char* service, const struct addrinfo* hints)
|
||||||
|
|
||||||
|
Asynchronous ``getaddrinfo(3)``.
|
||||||
|
|
||||||
|
Either node or service may be NULL but not both.
|
||||||
|
|
||||||
|
`hints` is a pointer to a struct addrinfo with additional address type
|
||||||
|
constraints, or NULL. Consult `man -s 3 getaddrinfo` for more details.
|
||||||
|
|
||||||
|
Returns 0 on success or an error code < 0 on failure. If successful, the
|
||||||
|
callback will get called sometime in the future with the lookup result,
|
||||||
|
which is either:
|
||||||
|
|
||||||
|
* status == 0, the res argument points to a valid `struct addrinfo`, or
|
||||||
|
* status < 0, the res argument is NULL. See the UV_EAI_* constants.
|
||||||
|
|
||||||
|
Call :c:func:`uv_freeaddrinfo` to free the addrinfo structure.
|
||||||
|
|
||||||
|
.. c:function:: void uv_freeaddrinfo(struct addrinfo* ai)
|
||||||
|
|
||||||
|
Free the struct addrinfo. Passing NULL is allowed and is a no-op.
|
||||||
|
|
||||||
|
.. c:function:: int uv_getnameinfo(uv_loop_t* loop, uv_getnameinfo_t* req, uv_getnameinfo_cb getnameinfo_cb, const struct sockaddr* addr, int flags)
|
||||||
|
|
||||||
|
Asynchronous ``getnameinfo(3)``.
|
||||||
|
|
||||||
|
Returns 0 on success or an error code < 0 on failure. If successful, the
|
||||||
|
callback will get called sometime in the future with the lookup result.
|
||||||
|
Consult `man -s 3 getnameinfo` for more details.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_req_t` API functions also apply.
|
329
deps/uv/docs/src/errors.rst
vendored
Normal file
@ -0,0 +1,329 @@
|
|||||||
|
|
||||||
|
.. _errors:
|
||||||
|
|
||||||
|
Error handling
|
||||||
|
==============
|
||||||
|
|
||||||
|
In libuv errors are negative numbered constants. As a rule of thumb, whenever
|
||||||
|
there is a status parameter, or an API functions returns an integer, a negative
|
||||||
|
number will imply an error.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Implementation detail: on Unix error codes are the negated `errno` (or `-errno`), while on
|
||||||
|
Windows they are defined by libuv to arbitrary negative numbers.
|
||||||
|
|
||||||
|
|
||||||
|
Error constants
|
||||||
|
---------------
|
||||||
|
|
||||||
|
.. c:macro:: UV_E2BIG
|
||||||
|
|
||||||
|
argument list too long
|
||||||
|
|
||||||
|
.. c:macro:: UV_EACCES
|
||||||
|
|
||||||
|
permission denied
|
||||||
|
|
||||||
|
.. c:macro:: UV_EADDRINUSE
|
||||||
|
|
||||||
|
address already in use
|
||||||
|
|
||||||
|
.. c:macro:: UV_EADDRNOTAVAIL
|
||||||
|
|
||||||
|
address not available
|
||||||
|
|
||||||
|
.. c:macro:: UV_EAFNOSUPPORT
|
||||||
|
|
||||||
|
address family not supported
|
||||||
|
|
||||||
|
.. c:macro:: UV_EAGAIN
|
||||||
|
|
||||||
|
resource temporarily unavailable
|
||||||
|
|
||||||
|
.. c:macro:: UV_EAI_ADDRFAMILY
|
||||||
|
|
||||||
|
address family not supported
|
||||||
|
|
||||||
|
.. c:macro:: UV_EAI_AGAIN
|
||||||
|
|
||||||
|
temporary failure
|
||||||
|
|
||||||
|
.. c:macro:: UV_EAI_BADFLAGS
|
||||||
|
|
||||||
|
bad ai_flags value
|
||||||
|
|
||||||
|
.. c:macro:: UV_EAI_BADHINTS
|
||||||
|
|
||||||
|
invalid value for hints
|
||||||
|
|
||||||
|
.. c:macro:: UV_EAI_CANCELED
|
||||||
|
|
||||||
|
request canceled
|
||||||
|
|
||||||
|
.. c:macro:: UV_EAI_FAIL
|
||||||
|
|
||||||
|
permanent failure
|
||||||
|
|
||||||
|
.. c:macro:: UV_EAI_FAMILY
|
||||||
|
|
||||||
|
ai_family not supported
|
||||||
|
|
||||||
|
.. c:macro:: UV_EAI_MEMORY
|
||||||
|
|
||||||
|
out of memory
|
||||||
|
|
||||||
|
.. c:macro:: UV_EAI_NODATA
|
||||||
|
|
||||||
|
no address
|
||||||
|
|
||||||
|
.. c:macro:: UV_EAI_NONAME
|
||||||
|
|
||||||
|
unknown node or service
|
||||||
|
|
||||||
|
.. c:macro:: UV_EAI_OVERFLOW
|
||||||
|
|
||||||
|
argument buffer overflow
|
||||||
|
|
||||||
|
.. c:macro:: UV_EAI_PROTOCOL
|
||||||
|
|
||||||
|
resolved protocol is unknown
|
||||||
|
|
||||||
|
.. c:macro:: UV_EAI_SERVICE
|
||||||
|
|
||||||
|
service not available for socket type
|
||||||
|
|
||||||
|
.. c:macro:: UV_EAI_SOCKTYPE
|
||||||
|
|
||||||
|
socket type not supported
|
||||||
|
|
||||||
|
.. c:macro:: UV_EALREADY
|
||||||
|
|
||||||
|
connection already in progress
|
||||||
|
|
||||||
|
.. c:macro:: UV_EBADF
|
||||||
|
|
||||||
|
bad file descriptor
|
||||||
|
|
||||||
|
.. c:macro:: UV_EBUSY
|
||||||
|
|
||||||
|
resource busy or locked
|
||||||
|
|
||||||
|
.. c:macro:: UV_ECANCELED
|
||||||
|
|
||||||
|
operation canceled
|
||||||
|
|
||||||
|
.. c:macro:: UV_ECHARSET
|
||||||
|
|
||||||
|
invalid Unicode character
|
||||||
|
|
||||||
|
.. c:macro:: UV_ECONNABORTED
|
||||||
|
|
||||||
|
software caused connection abort
|
||||||
|
|
||||||
|
.. c:macro:: UV_ECONNREFUSED
|
||||||
|
|
||||||
|
connection refused
|
||||||
|
|
||||||
|
.. c:macro:: UV_ECONNRESET
|
||||||
|
|
||||||
|
connection reset by peer
|
||||||
|
|
||||||
|
.. c:macro:: UV_EDESTADDRREQ
|
||||||
|
|
||||||
|
destination address required
|
||||||
|
|
||||||
|
.. c:macro:: UV_EEXIST
|
||||||
|
|
||||||
|
file already exists
|
||||||
|
|
||||||
|
.. c:macro:: UV_EFAULT
|
||||||
|
|
||||||
|
bad address in system call argument
|
||||||
|
|
||||||
|
.. c:macro:: UV_EFBIG
|
||||||
|
|
||||||
|
file too large
|
||||||
|
|
||||||
|
.. c:macro:: UV_EHOSTUNREACH
|
||||||
|
|
||||||
|
host is unreachable
|
||||||
|
|
||||||
|
.. c:macro:: UV_EINTR
|
||||||
|
|
||||||
|
interrupted system call
|
||||||
|
|
||||||
|
.. c:macro:: UV_EINVAL
|
||||||
|
|
||||||
|
invalid argument
|
||||||
|
|
||||||
|
.. c:macro:: UV_EIO
|
||||||
|
|
||||||
|
i/o error
|
||||||
|
|
||||||
|
.. c:macro:: UV_EISCONN
|
||||||
|
|
||||||
|
socket is already connected
|
||||||
|
|
||||||
|
.. c:macro:: UV_EISDIR
|
||||||
|
|
||||||
|
illegal operation on a directory
|
||||||
|
|
||||||
|
.. c:macro:: UV_ELOOP
|
||||||
|
|
||||||
|
too many symbolic links encountered
|
||||||
|
|
||||||
|
.. c:macro:: UV_EMFILE
|
||||||
|
|
||||||
|
too many open files
|
||||||
|
|
||||||
|
.. c:macro:: UV_EMSGSIZE
|
||||||
|
|
||||||
|
message too long
|
||||||
|
|
||||||
|
.. c:macro:: UV_ENAMETOOLONG
|
||||||
|
|
||||||
|
name too long
|
||||||
|
|
||||||
|
.. c:macro:: UV_ENETDOWN
|
||||||
|
|
||||||
|
network is down
|
||||||
|
|
||||||
|
.. c:macro:: UV_ENETUNREACH
|
||||||
|
|
||||||
|
network is unreachable
|
||||||
|
|
||||||
|
.. c:macro:: UV_ENFILE
|
||||||
|
|
||||||
|
file table overflow
|
||||||
|
|
||||||
|
.. c:macro:: UV_ENOBUFS
|
||||||
|
|
||||||
|
no buffer space available
|
||||||
|
|
||||||
|
.. c:macro:: UV_ENODEV
|
||||||
|
|
||||||
|
no such device
|
||||||
|
|
||||||
|
.. c:macro:: UV_ENOENT
|
||||||
|
|
||||||
|
no such file or directory
|
||||||
|
|
||||||
|
.. c:macro:: UV_ENOMEM
|
||||||
|
|
||||||
|
not enough memory
|
||||||
|
|
||||||
|
.. c:macro:: UV_ENONET
|
||||||
|
|
||||||
|
machine is not on the network
|
||||||
|
|
||||||
|
.. c:macro:: UV_ENOPROTOOPT
|
||||||
|
|
||||||
|
protocol not available
|
||||||
|
|
||||||
|
.. c:macro:: UV_ENOSPC
|
||||||
|
|
||||||
|
no space left on device
|
||||||
|
|
||||||
|
.. c:macro:: UV_ENOSYS
|
||||||
|
|
||||||
|
function not implemented
|
||||||
|
|
||||||
|
.. c:macro:: UV_ENOTCONN
|
||||||
|
|
||||||
|
socket is not connected
|
||||||
|
|
||||||
|
.. c:macro:: UV_ENOTDIR
|
||||||
|
|
||||||
|
not a directory
|
||||||
|
|
||||||
|
.. c:macro:: UV_ENOTEMPTY
|
||||||
|
|
||||||
|
directory not empty
|
||||||
|
|
||||||
|
.. c:macro:: UV_ENOTSOCK
|
||||||
|
|
||||||
|
socket operation on non-socket
|
||||||
|
|
||||||
|
.. c:macro:: UV_ENOTSUP
|
||||||
|
|
||||||
|
operation not supported on socket
|
||||||
|
|
||||||
|
.. c:macro:: UV_EPERM
|
||||||
|
|
||||||
|
operation not permitted
|
||||||
|
|
||||||
|
.. c:macro:: UV_EPIPE
|
||||||
|
|
||||||
|
broken pipe
|
||||||
|
|
||||||
|
.. c:macro:: UV_EPROTO
|
||||||
|
|
||||||
|
protocol error
|
||||||
|
|
||||||
|
.. c:macro:: UV_EPROTONOSUPPORT
|
||||||
|
|
||||||
|
protocol not supported
|
||||||
|
|
||||||
|
.. c:macro:: UV_EPROTOTYPE
|
||||||
|
|
||||||
|
protocol wrong type for socket
|
||||||
|
|
||||||
|
.. c:macro:: UV_ERANGE
|
||||||
|
|
||||||
|
result too large
|
||||||
|
|
||||||
|
.. c:macro:: UV_EROFS
|
||||||
|
|
||||||
|
read-only file system
|
||||||
|
|
||||||
|
.. c:macro:: UV_ESHUTDOWN
|
||||||
|
|
||||||
|
cannot send after transport endpoint shutdown
|
||||||
|
|
||||||
|
.. c:macro:: UV_ESPIPE
|
||||||
|
|
||||||
|
invalid seek
|
||||||
|
|
||||||
|
.. c:macro:: UV_ESRCH
|
||||||
|
|
||||||
|
no such process
|
||||||
|
|
||||||
|
.. c:macro:: UV_ETIMEDOUT
|
||||||
|
|
||||||
|
connection timed out
|
||||||
|
|
||||||
|
.. c:macro:: UV_ETXTBSY
|
||||||
|
|
||||||
|
text file is busy
|
||||||
|
|
||||||
|
.. c:macro:: UV_EXDEV
|
||||||
|
|
||||||
|
cross-device link not permitted
|
||||||
|
|
||||||
|
.. c:macro:: UV_UNKNOWN
|
||||||
|
|
||||||
|
unknown error
|
||||||
|
|
||||||
|
.. c:macro:: UV_EOF
|
||||||
|
|
||||||
|
end of file
|
||||||
|
|
||||||
|
.. c:macro:: UV_ENXIO
|
||||||
|
|
||||||
|
no such device or address
|
||||||
|
|
||||||
|
.. c:macro:: UV_EMLINK
|
||||||
|
|
||||||
|
too many links
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: const char* uv_strerror(int err)
|
||||||
|
|
||||||
|
Returns the error message for the given error code.
|
||||||
|
|
||||||
|
.. c:function:: const char* uv_err_name(int err)
|
||||||
|
|
||||||
|
Returns the error name for the given error code.
|
259
deps/uv/docs/src/fs.rst
vendored
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
|
||||||
|
.. _fs:
|
||||||
|
|
||||||
|
Filesystem operations
|
||||||
|
=====================
|
||||||
|
|
||||||
|
libuv provides a wide variety of cross-platform sync and async filesystem
|
||||||
|
operations. All functions defined in this document take a callback, which is
|
||||||
|
allowed to be NULL. If the callback is NULL the request is completed synchronously,
|
||||||
|
otherwise it will be performed asynchronously.
|
||||||
|
|
||||||
|
All file operations are run on the threadpool, see :ref:`threadpool` for information
|
||||||
|
on the threadpool size.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_fs_t
|
||||||
|
|
||||||
|
Filesystem request type.
|
||||||
|
|
||||||
|
.. c:type:: uv_stat_t
|
||||||
|
|
||||||
|
Portable equivalent of `struct stat`.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t st_dev;
|
||||||
|
uint64_t st_mode;
|
||||||
|
uint64_t st_nlink;
|
||||||
|
uint64_t st_uid;
|
||||||
|
uint64_t st_gid;
|
||||||
|
uint64_t st_rdev;
|
||||||
|
uint64_t st_ino;
|
||||||
|
uint64_t st_size;
|
||||||
|
uint64_t st_blksize;
|
||||||
|
uint64_t st_blocks;
|
||||||
|
uint64_t st_flags;
|
||||||
|
uint64_t st_gen;
|
||||||
|
uv_timespec_t st_atim;
|
||||||
|
uv_timespec_t st_mtim;
|
||||||
|
uv_timespec_t st_ctim;
|
||||||
|
uv_timespec_t st_birthtim;
|
||||||
|
} uv_stat_t;
|
||||||
|
|
||||||
|
.. c:type:: uv_fs_type
|
||||||
|
|
||||||
|
Filesystem request type.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UV_FS_UNKNOWN = -1,
|
||||||
|
UV_FS_CUSTOM,
|
||||||
|
UV_FS_OPEN,
|
||||||
|
UV_FS_CLOSE,
|
||||||
|
UV_FS_READ,
|
||||||
|
UV_FS_WRITE,
|
||||||
|
UV_FS_SENDFILE,
|
||||||
|
UV_FS_STAT,
|
||||||
|
UV_FS_LSTAT,
|
||||||
|
UV_FS_FSTAT,
|
||||||
|
UV_FS_FTRUNCATE,
|
||||||
|
UV_FS_UTIME,
|
||||||
|
UV_FS_FUTIME,
|
||||||
|
UV_FS_CHMOD,
|
||||||
|
UV_FS_FCHMOD,
|
||||||
|
UV_FS_FSYNC,
|
||||||
|
UV_FS_FDATASYNC,
|
||||||
|
UV_FS_UNLINK,
|
||||||
|
UV_FS_RMDIR,
|
||||||
|
UV_FS_MKDIR,
|
||||||
|
UV_FS_MKDTEMP,
|
||||||
|
UV_FS_RENAME,
|
||||||
|
UV_FS_READDIR,
|
||||||
|
UV_FS_LINK,
|
||||||
|
UV_FS_SYMLINK,
|
||||||
|
UV_FS_READLINK,
|
||||||
|
UV_FS_CHOWN,
|
||||||
|
UV_FS_FCHOWN
|
||||||
|
} uv_fs_type;
|
||||||
|
|
||||||
|
.. c:type:: uv_dirent_t
|
||||||
|
|
||||||
|
Cross platform (reduced) equivalent of ``struct dirent``.
|
||||||
|
Used in :c:func:`uv_fs_readdir_next`.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UV_DIRENT_UNKNOWN,
|
||||||
|
UV_DIRENT_FILE,
|
||||||
|
UV_DIRENT_DIR,
|
||||||
|
UV_DIRENT_LINK,
|
||||||
|
UV_DIRENT_FIFO,
|
||||||
|
UV_DIRENT_SOCKET,
|
||||||
|
UV_DIRENT_CHAR,
|
||||||
|
UV_DIRENT_BLOCK
|
||||||
|
} uv_dirent_type_t;
|
||||||
|
|
||||||
|
typedef struct uv_dirent_s {
|
||||||
|
const char* name;
|
||||||
|
uv_dirent_type_t type;
|
||||||
|
} uv_dirent_t;
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. c:member:: uv_loop_t* uv_fs_t.loop
|
||||||
|
|
||||||
|
Loop that started this request and where completion will be reported.
|
||||||
|
Readonly.
|
||||||
|
|
||||||
|
.. c:member:: uv_fs_type uv_fs_t.fs_type
|
||||||
|
|
||||||
|
FS request type.
|
||||||
|
|
||||||
|
.. c:member:: const char* uv_fs_t.path
|
||||||
|
|
||||||
|
Path affecting the request.
|
||||||
|
|
||||||
|
.. c:member:: ssize_t uv_fs_t.result
|
||||||
|
|
||||||
|
Result of the request. < 0 means error, success otherwise. On requests such
|
||||||
|
as :c:func:`uv_fs_read` or :c:func:`uv_fs_write` it indicates the amount of
|
||||||
|
data that was read or written, respectively.
|
||||||
|
|
||||||
|
.. c:member:: uv_stat_t uv_fs_t.statbuf
|
||||||
|
|
||||||
|
Stores the result of :c:func:`uv_fs_stat` and other stat requests.
|
||||||
|
|
||||||
|
.. c:member:: void* uv_fs_t.ptr
|
||||||
|
|
||||||
|
Stores the result of :c:func:`uv_fs_readlink` and serves as an alias to
|
||||||
|
`statbuf`.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_req_t` members also apply.
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: void uv_fs_req_cleanup(uv_fs_t* req)
|
||||||
|
|
||||||
|
Cleanup request. Must be called after a request is finished to deallocate
|
||||||
|
any memory libuv might have allocated.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
|
||||||
|
|
||||||
|
Equivalent to ``close(2)``.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb)
|
||||||
|
|
||||||
|
Equivalent to ``open(2)``.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb)
|
||||||
|
|
||||||
|
Equivalent to ``preadv(2)``.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
|
||||||
|
|
||||||
|
Equivalent to ``unlink(2)``.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb)
|
||||||
|
|
||||||
|
Equivalent to ``pwritev(2)``.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb)
|
||||||
|
|
||||||
|
Equivalent to ``mkdir(2)``.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
`mode` is currently not implemented on Windows.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, uv_fs_cb cb)
|
||||||
|
|
||||||
|
Equivalent to ``mkdtemp(3)``.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
|
||||||
|
|
||||||
|
Equivalent to ``rmdir(2)``.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, uv_fs_cb cb)
|
||||||
|
.. c:function:: int uv_fs_readdir_next(uv_fs_t* req, uv_dirent_t* ent)
|
||||||
|
|
||||||
|
Equivalent to ``readdir(2)``, with a slightly different API. Once the callback
|
||||||
|
for the request is called, the user can use :c:func:`uv_fs_readdir_next` to
|
||||||
|
get `ent` populated with the next directory entry data. When there are no
|
||||||
|
more entries ``UV_EOF`` will be returned.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
|
||||||
|
.. c:function:: int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
|
||||||
|
.. c:function:: int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
|
||||||
|
|
||||||
|
Equivalent to ``(f/l)stat(2)``.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb)
|
||||||
|
|
||||||
|
Equivalent to ``rename(2)``.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
|
||||||
|
|
||||||
|
Equivalent to ``fsync(2)``.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
|
||||||
|
|
||||||
|
Equivalent to ``fdatasync(2)``.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file, int64_t offset, uv_fs_cb cb)
|
||||||
|
|
||||||
|
Equivalent to ``ftruncate(2)``.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd, uv_file in_fd, int64_t in_offset, size_t length, uv_fs_cb cb)
|
||||||
|
|
||||||
|
Limited equivalent to ``sendfile(2)``.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb)
|
||||||
|
.. c:function:: int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode, uv_fs_cb cb)
|
||||||
|
|
||||||
|
Equivalent to ``(f)chmod(2)``.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime, double mtime, uv_fs_cb cb)
|
||||||
|
.. c:function:: int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime, double mtime, uv_fs_cb cb)
|
||||||
|
|
||||||
|
Equivalent to ``(f)utime(s)(2)``.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb)
|
||||||
|
|
||||||
|
Equivalent to ``link(2)``.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, int flags, uv_fs_cb cb)
|
||||||
|
|
||||||
|
Equivalent to ``symlink(2)``.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
On Windows the `flags` parameter can be specified to control how the symlink will
|
||||||
|
be created:
|
||||||
|
|
||||||
|
* ``UV_FS_SYMLINK_DIR``: indicates that `path` points to a directory.
|
||||||
|
|
||||||
|
* ``UV_FS_SYMLINK_JUNCTION``: request that the symlink is created
|
||||||
|
using junktion points.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
|
||||||
|
|
||||||
|
Equivalent to ``readlink(2)``.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb)
|
||||||
|
.. c:function:: int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb)
|
||||||
|
|
||||||
|
Equivalent to ``(f)chown(2)``.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
These functions are not implemented on Windows.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_req_t` API functions also apply.
|
102
deps/uv/docs/src/fs_event.rst
vendored
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
|
||||||
|
.. _fs_event:
|
||||||
|
|
||||||
|
:c:type:`uv_fs_event_t` --- FS Event handle
|
||||||
|
===========================================
|
||||||
|
|
||||||
|
FS Event handles allow the user to monitor a given path for changes, for example,
|
||||||
|
if the file was renamed or there was a generic change in it. This handle uses
|
||||||
|
the best backend for the job on each platform.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_fs_event_t
|
||||||
|
|
||||||
|
FS Event handle type.
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_fs_event_cb)(uv_fs_event_t* handle, const char* filename, int events, int status)
|
||||||
|
|
||||||
|
Callback passed to :c:func:`uv_fs_event_start` which will be called repeatedly
|
||||||
|
after the handle is started. If the handle was started with a directory the
|
||||||
|
`filename` parameter will be a relative path to a file contained in the directory.
|
||||||
|
The `events` parameter is an ORed mask of :c:type:`uv_fs_event` elements.
|
||||||
|
|
||||||
|
.. c:type:: uv_fs_event
|
||||||
|
|
||||||
|
Event types that :c:type:`uv_fs_event_t` handles monitor.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
enum uv_fs_event {
|
||||||
|
UV_RENAME = 1,
|
||||||
|
UV_CHANGE = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
.. c:type:: uv_fs_event_flags
|
||||||
|
|
||||||
|
Flags that can be passed to :c:func:`uv_fs_event_start` to control its
|
||||||
|
behavior.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
enum uv_fs_event_flags {
|
||||||
|
/*
|
||||||
|
* By default, if the fs event watcher is given a directory name, we will
|
||||||
|
* watch for all events in that directory. This flags overrides this behavior
|
||||||
|
* and makes fs_event report only changes to the directory entry itself. This
|
||||||
|
* flag does not affect individual files watched.
|
||||||
|
* This flag is currently not implemented yet on any backend.
|
||||||
|
*/
|
||||||
|
UV_FS_EVENT_WATCH_ENTRY = 1,
|
||||||
|
/*
|
||||||
|
* By default uv_fs_event will try to use a kernel interface such as inotify
|
||||||
|
* or kqueue to detect events. This may not work on remote filesystems such
|
||||||
|
* as NFS mounts. This flag makes fs_event fall back to calling stat() on a
|
||||||
|
* regular interval.
|
||||||
|
* This flag is currently not implemented yet on any backend.
|
||||||
|
*/
|
||||||
|
UV_FS_EVENT_STAT = 2,
|
||||||
|
/*
|
||||||
|
* By default, event watcher, when watching directory, is not registering
|
||||||
|
* (is ignoring) changes in it's subdirectories.
|
||||||
|
* This flag will override this behaviour on platforms that support it.
|
||||||
|
*/
|
||||||
|
UV_FS_EVENT_RECURSIVE = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
N/A
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle)
|
||||||
|
|
||||||
|
Initialize the handle.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, const char* path, unsigned int flags)
|
||||||
|
|
||||||
|
Start the handle with the given callback, which will watch the specified
|
||||||
|
`path` for changes. `flags` can be an ORed mask of :c:type:`uv_fs_event_flags`.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_event_stop(uv_fs_event_t* handle)
|
||||||
|
|
||||||
|
Stop the handle, the callback will no longer be called.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_event_getpath(uv_fs_event_t* handle, char* buf, size_t* len)
|
||||||
|
|
||||||
|
Get the path being monitored by the handle. The buffer must be preallocated
|
||||||
|
by the user. Returns 0 on success or an error code < 0 in case of failure.
|
||||||
|
On sucess, `buf` will contain the path and `len` its length. If the buffer
|
||||||
|
is not big enough UV_ENOBUFS will be returned and len will be set to the
|
||||||
|
required size.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
65
deps/uv/docs/src/fs_poll.rst
vendored
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
|
||||||
|
.. _fs_poll:
|
||||||
|
|
||||||
|
:c:type:`uv_fs_poll_t` --- FS Poll handle
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
FS Poll handles allow the user to monitor a given path for changes. Unlike
|
||||||
|
:c:type:`uv_fs_event_t`, fs poll handles use `stat` to detect when a file has
|
||||||
|
changed so they can work on file systems where fs event handles can't.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_fs_poll_t
|
||||||
|
|
||||||
|
FS Poll handle type.
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_fs_poll_cb)(uv_fs_poll_t* handle, int status, const uv_stat_t* prev, const uv_stat_t* curr)
|
||||||
|
|
||||||
|
Callback passed to :c:func:`uv_fs_poll_start` which will be called repeatedly
|
||||||
|
after the handle is started, when any change happens to the monitored path.
|
||||||
|
|
||||||
|
The callback is invoked with `status < 0` if `path` does not exist
|
||||||
|
or is inaccessible. The watcher is *not* stopped but your callback is
|
||||||
|
not called again until something changes (e.g. when the file is created
|
||||||
|
or the error reason changes).
|
||||||
|
|
||||||
|
When `status == 0`, the callback receives pointers to the old and new
|
||||||
|
:c:type:`uv_stat_t` structs. They are valid for the duration of the
|
||||||
|
callback only.
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
N/A
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_poll_start(uv_fs_poll_t* handle, uv_fs_poll_cb poll_cb, const char* path, unsigned int interval)
|
||||||
|
|
||||||
|
Check the file at `path` for changes every `interval` milliseconds.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
For maximum portability, use multi-second intervals. Sub-second intervals will not detect
|
||||||
|
all changes on many file systems.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_poll_stop(uv_fs_poll_t* handle)
|
||||||
|
|
||||||
|
Stop the handle, the callback will no longer be called.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fs_poll_getpath(uv_fs_poll_t* handle, char* buf, size_t* len)
|
||||||
|
|
||||||
|
Get the path being monitored by the handle. The buffer must be preallocated
|
||||||
|
by the user. Returns 0 on success or an error code < 0 in case of failure.
|
||||||
|
On sucess, `buf` will contain the path and `len` its length. If the buffer
|
||||||
|
is not big enough UV_ENOBUFS will be returned and len will be set to the
|
||||||
|
required size.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
172
deps/uv/docs/src/handle.rst
vendored
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
|
||||||
|
.. _handle:
|
||||||
|
|
||||||
|
:c:type:`uv_handle_t` --- Base handle
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
`uv_handle_t` is the base type for all libuv handle types.
|
||||||
|
|
||||||
|
Strcutures are aligned so that any libuv handle can be cast to `uv_handle_t`.
|
||||||
|
All API functions defined here work with any handle type.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_handle_t
|
||||||
|
|
||||||
|
The base libuv handle type.
|
||||||
|
|
||||||
|
.. c:type:: uv_any_handle
|
||||||
|
|
||||||
|
Union of all handle types.
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_close_cb)(uv_handle_t* handle)
|
||||||
|
|
||||||
|
Type definition for callback passed to :c:func:`uv_close`.
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. c:member:: uv_loop_t* uv_handle_t.loop
|
||||||
|
|
||||||
|
Pointer to the :c:type:`uv_loop_t` where the handle is running on. Readonly.
|
||||||
|
|
||||||
|
.. c:member:: void* uv_handle_t.data
|
||||||
|
|
||||||
|
Space for user-defined arbitrary data. libuv does not use this field.
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: int uv_is_active(const uv_handle_t* handle)
|
||||||
|
|
||||||
|
Returns non-zero if the handle is active, zero if it's inactive. What
|
||||||
|
"active" means depends on the type of handle:
|
||||||
|
|
||||||
|
- A uv_async_t handle is always active and cannot be deactivated, except
|
||||||
|
by closing it with uv_close().
|
||||||
|
|
||||||
|
- A uv_pipe_t, uv_tcp_t, uv_udp_t, etc. handle - basically any handle that
|
||||||
|
deals with i/o - is active when it is doing something that involves i/o,
|
||||||
|
like reading, writing, connecting, accepting new connections, etc.
|
||||||
|
|
||||||
|
- A uv_check_t, uv_idle_t, uv_timer_t, etc. handle is active when it has
|
||||||
|
been started with a call to uv_check_start(), uv_idle_start(), etc.
|
||||||
|
|
||||||
|
Rule of thumb: if a handle of type `uv_foo_t` has a `uv_foo_start()`
|
||||||
|
function, then it's active from the moment that function is called.
|
||||||
|
Likewise, `uv_foo_stop()` deactivates the handle again.
|
||||||
|
|
||||||
|
.. c:function:: int uv_is_closing(const uv_handle_t* handle)
|
||||||
|
|
||||||
|
Returns non-zero if the handle is closing or closed, zero otherwise.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
This function should only be used between the initialization of the handle and the
|
||||||
|
arrival of the close callback.
|
||||||
|
|
||||||
|
.. c:function:: void uv_close(uv_handle_t* handle, uv_close_cb close_cb)
|
||||||
|
|
||||||
|
Request handle to be closed. `close_cb` will be called asynchronously after
|
||||||
|
this call. This MUST be called on each handle before memory is released.
|
||||||
|
|
||||||
|
Handles that wrap file descriptors are closed immediately but
|
||||||
|
`close_cb` will still be deferred to the next iteration of the event loop.
|
||||||
|
It gives you a chance to free up any resources associated with the handle.
|
||||||
|
|
||||||
|
In-progress requests, like uv_connect_t or uv_write_t, are cancelled and
|
||||||
|
have their callbacks called asynchronously with status=UV_ECANCELED.
|
||||||
|
|
||||||
|
.. c:function:: void uv_ref(uv_handle_t* handle)
|
||||||
|
|
||||||
|
Reference the given handle. References are idempotent, that is, if a handle
|
||||||
|
is already referenced calling this function again will have no effect.
|
||||||
|
|
||||||
|
See :ref:`refcount`.
|
||||||
|
|
||||||
|
.. c:function:: void uv_unref(uv_handle_t* handle)
|
||||||
|
|
||||||
|
Un-reference the given handle. References are idempotent, that is, if a handle
|
||||||
|
is not referenced calling this function again will have no effect.
|
||||||
|
|
||||||
|
See :ref:`refcount`.
|
||||||
|
|
||||||
|
.. c:function:: int uv_has_ref(const uv_handle_t* handle)
|
||||||
|
|
||||||
|
Returns non-zero if the handle referenced, zero otherwise.
|
||||||
|
|
||||||
|
See :ref:`refcount`.
|
||||||
|
|
||||||
|
.. c:function:: size_t uv_handle_size(uv_handle_type type)
|
||||||
|
|
||||||
|
Returns the size of the given handle type. Useful for FFI binding writers
|
||||||
|
who don't want to know the structure layout.
|
||||||
|
|
||||||
|
|
||||||
|
Miscellaneous API functions
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
The following API functions take a :c:type:`uv_handle_t` argument but they work
|
||||||
|
just for some handle types.
|
||||||
|
|
||||||
|
.. c:function:: int uv_send_buffer_size(uv_handle_t* handle, int* value)
|
||||||
|
|
||||||
|
Gets or sets the size of the send buffer that the operating
|
||||||
|
system uses for the socket.
|
||||||
|
|
||||||
|
If `*value` == 0, it will return the current send buffer size,
|
||||||
|
otherwise it will use `*value` to set the new send buffer size.
|
||||||
|
|
||||||
|
This function works for TCP, pipe and UDP handles on Unix and for TCP and
|
||||||
|
UDP handles on Windows.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Linux will set double the size and return double the size of the original set value.
|
||||||
|
|
||||||
|
.. c:function:: int uv_recv_buffer_size(uv_handle_t* handle, int* value)
|
||||||
|
|
||||||
|
Gets or sets the size of the receive buffer that the operating
|
||||||
|
system uses for the socket.
|
||||||
|
|
||||||
|
If `*value` == 0, it will return the current receive buffer size,
|
||||||
|
otherwise it will use `*value` to set the new receive buffer size.
|
||||||
|
|
||||||
|
This function works for TCP, pipe and UDP handles on Unix and for TCP and
|
||||||
|
UDP handles on Windows.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Linux will set double the size and return double the size of the original set value.
|
||||||
|
|
||||||
|
.. c:function:: int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd)
|
||||||
|
|
||||||
|
Gets the platform dependent file descriptor equivalent.
|
||||||
|
|
||||||
|
The following handles are supported: TCP, pipes, TTY, UDP and poll. Passing
|
||||||
|
any other handle type will fail with `UV_EINVAL`.
|
||||||
|
|
||||||
|
If a handle doesn't have an attached file descriptor yet or the handle
|
||||||
|
itself has been closed, this function will return `UV_EBADF`.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
Be very careful when using this function. libuv assumes it's in control of the file
|
||||||
|
descriptor so any change to it may lead to malfunction.
|
||||||
|
|
||||||
|
|
||||||
|
.. _refcount:
|
||||||
|
|
||||||
|
Reference counting
|
||||||
|
------------------
|
||||||
|
|
||||||
|
The libuv event loop (if run in the default mode) will run until there are no
|
||||||
|
active `and` referenced handles left. The user can force the loop to exit early
|
||||||
|
by unreferencing handles which are active, for example by calling :c:func:`uv_unref`
|
||||||
|
after calling :c:func:`uv_timer_start`.
|
||||||
|
|
||||||
|
A handle can be referenced or unreferenced, the refcounting scheme doesn't use
|
||||||
|
a counter, so both operations are idempotent.
|
||||||
|
|
||||||
|
All handles are referenced when active by default, see :c:func:`uv_is_active`
|
||||||
|
for a more detailed explanation on what being `active` involves.
|
54
deps/uv/docs/src/idle.rst
vendored
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
|
||||||
|
.. _idle:
|
||||||
|
|
||||||
|
:c:type:`uv_idle_t` --- Idle handle
|
||||||
|
===================================
|
||||||
|
|
||||||
|
Idle handles will run the given callback once per loop iteration, right
|
||||||
|
before the :c:type:`uv_prepare_t` handles.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
The notable difference with prepare handles is that when there are active idle handles,
|
||||||
|
the loop will perform a zero timeout poll instead of blocking for i/o.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
Despite the name, idle handles will get their callbacks called on every loop iteration,
|
||||||
|
not when the loop is actually "idle".
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_idle_t
|
||||||
|
|
||||||
|
Idle handle type.
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_idle_cb)(uv_idle_t* handle)
|
||||||
|
|
||||||
|
Type definition for callback passed to :c:func:`uv_idle_start`.
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
N/A
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: int uv_idle_init(uv_loop_t*, uv_idle_t* idle)
|
||||||
|
|
||||||
|
Initialize the handle.
|
||||||
|
|
||||||
|
.. c:function:: int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb)
|
||||||
|
|
||||||
|
Start the handle with the given callback.
|
||||||
|
|
||||||
|
.. c:function:: int uv_idle_stop(uv_idle_t* idle)
|
||||||
|
|
||||||
|
Stop the handle, the callback will no longer be called.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
84
deps/uv/docs/src/index.rst
vendored
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
|
||||||
|
Welcome to the libuv API documentation
|
||||||
|
======================================
|
||||||
|
|
||||||
|
Overview
|
||||||
|
--------
|
||||||
|
|
||||||
|
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 Mozilla's
|
||||||
|
`Rust language`_, `Luvit`_, `Julia`_, `pyuv`_, and `others`_.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
In case you find errors in this documentation you can help by sending
|
||||||
|
`pull requests <https://github.com/joyent/libuv>`_!
|
||||||
|
|
||||||
|
.. _Node.js: http://nodejs.org
|
||||||
|
.. _Rust language: http://www.rust-lang.org
|
||||||
|
.. _Luvit: http://luvit.io
|
||||||
|
.. _Julia: http://julialang.org
|
||||||
|
.. _pyuv: https://github.com/saghul/pyuv
|
||||||
|
.. _others: https://github.com/joyent/libuv/wiki/Projects-that-use-libuv
|
||||||
|
|
||||||
|
|
||||||
|
Features
|
||||||
|
--------
|
||||||
|
|
||||||
|
* Full-featured event loop backed by epoll, kqueue, IOCP, event ports.
|
||||||
|
* Asynchronous TCP and UDP sockets
|
||||||
|
* Asynchronous DNS resolution
|
||||||
|
* Asynchronous file and file system operations
|
||||||
|
* File system events
|
||||||
|
* ANSI escape code controlled TTY
|
||||||
|
* IPC with socket sharing, using Unix domain sockets or named pipes (Windows)
|
||||||
|
* Child processes
|
||||||
|
* Thread pool
|
||||||
|
* Signal handling
|
||||||
|
* High resolution clock
|
||||||
|
* Threading and synchronization primitives
|
||||||
|
|
||||||
|
|
||||||
|
Downloads
|
||||||
|
---------
|
||||||
|
|
||||||
|
libuv can be downloaded from `here <http://dist.libuv.org/dist/>`_.
|
||||||
|
|
||||||
|
|
||||||
|
Installation
|
||||||
|
------------
|
||||||
|
|
||||||
|
Installation instructions can be found on `the README <https://github.com/joyent/libuv/blob/master/README.md>`_.
|
||||||
|
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
-------------
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
design
|
||||||
|
errors
|
||||||
|
loop
|
||||||
|
handle
|
||||||
|
request
|
||||||
|
timer
|
||||||
|
prepare
|
||||||
|
check
|
||||||
|
idle
|
||||||
|
async
|
||||||
|
poll
|
||||||
|
signal
|
||||||
|
process
|
||||||
|
stream
|
||||||
|
tcp
|
||||||
|
pipe
|
||||||
|
tty
|
||||||
|
udp
|
||||||
|
fs_event
|
||||||
|
fs_poll
|
||||||
|
fs
|
||||||
|
threadpool
|
||||||
|
dns
|
||||||
|
dll
|
||||||
|
threading
|
||||||
|
misc
|
137
deps/uv/docs/src/loop.rst
vendored
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
|
||||||
|
.. _loop:
|
||||||
|
|
||||||
|
:c:type:`uv_loop_t` --- Event loop
|
||||||
|
==================================
|
||||||
|
|
||||||
|
The event loop is the central part of libuv's functionality. It takes care
|
||||||
|
of polling for i/o and scheduling callbacks to be run based on different sources
|
||||||
|
of events.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_loop_t
|
||||||
|
|
||||||
|
Loop data type.
|
||||||
|
|
||||||
|
.. c:type:: uv_run_mode
|
||||||
|
|
||||||
|
Mode used to run the loop with :c:func:`uv_run`.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UV_RUN_DEFAULT = 0,
|
||||||
|
UV_RUN_ONCE,
|
||||||
|
UV_RUN_NOWAIT
|
||||||
|
} uv_run_mode;
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_walk_cb)(uv_handle_t* handle, void* arg)
|
||||||
|
|
||||||
|
Type definition for callback passed to :c:func:`uv_walk`.
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. c:member:: void* uv_loop_t.data
|
||||||
|
|
||||||
|
Space for user-defined arbitrary data. libuv does not use this field.
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: int uv_loop_init(uv_loop_t* loop)
|
||||||
|
|
||||||
|
Initializes the given `uv_loop_t` structure.
|
||||||
|
|
||||||
|
.. c:function:: int uv_loop_close(uv_loop_t* loop)
|
||||||
|
|
||||||
|
Closes all internal loop resources. This function must only be called once
|
||||||
|
the loop has finished its execution or it will return UV_EBUSY. After this
|
||||||
|
function returns the user shall free the memory allocated for the loop.
|
||||||
|
|
||||||
|
.. c:function:: uv_loop_t* uv_default_loop(void)
|
||||||
|
|
||||||
|
Returns the initialized default loop. It may return NULL in case of
|
||||||
|
allocation failture.
|
||||||
|
|
||||||
|
.. c:function:: int uv_run(uv_loop_t* loop, uv_run_mode mode)
|
||||||
|
|
||||||
|
This function runs the event loop. It will act differently depending on the
|
||||||
|
specified mode:
|
||||||
|
|
||||||
|
- UV_RUN_DEFAULT: Runs the event loop until there are no more active and
|
||||||
|
referenced handles or requests. Always returns zero.
|
||||||
|
- UV_RUN_ONCE: Poll for i/o once. Note that this function blocks if
|
||||||
|
there are no pending callbacks. Returns zero when done (no active handles
|
||||||
|
or requests left), or non-zero if more callbacks are expected (meaning
|
||||||
|
you should run the event loop again sometime in the future).
|
||||||
|
- UV_RUN_NOWAIT: Poll for i/o once but don't block if there are no
|
||||||
|
pending callbacks. Returns zero if done (no active handles
|
||||||
|
or requests left), or non-zero if more callbacks are expected (meaning
|
||||||
|
you should run the event loop again sometime in the future).
|
||||||
|
|
||||||
|
.. c:function:: int uv_loop_alive(const uv_loop_t* loop)
|
||||||
|
|
||||||
|
Returns non-zero if there are active handles or request in the loop.
|
||||||
|
|
||||||
|
.. c:function:: void uv_stop(uv_loop_t* loop)
|
||||||
|
|
||||||
|
Stop the event loop, causing :c:func:`uv_run` to end as soon as
|
||||||
|
possible. This will happen not sooner than the next loop iteration.
|
||||||
|
If this function was called before blocking for i/o, the loop won't block
|
||||||
|
for i/o on this iteration.
|
||||||
|
|
||||||
|
.. c:function:: size_t uv_loop_size(void)
|
||||||
|
|
||||||
|
Returns the size of the `uv_loop_t` structure. Useful for FFI binding
|
||||||
|
writers who don't want to know the structure layout.
|
||||||
|
|
||||||
|
.. c:function:: int uv_backend_fd(const uv_loop_t* loop)
|
||||||
|
|
||||||
|
Get backend file descriptor. Only kqueue, epoll and event ports are
|
||||||
|
supported.
|
||||||
|
|
||||||
|
This can be used in conjunction with `uv_run(loop, UV_RUN_NOWAIT)` to
|
||||||
|
poll in one thread and run the event loop's callbacks in another see
|
||||||
|
test/test-embed.c for an example.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Embedding a kqueue fd in another kqueue pollset doesn't work on all platforms. It's not
|
||||||
|
an error to add the fd but it never generates events.
|
||||||
|
|
||||||
|
.. c:function:: int uv_backend_timeout(const uv_loop_t* loop)
|
||||||
|
|
||||||
|
Get the poll timeout. The return value is in milliseconds, or -1 for no
|
||||||
|
timeout.
|
||||||
|
|
||||||
|
.. c:function:: uint64_t uv_now(const uv_loop_t* loop)
|
||||||
|
|
||||||
|
Return the current timestamp in milliseconds. The timestamp is cached at
|
||||||
|
the start of the event loop tick, see :c:func:`uv_update_time` for details
|
||||||
|
and rationale.
|
||||||
|
|
||||||
|
The timestamp increases monotonically from some arbitrary point in time.
|
||||||
|
Don't make assumptions about the starting point, you will only get
|
||||||
|
disappointed.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Use :c:func:`uv_hrtime` if you need sub-millisecond granularity.
|
||||||
|
|
||||||
|
.. c:function:: void uv_update_time(uv_loop_t* loop)
|
||||||
|
|
||||||
|
Update the event loop's concept of "now". Libuv caches the current time
|
||||||
|
at the start of the event loop tick in order to reduce the number of
|
||||||
|
time-related system calls.
|
||||||
|
|
||||||
|
You won't normally need to call this function unless you have callbacks
|
||||||
|
that block the event loop for longer periods of time, where "longer" is
|
||||||
|
somewhat subjective but probably on the order of a millisecond or more.
|
||||||
|
|
||||||
|
.. c:function:: void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg)
|
||||||
|
|
||||||
|
Walk the list of handles: `walk_cb` will be executed with the given `arg`.
|
228
deps/uv/docs/src/misc.rst
vendored
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
|
||||||
|
.. _misc:
|
||||||
|
|
||||||
|
Miscelaneous utilities
|
||||||
|
======================
|
||||||
|
|
||||||
|
This section contains miscelaneous functions that don't really belong in any
|
||||||
|
other section.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_buf_t
|
||||||
|
|
||||||
|
Buffer data type.
|
||||||
|
|
||||||
|
.. c:type:: uv_file
|
||||||
|
|
||||||
|
Cross platform representation of a file handle.
|
||||||
|
|
||||||
|
.. c:type:: uv_os_sock_t
|
||||||
|
|
||||||
|
Cross platform representation of a socket handle.
|
||||||
|
|
||||||
|
.. c:type:: uv_os_fd_t
|
||||||
|
|
||||||
|
Abstract representation of a file descriptor. On Unix systems this is a
|
||||||
|
`typedef` of `int` and on Windows fa `HANDLE`.
|
||||||
|
|
||||||
|
.. c:type:: uv_rusage_t
|
||||||
|
|
||||||
|
Data type for resource usage results.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uv_timeval_t ru_utime; /* user CPU time used */
|
||||||
|
uv_timeval_t ru_stime; /* system CPU time used */
|
||||||
|
uint64_t ru_maxrss; /* maximum resident set size */
|
||||||
|
uint64_t ru_ixrss; /* integral shared memory size */
|
||||||
|
uint64_t ru_idrss; /* integral unshared data size */
|
||||||
|
uint64_t ru_isrss; /* integral unshared stack size */
|
||||||
|
uint64_t ru_minflt; /* page reclaims (soft page faults) */
|
||||||
|
uint64_t ru_majflt; /* page faults (hard page faults) */
|
||||||
|
uint64_t ru_nswap; /* swaps */
|
||||||
|
uint64_t ru_inblock; /* block input operations */
|
||||||
|
uint64_t ru_oublock; /* block output operations */
|
||||||
|
uint64_t ru_msgsnd; /* IPC messages sent */
|
||||||
|
uint64_t ru_msgrcv; /* IPC messages received */
|
||||||
|
uint64_t ru_nsignals; /* signals received */
|
||||||
|
uint64_t ru_nvcsw; /* voluntary context switches */
|
||||||
|
uint64_t ru_nivcsw; /* involuntary context switches */
|
||||||
|
} uv_rusage_t;
|
||||||
|
|
||||||
|
.. c:type:: uv_cpu_info_t
|
||||||
|
|
||||||
|
Data type for CPU information.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
typedef struct uv_cpu_info_s {
|
||||||
|
char* model;
|
||||||
|
int speed;
|
||||||
|
struct uv_cpu_times_s {
|
||||||
|
uint64_t user;
|
||||||
|
uint64_t nice;
|
||||||
|
uint64_t sys;
|
||||||
|
uint64_t idle;
|
||||||
|
uint64_t irq;
|
||||||
|
} cpu_times;
|
||||||
|
} uv_cpu_info_t;
|
||||||
|
|
||||||
|
.. c:type:: uv_interface_address_t
|
||||||
|
|
||||||
|
Data type for interface addresses.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
typedef struct uv_interface_address_s {
|
||||||
|
char* name;
|
||||||
|
char phys_addr[6];
|
||||||
|
int is_internal;
|
||||||
|
union {
|
||||||
|
struct sockaddr_in address4;
|
||||||
|
struct sockaddr_in6 address6;
|
||||||
|
} address;
|
||||||
|
union {
|
||||||
|
struct sockaddr_in netmask4;
|
||||||
|
struct sockaddr_in6 netmask6;
|
||||||
|
} netmask;
|
||||||
|
} uv_interface_address_t;
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: uv_handle_type uv_guess_handle(uv_file file)
|
||||||
|
|
||||||
|
Used to detect what type of stream should be used with a given file
|
||||||
|
descriptor. Usually this will be used during initialization to guess the
|
||||||
|
type of the stdio streams.
|
||||||
|
|
||||||
|
For ``isatty()`` functionality use this function and test for ``UV_TTY``.
|
||||||
|
|
||||||
|
.. c:function:: unsigned int uv_version(void)
|
||||||
|
|
||||||
|
Returns the libuv version packed into a single integer. 8 bits are used for
|
||||||
|
each component, with the patch number stored in the 8 least significant
|
||||||
|
bits. E.g. for libuv 1.2.3 this would return 0x010203.
|
||||||
|
|
||||||
|
.. c:function:: const char* uv_version_string(void)
|
||||||
|
|
||||||
|
Returns the libuv version number as a string. For non-release versions
|
||||||
|
"-pre" is appended, so the version number could be "1.2.3-pre".
|
||||||
|
|
||||||
|
.. c:function:: uv_buf_t uv_buf_init(char* base, unsigned int len)
|
||||||
|
|
||||||
|
Constructor for :c:type:`uv_buf_t`.
|
||||||
|
|
||||||
|
Due to platform differences the user cannot rely on the ordering of the
|
||||||
|
`base` and `len` members of the uv_buf_t struct. The user is responsible for
|
||||||
|
freeing `base` after the uv_buf_t is done. Return struct passed by value.
|
||||||
|
|
||||||
|
.. c:function:: char** uv_setup_args(int argc, char** argv)
|
||||||
|
|
||||||
|
Store the program arguments. Required for getting / setting the process title.
|
||||||
|
|
||||||
|
.. c:function:: int uv_get_process_title(char* buffer, size_t size)
|
||||||
|
|
||||||
|
Gets the title of the current process.
|
||||||
|
|
||||||
|
.. c:function:: int uv_set_process_title(const char* title)
|
||||||
|
|
||||||
|
Sets the current process title.
|
||||||
|
|
||||||
|
.. c:function:: int uv_resident_set_memory(size_t* rss)
|
||||||
|
|
||||||
|
Gets the resident set size (RSS) for the current process.
|
||||||
|
|
||||||
|
.. c:function:: int uv_uptime(double* uptime)
|
||||||
|
|
||||||
|
Gets the current system uptime.
|
||||||
|
|
||||||
|
.. c:function:: int uv_getrusage(uv_rusage_t* rusage)
|
||||||
|
|
||||||
|
Gets the resource usage measures for the current process.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
On Windows not all fields are set, the unsupported fields are filled with zeroes.
|
||||||
|
|
||||||
|
.. c:function:: int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count)
|
||||||
|
|
||||||
|
Gets information about the CPUs on the system. The `cpu_infos` array will
|
||||||
|
have `count` elements and needs to be freed with :c:func:`uv_free_cpu_info`.
|
||||||
|
|
||||||
|
.. c:function:: void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count)
|
||||||
|
|
||||||
|
Frees the `cpu_infos` array previously allocated with :c:func:`uv_cpu_info`.
|
||||||
|
|
||||||
|
.. c:function:: int uv_interface_addresses(uv_interface_address_t** addresses, int* count)
|
||||||
|
|
||||||
|
Gets address information about the network interfaces on the system. An
|
||||||
|
array of `count` elements is allocated and returned in `addresses`. It must
|
||||||
|
be freed by the user, calling :c:func:`uv_free_interface_addresses`.
|
||||||
|
|
||||||
|
.. c:function:: void uv_free_interface_addresses(uv_interface_address_t* addresses, int count)
|
||||||
|
|
||||||
|
Free an array of :c:type:`uv_interface_address_t` which was returned by
|
||||||
|
:c:func:`uv_interface_addresses`.
|
||||||
|
|
||||||
|
.. c:function:: void uv_loadavg(double avg[3])
|
||||||
|
|
||||||
|
Gets the load average. See: http://en.wikipedia.org/wiki/Load_(computing)
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Returns [0,0,0] on Windows (i.e., it's not implemented).
|
||||||
|
|
||||||
|
.. c:function:: int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr)
|
||||||
|
|
||||||
|
Convert a string containing an IPv4 addresses to a binary structure.
|
||||||
|
|
||||||
|
.. c:function:: int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr)
|
||||||
|
|
||||||
|
Convert a string containing an IPv6 addresses to a binary structure.
|
||||||
|
|
||||||
|
.. c:function:: int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size)
|
||||||
|
|
||||||
|
Convert a binary structure containing an IPv4 addres to a string.
|
||||||
|
|
||||||
|
.. c:function:: int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size)
|
||||||
|
|
||||||
|
Convert a binary structure containing an IPv6 addres to a string.
|
||||||
|
|
||||||
|
.. c:function:: int uv_inet_ntop(int af, const void* src, char* dst, size_t size)
|
||||||
|
.. c:function:: int uv_inet_pton(int af, const char* src, void* dst)
|
||||||
|
|
||||||
|
Cross-platform IPv6-capable implementation of the 'standard' ``inet_ntop()``
|
||||||
|
and ``inet_pton()`` functions. On success they return 0. In case of error
|
||||||
|
the target `dst` pointer is unmodified.
|
||||||
|
|
||||||
|
.. c:function:: int uv_exepath(char* buffer, size_t* size)
|
||||||
|
|
||||||
|
Gets the executable path.
|
||||||
|
|
||||||
|
.. c:function:: int uv_cwd(char* buffer, size_t* size)
|
||||||
|
|
||||||
|
Gets the current working directory.
|
||||||
|
|
||||||
|
.. c:function:: int uv_chdir(const char* dir)
|
||||||
|
|
||||||
|
Changes the current working directory.
|
||||||
|
|
||||||
|
.. uint64_t uv_get_free_memory(void)
|
||||||
|
.. c:function:: uint64_t uv_get_total_memory(void)
|
||||||
|
|
||||||
|
Gets memory information (in bytes).
|
||||||
|
|
||||||
|
.. c:function:: uint64_t uv_hrtime(void)
|
||||||
|
|
||||||
|
Returns the current high-resolution real time. This is expressed in
|
||||||
|
nanoseconds. It is relative to an arbitrary time in the past. It is not
|
||||||
|
related to the time of day and therefore not subject to clock drift. The
|
||||||
|
primary use is for measuring performance between intervals.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Not every platform can support nanosecond resolution; however, this value will always
|
||||||
|
be in nanoseconds.
|
86
deps/uv/docs/src/pipe.rst
vendored
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
|
||||||
|
.. _pipe:
|
||||||
|
|
||||||
|
:c:type:`uv_pipe_t` --- Pipe handle
|
||||||
|
===================================
|
||||||
|
|
||||||
|
Pipe handles provide an abstraction over local domain sockets on Unix and named
|
||||||
|
pipes on Windows.
|
||||||
|
|
||||||
|
:c:type:`uv_pipe_t` is a 'subclass' of :c:type:`uv_stream_t`.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_pipe_t
|
||||||
|
|
||||||
|
Pipe handle type.
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
N/A
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_stream_t` members also apply.
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle, int ipc)
|
||||||
|
|
||||||
|
Initialize a pipe handle. The `ipc` argument is a boolean to indicate if
|
||||||
|
this pipe will be used for handle passing between processes.
|
||||||
|
|
||||||
|
.. c:function:: int uv_pipe_open(uv_pipe_t*, uv_file file)
|
||||||
|
|
||||||
|
Open an existing file descriptor or HANDLE as a pipe.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
The user is responsible for setting the dile descriptor in non-blocking mode.
|
||||||
|
|
||||||
|
.. c:function:: int uv_pipe_bind(uv_pipe_t* handle, const char* name)
|
||||||
|
|
||||||
|
Bind the pipe to a file path (Unix) or a name (Windows).
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes, typically between
|
||||||
|
92 and 108 bytes.
|
||||||
|
|
||||||
|
.. c:function:: void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, const char* name, uv_connect_cb cb)
|
||||||
|
|
||||||
|
Connect to the Unix domain socket or the named pipe.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes, typically between
|
||||||
|
92 and 108 bytes.
|
||||||
|
|
||||||
|
.. c:function:: int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len)
|
||||||
|
|
||||||
|
Get the name of the Unix domain socket or the named pipe.
|
||||||
|
|
||||||
|
A preallocated buffer must be provided. The len parameter holds the length
|
||||||
|
of the buffer and it's set to the number of bytes written to the buffer on
|
||||||
|
output. If the buffer is not big enough ``UV_ENOBUFS`` will be returned and
|
||||||
|
len will contain the required size.
|
||||||
|
|
||||||
|
.. c:function:: void uv_pipe_pending_instances(uv_pipe_t* handle, int count)
|
||||||
|
|
||||||
|
Set the number of pending pipe instance handles when the pipe server is
|
||||||
|
waiting for connections.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
This setting applies to Windows only.
|
||||||
|
|
||||||
|
.. c:function:: int uv_pipe_pending_count(uv_pipe_t* handle)
|
||||||
|
.. c:function:: uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle)
|
||||||
|
|
||||||
|
Used to receive handles over IPC pipes.
|
||||||
|
|
||||||
|
First - call :c:func:`uv_pipe_pending_count`, if it's > 0 then initialize
|
||||||
|
a handle of the given `type`, returned by :c:func:`uv_pipe_pending_type`
|
||||||
|
and call ``uv_accept(pipe, handle)``.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_stream_t` API functions also apply.
|
99
deps/uv/docs/src/poll.rst
vendored
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
|
||||||
|
.. _poll:
|
||||||
|
|
||||||
|
:c:type:`uv_poll_t` --- Poll handle
|
||||||
|
===================================
|
||||||
|
|
||||||
|
Poll handles are used to watch file descriptors for readability and
|
||||||
|
writability, similar to the purpose of poll(2).
|
||||||
|
|
||||||
|
The purpose of poll handles is to enable integrating external libraries that
|
||||||
|
rely on the event loop to signal it about the socket status changes, like
|
||||||
|
c-ares or libssh2. Using uv_poll_t for any other purpose is not recommended;
|
||||||
|
:c:type:`uv_tcp_t`, :c:type:`uv_udp_t`, etc. provide an implementation that is faster and
|
||||||
|
more scalable than what can be achieved with :c:type:`uv_poll_t`, especially on
|
||||||
|
Windows.
|
||||||
|
|
||||||
|
It is possible that poll handles occasionally signal that a file descriptor is
|
||||||
|
readable or writable even when it isn't. The user should therefore always
|
||||||
|
be prepared to handle EAGAIN or equivalent when it attempts to read from or
|
||||||
|
write to the fd.
|
||||||
|
|
||||||
|
It is not okay to have multiple active poll handles for the same socket, this
|
||||||
|
can cause libuv to busyloop or otherwise malfunction.
|
||||||
|
|
||||||
|
The user should not close a file descriptor while it is being polled by an
|
||||||
|
active poll handle. This can cause the handle to report an error,
|
||||||
|
but it might also start polling another socket. However the fd can be safely
|
||||||
|
closed immediately after a call to :c:func:`uv_poll_stop` or :c:func:`uv_close`.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
On windows only sockets can be polled with poll handles. On Unix any file
|
||||||
|
descriptor that would be accepted by poll(2) can be used.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_poll_t
|
||||||
|
|
||||||
|
Poll handle type.
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_poll_cb)(uv_poll_t* handle, int status, int events)
|
||||||
|
|
||||||
|
Type definition for callback passed to :c:func:`uv_poll_start`.
|
||||||
|
|
||||||
|
.. c:type:: uv_poll_event
|
||||||
|
|
||||||
|
Poll event types
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
enum uv_poll_event {
|
||||||
|
UV_READABLE = 1,
|
||||||
|
UV_WRITABLE = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
N/A
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd)
|
||||||
|
|
||||||
|
Initialize the handle using a file descriptor.
|
||||||
|
|
||||||
|
.. c:function:: int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, uv_os_sock_t socket)
|
||||||
|
|
||||||
|
Initialize the handle using a socket descriptor. On Unix this is identical
|
||||||
|
to :c:func:`uv_poll_init`. On windows it takes a SOCKET handle.
|
||||||
|
|
||||||
|
.. c:function:: int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb)
|
||||||
|
|
||||||
|
Starts polling the file descriptor. `events` is a bitmask consisting made up
|
||||||
|
of UV_READABLE and UV_WRITABLE. As soon as an event is detected the callback
|
||||||
|
will be called with `status` set to 0, and the detected events set on the
|
||||||
|
`events` field.
|
||||||
|
|
||||||
|
If an error happens while polling, `status` will be < 0 and corresponds
|
||||||
|
with one of the UV_E* error codes (see :ref:`errors`). The user should
|
||||||
|
not close the socket while the handle is active. If the user does that
|
||||||
|
anyway, the callback *may* be called reporting an error status, but this
|
||||||
|
is **not** guaranteed.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Calling :c:func:`uv_poll_start` on a handle that is already active is fine. Doing so
|
||||||
|
will update the events mask that is being watched for.
|
||||||
|
|
||||||
|
.. c:function:: int uv_poll_stop(uv_poll_t* poll)
|
||||||
|
|
||||||
|
Stop polling the file descriptor, the callback will no longer be called.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
46
deps/uv/docs/src/prepare.rst
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
|
||||||
|
.. _prepare:
|
||||||
|
|
||||||
|
:c:type:`uv_prepare_t` --- Prepare handle
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
Prepare handles will run the given callback once per loop iteration, right
|
||||||
|
before polling for i/o.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_prepare_t
|
||||||
|
|
||||||
|
Prepare handle type.
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_prepare_cb)(uv_prepare_t* handle)
|
||||||
|
|
||||||
|
Type definition for callback passed to :c:func:`uv_prepare_start`.
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
N/A
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: int uv_prepare_init(uv_loop_t* loop, uv_prepare_t* prepare)
|
||||||
|
|
||||||
|
Initialize the handle.
|
||||||
|
|
||||||
|
.. c:function:: int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb)
|
||||||
|
|
||||||
|
Start the handle with the given callback.
|
||||||
|
|
||||||
|
.. c:function:: int uv_prepare_stop(uv_prepare_t* prepare)
|
||||||
|
|
||||||
|
Stop the handle, the callback will no longer be called.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
215
deps/uv/docs/src/process.rst
vendored
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
|
||||||
|
.. _process:
|
||||||
|
|
||||||
|
:c:type:`uv_process_t` --- Process handle
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
Process handles will spawn a new process and allow the user to control it and
|
||||||
|
establish communication channels with it using streams.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_process_t
|
||||||
|
|
||||||
|
Process handle type.
|
||||||
|
|
||||||
|
.. c:type:: uv_process_options_t
|
||||||
|
|
||||||
|
Options for spawning the process (passed to :c:func:`uv_spawn`.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
typedef struct uv_process_options_s {
|
||||||
|
uv_exit_cb exit_cb;
|
||||||
|
const char* file;
|
||||||
|
char** args;
|
||||||
|
char** env;
|
||||||
|
const char* cwd;
|
||||||
|
unsigned int flags;
|
||||||
|
int stdio_count;
|
||||||
|
uv_stdio_container_t* stdio;
|
||||||
|
uv_uid_t uid;
|
||||||
|
uv_gid_t gid;
|
||||||
|
} uv_process_options_t;
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_exit_cb)(uv_process_t*, int64_t exit_status, int term_signal)
|
||||||
|
|
||||||
|
Type definition for callback passed in :c:type:`uv_process_options_t` which
|
||||||
|
will indicate the exit status and the signal that caused the process to
|
||||||
|
terminate, if any.
|
||||||
|
|
||||||
|
.. c:type:: uv_process_flags
|
||||||
|
|
||||||
|
Flags to be set on the flags field of :c:type:`uv_process_options_t`.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
enum uv_process_flags {
|
||||||
|
/*
|
||||||
|
* Set the child process' user id.
|
||||||
|
*/
|
||||||
|
UV_PROCESS_SETUID = (1 << 0),
|
||||||
|
/*
|
||||||
|
* Set the child process' group id.
|
||||||
|
*/
|
||||||
|
UV_PROCESS_SETGID = (1 << 1),
|
||||||
|
/*
|
||||||
|
* Do not wrap any arguments in quotes, or perform any other escaping, when
|
||||||
|
* converting the argument list into a command line string. This option is
|
||||||
|
* only meaningful on Windows systems. On Unix it is silently ignored.
|
||||||
|
*/
|
||||||
|
UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS = (1 << 2),
|
||||||
|
/*
|
||||||
|
* Spawn the child process in a detached state - this will make it a process
|
||||||
|
* group leader, and will effectively enable the child to keep running after
|
||||||
|
* the parent exits. Note that the child process will still keep the
|
||||||
|
* parent's event loop alive unless the parent process calls uv_unref() on
|
||||||
|
* the child's process handle.
|
||||||
|
*/
|
||||||
|
UV_PROCESS_DETACHED = (1 << 3),
|
||||||
|
/*
|
||||||
|
* Hide the subprocess console window that would normally be created. This
|
||||||
|
* option is only meaningful on Windows systems. On Unix it is silently
|
||||||
|
* ignored.
|
||||||
|
*/
|
||||||
|
UV_PROCESS_WINDOWS_HIDE = (1 << 4)
|
||||||
|
};
|
||||||
|
|
||||||
|
.. c:type:: uv_stdio_container_t
|
||||||
|
|
||||||
|
Container for each stdio handle or fd passed to a child process.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
typedef struct uv_stdio_container_s {
|
||||||
|
uv_stdio_flags flags;
|
||||||
|
union {
|
||||||
|
uv_stream_t* stream;
|
||||||
|
int fd;
|
||||||
|
} data;
|
||||||
|
} uv_stdio_container_t;
|
||||||
|
|
||||||
|
.. c:type:: uv_stdio_flags
|
||||||
|
|
||||||
|
Flags specifying how a stdio should be transmitted to the child process.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UV_IGNORE = 0x00,
|
||||||
|
UV_CREATE_PIPE = 0x01,
|
||||||
|
UV_INHERIT_FD = 0x02,
|
||||||
|
UV_INHERIT_STREAM = 0x04,
|
||||||
|
/*
|
||||||
|
* When UV_CREATE_PIPE is specified, UV_READABLE_PIPE and UV_WRITABLE_PIPE
|
||||||
|
* determine the direction of flow, from the child process' perspective. Both
|
||||||
|
* flags may be specified to create a duplex data stream.
|
||||||
|
*/
|
||||||
|
UV_READABLE_PIPE = 0x10,
|
||||||
|
UV_WRITABLE_PIPE = 0x20
|
||||||
|
} uv_stdio_flags;
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. c:member:: uv_process_t.pid
|
||||||
|
|
||||||
|
The PID of the spawned process. It's set after calling :c:func:`uv_spawn`.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
The :c:type:`uv_handle_t` members also apply.
|
||||||
|
|
||||||
|
.. c:member:: uv_process_options_t.exit_cb
|
||||||
|
|
||||||
|
Callback called after the process exits.
|
||||||
|
|
||||||
|
.. c:member:: uv_process_options_t.file
|
||||||
|
|
||||||
|
Path pointing to the program to be executed.
|
||||||
|
|
||||||
|
.. c:member:: uv_process_options_t.args
|
||||||
|
|
||||||
|
Command line arguments. args[0] should be the path to the program. On
|
||||||
|
Windows this uses `CreateProcess` which concatenates the arguments into a
|
||||||
|
string this can cause some strange errors. See the
|
||||||
|
``UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS`` flag on :c:type:`uv_process_flags`.
|
||||||
|
|
||||||
|
.. c:member:: uv_process_options_t.env
|
||||||
|
|
||||||
|
Environment for the new process. If NULL the parents environment is used.
|
||||||
|
|
||||||
|
.. c:member:: uv_process_options_t.cwd
|
||||||
|
|
||||||
|
Current working directory for the subprocess.
|
||||||
|
|
||||||
|
.. c:member:: uv_process_options_t.flags
|
||||||
|
|
||||||
|
Various flags that control how :c:func:`uv_spawn` behaves. See
|
||||||
|
:c:type:`uv_process_flags`.
|
||||||
|
|
||||||
|
.. c:member:: uv_process_options_t.stdio_count
|
||||||
|
.. c:member:: uv_process_options_t.stdio
|
||||||
|
|
||||||
|
The `stdio` field points to an array of :c:type:`uv_stdio_container_t`
|
||||||
|
structs that describe the file descriptors that will be made available to
|
||||||
|
the child process. The convention is that stdio[0] points to stdin,
|
||||||
|
fd 1 is used for stdout, and fd 2 is stderr.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
On Windows file descriptors greater than 2 are available to the child process only if
|
||||||
|
the child processes uses the MSVCRT runtime.
|
||||||
|
|
||||||
|
.. c:member:: uv_process_options_t.uid
|
||||||
|
.. c:member:: uv_process_options_t.gid
|
||||||
|
|
||||||
|
Libuv can change the child process' user/group id. This happens only when
|
||||||
|
the appropriate bits are set in the flags fields.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
This is not supported on Windows, :c:func:`uv_spawn` will fail and set the error
|
||||||
|
to ``UV_ENOTSUP``.
|
||||||
|
|
||||||
|
.. c:member:: uv_stdio_container_t.flags
|
||||||
|
|
||||||
|
Flags specifying how the stdio container should be passed to the child. See
|
||||||
|
:c:type:`uv_stdio_flags`.
|
||||||
|
|
||||||
|
.. c:member:: uv_stdio_container_t.data
|
||||||
|
|
||||||
|
Union containing either the stream or fd to be passed on to the child
|
||||||
|
process.
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: void uv_disable_stdio_inheritance(void)
|
||||||
|
|
||||||
|
Disables inheritance for file descriptors / handles that this process
|
||||||
|
inherited from its parent. The effect is that child processes spawned by
|
||||||
|
this process don't accidentally inherit these handles.
|
||||||
|
|
||||||
|
It is recommended to call this function as early in your program as possible,
|
||||||
|
before the inherited file descriptors can be closed or duplicated.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
This function works on a best-effort basis: there is no guarantee that libuv can discover
|
||||||
|
all file descriptors that were inherited. In general it does a better job on Windows than
|
||||||
|
it does on Unix.
|
||||||
|
|
||||||
|
.. c:function:: int uv_spawn(uv_loop_t* loop, uv_process_t* handle, const uv_process_options_t* options)
|
||||||
|
|
||||||
|
Initializes the process handle and starts the process. If the process is
|
||||||
|
successfully spawned, this function will return 0. Otherwise, the
|
||||||
|
negative error code corresponding to the reason it couldn't spawn is
|
||||||
|
returned.
|
||||||
|
|
||||||
|
Possible reasons for failing to spawn would include (but not be limited to)
|
||||||
|
the file to execute not existing, not having permissions to use the setuid or
|
||||||
|
setgid specified, or not having enough memory to allocate for the new
|
||||||
|
process.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
82
deps/uv/docs/src/request.rst
vendored
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
|
||||||
|
.. _request:
|
||||||
|
|
||||||
|
:c:type:`uv_req_t` --- Base request
|
||||||
|
===================================
|
||||||
|
|
||||||
|
`uv_req_t` is the base type for all libuv request types.
|
||||||
|
|
||||||
|
Strcutures are aligned so that any libuv request can be cast to `uv_req_t`.
|
||||||
|
All API functions defined here work with any request type.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_req_t
|
||||||
|
|
||||||
|
The base libuv request structure.
|
||||||
|
|
||||||
|
.. c:type:: uv_any_req
|
||||||
|
|
||||||
|
Union of all request types.
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. c:member:: void* uv_request_t.data
|
||||||
|
|
||||||
|
Space for user-defined arbitrary data. libuv does not use this field.
|
||||||
|
|
||||||
|
.. c:member:: uv_req_type uv_req_t.type
|
||||||
|
|
||||||
|
Indicated the type of request. Readonly.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UV_UNKNOWN_REQ = 0,
|
||||||
|
UV_REQ,
|
||||||
|
UV_CONNECT,
|
||||||
|
UV_WRITE,
|
||||||
|
UV_SHUTDOWN,
|
||||||
|
UV_UDP_SEND,
|
||||||
|
UV_FS,
|
||||||
|
UV_WORK,
|
||||||
|
UV_GETADDRINFO,
|
||||||
|
UV_GETNAMEINFO,
|
||||||
|
UV_REQ_TYPE_PRIVATE,
|
||||||
|
UV_REQ_TYPE_MAX,
|
||||||
|
} uv_req_type;
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: int uv_cancel(uv_req_t* req)
|
||||||
|
|
||||||
|
Cancel a pending request. Fails if the request is executing or has finished
|
||||||
|
executing.
|
||||||
|
|
||||||
|
Returns 0 on success, or an error code < 0 on failure.
|
||||||
|
|
||||||
|
Only cancellation of :c:type:`uv_fs_t`, :c:type:`uv_getaddrinfo_t`,
|
||||||
|
:c:type:`uv_getnameinfo_t` and :c:type:`uv_work_t` requests is
|
||||||
|
currently supported.
|
||||||
|
|
||||||
|
Cancelled requests have their callbacks invoked some time in the future.
|
||||||
|
It's **not** safe to free the memory associated with the request until the
|
||||||
|
callback is called.
|
||||||
|
|
||||||
|
Here is how cancellation is reported to the callback:
|
||||||
|
|
||||||
|
* A :c:type:`uv_fs_t` request has its req->result field set to `UV_ECANCELED`.
|
||||||
|
|
||||||
|
* A :c:type:`uv_work_t`, :c:type:`uv_getaddrinfo_t` or c:type:`uv_getnameinfo_t`
|
||||||
|
request has its callback invoked with status == `UV_ECANCELED`.
|
||||||
|
|
||||||
|
.. c:function:: size_t uv_req_size(uv_req_type type)
|
||||||
|
|
||||||
|
Returns the size of the given request type. Useful for FFI binding writers
|
||||||
|
who don't want to know the structure layout.
|
77
deps/uv/docs/src/signal.rst
vendored
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
|
||||||
|
.. _signal:
|
||||||
|
|
||||||
|
:c:type:`uv_signal_t` --- Signal handle
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
Signal handles implement Unix style signal handling on a per-event loop bases.
|
||||||
|
|
||||||
|
Reception of some signals is emulated on Windows:
|
||||||
|
|
||||||
|
* SIGINT is normally delivered when the user presses CTRL+C. However, like
|
||||||
|
on Unix, it is not generated when terminal raw mode is enabled.
|
||||||
|
|
||||||
|
* SIGBREAK is delivered when the user pressed CTRL + BREAK.
|
||||||
|
|
||||||
|
* SIGHUP is generated when the user closes the console window. On SIGHUP the
|
||||||
|
program is given approximately 10 seconds to perform cleanup. After that
|
||||||
|
Windows will unconditionally terminate it.
|
||||||
|
|
||||||
|
* SIGWINCH is raised whenever libuv detects that the console has been
|
||||||
|
resized. SIGWINCH is emulated by libuv when the program uses a :c:type:`uv_tty_t`
|
||||||
|
handle to write to the console. SIGWINCH may not always be delivered in a
|
||||||
|
timely manner; libuv will only detect size changes when the cursor is
|
||||||
|
being moved. When a readable :c:type:`uv_tty_t` handle is used in raw mode,
|
||||||
|
resizing the console buffer will also trigger a SIGWINCH signal.
|
||||||
|
|
||||||
|
Watchers for other signals can be successfully created, but these signals
|
||||||
|
are never received. These signals are: `SIGILL`, `SIGABRT`, `SIGFPE`, `SIGSEGV`,
|
||||||
|
`SIGTERM` and `SIGKILL.`
|
||||||
|
|
||||||
|
Calls to raise() or abort() to programmatically raise a signal are
|
||||||
|
not detected by libuv; these will not trigger a signal watcher.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
On Linux SIGRT0 and SIGRT1 (signals 32 and 33) are used by the NPTL pthreads library to
|
||||||
|
manage threads. Installing watchers for those signals will lead to unpredictable behavior
|
||||||
|
and is strongly discouraged. Future versions of libuv may simply reject them.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_signal_t
|
||||||
|
|
||||||
|
Signal handle type.
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_signal_cb)(uv_signal_t* handle, int signum)
|
||||||
|
|
||||||
|
Type definition for callback passed to :c:func:`uv_signal_start`.
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. c:member:: int uv_signal_t.signum
|
||||||
|
|
||||||
|
Signal being monitored by this handle. Readonly.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: int uv_signal_init(uv_loop_t*, uv_signal_t* signal)
|
||||||
|
|
||||||
|
Initialize the handle.
|
||||||
|
|
||||||
|
.. c:function:: int uv_signal_start(uv_signal_t* signal, uv_signal_cb cb, int signum)
|
||||||
|
|
||||||
|
Start the handle with the given callback, watching for the given signal.
|
||||||
|
|
||||||
|
.. c:function:: int uv_signal_stop(uv_signal_t* signal)
|
||||||
|
|
||||||
|
Stop the handle, the callback will no longer be called.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
BIN
deps/uv/docs/src/static/architecture.png
vendored
Normal file
After Width: | Height: | Size: 202 KiB |
BIN
deps/uv/docs/src/static/diagrams.key/Data/st0-311.jpg
vendored
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
deps/uv/docs/src/static/diagrams.key/Data/st1-475.jpg
vendored
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
deps/uv/docs/src/static/diagrams.key/Index.zip
vendored
Normal file
8
deps/uv/docs/src/static/diagrams.key/Metadata/BuildVersionHistory.plist
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<array>
|
||||||
|
<string>Template: White (2014-02-28 09:41)</string>
|
||||||
|
<string>M6.2.2-1878-1</string>
|
||||||
|
</array>
|
||||||
|
</plist>
|
1
deps/uv/docs/src/static/diagrams.key/Metadata/DocumentIdentifier
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
F69E9CD9-EEF1-4223-9DA4-A1EA7FE112BA
|
BIN
deps/uv/docs/src/static/diagrams.key/Metadata/Properties.plist
vendored
Normal file
BIN
deps/uv/docs/src/static/diagrams.key/preview-micro.jpg
vendored
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
deps/uv/docs/src/static/diagrams.key/preview-web.jpg
vendored
Normal file
After Width: | Height: | Size: 7.9 KiB |
BIN
deps/uv/docs/src/static/diagrams.key/preview.jpg
vendored
Normal file
After Width: | Height: | Size: 105 KiB |
BIN
deps/uv/docs/src/static/favicon.ico
vendored
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
deps/uv/docs/src/static/logo.png
vendored
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
deps/uv/docs/src/static/loop_iteration.png
vendored
Normal file
After Width: | Height: | Size: 79 KiB |
189
deps/uv/docs/src/stream.rst
vendored
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
|
||||||
|
.. _stream:
|
||||||
|
|
||||||
|
:c:type:`uv_stream_t` --- Stream handle
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
Stream handles provide an abstraction of a duplex communication channel.
|
||||||
|
:c:type:`uv_stream_t` is an abstract type, libuv provides 3 stream implementations
|
||||||
|
in the for of :c:type:`uv_tcp_t`, :c:type:`uv_pipe_t` and :c:type:`uv_tty_t`.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_stream_t
|
||||||
|
|
||||||
|
Stream handle type.
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_read_cb)(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf)
|
||||||
|
|
||||||
|
Callback called when data was read on a stream.
|
||||||
|
|
||||||
|
`nread` is > 0 if there is data available, 0 if libuv is done reading for
|
||||||
|
now, or < 0 on error.
|
||||||
|
|
||||||
|
The callee is responsible for stopping closing the stream when an error happens
|
||||||
|
by calling :c:func:`uv_read_stop` or :c:func:`uv_close`. Trying to read
|
||||||
|
from the stream again is undefined.
|
||||||
|
|
||||||
|
The callee is responsible for freeing the buffer, libuv does not reuse it.
|
||||||
|
The buffer may be a null buffer (where buf->base=NULL and buf->len=0) on
|
||||||
|
error.
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_write_cb)(uv_write_t* req, int status)
|
||||||
|
|
||||||
|
Callback called after data was written on a stream. `status` will be 0 in
|
||||||
|
case of success, < 0 otherwise.
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_connect_cb)(uv_connect_t* req, int status)
|
||||||
|
|
||||||
|
Callback called after a connection started by :c:func:`uv_connect` is done.
|
||||||
|
`status` will be 0 in case of success, < 0 otherwise.
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_shutdown_cb)(uv_shutdown_t* req, int status)
|
||||||
|
|
||||||
|
Callback called after s shutdown request has been completed. `status` will
|
||||||
|
be 0 in case of success, < 0 otherwise.
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_connection_cb)(uv_stream_t* server, int status)
|
||||||
|
|
||||||
|
Callback called when a stream server has received an incoming connection.
|
||||||
|
The user can accept the connection by calling :c:func:`uv_accept`.
|
||||||
|
`status` will de 0 in case of success, < 0 otherwise.
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. c:member:: size_t uv_stream_t.write_queue_size
|
||||||
|
|
||||||
|
Contains the amount of queued bytes waiting to be sent. Readonly.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb)
|
||||||
|
|
||||||
|
Shutdown the outgoing (write) side of a duplex stream. It waits for pending
|
||||||
|
write requests to complete. The `handle` should refer to a initialized stream.
|
||||||
|
`req` should be an uninitialized shutdown request struct. The `cb` is called
|
||||||
|
after shutdown is complete.
|
||||||
|
|
||||||
|
.. c:function:: int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb)
|
||||||
|
|
||||||
|
Start listening for incoming connections. `backlog` indicates the number of
|
||||||
|
connections the kernel might queue, same as ``listen(2)``. When a new
|
||||||
|
incoming connection is received the :c:type:`uv_connection_cb` callback is
|
||||||
|
called.
|
||||||
|
|
||||||
|
.. c:function:: int uv_accept(uv_stream_t* server, uv_stream_t* client)
|
||||||
|
|
||||||
|
This call is used in conjunction with :c:func:`uv_listen` to accept incoming
|
||||||
|
connections. Call this function after receiving a :c:type:`uv_connection_cb`
|
||||||
|
to accept the connection. Before calling this function the client handle must
|
||||||
|
be initialized. < 0 return value indicates an error.
|
||||||
|
|
||||||
|
When the :c:type:`uv_connection_cb` callback is called it is guaranteed that
|
||||||
|
this function will complete successfully the first time. If you attempt to use
|
||||||
|
it more than once, it may fail. It is suggested to only call this function once
|
||||||
|
per :c:type:`uv_connection_cb` call.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
`server` and `client` must be handles running on the same loop.
|
||||||
|
|
||||||
|
.. c:function:: int uv_read_start(uv_stream_t*, uv_alloc_cb alloc_cb, uv_read_cb read_cb)
|
||||||
|
|
||||||
|
Read data from an incoming stream. The callback will be made several
|
||||||
|
times until there is no more data to read or :c:func:`uv_read_stop` is called.
|
||||||
|
When we've reached EOF `nread` will be set to ``UV_EOF``.
|
||||||
|
|
||||||
|
When `nread` < 0, the `buf` parameter might not point to a valid buffer;
|
||||||
|
in that case `buf.len` and `buf.base` are both set to 0.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
`nread` might also be 0, which does *not* indicate an error or EOF, it happens when
|
||||||
|
libuv requested a buffer through the alloc callback but then decided that it didn't
|
||||||
|
need that buffer.
|
||||||
|
|
||||||
|
.. c:function:: int uv_read_stop(uv_stream_t*)
|
||||||
|
|
||||||
|
Stop reading data from the stream. The :c:type:`uv_read_cb` callback will
|
||||||
|
no longer be called.
|
||||||
|
|
||||||
|
.. 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:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
uv_buf_t a[] = {
|
||||||
|
{ .base = "1", .len = 1 },
|
||||||
|
{ .base = "2", .len = 1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
uv_buf_t b[] = {
|
||||||
|
{ .base = "3", .len = 1 },
|
||||||
|
{ .base = "4", .len = 1 }
|
||||||
|
};
|
||||||
|
|
||||||
|
uv_write_t req1;
|
||||||
|
uv_write_t req2;
|
||||||
|
|
||||||
|
/* writes "1234" */
|
||||||
|
uv_write(&req1, stream, a, 2);
|
||||||
|
uv_write(&req2, stream, b, 2);
|
||||||
|
|
||||||
|
.. c:function:: int uv_write2(uv_write_t* req, uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle, uv_write_cb cb)
|
||||||
|
|
||||||
|
Extended write function for sending handles over a pipe. The pipe must be
|
||||||
|
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.
|
||||||
|
|
||||||
|
.. c:function:: int uv_try_write(uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs)
|
||||||
|
|
||||||
|
Same as :c:func:`uv_write`, but won't queue a write request if it can't be
|
||||||
|
completed immediately.
|
||||||
|
|
||||||
|
Will return either:
|
||||||
|
|
||||||
|
* > 0: number of bytes written (can be less than the supplied buffer size).
|
||||||
|
* < 0: negative error code (``UV_EAGAIN`` is returned if no data can be sent
|
||||||
|
immediately).
|
||||||
|
|
||||||
|
.. c:function:: int uv_is_readable(const uv_stream_t* handle)
|
||||||
|
|
||||||
|
Returns 1 if the stream is readable, 0 otherwise.
|
||||||
|
|
||||||
|
.. c:function:: int uv_is_writable(const uv_stream_t* handle)
|
||||||
|
|
||||||
|
Returns 1 if the stream is writable, 0 otherwise.
|
||||||
|
|
||||||
|
.. c:function:: int uv_stream_set_blocking(uv_stream_t* handle, int blocking)
|
||||||
|
|
||||||
|
Enable or disable blocking mode for a stream.
|
||||||
|
|
||||||
|
When blocking mode is enabled all writes complete synchronously. The
|
||||||
|
interface remains unchanged otherwise, e.g. completion or failure of the
|
||||||
|
operation will still be reported through a callback which is made
|
||||||
|
asychronously.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
Relying too much on this API is not recommended. It is likely to change
|
||||||
|
significantly in the future.
|
||||||
|
|
||||||
|
Currently this only works on Windows and only for
|
||||||
|
:c:type:`uv_pipe_t` handles.
|
||||||
|
|
||||||
|
Also libuv currently makes no ordering guarantee when the blocking mode
|
||||||
|
is changed after write requests have already been submitted. Therefore it is
|
||||||
|
recommended to set the blocking mode immediately after opening or creating
|
||||||
|
the stream.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
97
deps/uv/docs/src/tcp.rst
vendored
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
|
||||||
|
.. _tcp:
|
||||||
|
|
||||||
|
:c:type:`uv_tcp_t` --- TCP handle
|
||||||
|
=================================
|
||||||
|
|
||||||
|
TCP handles are used to represent both TCP streams and servers.
|
||||||
|
|
||||||
|
:c:type:`uv_tcp_t` is a 'subclass' of :c:type:`uv_stream_t`.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_tcp_t
|
||||||
|
|
||||||
|
TCP handle type.
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
N/A
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_stream_t` members also apply.
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle)
|
||||||
|
|
||||||
|
Initialize the handle.
|
||||||
|
|
||||||
|
.. c:function:: int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock)
|
||||||
|
|
||||||
|
Open an existing file descriptor or SOCKET as a TCP handle.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
The user is responsible for setting the file descriptor in
|
||||||
|
non-blocking mode.
|
||||||
|
|
||||||
|
.. c:function:: int uv_tcp_nodelay(uv_tcp_t* handle, int enable)
|
||||||
|
|
||||||
|
Enable / disable Nagle's algorithm.
|
||||||
|
|
||||||
|
.. c:function:: int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay)
|
||||||
|
|
||||||
|
Enable / disable TCP keep-alive. `delay` is the initial delay in seconds,
|
||||||
|
ignored when `enable` is zero.
|
||||||
|
|
||||||
|
.. c:function:: int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable)
|
||||||
|
|
||||||
|
Enable / disable simultaneous asynchronous accept requests that are
|
||||||
|
queued by the operating system when listening for new TCP connections.
|
||||||
|
|
||||||
|
This setting is used to tune a TCP server for the desired performance.
|
||||||
|
Having simultaneous accepts can significantly improve the rate of accepting
|
||||||
|
connections (which is why it is enabled by default) but may lead to uneven
|
||||||
|
load distribution in multi-process setups.
|
||||||
|
|
||||||
|
.. c:function:: int uv_tcp_bind(uv_tcp_t* handle, const struct sockaddr* addr, unsigned int flags)
|
||||||
|
|
||||||
|
Bind the handle to an address and port. `addr` should point to an
|
||||||
|
initialized ``struct sockaddr_in`` or ``struct sockaddr_in6``.
|
||||||
|
|
||||||
|
When the port is already taken, you can expect to see an ``UV_EADDRINUSE``
|
||||||
|
error from either :c:func:`uv_tcp_bind`, :c:func:`uv_listen` or
|
||||||
|
:c:func:`uv_tcp_connect`. That is, a successful call to this function does
|
||||||
|
not guarantee that the call to :c:func:`uv_listen` or :c:func:`uv_tcp_connect`
|
||||||
|
will succeed as well.
|
||||||
|
|
||||||
|
`flags` con contain ``UV_TCP_IPV6ONLY``, in which case dual-stack support
|
||||||
|
is disabled and only IPv6 is used.
|
||||||
|
|
||||||
|
.. c:function:: int uv_tcp_getsockname(const uv_tcp_t* handle, struct sockaddr* name, int* namelen)
|
||||||
|
|
||||||
|
Get the current address to which the handle is bound. `addr` must point to
|
||||||
|
a valid and big enough chunk of memory, ``struct sockaddr_storage`` is
|
||||||
|
recommended for IPv4 and IPv6 support.
|
||||||
|
|
||||||
|
.. c:function:: int uv_tcp_getpeername(const uv_tcp_t* handle, struct sockaddr* name, int* namelen)
|
||||||
|
|
||||||
|
Get the address of the peer connected to the handle. `addr` must point to
|
||||||
|
a valid and big enough chunk of memory, ``struct sockaddr_storage`` is
|
||||||
|
recommended for IPv4 and IPv6 support.
|
||||||
|
|
||||||
|
.. c:function:: int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle, const struct sockaddr* addr, uv_connect_cb cb)
|
||||||
|
|
||||||
|
Establish an IPv4 or IPv6 TCP connection. Provide an initialized TCP handle
|
||||||
|
and an uninitialized :c:type:`uv_connect_t`. `addr` should point to an
|
||||||
|
initialized ``struct sockaddr_in`` or ``struct sockaddr_in6``.
|
||||||
|
|
||||||
|
The callback is made when the connection has been established or when a
|
||||||
|
connection error happened.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_stream_t` API functions also apply.
|
156
deps/uv/docs/src/threading.rst
vendored
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
|
||||||
|
.. _threading:
|
||||||
|
|
||||||
|
Threading and synchronization utilities
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
libuv provides cross-platform implementations for multiple threading and
|
||||||
|
synchronization primitives. The API largely follows the pthreads API.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_thread_t
|
||||||
|
|
||||||
|
Thread data type.
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_thread_cb)(void* arg)
|
||||||
|
|
||||||
|
Callback that is invoked to initialize thread execution. `arg` is the same
|
||||||
|
value that was passed to :c:func:`uv_thread_create`.
|
||||||
|
|
||||||
|
.. c:type:: uv_key_t
|
||||||
|
|
||||||
|
Thread-local key data type.
|
||||||
|
|
||||||
|
.. c:type:: uv_once_t
|
||||||
|
|
||||||
|
Once-only initializer data type.
|
||||||
|
|
||||||
|
.. c:type:: uv_mutex_t
|
||||||
|
|
||||||
|
Mutex data type.
|
||||||
|
|
||||||
|
.. c:type:: uv_rwlock_t
|
||||||
|
|
||||||
|
Read-write lock data type.
|
||||||
|
|
||||||
|
.. c:type:: uv_sem_t
|
||||||
|
|
||||||
|
Semaphore data type.
|
||||||
|
|
||||||
|
.. c:type:: uv_cond_t
|
||||||
|
|
||||||
|
Condition data type.
|
||||||
|
|
||||||
|
.. c:type:: uv_barrier_t
|
||||||
|
|
||||||
|
Barrier data type.
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
Threads
|
||||||
|
^^^^^^^
|
||||||
|
|
||||||
|
.. c:function:: int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg)
|
||||||
|
.. c:function:: unsigned long uv_thread_self(void)
|
||||||
|
.. c:function:: int uv_thread_join(uv_thread_t *tid)
|
||||||
|
|
||||||
|
Thread-local storage
|
||||||
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
The total thread-local storage size may be limited. That is, it may not be possible to
|
||||||
|
create many TLS keys.
|
||||||
|
|
||||||
|
.. c:function:: int uv_key_create(uv_key_t* key)
|
||||||
|
.. c:function:: void uv_key_delete(uv_key_t* key)
|
||||||
|
.. c:function:: void* uv_key_get(uv_key_t* key)
|
||||||
|
.. c:function:: void uv_key_set(uv_key_t* key, void* value)
|
||||||
|
|
||||||
|
Once-only initialization
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Runs a function once and only once. Concurrent calls to :c:func:`uv_once` with the
|
||||||
|
same guard will block all callers except one (it's unspecified which one).
|
||||||
|
The guard should be initialized statically with the UV_ONCE_INIT macro.
|
||||||
|
|
||||||
|
.. c:function:: void uv_once(uv_once_t* guard, void (*callback)(void))
|
||||||
|
|
||||||
|
Mutex locks
|
||||||
|
^^^^^^^^^^^
|
||||||
|
|
||||||
|
Functions return 0 on success or an error code < 0 (unless the
|
||||||
|
return type is void, of course).
|
||||||
|
|
||||||
|
.. c:function:: int uv_mutex_init(uv_mutex_t* handle)
|
||||||
|
.. c:function:: void uv_mutex_destroy(uv_mutex_t* handle)
|
||||||
|
.. c:function:: void uv_mutex_lock(uv_mutex_t* handle)
|
||||||
|
.. c:function:: int uv_mutex_trylock(uv_mutex_t* handle)
|
||||||
|
.. c:function:: void uv_mutex_unlock(uv_mutex_t* handle)
|
||||||
|
|
||||||
|
Read-write locks
|
||||||
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Functions return 0 on success or an error code < 0 (unless the
|
||||||
|
return type is void, of course).
|
||||||
|
|
||||||
|
.. c:function:: int uv_rwlock_init(uv_rwlock_t* rwlock)
|
||||||
|
.. c:function:: void uv_rwlock_destroy(uv_rwlock_t* rwlock)
|
||||||
|
.. c:function:: void uv_rwlock_rdlock(uv_rwlock_t* rwlock)
|
||||||
|
.. c:function:: int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock)
|
||||||
|
.. c:function:: void uv_rwlock_rdunlock(uv_rwlock_t* rwlock)
|
||||||
|
.. c:function:: void uv_rwlock_wrlock(uv_rwlock_t* rwlock)
|
||||||
|
.. c:function:: int uv_rwlock_trywrlock(uv_rwlock_t* rwlock)
|
||||||
|
.. c:function:: void uv_rwlock_wrunlock(uv_rwlock_t* rwlock)
|
||||||
|
|
||||||
|
Semaphores
|
||||||
|
^^^^^^^^^^
|
||||||
|
|
||||||
|
Functions return 0 on success or an error code < 0 (unless the
|
||||||
|
return type is void, of course).
|
||||||
|
|
||||||
|
.. c:function:: int uv_sem_init(uv_sem_t* sem, unsigned int value)
|
||||||
|
.. c:function:: void uv_sem_destroy(uv_sem_t* sem)
|
||||||
|
.. c:function:: void uv_sem_post(uv_sem_t* sem)
|
||||||
|
.. c:function:: void uv_sem_wait(uv_sem_t* sem)
|
||||||
|
.. c:function:: int uv_sem_trywait(uv_sem_t* sem)
|
||||||
|
|
||||||
|
Conditions
|
||||||
|
^^^^^^^^^^
|
||||||
|
|
||||||
|
Functions return 0 on success or an error code < 0 (unless the
|
||||||
|
return type is void, of course).
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Callers should be prepared to deal with spurious wakeups on :c:func:`uv_cond_wait` and
|
||||||
|
:c:func:`uv_cond_timedwait`.
|
||||||
|
|
||||||
|
.. c:function:: int uv_cond_init(uv_cond_t* cond)
|
||||||
|
.. c:function:: void uv_cond_destroy(uv_cond_t* cond)
|
||||||
|
.. c:function:: void uv_cond_signal(uv_cond_t* cond)
|
||||||
|
.. c:function:: void uv_cond_broadcast(uv_cond_t* cond)
|
||||||
|
.. c:function:: void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex)
|
||||||
|
.. c:function:: int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout)
|
||||||
|
|
||||||
|
Barriers
|
||||||
|
^^^^^^^^
|
||||||
|
|
||||||
|
Functions return 0 on success or an error code < 0 (unless the
|
||||||
|
return type is void, of course).
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
:c:func:`uv_barrier_wait` returns a value > 0 to an arbitrarily chosen "serializer" thread
|
||||||
|
to facilitate cleanup, i.e.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
if (uv_barrier_wait(&barrier) > 0)
|
||||||
|
uv_barrier_destroy(&barrier);
|
||||||
|
|
||||||
|
.. c:function:: int uv_barrier_init(uv_barrier_t* barrier, unsigned int count)
|
||||||
|
.. c:function:: void uv_barrier_destroy(uv_barrier_t* barrier)
|
||||||
|
.. c:function:: int uv_barrier_wait(uv_barrier_t* barrier)
|
59
deps/uv/docs/src/threadpool.rst
vendored
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
|
||||||
|
.. _threadpool:
|
||||||
|
|
||||||
|
Thread pool work scheduling
|
||||||
|
===========================
|
||||||
|
|
||||||
|
libuv provides a threadpool which can be used to run user code and get notified
|
||||||
|
in the loop thread. This thread pool is internally used to run al filesystem
|
||||||
|
operations, as well as getaddrinfo and getnameinfo requests.
|
||||||
|
|
||||||
|
Its default size is 4, but it can be changed at startup time by setting the
|
||||||
|
``UV_THREADPOOL_SIZE`` environment variable to any value (the absolute maximum
|
||||||
|
is 128).
|
||||||
|
|
||||||
|
The threadpool is global and shared across all event loops.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_work_t
|
||||||
|
|
||||||
|
Work request type.
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_work_cb)(uv_work_t* req)
|
||||||
|
|
||||||
|
Callback passed to :c:func:`uv_queue_work` which will be run on the thread
|
||||||
|
pool.
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_after_work_cb)(uv_work_t* req, int status)
|
||||||
|
|
||||||
|
Callback passed to :c:func:`uv_queue_work` which will be called on the loop
|
||||||
|
thread after the work on the threadpool has been completed. If the work
|
||||||
|
was cancelled using :c:func:`uv_cancel` `status` will be ``UV_ECANCELED``.
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. c:member:: uv_loop_t* uv_work_t.loop
|
||||||
|
|
||||||
|
Loop that started this request and where completion will be reported.
|
||||||
|
Readonly.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_req_t` members also apply.
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb, uv_after_work_cb after_work_cb)
|
||||||
|
|
||||||
|
Initializes a work request which will run the given `work_cb` in a thread
|
||||||
|
from the threadpool. Once `work_cb` is completed, `after_work_cb` will be
|
||||||
|
called on the loop thread.
|
||||||
|
|
||||||
|
This request can be cancelled with :c:func:`uv_cancel`.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_req_t` API functions also apply.
|
68
deps/uv/docs/src/timer.rst
vendored
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
|
||||||
|
.. _timer:
|
||||||
|
|
||||||
|
:c:type:`uv_timer_t` --- Timer handle
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Timer handles are used to schedule callbacks to be called in the future.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_timer_t
|
||||||
|
|
||||||
|
Timer handle type.
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_timer_cb)(uv_timer_t* handle)
|
||||||
|
|
||||||
|
Type definition for callback passed to :c:func:`uv_timer_start`.
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
N/A
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle)
|
||||||
|
|
||||||
|
Initialize the handle.
|
||||||
|
|
||||||
|
.. c:function:: int uv_timer_start(uv_timer_t* handle, uv_timer_cb cb, uint64_t timeout, uint64_t repeat)
|
||||||
|
|
||||||
|
Start the timer. `timeout` and `repeat` are in milliseconds.
|
||||||
|
|
||||||
|
If `timeout` is zero, the callback fires on the next event loop iteration.
|
||||||
|
If `repeat` is non-zero, the callback fires first after `timeout`
|
||||||
|
milliseconds and then repeatedly after `repeat` milliseconds.
|
||||||
|
|
||||||
|
.. c:function:: int uv_timer_stop(uv_timer_t* handle)
|
||||||
|
|
||||||
|
Stop the timer, the callback will not be called anymore.
|
||||||
|
|
||||||
|
.. c:function:: int uv_timer_again(uv_timer_t* handle)
|
||||||
|
|
||||||
|
Stop the timer, and if it is repeating restart it using the repeat value
|
||||||
|
as the timeout. If the timer has never been started before it returns
|
||||||
|
UV_EINVAL.
|
||||||
|
|
||||||
|
.. c:function:: void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat)
|
||||||
|
|
||||||
|
Set the repeat value in milliseconds.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
If the repeat value is set from a timer callback it does not immediately take effect.
|
||||||
|
If the timer was non-repeating before, it will have been stopped. If it was repeating,
|
||||||
|
then the old repeat value will have been used to schedule the next timeout.
|
||||||
|
|
||||||
|
.. c:function:: uint64_t uv_timer_get_repeat(const uv_timer_t* handle)
|
||||||
|
|
||||||
|
Get the timer repeat value.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
63
deps/uv/docs/src/tty.rst
vendored
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
|
||||||
|
.. _tty:
|
||||||
|
|
||||||
|
:c:type:`uv_tty_t` --- TTY handle
|
||||||
|
=================================
|
||||||
|
|
||||||
|
TTY handles represent a stream for the console.
|
||||||
|
|
||||||
|
:c:type:`uv_tty_t` is a 'subclass' of :c:type:`uv_stream_t`.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_tty_t
|
||||||
|
|
||||||
|
TTY handle type.
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
N/A
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_stream_t` members also apply.
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int readable)
|
||||||
|
|
||||||
|
Initialize a new TTY stream with the given file descriptor. Usually the
|
||||||
|
file descriptor will be:
|
||||||
|
|
||||||
|
* 0 = stdin
|
||||||
|
* 1 = stdout
|
||||||
|
* 2 = stderr
|
||||||
|
|
||||||
|
`readable`, specifies if you plan on calling :c:func:`uv_read_start` with
|
||||||
|
this stream. stdin is readable, stdout is not.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
TTY streams which are not readable have blocking writes.
|
||||||
|
|
||||||
|
.. c:function:: int uv_tty_set_mode(uv_tty_t*, int mode)
|
||||||
|
|
||||||
|
Set the TTY mode. 0 for normal, 1 for raw.
|
||||||
|
|
||||||
|
.. c:function:: int uv_tty_reset_mode(void)
|
||||||
|
|
||||||
|
To be called when the program exits. Resets TTY settings to default
|
||||||
|
values for the next process to take over.
|
||||||
|
|
||||||
|
This function is async signal-safe on Unix platforms but can fail with error
|
||||||
|
code ``UV_EBUSY`` if you call it when execution is inside
|
||||||
|
:c:func:`uv_tty_set_mode`.
|
||||||
|
|
||||||
|
.. c:function:: int uv_tty_get_winsize(uv_tty_t*, int* width, int* height)
|
||||||
|
|
||||||
|
Gets the current Window size. On success it returns 0.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_stream_t` API functions also apply.
|
280
deps/uv/docs/src/udp.rst
vendored
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
|
||||||
|
.. _udp:
|
||||||
|
|
||||||
|
:c:type:`uv_udp_t` --- UDP handle
|
||||||
|
=================================
|
||||||
|
|
||||||
|
UDP handles encapsulate UDP communication for both clients and servers.
|
||||||
|
|
||||||
|
|
||||||
|
Data types
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. c:type:: uv_udp_t
|
||||||
|
|
||||||
|
UDP handle type.
|
||||||
|
|
||||||
|
.. c:type:: uv_udp_send_t
|
||||||
|
|
||||||
|
UDP send request type.
|
||||||
|
|
||||||
|
.. c:type:: uv_udp_flags
|
||||||
|
|
||||||
|
Flags used in :c:func:`uv_udp_bind` and :c:type:`uv_udp_recv_cb`..
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
enum uv_udp_flags {
|
||||||
|
/* Disables dual stack mode. */
|
||||||
|
UV_UDP_IPV6ONLY = 1,
|
||||||
|
/*
|
||||||
|
* Indicates message was truncated because read buffer was too small. The
|
||||||
|
* remainder was discarded by the OS. Used in uv_udp_recv_cb.
|
||||||
|
*/
|
||||||
|
UV_UDP_PARTIAL = 2,
|
||||||
|
/*
|
||||||
|
* Indicates if SO_REUSEADDR will be set when binding the handle in
|
||||||
|
* uv_udp_bind.
|
||||||
|
* This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other
|
||||||
|
* Unix platforms, it sets the SO_REUSEADDR flag. What that means is that
|
||||||
|
* multiple threads or processes can bind to the same address without error
|
||||||
|
* (provided they all set the flag) but only the last one to bind will receive
|
||||||
|
* any traffic, in effect "stealing" the port from the previous listener.
|
||||||
|
*/
|
||||||
|
UV_UDP_REUSEADDR = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_udp_send_cb)(uv_udp_send_t* req, int status)
|
||||||
|
|
||||||
|
Type definition for callback passed to :c:func:`uv_udp_send`, which is
|
||||||
|
called after the data was sent.
|
||||||
|
|
||||||
|
.. c:type:: void (*uv_udp_recv_cb)(uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned flags)
|
||||||
|
|
||||||
|
Type definition for callback passed to :c:func:`uv_udp_recv_start`, which
|
||||||
|
is called when the endpoint receives data.
|
||||||
|
|
||||||
|
* `handle`: UDP handle
|
||||||
|
* `nread`: Number of bytes that have been received.
|
||||||
|
0 if there is no more data to read. You may discard or repurpose
|
||||||
|
the read buffer. Note that 0 may also mean that an empty datagram
|
||||||
|
was received (in this case `addr` is not NULL). < 0 if a transmission
|
||||||
|
error was detected.
|
||||||
|
* `buf`: :c:type:`uv_buf_t` with the received data.
|
||||||
|
* `addr`: ``struct sockaddr*`` containing the address of the sender.
|
||||||
|
Can be NULL. Valid for the duration of the callback only.
|
||||||
|
* `flags`: One or more or'ed UV_UDP_* constants. Right now only
|
||||||
|
``UV_UDP_PARTIAL`` is used.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
The receive callback will be called with `nread` == 0 and `addr` == NULL when there is
|
||||||
|
nothing to read, and with `nread` == 0 and `addr` != NULL when an empty UDP packet is
|
||||||
|
received.
|
||||||
|
|
||||||
|
.. c:type:: uv_membership
|
||||||
|
|
||||||
|
Membership type for a multicast address.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UV_LEAVE_GROUP = 0,
|
||||||
|
UV_JOIN_GROUP
|
||||||
|
} uv_membership;
|
||||||
|
|
||||||
|
|
||||||
|
Public members
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. c:member:: size_t uv_udp_t.send_queue_size
|
||||||
|
|
||||||
|
Number of bytes queued for sending. This field strictly shows how much
|
||||||
|
information is currently queued.
|
||||||
|
|
||||||
|
.. c:member:: size_t uv_udp_t.send_queue_count
|
||||||
|
|
||||||
|
Number of send requests currently in the queue awaiting to be processed.
|
||||||
|
|
||||||
|
.. c:member:: uv_udp_t* uv_udp_send_t.handle
|
||||||
|
|
||||||
|
UDP handle where this send request is taking place.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_handle_t` members also apply.
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
---
|
||||||
|
|
||||||
|
.. c:function:: int uv_udp_init(uv_loop_t*, uv_udp_t* handle)
|
||||||
|
|
||||||
|
Initialize a new UDP handle. The actual socket is created lazily.
|
||||||
|
Returns 0 on success.
|
||||||
|
|
||||||
|
.. c:function:: int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock)
|
||||||
|
|
||||||
|
Opens an existing file descriptor or Windows SOCKET as a UDP handle.
|
||||||
|
|
||||||
|
Unix only:
|
||||||
|
The only requirement of the `sock` argument is that it follows the datagram
|
||||||
|
contract (works in unconnected mode, supports sendmsg()/recvmsg(), etc).
|
||||||
|
In other words, other datagram-type sockets like raw sockets or netlink
|
||||||
|
sockets can also be passed to this function.
|
||||||
|
|
||||||
|
.. c:function:: int uv_udp_bind(uv_udp_t* handle, const struct sockaddr* addr, unsigned int flags)
|
||||||
|
|
||||||
|
Bind the UDP handle to an IP address and port.
|
||||||
|
|
||||||
|
:param handle: UDP handle. Should have been initialized with
|
||||||
|
:c:func:`uv_udp_init`.
|
||||||
|
|
||||||
|
:param addr: `struct sockaddr_in` or `struct sockaddr_in6`
|
||||||
|
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.
|
||||||
|
|
||||||
|
:returns: 0 on success, or an error code < 0 on failure.
|
||||||
|
|
||||||
|
.. c:function:: int uv_udp_getsockname(const uv_udp_t* handle, struct sockaddr* name, int* namelen)
|
||||||
|
|
||||||
|
Get the local IP and port of the UDP handle.
|
||||||
|
|
||||||
|
:param handle: UDP handle. Should have been initialized with
|
||||||
|
:c:func:`uv_udp_init` and bound.
|
||||||
|
|
||||||
|
:param name: Pointer to the structure to be filled with the address data.
|
||||||
|
In order to support IPv4 and IPv6 `struct sockaddr_storage` should be
|
||||||
|
used.
|
||||||
|
|
||||||
|
:param namelen: On input it indicates the data of the `name` field. On
|
||||||
|
output it indicates how much of it was filled.
|
||||||
|
|
||||||
|
:returns: 0 on success, or an error code < 0 on failure.
|
||||||
|
|
||||||
|
.. c:function:: int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr, const char* interface_addr, uv_membership membership)
|
||||||
|
|
||||||
|
Set membership for a multicast address
|
||||||
|
|
||||||
|
:param handle: UDP handle. Should have been initialized with
|
||||||
|
:c:func:`uv_udp_init`.
|
||||||
|
|
||||||
|
:param multicast_addr: Multicast address to set membership for.
|
||||||
|
|
||||||
|
:param interface_addr: Interface address.
|
||||||
|
|
||||||
|
:param membership: Should be ``UV_JOIN_GROUP`` or ``UV_LEAVE_GROUP``.
|
||||||
|
|
||||||
|
:returns: 0 on success, or an error code < 0 on failure.
|
||||||
|
|
||||||
|
.. c:function:: int uv_udp_set_multicast_loop(uv_udp_t* handle, int on)
|
||||||
|
|
||||||
|
Set IP multicast loop flag. Makes multicast packets loop back to
|
||||||
|
local sockets.
|
||||||
|
|
||||||
|
:param handle: UDP handle. Should have been initialized with
|
||||||
|
:c:func:`uv_udp_init`.
|
||||||
|
|
||||||
|
:param on: 1 for on, 0 for off.
|
||||||
|
|
||||||
|
:returns: 0 on success, or an error code < 0 on failure.
|
||||||
|
|
||||||
|
.. c:function:: int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl)
|
||||||
|
|
||||||
|
Set the multicast ttl.
|
||||||
|
|
||||||
|
:param handle: UDP handle. Should have been initialized with
|
||||||
|
:c:func:`uv_udp_init`.
|
||||||
|
|
||||||
|
:param ttl: 1 through 255.
|
||||||
|
|
||||||
|
:returns: 0 on success, or an error code < 0 on failure.
|
||||||
|
|
||||||
|
.. c:function:: int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr)
|
||||||
|
|
||||||
|
Set the multicast interface to send or receive data on.
|
||||||
|
|
||||||
|
:param handle: UDP handle. Should have been initialized with
|
||||||
|
:c:func:`uv_udp_init`.
|
||||||
|
|
||||||
|
:param interface_addr: interface address.
|
||||||
|
|
||||||
|
:returns: 0 on success, or an error code < 0 on failure.
|
||||||
|
|
||||||
|
.. c:function:: int uv_udp_set_broadcast(uv_udp_t* handle, int on)
|
||||||
|
|
||||||
|
Set broadcast on or off.
|
||||||
|
|
||||||
|
:param handle: UDP handle. Should have been initialized with
|
||||||
|
:c:func:`uv_udp_init`.
|
||||||
|
|
||||||
|
:param on: 1 for on, 0 for off.
|
||||||
|
|
||||||
|
:returns: 0 on success, or an error code < 0 on failure.
|
||||||
|
|
||||||
|
.. c:function:: int uv_udp_set_ttl(uv_udp_t* handle, int ttl)
|
||||||
|
|
||||||
|
Set the time to live.
|
||||||
|
|
||||||
|
:param handle: UDP handle. Should have been initialized with
|
||||||
|
:c:func:`uv_udp_init`.
|
||||||
|
|
||||||
|
:param ttl: 1 through 255.
|
||||||
|
|
||||||
|
:returns: 0 on success, or an error code < 0 on failure.
|
||||||
|
|
||||||
|
.. c:function:: int uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle, const uv_buf_t bufs[], unsigned int nbufs, const struct sockaddr* addr, uv_udp_send_cb send_cb)
|
||||||
|
|
||||||
|
Send data over the UDP socket. If the socket has not previously been bound
|
||||||
|
with :c:func:`uv_udp_bind` it will be bound to 0.0.0.0
|
||||||
|
(the "all interfaces" IPv4 address) and a random port number.
|
||||||
|
|
||||||
|
:param req: UDP request handle. Need not be initialized.
|
||||||
|
|
||||||
|
:param handle: UDP handle. Should have been initialized with
|
||||||
|
:c:func:`uv_udp_init`.
|
||||||
|
|
||||||
|
:param bufs: List of buffers to send.
|
||||||
|
|
||||||
|
:param nbufs: Number of buffers in `bufs`.
|
||||||
|
|
||||||
|
:param addr: `struct sockaddr_in` or `struct sockaddr_in6` with the
|
||||||
|
address and port of the remote peer.
|
||||||
|
|
||||||
|
:param send_cb: Callback to invoke when the data has been sent out.
|
||||||
|
|
||||||
|
:returns: 0 on success, or an error code < 0 on failure.
|
||||||
|
|
||||||
|
.. c:function:: int uv_udp_try_send(uv_udp_t* handle, const uv_buf_t bufs[], unsigned int nbufs, const struct sockaddr* addr)
|
||||||
|
|
||||||
|
Same as :c:func:`uv_udp_send`, but won't queue a send request if it can't
|
||||||
|
be completed immediately.
|
||||||
|
|
||||||
|
:returns: >= 0: number of bytes sent (it matches the given buffer size).
|
||||||
|
< 0: negative error code (``UV_EAGAIN`` is returned when the message
|
||||||
|
can't be sent immediately).
|
||||||
|
|
||||||
|
.. c:function:: int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb, uv_udp_recv_cb recv_cb)
|
||||||
|
|
||||||
|
Prepare for receiving data. If the socket has not previously been bound
|
||||||
|
with :c:func:`uv_udp_bind` it is bound to 0.0.0.0 (the "all interfaces"
|
||||||
|
IPv4 address) and a random port number.
|
||||||
|
|
||||||
|
:param handle: UDP handle. Should have been initialized with
|
||||||
|
:c:func:`uv_udp_init`.
|
||||||
|
|
||||||
|
:param alloc_cb: Callback to invoke when temporary storage is needed.
|
||||||
|
|
||||||
|
:param recv_cb: Callback to invoke with received data.
|
||||||
|
|
||||||
|
:returns: 0 on success, or an error code < 0 on failure.
|
||||||
|
|
||||||
|
.. c:function:: int uv_udp_recv_stop(uv_udp_t* handle)
|
||||||
|
|
||||||
|
Stop listening for incoming datagrams.
|
||||||
|
|
||||||
|
:param handle: UDP handle. Should have been initialized with
|
||||||
|
:c:func:`uv_udp_init`.
|
||||||
|
|
||||||
|
:returns: 0 on success, or an error code < 0 on failure.
|
||||||
|
|
||||||
|
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
|
6
deps/uv/include/uv-errno.h
vendored
@ -57,12 +57,6 @@
|
|||||||
# define UV__EACCES (-4092)
|
# define UV__EACCES (-4092)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(EADDRINFO) && !defined(_WIN32)
|
|
||||||
# define UV__EADDRINFO EADDRINFO
|
|
||||||
#else
|
|
||||||
# define UV__EADDRINFO (-4091)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(EADDRINUSE) && !defined(_WIN32)
|
#if defined(EADDRINUSE) && !defined(_WIN32)
|
||||||
# define UV__EADDRINUSE (-EADDRINUSE)
|
# define UV__EADDRINUSE (-EADDRINUSE)
|
||||||
#else
|
#else
|
||||||
|
47
deps/uv/include/uv-unix.h
vendored
@ -25,6 +25,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
@ -117,13 +118,14 @@ struct uv__async {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Note: May be cast to struct iovec. See writev(2). */
|
/* Note: May be cast to struct iovec. See writev(2). */
|
||||||
typedef struct {
|
typedef struct uv_buf_t {
|
||||||
char* base;
|
char* base;
|
||||||
size_t len;
|
size_t len;
|
||||||
} uv_buf_t;
|
} uv_buf_t;
|
||||||
|
|
||||||
typedef int uv_file;
|
typedef int uv_file;
|
||||||
typedef int uv_os_sock_t;
|
typedef int uv_os_sock_t;
|
||||||
|
typedef int uv_os_fd_t;
|
||||||
|
|
||||||
#define UV_ONCE_INIT PTHREAD_ONCE_INIT
|
#define UV_ONCE_INIT PTHREAD_ONCE_INIT
|
||||||
|
|
||||||
@ -155,6 +157,47 @@ typedef pthread_barrier_t uv_barrier_t;
|
|||||||
typedef gid_t uv_gid_t;
|
typedef gid_t uv_gid_t;
|
||||||
typedef uid_t uv_uid_t;
|
typedef uid_t uv_uid_t;
|
||||||
|
|
||||||
|
typedef struct dirent uv__dirent_t;
|
||||||
|
|
||||||
|
#if defined(DT_UNKNOWN)
|
||||||
|
# define HAVE_DIRENT_TYPES
|
||||||
|
# if defined(DT_REG)
|
||||||
|
# define UV__DT_FILE DT_REG
|
||||||
|
# else
|
||||||
|
# define UV__DT_FILE -1
|
||||||
|
# endif
|
||||||
|
# if defined(DT_DIR)
|
||||||
|
# define UV__DT_DIR DT_DIR
|
||||||
|
# else
|
||||||
|
# define UV__DT_DIR -2
|
||||||
|
# endif
|
||||||
|
# if defined(DT_LNK)
|
||||||
|
# define UV__DT_LINK DT_LNK
|
||||||
|
# else
|
||||||
|
# define UV__DT_LINK -3
|
||||||
|
# endif
|
||||||
|
# if defined(DT_FIFO)
|
||||||
|
# define UV__DT_FIFO DT_FIFO
|
||||||
|
# else
|
||||||
|
# define UV__DT_FIFO -4
|
||||||
|
# endif
|
||||||
|
# if defined(DT_SOCK)
|
||||||
|
# define UV__DT_SOCKET DT_SOCK
|
||||||
|
# else
|
||||||
|
# define UV__DT_SOCKET -5
|
||||||
|
# endif
|
||||||
|
# if defined(DT_CHR)
|
||||||
|
# define UV__DT_CHAR DT_CHR
|
||||||
|
# else
|
||||||
|
# define UV__DT_CHAR -6
|
||||||
|
# endif
|
||||||
|
# if defined(DT_BLK)
|
||||||
|
# define UV__DT_BLOCK DT_BLK
|
||||||
|
# else
|
||||||
|
# define UV__DT_BLOCK -7
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Platform-specific definitions for uv_dlopen support. */
|
/* Platform-specific definitions for uv_dlopen support. */
|
||||||
#define UV_DYNAMIC /* empty */
|
#define UV_DYNAMIC /* empty */
|
||||||
|
|
||||||
@ -176,7 +219,7 @@ typedef struct {
|
|||||||
uv_async_t wq_async; \
|
uv_async_t wq_async; \
|
||||||
uv_rwlock_t cloexec_lock; \
|
uv_rwlock_t cloexec_lock; \
|
||||||
uv_handle_t* closing_handles; \
|
uv_handle_t* closing_handles; \
|
||||||
void* process_handles[1][2]; \
|
void* process_handles[2]; \
|
||||||
void* prepare_handles[2]; \
|
void* prepare_handles[2]; \
|
||||||
void* check_handles[2]; \
|
void* check_handles[2]; \
|
||||||
void* idle_handles[2]; \
|
void* idle_handles[2]; \
|
||||||
|
13
deps/uv/include/uv-version.h
vendored
@ -23,16 +23,17 @@
|
|||||||
#define UV_VERSION_H
|
#define UV_VERSION_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Versions with an even minor version (e.g. 0.6.1 or 1.0.4) are API and ABI
|
* Versions with the same major number are ABI stable. API is allowed to
|
||||||
* stable. When the minor version is odd, the API can change between patch
|
* evolve between minor releases, but only in a backwards compatible way.
|
||||||
* releases. Make sure you update the -soname directives in configure.ac
|
* Make sure you update the -soname directives in configure.ac
|
||||||
* and uv.gyp whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but
|
* and uv.gyp whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but
|
||||||
* not UV_VERSION_PATCH.)
|
* not UV_VERSION_PATCH.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define UV_VERSION_MAJOR 0
|
#define UV_VERSION_MAJOR 1
|
||||||
#define UV_VERSION_MINOR 11
|
#define UV_VERSION_MINOR 0
|
||||||
#define UV_VERSION_PATCH 28
|
#define UV_VERSION_PATCH 0
|
||||||
#define UV_VERSION_IS_RELEASE 1
|
#define UV_VERSION_IS_RELEASE 1
|
||||||
|
#define UV_VERSION_SUFFIX "rc1"
|
||||||
|
|
||||||
#endif /* UV_VERSION_H */
|
#endif /* UV_VERSION_H */
|
||||||
|
34
deps/uv/include/uv-win.h
vendored
@ -39,6 +39,20 @@ typedef struct pollfd {
|
|||||||
} WSAPOLLFD, *PWSAPOLLFD, *LPWSAPOLLFD;
|
} WSAPOLLFD, *PWSAPOLLFD, *LPWSAPOLLFD;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef LOCALE_INVARIANT
|
||||||
|
# define LOCALE_INVARIANT 0x007f
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _malloca
|
||||||
|
# if defined(_DEBUG)
|
||||||
|
# define _malloca(size) malloc(size)
|
||||||
|
# define _freea(ptr) free(ptr)
|
||||||
|
# else
|
||||||
|
# define _malloca(size) alloca(size)
|
||||||
|
# define _freea(ptr)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <mswsock.h>
|
#include <mswsock.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
@ -215,8 +229,8 @@ typedef struct uv_buf_t {
|
|||||||
} uv_buf_t;
|
} uv_buf_t;
|
||||||
|
|
||||||
typedef int uv_file;
|
typedef int uv_file;
|
||||||
|
|
||||||
typedef SOCKET uv_os_sock_t;
|
typedef SOCKET uv_os_sock_t;
|
||||||
|
typedef HANDLE uv_os_fd_t;
|
||||||
|
|
||||||
typedef HANDLE uv_thread_t;
|
typedef HANDLE uv_thread_t;
|
||||||
|
|
||||||
@ -275,6 +289,19 @@ typedef struct uv_once_s {
|
|||||||
typedef unsigned char uv_uid_t;
|
typedef unsigned char uv_uid_t;
|
||||||
typedef unsigned char uv_gid_t;
|
typedef unsigned char uv_gid_t;
|
||||||
|
|
||||||
|
typedef struct uv__dirent_s {
|
||||||
|
int d_type;
|
||||||
|
char d_name[1];
|
||||||
|
} uv__dirent_t;
|
||||||
|
|
||||||
|
#define UV__DT_DIR UV_DIRENT_DIR
|
||||||
|
#define UV__DT_FILE UV_DIRENT_FILE
|
||||||
|
#define UV__DT_LINK UV_DIRENT_LINK
|
||||||
|
#define UV__DT_FIFO UV_DIRENT_FIFO
|
||||||
|
#define UV__DT_SOCKET UV_DIRENT_SOCKET
|
||||||
|
#define UV__DT_CHAR UV_DIRENT_CHAR
|
||||||
|
#define UV__DT_BLOCK UV_DIRENT_BLOCK
|
||||||
|
|
||||||
/* Platform-specific definitions for uv_dlopen support. */
|
/* Platform-specific definitions for uv_dlopen support. */
|
||||||
#define UV_DYNAMIC FAR WINAPI
|
#define UV_DYNAMIC FAR WINAPI
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -289,8 +316,6 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
|
|||||||
HANDLE iocp; \
|
HANDLE iocp; \
|
||||||
/* The current time according to the event loop. in msecs. */ \
|
/* The current time according to the event loop. in msecs. */ \
|
||||||
uint64_t time; \
|
uint64_t time; \
|
||||||
/* GetTickCount() result when the event loop time was last updated. */ \
|
|
||||||
DWORD last_tick_count; \
|
|
||||||
/* Tail of a single-linked circular queue of pending reqs. If the queue */ \
|
/* Tail of a single-linked circular queue of pending reqs. If the queue */ \
|
||||||
/* is empty, tail_ is NULL. If there is only one item, */ \
|
/* is empty, tail_ is NULL. If there is only one item, */ \
|
||||||
/* tail_->next_req == tail_ */ \
|
/* tail_->next_req == tail_ */ \
|
||||||
@ -443,7 +468,8 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
|
|||||||
int queue_len; \
|
int queue_len; \
|
||||||
} pending_ipc_info; \
|
} pending_ipc_info; \
|
||||||
uv_write_t* non_overlapped_writes_tail; \
|
uv_write_t* non_overlapped_writes_tail; \
|
||||||
void* reserved;
|
uv_mutex_t readfile_mutex; \
|
||||||
|
volatile HANDLE readfile_thread;
|
||||||
|
|
||||||
#define UV_PIPE_PRIVATE_FIELDS \
|
#define UV_PIPE_PRIVATE_FIELDS \
|
||||||
HANDLE handle; \
|
HANDLE handle; \
|
||||||
|
1281
deps/uv/include/uv.h
vendored
3
deps/uv/m4/.gitignore
vendored
@ -1,2 +1,5 @@
|
|||||||
# Ignore libtoolize-generated files.
|
# Ignore libtoolize-generated files.
|
||||||
*.m4
|
*.m4
|
||||||
|
!as_case.m4
|
||||||
|
!dtrace.m4
|
||||||
|
!libuv-check-flags.m4
|
21
deps/uv/m4/as_case.m4
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# AS_CASE(WORD, [PATTERN1], [IF-MATCHED1]...[DEFAULT])
|
||||||
|
# ----------------------------------------------------
|
||||||
|
# Expand into
|
||||||
|
# | case WORD in
|
||||||
|
# | PATTERN1) IF-MATCHED1 ;;
|
||||||
|
# | ...
|
||||||
|
# | *) DEFAULT ;;
|
||||||
|
# | esac
|
||||||
|
m4_define([_AS_CASE],
|
||||||
|
[m4_if([$#], 0, [m4_fatal([$0: too few arguments: $#])],
|
||||||
|
[$#], 1, [ *) $1 ;;],
|
||||||
|
[$#], 2, [ $1) m4_default([$2], [:]) ;;],
|
||||||
|
[ $1) m4_default([$2], [:]) ;;
|
||||||
|
$0(m4_shiftn(2, $@))])dnl
|
||||||
|
])
|
||||||
|
m4_defun([AS_CASE],
|
||||||
|
[m4_ifval([$2$3],
|
||||||
|
[case $1 in
|
||||||
|
_AS_CASE(m4_shift($@))
|
||||||
|
esac])])
|
||||||
|
|
66
deps/uv/m4/dtrace.m4
vendored
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
dnl Copyright (C) 2009 Sun Microsystems
|
||||||
|
dnl This file is free software; Sun Microsystems
|
||||||
|
dnl gives unlimited permission to copy and/or distribute it,
|
||||||
|
dnl with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
dnl ---------------------------------------------------------------------------
|
||||||
|
dnl Macro: PANDORA_ENABLE_DTRACE
|
||||||
|
dnl ---------------------------------------------------------------------------
|
||||||
|
AC_DEFUN([PANDORA_ENABLE_DTRACE],[
|
||||||
|
AC_ARG_ENABLE([dtrace],
|
||||||
|
[AS_HELP_STRING([--disable-dtrace],
|
||||||
|
[enable DTrace USDT probes. @<:@default=yes@:>@])],
|
||||||
|
[ac_cv_enable_dtrace="$enableval"],
|
||||||
|
[ac_cv_enable_dtrace="yes"])
|
||||||
|
|
||||||
|
AS_IF([test "$ac_cv_enable_dtrace" = "yes"],[
|
||||||
|
AC_CHECK_PROGS([DTRACE], [dtrace])
|
||||||
|
AS_IF([test "x$ac_cv_prog_DTRACE" = "xdtrace"],[
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([if dtrace works],[ac_cv_dtrace_works],[
|
||||||
|
cat >conftest.d <<_ACEOF
|
||||||
|
provider Example {
|
||||||
|
probe increment(int);
|
||||||
|
};
|
||||||
|
_ACEOF
|
||||||
|
$DTRACE -h -o conftest.h -s conftest.d 2>/dev/zero
|
||||||
|
AS_IF([test $? -eq 0],[ac_cv_dtrace_works=yes],
|
||||||
|
[ac_cv_dtrace_works=no])
|
||||||
|
rm -f conftest.h conftest.d
|
||||||
|
])
|
||||||
|
AS_IF([test "x$ac_cv_dtrace_works" = "xyes"],[
|
||||||
|
AC_DEFINE([HAVE_DTRACE], [1], [Enables DTRACE Support])
|
||||||
|
AC_CACHE_CHECK([if dtrace should instrument object files],
|
||||||
|
[ac_cv_dtrace_needs_objects],[
|
||||||
|
dnl DTrace on MacOSX does not use -G option
|
||||||
|
cat >conftest.d <<_ACEOF
|
||||||
|
provider Example {
|
||||||
|
probe increment(int);
|
||||||
|
};
|
||||||
|
_ACEOF
|
||||||
|
cat > conftest.c <<_ACEOF
|
||||||
|
#include "conftest.h"
|
||||||
|
void foo() {
|
||||||
|
EXAMPLE_INCREMENT(1);
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
$DTRACE -h -o conftest.h -s conftest.d 2>/dev/zero
|
||||||
|
$CC -c -o conftest.o conftest.c
|
||||||
|
$DTRACE -G -o conftest.d.o -s conftest.d conftest.o 2>/dev/zero
|
||||||
|
AS_IF([test $? -eq 0],[ac_cv_dtrace_needs_objects=yes],
|
||||||
|
[ac_cv_dtrace_needs_objects=no])
|
||||||
|
rm -f conftest.d.o conftest.d conftest.h conftest.o conftest.c
|
||||||
|
])
|
||||||
|
])
|
||||||
|
AC_SUBST(DTRACEFLAGS) dnl TODO: test for -G on OSX
|
||||||
|
ac_cv_have_dtrace=yes
|
||||||
|
])])
|
||||||
|
|
||||||
|
AM_CONDITIONAL([HAVE_DTRACE], [test "x$ac_cv_dtrace_works" = "xyes"])
|
||||||
|
AM_CONDITIONAL([DTRACE_NEEDS_OBJECTS],
|
||||||
|
[test "x$ac_cv_dtrace_needs_objects" = "xyes"])
|
||||||
|
|
||||||
|
])
|
||||||
|
dnl ---------------------------------------------------------------------------
|
||||||
|
dnl End Macro: PANDORA_ENABLE_DTRACE
|
||||||
|
dnl ---------------------------------------------------------------------------
|
319
deps/uv/m4/libuv-check-flags.m4
vendored
Normal file
@ -0,0 +1,319 @@
|
|||||||
|
dnl Macros to check the presence of generic (non-typed) symbols.
|
||||||
|
dnl Copyright (c) 2006-2008 Diego Pettenà <flameeyes gmail com>
|
||||||
|
dnl Copyright (c) 2006-2008 xine project
|
||||||
|
dnl
|
||||||
|
dnl This program is free software; you can redistribute it and/or modify
|
||||||
|
dnl it under the terms of the GNU General Public License as published by
|
||||||
|
dnl the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
dnl any later version.
|
||||||
|
dnl
|
||||||
|
dnl This program is distributed in the hope that it will be useful,
|
||||||
|
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
dnl GNU General Public License for more details.
|
||||||
|
dnl
|
||||||
|
dnl You should have received a copy of the GNU General Public License
|
||||||
|
dnl along with this program; if not, write to the Free Software
|
||||||
|
dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
dnl 02110-1301, USA.
|
||||||
|
dnl
|
||||||
|
dnl As a special exception, the copyright owners of the
|
||||||
|
dnl macro gives unlimited permission to copy, distribute and modify the
|
||||||
|
dnl configure scripts that are the output of Autoconf when processing the
|
||||||
|
dnl Macro. You need not follow the terms of the GNU General Public
|
||||||
|
dnl License when using or distributing such scripts, even though portions
|
||||||
|
dnl of the text of the Macro appear in them. The GNU General Public
|
||||||
|
dnl License (GPL) does govern all other use of the material that
|
||||||
|
dnl constitutes the Autoconf Macro.
|
||||||
|
dnl
|
||||||
|
dnl This special exception to the GPL applies to versions of the
|
||||||
|
dnl Autoconf Macro released by this project. When you make and
|
||||||
|
dnl distribute a modified version of the Autoconf Macro, you may extend
|
||||||
|
dnl this special exception to the GPL to apply to your modified version as
|
||||||
|
dnl well.
|
||||||
|
|
||||||
|
dnl Check if the flag is supported by compiler
|
||||||
|
dnl CC_CHECK_CFLAGS_SILENT([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
|
||||||
|
|
||||||
|
AC_DEFUN([CC_CHECK_CFLAGS_SILENT], [
|
||||||
|
AC_CACHE_VAL(AS_TR_SH([cc_cv_cflags_$1]),
|
||||||
|
[ac_save_CFLAGS="$CFLAGS"
|
||||||
|
CFLAGS="$CFLAGS $1"
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a;])],
|
||||||
|
[eval "AS_TR_SH([cc_cv_cflags_$1])='yes'"],
|
||||||
|
[eval "AS_TR_SH([cc_cv_cflags_$1])='no'"])
|
||||||
|
CFLAGS="$ac_save_CFLAGS"
|
||||||
|
])
|
||||||
|
|
||||||
|
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
|
||||||
|
[$2], [$3])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl Check if the flag is supported by compiler (cacheable)
|
||||||
|
dnl CC_CHECK_CFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
|
||||||
|
|
||||||
|
AC_DEFUN([CC_CHECK_CFLAGS], [
|
||||||
|
AC_CACHE_CHECK([if $CC supports $1 flag],
|
||||||
|
AS_TR_SH([cc_cv_cflags_$1]),
|
||||||
|
CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here!
|
||||||
|
)
|
||||||
|
|
||||||
|
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
|
||||||
|
[$2], [$3])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl CC_CHECK_CFLAG_APPEND(FLAG, [action-if-found], [action-if-not-found])
|
||||||
|
dnl Check for CFLAG and appends them to CFLAGS if supported
|
||||||
|
AC_DEFUN([CC_CHECK_CFLAG_APPEND], [
|
||||||
|
AC_CACHE_CHECK([if $CC supports $1 flag],
|
||||||
|
AS_TR_SH([cc_cv_cflags_$1]),
|
||||||
|
CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here!
|
||||||
|
)
|
||||||
|
|
||||||
|
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
|
||||||
|
[CFLAGS="$CFLAGS $1"; DEBUG_CFLAGS="$DEBUG_CFLAGS $1"; $2], [$3])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl CC_CHECK_CFLAGS_APPEND([FLAG1 FLAG2], [action-if-found], [action-if-not])
|
||||||
|
AC_DEFUN([CC_CHECK_CFLAGS_APPEND], [
|
||||||
|
for flag in $1; do
|
||||||
|
CC_CHECK_CFLAG_APPEND($flag, [$2], [$3])
|
||||||
|
done
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl Check if the flag is supported by linker (cacheable)
|
||||||
|
dnl CC_CHECK_LDFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
|
||||||
|
|
||||||
|
AC_DEFUN([CC_CHECK_LDFLAGS], [
|
||||||
|
AC_CACHE_CHECK([if $CC supports $1 flag],
|
||||||
|
AS_TR_SH([cc_cv_ldflags_$1]),
|
||||||
|
[ac_save_LDFLAGS="$LDFLAGS"
|
||||||
|
LDFLAGS="$LDFLAGS $1"
|
||||||
|
AC_LANG_PUSH([C])
|
||||||
|
AC_LINK_IFELSE([AC_LANG_SOURCE([int main() { return 1; }])],
|
||||||
|
[eval "AS_TR_SH([cc_cv_ldflags_$1])='yes'"],
|
||||||
|
[eval "AS_TR_SH([cc_cv_ldflags_$1])="])
|
||||||
|
AC_LANG_POP([C])
|
||||||
|
LDFLAGS="$ac_save_LDFLAGS"
|
||||||
|
])
|
||||||
|
|
||||||
|
AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes],
|
||||||
|
[$2], [$3])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl define the LDFLAGS_NOUNDEFINED variable with the correct value for
|
||||||
|
dnl the current linker to avoid undefined references in a shared object.
|
||||||
|
AC_DEFUN([CC_NOUNDEFINED], [
|
||||||
|
dnl We check $host for which systems to enable this for.
|
||||||
|
AC_REQUIRE([AC_CANONICAL_HOST])
|
||||||
|
|
||||||
|
case $host in
|
||||||
|
dnl FreeBSD (et al.) does not complete linking for shared objects when pthreads
|
||||||
|
dnl are requested, as different implementations are present; to avoid problems
|
||||||
|
dnl use -Wl,-z,defs only for those platform not behaving this way.
|
||||||
|
*-freebsd* | *-openbsd*) ;;
|
||||||
|
*)
|
||||||
|
dnl First of all check for the --no-undefined variant of GNU ld. This allows
|
||||||
|
dnl for a much more readable commandline, so that people can understand what
|
||||||
|
dnl it does without going to look for what the heck -z defs does.
|
||||||
|
for possible_flags in "-Wl,--no-undefined" "-Wl,-z,defs"; do
|
||||||
|
CC_CHECK_LDFLAGS([$possible_flags], [LDFLAGS_NOUNDEFINED="$possible_flags"])
|
||||||
|
break
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
AC_SUBST([LDFLAGS_NOUNDEFINED])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl Check for a -Werror flag or equivalent. -Werror is the GCC
|
||||||
|
dnl and ICC flag that tells the compiler to treat all the warnings
|
||||||
|
dnl as fatal. We usually need this option to make sure that some
|
||||||
|
dnl constructs (like attributes) are not simply ignored.
|
||||||
|
dnl
|
||||||
|
dnl Other compilers don't support -Werror per se, but they support
|
||||||
|
dnl an equivalent flag:
|
||||||
|
dnl - Sun Studio compiler supports -errwarn=%all
|
||||||
|
AC_DEFUN([CC_CHECK_WERROR], [
|
||||||
|
AC_CACHE_CHECK(
|
||||||
|
[for $CC way to treat warnings as errors],
|
||||||
|
[cc_cv_werror],
|
||||||
|
[CC_CHECK_CFLAGS_SILENT([-Werror], [cc_cv_werror=-Werror],
|
||||||
|
[CC_CHECK_CFLAGS_SILENT([-errwarn=%all], [cc_cv_werror=-errwarn=%all])])
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([CC_CHECK_ATTRIBUTE], [
|
||||||
|
AC_REQUIRE([CC_CHECK_WERROR])
|
||||||
|
AC_CACHE_CHECK([if $CC supports __attribute__(( ifelse([$2], , [$1], [$2]) ))],
|
||||||
|
AS_TR_SH([cc_cv_attribute_$1]),
|
||||||
|
[ac_save_CFLAGS="$CFLAGS"
|
||||||
|
CFLAGS="$CFLAGS $cc_cv_werror"
|
||||||
|
AC_LANG_PUSH([C])
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_SOURCE([$3])],
|
||||||
|
[eval "AS_TR_SH([cc_cv_attribute_$1])='yes'"],
|
||||||
|
[eval "AS_TR_SH([cc_cv_attribute_$1])='no'"])
|
||||||
|
AC_LANG_POP([C])
|
||||||
|
CFLAGS="$ac_save_CFLAGS"
|
||||||
|
])
|
||||||
|
|
||||||
|
AS_IF([eval test x$]AS_TR_SH([cc_cv_attribute_$1])[ = xyes],
|
||||||
|
[AC_DEFINE(
|
||||||
|
AS_TR_CPP([SUPPORT_ATTRIBUTE_$1]), 1,
|
||||||
|
[Define this if the compiler supports __attribute__(( ifelse([$2], , [$1], [$2]) ))]
|
||||||
|
)
|
||||||
|
$4],
|
||||||
|
[$5])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_CONSTRUCTOR], [
|
||||||
|
CC_CHECK_ATTRIBUTE(
|
||||||
|
[constructor],,
|
||||||
|
[void __attribute__((constructor)) ctor() { int a; }],
|
||||||
|
[$1], [$2])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_FORMAT], [
|
||||||
|
CC_CHECK_ATTRIBUTE(
|
||||||
|
[format], [format(printf, n, n)],
|
||||||
|
[void __attribute__((format(printf, 1, 2))) printflike(const char *fmt, ...) { fmt = (void *)0; }],
|
||||||
|
[$1], [$2])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_FORMAT_ARG], [
|
||||||
|
CC_CHECK_ATTRIBUTE(
|
||||||
|
[format_arg], [format_arg(printf)],
|
||||||
|
[char *__attribute__((format_arg(1))) gettextlike(const char *fmt) { fmt = (void *)0; }],
|
||||||
|
[$1], [$2])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_VISIBILITY], [
|
||||||
|
CC_CHECK_ATTRIBUTE(
|
||||||
|
[visibility_$1], [visibility("$1")],
|
||||||
|
[void __attribute__((visibility("$1"))) $1_function() { }],
|
||||||
|
[$2], [$3])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_NONNULL], [
|
||||||
|
CC_CHECK_ATTRIBUTE(
|
||||||
|
[nonnull], [nonnull()],
|
||||||
|
[void __attribute__((nonnull())) some_function(void *foo, void *bar) { foo = (void*)0; bar = (void*)0; }],
|
||||||
|
[$1], [$2])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_UNUSED], [
|
||||||
|
CC_CHECK_ATTRIBUTE(
|
||||||
|
[unused], ,
|
||||||
|
[void some_function(void *foo, __attribute__((unused)) void *bar);],
|
||||||
|
[$1], [$2])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_SENTINEL], [
|
||||||
|
CC_CHECK_ATTRIBUTE(
|
||||||
|
[sentinel], ,
|
||||||
|
[void some_function(void *foo, ...) __attribute__((sentinel));],
|
||||||
|
[$1], [$2])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_DEPRECATED], [
|
||||||
|
CC_CHECK_ATTRIBUTE(
|
||||||
|
[deprecated], ,
|
||||||
|
[void some_function(void *foo, ...) __attribute__((deprecated));],
|
||||||
|
[$1], [$2])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_ALIAS], [
|
||||||
|
CC_CHECK_ATTRIBUTE(
|
||||||
|
[alias], [weak, alias],
|
||||||
|
[void other_function(void *foo) { }
|
||||||
|
void some_function(void *foo) __attribute__((weak, alias("other_function")));],
|
||||||
|
[$1], [$2])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_MALLOC], [
|
||||||
|
CC_CHECK_ATTRIBUTE(
|
||||||
|
[malloc], ,
|
||||||
|
[void * __attribute__((malloc)) my_alloc(int n);],
|
||||||
|
[$1], [$2])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_PACKED], [
|
||||||
|
CC_CHECK_ATTRIBUTE(
|
||||||
|
[packed], ,
|
||||||
|
[struct astructure { char a; int b; long c; void *d; } __attribute__((packed));],
|
||||||
|
[$1], [$2])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_CONST], [
|
||||||
|
CC_CHECK_ATTRIBUTE(
|
||||||
|
[const], ,
|
||||||
|
[int __attribute__((const)) twopow(int n) { return 1 << n; } ],
|
||||||
|
[$1], [$2])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([CC_FLAG_VISIBILITY], [
|
||||||
|
AC_REQUIRE([CC_CHECK_WERROR])
|
||||||
|
AC_CACHE_CHECK([if $CC supports -fvisibility=hidden],
|
||||||
|
[cc_cv_flag_visibility],
|
||||||
|
[cc_flag_visibility_save_CFLAGS="$CFLAGS"
|
||||||
|
CFLAGS="$CFLAGS $cc_cv_werror"
|
||||||
|
CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden],
|
||||||
|
cc_cv_flag_visibility='yes',
|
||||||
|
cc_cv_flag_visibility='no')
|
||||||
|
CFLAGS="$cc_flag_visibility_save_CFLAGS"])
|
||||||
|
|
||||||
|
AS_IF([test "x$cc_cv_flag_visibility" = "xyes"],
|
||||||
|
[AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1,
|
||||||
|
[Define this if the compiler supports the -fvisibility flag])
|
||||||
|
$1],
|
||||||
|
[$2])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([CC_FUNC_EXPECT], [
|
||||||
|
AC_REQUIRE([CC_CHECK_WERROR])
|
||||||
|
AC_CACHE_CHECK([if compiler has __builtin_expect function],
|
||||||
|
[cc_cv_func_expect],
|
||||||
|
[ac_save_CFLAGS="$CFLAGS"
|
||||||
|
CFLAGS="$CFLAGS $cc_cv_werror"
|
||||||
|
AC_LANG_PUSH([C])
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_SOURCE(
|
||||||
|
[int some_function() {
|
||||||
|
int a = 3;
|
||||||
|
return (int)__builtin_expect(a, 3);
|
||||||
|
}])],
|
||||||
|
[cc_cv_func_expect=yes],
|
||||||
|
[cc_cv_func_expect=no])
|
||||||
|
AC_LANG_POP([C])
|
||||||
|
CFLAGS="$ac_save_CFLAGS"
|
||||||
|
])
|
||||||
|
|
||||||
|
AS_IF([test "x$cc_cv_func_expect" = "xyes"],
|
||||||
|
[AC_DEFINE([SUPPORT__BUILTIN_EXPECT], 1,
|
||||||
|
[Define this if the compiler supports __builtin_expect() function])
|
||||||
|
$1],
|
||||||
|
[$2])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [
|
||||||
|
AC_REQUIRE([CC_CHECK_WERROR])
|
||||||
|
AC_CACHE_CHECK([highest __attribute__ ((aligned ())) supported],
|
||||||
|
[cc_cv_attribute_aligned],
|
||||||
|
[ac_save_CFLAGS="$CFLAGS"
|
||||||
|
CFLAGS="$CFLAGS $cc_cv_werror"
|
||||||
|
AC_LANG_PUSH([C])
|
||||||
|
for cc_attribute_align_try in 64 32 16 8 4 2; do
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
|
||||||
|
int main() {
|
||||||
|
static char c __attribute__ ((aligned($cc_attribute_align_try))) = 0;
|
||||||
|
return c;
|
||||||
|
}])], [cc_cv_attribute_aligned=$cc_attribute_align_try; break])
|
||||||
|
done
|
||||||
|
AC_LANG_POP([C])
|
||||||
|
CFLAGS="$ac_save_CFLAGS"
|
||||||
|
])
|
||||||
|
|
||||||
|
if test "x$cc_cv_attribute_aligned" != "x"; then
|
||||||
|
AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned],
|
||||||
|
[Define the highest alignment supported])
|
||||||
|
fi
|
||||||
|
])
|
15
deps/uv/src/fs-poll.c
vendored
@ -60,6 +60,7 @@ int uv_fs_poll_start(uv_fs_poll_t* handle,
|
|||||||
struct poll_ctx* ctx;
|
struct poll_ctx* ctx;
|
||||||
uv_loop_t* loop;
|
uv_loop_t* loop;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
int err;
|
||||||
|
|
||||||
if (uv__is_active(handle))
|
if (uv__is_active(handle))
|
||||||
return 0;
|
return 0;
|
||||||
@ -78,19 +79,25 @@ int uv_fs_poll_start(uv_fs_poll_t* handle,
|
|||||||
ctx->parent_handle = handle;
|
ctx->parent_handle = handle;
|
||||||
memcpy(ctx->path, path, len + 1);
|
memcpy(ctx->path, path, len + 1);
|
||||||
|
|
||||||
if (uv_timer_init(loop, &ctx->timer_handle))
|
err = uv_timer_init(loop, &ctx->timer_handle);
|
||||||
abort();
|
if (err < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
ctx->timer_handle.flags |= UV__HANDLE_INTERNAL;
|
ctx->timer_handle.flags |= UV__HANDLE_INTERNAL;
|
||||||
uv__handle_unref(&ctx->timer_handle);
|
uv__handle_unref(&ctx->timer_handle);
|
||||||
|
|
||||||
if (uv_fs_stat(loop, &ctx->fs_req, ctx->path, poll_cb))
|
err = uv_fs_stat(loop, &ctx->fs_req, ctx->path, poll_cb);
|
||||||
abort();
|
if (err < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
handle->poll_ctx = ctx;
|
handle->poll_ctx = ctx;
|
||||||
uv__handle_start(handle);
|
uv__handle_start(handle);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
free(ctx);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
57
deps/uv/src/unix/core.c
vendored
@ -163,6 +163,33 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
|
|||||||
uv__make_close_pending(handle);
|
uv__make_close_pending(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) {
|
||||||
|
int r;
|
||||||
|
int fd;
|
||||||
|
socklen_t len;
|
||||||
|
|
||||||
|
if (handle == NULL || value == NULL)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (handle->type == UV_TCP || handle->type == UV_NAMED_PIPE)
|
||||||
|
fd = uv__stream_fd((uv_stream_t*) handle);
|
||||||
|
else if (handle->type == UV_UDP)
|
||||||
|
fd = ((uv_udp_t *) handle)->io_watcher.fd;
|
||||||
|
else
|
||||||
|
return -ENOTSUP;
|
||||||
|
|
||||||
|
len = sizeof(*value);
|
||||||
|
|
||||||
|
if (*value == 0)
|
||||||
|
r = getsockopt(fd, SOL_SOCKET, optname, value, &len);
|
||||||
|
else
|
||||||
|
r = setsockopt(fd, SOL_SOCKET, optname, (const void*) value, len);
|
||||||
|
|
||||||
|
if (r < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void uv__make_close_pending(uv_handle_t* handle) {
|
void uv__make_close_pending(uv_handle_t* handle) {
|
||||||
assert(handle->flags & UV_CLOSING);
|
assert(handle->flags & UV_CLOSING);
|
||||||
@ -635,6 +662,36 @@ void uv_disable_stdio_inheritance(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) {
|
||||||
|
int fd_out;
|
||||||
|
|
||||||
|
switch (handle->type) {
|
||||||
|
case UV_TCP:
|
||||||
|
case UV_NAMED_PIPE:
|
||||||
|
case UV_TTY:
|
||||||
|
fd_out = uv__stream_fd((uv_stream_t*) handle);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UV_UDP:
|
||||||
|
fd_out = ((uv_udp_t *) handle)->io_watcher.fd;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UV_POLL:
|
||||||
|
fd_out = ((uv_poll_t *) handle)->io_watcher.fd;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uv__is_closing(handle) || fd_out == -1)
|
||||||
|
return -EBADF;
|
||||||
|
|
||||||
|
*fd = fd_out;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void uv__run_pending(uv_loop_t* loop) {
|
static void uv__run_pending(uv_loop_t* loop) {
|
||||||
QUEUE* q;
|
QUEUE* q;
|
||||||
uv__io_t* w;
|
uv__io_t* w;
|
||||||
|
24
deps/uv/src/unix/darwin-proctitle.c
vendored
@ -36,7 +36,7 @@ static int uv__pthread_setname_np(const char* name) {
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* pthread_setname_np() first appeared in OS X 10.6 and iOS 3.2. */
|
/* pthread_setname_np() first appeared in OS X 10.6 and iOS 3.2. */
|
||||||
dynamic_pthread_setname_np = dlsym(RTLD_DEFAULT, "pthread_setname_np");
|
*(void **)(&dynamic_pthread_setname_np) = dlsym(RTLD_DEFAULT, "pthread_setname_np");
|
||||||
if (dynamic_pthread_setname_np == NULL)
|
if (dynamic_pthread_setname_np == NULL)
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
|
|
||||||
@ -94,13 +94,13 @@ int uv__set_process_title(const char* title) {
|
|||||||
if (application_services_handle == NULL || core_foundation_handle == NULL)
|
if (application_services_handle == NULL || core_foundation_handle == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
pCFStringCreateWithCString =
|
*(void **)(&pCFStringCreateWithCString) =
|
||||||
dlsym(core_foundation_handle, "CFStringCreateWithCString");
|
dlsym(core_foundation_handle, "CFStringCreateWithCString");
|
||||||
pCFBundleGetBundleWithIdentifier =
|
*(void **)(&pCFBundleGetBundleWithIdentifier) =
|
||||||
dlsym(core_foundation_handle, "CFBundleGetBundleWithIdentifier");
|
dlsym(core_foundation_handle, "CFBundleGetBundleWithIdentifier");
|
||||||
pCFBundleGetDataPointerForName =
|
*(void **)(&pCFBundleGetDataPointerForName) =
|
||||||
dlsym(core_foundation_handle, "CFBundleGetDataPointerForName");
|
dlsym(core_foundation_handle, "CFBundleGetDataPointerForName");
|
||||||
pCFBundleGetFunctionPointerForName =
|
*(void **)(&pCFBundleGetFunctionPointerForName) =
|
||||||
dlsym(core_foundation_handle, "CFBundleGetFunctionPointerForName");
|
dlsym(core_foundation_handle, "CFBundleGetFunctionPointerForName");
|
||||||
|
|
||||||
if (pCFStringCreateWithCString == NULL ||
|
if (pCFStringCreateWithCString == NULL ||
|
||||||
@ -118,14 +118,14 @@ int uv__set_process_title(const char* title) {
|
|||||||
if (launch_services_bundle == NULL)
|
if (launch_services_bundle == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
pLSGetCurrentApplicationASN =
|
*(void **)(&pLSGetCurrentApplicationASN) =
|
||||||
pCFBundleGetFunctionPointerForName(launch_services_bundle,
|
pCFBundleGetFunctionPointerForName(launch_services_bundle,
|
||||||
S("_LSGetCurrentApplicationASN"));
|
S("_LSGetCurrentApplicationASN"));
|
||||||
|
|
||||||
if (pLSGetCurrentApplicationASN == NULL)
|
if (pLSGetCurrentApplicationASN == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
pLSSetApplicationInformationItem =
|
*(void **)(&pLSSetApplicationInformationItem) =
|
||||||
pCFBundleGetFunctionPointerForName(launch_services_bundle,
|
pCFBundleGetFunctionPointerForName(launch_services_bundle,
|
||||||
S("_LSSetApplicationInformationItem"));
|
S("_LSSetApplicationInformationItem"));
|
||||||
|
|
||||||
@ -138,9 +138,9 @@ int uv__set_process_title(const char* title) {
|
|||||||
if (display_name_key == NULL || *display_name_key == NULL)
|
if (display_name_key == NULL || *display_name_key == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
pCFBundleGetInfoDictionary = dlsym(core_foundation_handle,
|
*(void **)(&pCFBundleGetInfoDictionary) = dlsym(core_foundation_handle,
|
||||||
"CFBundleGetInfoDictionary");
|
"CFBundleGetInfoDictionary");
|
||||||
pCFBundleGetMainBundle = dlsym(core_foundation_handle,
|
*(void **)(&pCFBundleGetMainBundle) = dlsym(core_foundation_handle,
|
||||||
"CFBundleGetMainBundle");
|
"CFBundleGetMainBundle");
|
||||||
if (pCFBundleGetInfoDictionary == NULL || pCFBundleGetMainBundle == NULL)
|
if (pCFBundleGetInfoDictionary == NULL || pCFBundleGetMainBundle == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
@ -152,13 +152,13 @@ int uv__set_process_title(const char* title) {
|
|||||||
if (hi_services_bundle == NULL)
|
if (hi_services_bundle == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
pSetApplicationIsDaemon = pCFBundleGetFunctionPointerForName(
|
*(void **)(&pSetApplicationIsDaemon) = pCFBundleGetFunctionPointerForName(
|
||||||
hi_services_bundle,
|
hi_services_bundle,
|
||||||
S("SetApplicationIsDaemon"));
|
S("SetApplicationIsDaemon"));
|
||||||
pLSApplicationCheckIn = pCFBundleGetFunctionPointerForName(
|
*(void **)(&pLSApplicationCheckIn) = pCFBundleGetFunctionPointerForName(
|
||||||
launch_services_bundle,
|
launch_services_bundle,
|
||||||
S("_LSApplicationCheckIn"));
|
S("_LSApplicationCheckIn"));
|
||||||
pLSSetApplicationLaunchServicesServerConnectionStatus =
|
*(void **)(&pLSSetApplicationLaunchServicesServerConnectionStatus) =
|
||||||
pCFBundleGetFunctionPointerForName(
|
pCFBundleGetFunctionPointerForName(
|
||||||
launch_services_bundle,
|
launch_services_bundle,
|
||||||
S("_LSSetApplicationLaunchServicesServerConnectionStatus"));
|
S("_LSSetApplicationLaunchServicesServerConnectionStatus"));
|
||||||
|
41
deps/uv/src/unix/fs.c
vendored
@ -38,7 +38,6 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <dirent.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <utime.h>
|
#include <utime.h>
|
||||||
@ -296,9 +295,9 @@ done:
|
|||||||
|
|
||||||
|
|
||||||
#if defined(__OpenBSD__) || (defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_8))
|
#if defined(__OpenBSD__) || (defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_8))
|
||||||
static int uv__fs_readdir_filter(struct dirent* dent) {
|
static int uv__fs_readdir_filter(uv__dirent_t* dent) {
|
||||||
#else
|
#else
|
||||||
static int uv__fs_readdir_filter(const struct dirent* dent) {
|
static int uv__fs_readdir_filter(const uv__dirent_t* dent) {
|
||||||
#endif
|
#endif
|
||||||
return strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0;
|
return strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0;
|
||||||
}
|
}
|
||||||
@ -306,12 +305,8 @@ static int uv__fs_readdir_filter(const struct dirent* dent) {
|
|||||||
|
|
||||||
/* This should have been called uv__fs_scandir(). */
|
/* This should have been called uv__fs_scandir(). */
|
||||||
static ssize_t uv__fs_readdir(uv_fs_t* req) {
|
static ssize_t uv__fs_readdir(uv_fs_t* req) {
|
||||||
struct dirent **dents;
|
uv__dirent_t **dents;
|
||||||
int saved_errno;
|
int saved_errno;
|
||||||
size_t off;
|
|
||||||
size_t len;
|
|
||||||
char *buf;
|
|
||||||
int i;
|
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
dents = NULL;
|
dents = NULL;
|
||||||
@ -322,32 +317,17 @@ static ssize_t uv__fs_readdir(uv_fs_t* req) {
|
|||||||
else if (n == -1)
|
else if (n == -1)
|
||||||
return n;
|
return n;
|
||||||
|
|
||||||
len = 0;
|
/* NOTE: We will use nbufs as an index field */
|
||||||
|
req->ptr = dents;
|
||||||
|
req->nbufs = 0;
|
||||||
|
|
||||||
for (i = 0; i < n; i++)
|
return n;
|
||||||
len += strlen(dents[i]->d_name) + 1;
|
|
||||||
|
|
||||||
buf = malloc(len);
|
|
||||||
|
|
||||||
if (buf == NULL) {
|
|
||||||
errno = ENOMEM;
|
|
||||||
n = -1;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
off = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
len = strlen(dents[i]->d_name) + 1;
|
|
||||||
memcpy(buf + off, dents[i]->d_name, len);
|
|
||||||
off += len;
|
|
||||||
}
|
|
||||||
|
|
||||||
req->ptr = buf;
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
saved_errno = errno;
|
saved_errno = errno;
|
||||||
if (dents != NULL) {
|
if (dents != NULL) {
|
||||||
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
free(dents[i]);
|
free(dents[i]);
|
||||||
free(dents);
|
free(dents);
|
||||||
@ -1184,6 +1164,9 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
|
|||||||
req->path = NULL;
|
req->path = NULL;
|
||||||
req->new_path = NULL;
|
req->new_path = NULL;
|
||||||
|
|
||||||
|
if (req->fs_type == UV_FS_READDIR && req->ptr != NULL)
|
||||||
|
uv__fs_readdir_cleanup(req);
|
||||||
|
|
||||||
if (req->ptr != &req->statbuf)
|
if (req->ptr != &req->statbuf)
|
||||||
free(req->ptr);
|
free(req->ptr);
|
||||||
req->ptr = NULL;
|
req->ptr = NULL;
|
||||||
|
2
deps/uv/src/unix/fsevents.c
vendored
@ -525,7 +525,7 @@ static int uv__fsevents_global_init(void) {
|
|||||||
err = -ENOENT;
|
err = -ENOENT;
|
||||||
#define V(handle, symbol) \
|
#define V(handle, symbol) \
|
||||||
do { \
|
do { \
|
||||||
p ## symbol = dlsym((handle), #symbol); \
|
*(void **)(&p ## symbol) = dlsym((handle), #symbol); \
|
||||||
if (p ## symbol == NULL) \
|
if (p ## symbol == NULL) \
|
||||||
goto out; \
|
goto out; \
|
||||||
} \
|
} \
|
||||||
|
67
deps/uv/src/unix/getaddrinfo.c
vendored
@ -18,6 +18,13 @@
|
|||||||
* IN THE SOFTWARE.
|
* IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* 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 "uv.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
@ -26,6 +33,66 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
/* EAI_* constants. */
|
||||||
|
#include <netdb.h>
|
||||||
|
|
||||||
|
|
||||||
|
int uv__getaddrinfo_translate_error(int sys_err) {
|
||||||
|
switch (sys_err) {
|
||||||
|
case 0: return 0;
|
||||||
|
#if defined(EAI_ADDRFAMILY)
|
||||||
|
case EAI_ADDRFAMILY: return UV_EAI_ADDRFAMILY;
|
||||||
|
#endif
|
||||||
|
#if defined(EAI_AGAIN)
|
||||||
|
case EAI_AGAIN: return UV_EAI_AGAIN;
|
||||||
|
#endif
|
||||||
|
#if defined(EAI_BADFLAGS)
|
||||||
|
case EAI_BADFLAGS: return UV_EAI_BADFLAGS;
|
||||||
|
#endif
|
||||||
|
#if defined(EAI_BADHINTS)
|
||||||
|
case EAI_BADHINTS: return UV_EAI_BADHINTS;
|
||||||
|
#endif
|
||||||
|
#if defined(EAI_CANCELED)
|
||||||
|
case EAI_CANCELED: return UV_EAI_CANCELED;
|
||||||
|
#endif
|
||||||
|
#if defined(EAI_FAIL)
|
||||||
|
case EAI_FAIL: return UV_EAI_FAIL;
|
||||||
|
#endif
|
||||||
|
#if defined(EAI_FAMILY)
|
||||||
|
case EAI_FAMILY: return UV_EAI_FAMILY;
|
||||||
|
#endif
|
||||||
|
#if defined(EAI_MEMORY)
|
||||||
|
case EAI_MEMORY: return UV_EAI_MEMORY;
|
||||||
|
#endif
|
||||||
|
#if defined(EAI_NODATA)
|
||||||
|
case EAI_NODATA: return UV_EAI_NODATA;
|
||||||
|
#endif
|
||||||
|
#if defined(EAI_NONAME)
|
||||||
|
# if !defined(EAI_NODATA) || EAI_NODATA != EAI_NONAME
|
||||||
|
case EAI_NONAME: return UV_EAI_NONAME;
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#if defined(EAI_OVERFLOW)
|
||||||
|
case EAI_OVERFLOW: return UV_EAI_OVERFLOW;
|
||||||
|
#endif
|
||||||
|
#if defined(EAI_PROTOCOL)
|
||||||
|
case EAI_PROTOCOL: return UV_EAI_PROTOCOL;
|
||||||
|
#endif
|
||||||
|
#if defined(EAI_SERVICE)
|
||||||
|
case EAI_SERVICE: return UV_EAI_SERVICE;
|
||||||
|
#endif
|
||||||
|
#if defined(EAI_SOCKTYPE)
|
||||||
|
case EAI_SOCKTYPE: return UV_EAI_SOCKTYPE;
|
||||||
|
#endif
|
||||||
|
#if defined(EAI_SYSTEM)
|
||||||
|
case EAI_SYSTEM: return -errno;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
assert(!"unknown EAI_* error code");
|
||||||
|
abort();
|
||||||
|
return 0; /* Pacify compiler. */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void uv__getaddrinfo_work(struct uv__work* w) {
|
static void uv__getaddrinfo_work(struct uv__work* w) {
|
||||||
uv_getaddrinfo_t* req;
|
uv_getaddrinfo_t* req;
|
||||||
|
2
deps/uv/src/unix/internal.h
vendored
@ -143,7 +143,7 @@ enum {
|
|||||||
UV_TCP_NODELAY = 0x400, /* Disable Nagle. */
|
UV_TCP_NODELAY = 0x400, /* Disable Nagle. */
|
||||||
UV_TCP_KEEPALIVE = 0x800, /* Turn on keep-alive. */
|
UV_TCP_KEEPALIVE = 0x800, /* Turn on keep-alive. */
|
||||||
UV_TCP_SINGLE_ACCEPT = 0x1000, /* Only accept() when idle. */
|
UV_TCP_SINGLE_ACCEPT = 0x1000, /* Only accept() when idle. */
|
||||||
UV_HANDLE_IPV6 = 0x2000 /* Handle is bound to a IPv6 socket. */
|
UV_HANDLE_IPV6 = 0x10000 /* Handle is bound to a IPv6 socket. */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
21
deps/uv/src/unix/linux-core.c
vendored
@ -149,6 +149,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
|||||||
int fd;
|
int fd;
|
||||||
int op;
|
int op;
|
||||||
int i;
|
int i;
|
||||||
|
static int no_epoll_wait;
|
||||||
|
|
||||||
if (loop->nfds == 0) {
|
if (loop->nfds == 0) {
|
||||||
assert(QUEUE_EMPTY(&loop->watcher_queue));
|
assert(QUEUE_EMPTY(&loop->watcher_queue));
|
||||||
@ -195,10 +196,22 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
|||||||
count = 48; /* Benchmarks suggest this gives the best throughput. */
|
count = 48; /* Benchmarks suggest this gives the best throughput. */
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
nfds = uv__epoll_wait(loop->backend_fd,
|
if (!no_epoll_wait) {
|
||||||
events,
|
nfds = uv__epoll_wait(loop->backend_fd,
|
||||||
ARRAY_SIZE(events),
|
events,
|
||||||
timeout);
|
ARRAY_SIZE(events),
|
||||||
|
timeout);
|
||||||
|
if (nfds == -1 && errno == ENOSYS) {
|
||||||
|
no_epoll_wait = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nfds = uv__epoll_pwait(loop->backend_fd,
|
||||||
|
events,
|
||||||
|
ARRAY_SIZE(events),
|
||||||
|
timeout,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Update loop->time unconditionally. It's tempting to skip the update when
|
/* 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
|
* timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
|
||||||
|
5
deps/uv/src/unix/loop.c
vendored
@ -99,7 +99,6 @@ void uv_loop_delete(uv_loop_t* loop) {
|
|||||||
|
|
||||||
|
|
||||||
static int uv__loop_init(uv_loop_t* loop, int default_loop) {
|
static int uv__loop_init(uv_loop_t* loop, int default_loop) {
|
||||||
unsigned int i;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
uv__signal_global_once_init();
|
uv__signal_global_once_init();
|
||||||
@ -138,9 +137,7 @@ static int uv__loop_init(uv_loop_t* loop, int default_loop) {
|
|||||||
uv_signal_init(loop, &loop->child_watcher);
|
uv_signal_init(loop, &loop->child_watcher);
|
||||||
uv__handle_unref(&loop->child_watcher);
|
uv__handle_unref(&loop->child_watcher);
|
||||||
loop->child_watcher.flags |= UV__HANDLE_INTERNAL;
|
loop->child_watcher.flags |= UV__HANDLE_INTERNAL;
|
||||||
|
QUEUE_INIT(&loop->process_handles);
|
||||||
for (i = 0; i < ARRAY_SIZE(loop->process_handles); i++)
|
|
||||||
QUEUE_INIT(loop->process_handles + i);
|
|
||||||
|
|
||||||
if (uv_rwlock_init(&loop->cloexec_lock))
|
if (uv_rwlock_init(&loop->cloexec_lock))
|
||||||
abort();
|
abort();
|
||||||
|
1
deps/uv/src/unix/netbsd.c
vendored
@ -38,6 +38,7 @@
|
|||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
|
#include <uvm/uvm_extern.h>
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
95
deps/uv/src/unix/process.c
vendored
@ -45,77 +45,65 @@ extern char **environ;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static QUEUE* uv__process_queue(uv_loop_t* loop, int pid) {
|
|
||||||
assert(pid > 0);
|
|
||||||
return loop->process_handles + pid % ARRAY_SIZE(loop->process_handles);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void uv__chld(uv_signal_t* handle, int signum) {
|
static void uv__chld(uv_signal_t* handle, int signum) {
|
||||||
uv_process_t* process;
|
uv_process_t* process;
|
||||||
uv_loop_t* loop;
|
uv_loop_t* loop;
|
||||||
int exit_status;
|
int exit_status;
|
||||||
int term_signal;
|
int term_signal;
|
||||||
unsigned int i;
|
|
||||||
int status;
|
int status;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
QUEUE pending;
|
QUEUE pending;
|
||||||
QUEUE* h;
|
|
||||||
QUEUE* q;
|
QUEUE* q;
|
||||||
|
QUEUE* h;
|
||||||
|
|
||||||
assert(signum == SIGCHLD);
|
assert(signum == SIGCHLD);
|
||||||
|
|
||||||
QUEUE_INIT(&pending);
|
QUEUE_INIT(&pending);
|
||||||
loop = handle->loop;
|
loop = handle->loop;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(loop->process_handles); i++) {
|
h = &loop->process_handles;
|
||||||
h = loop->process_handles + i;
|
q = QUEUE_HEAD(h);
|
||||||
q = QUEUE_HEAD(h);
|
while (q != h) {
|
||||||
|
process = QUEUE_DATA(q, uv_process_t, queue);
|
||||||
|
q = QUEUE_NEXT(q);
|
||||||
|
|
||||||
while (q != h) {
|
do
|
||||||
process = QUEUE_DATA(q, uv_process_t, queue);
|
pid = waitpid(process->pid, &status, WNOHANG);
|
||||||
q = QUEUE_NEXT(q);
|
while (pid == -1 && errno == EINTR);
|
||||||
|
|
||||||
do
|
if (pid == 0)
|
||||||
pid = waitpid(process->pid, &status, WNOHANG);
|
continue;
|
||||||
while (pid == -1 && errno == EINTR);
|
|
||||||
|
|
||||||
if (pid == 0)
|
if (pid == -1) {
|
||||||
continue;
|
if (errno != ECHILD)
|
||||||
|
abort();
|
||||||
if (pid == -1) {
|
continue;
|
||||||
if (errno != ECHILD)
|
|
||||||
abort();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
process->status = status;
|
|
||||||
QUEUE_REMOVE(&process->queue);
|
|
||||||
QUEUE_INSERT_TAIL(&pending, &process->queue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!QUEUE_EMPTY(&pending)) {
|
process->status = status;
|
||||||
q = QUEUE_HEAD(&pending);
|
QUEUE_REMOVE(&process->queue);
|
||||||
QUEUE_REMOVE(q);
|
QUEUE_INSERT_TAIL(&pending, &process->queue);
|
||||||
QUEUE_INIT(q);
|
|
||||||
|
|
||||||
process = QUEUE_DATA(q, uv_process_t, queue);
|
|
||||||
uv__handle_stop(process);
|
|
||||||
|
|
||||||
if (process->exit_cb == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
exit_status = 0;
|
|
||||||
if (WIFEXITED(process->status))
|
|
||||||
exit_status = WEXITSTATUS(process->status);
|
|
||||||
|
|
||||||
term_signal = 0;
|
|
||||||
if (WIFSIGNALED(process->status))
|
|
||||||
term_signal = WTERMSIG(process->status);
|
|
||||||
|
|
||||||
process->exit_cb(process, exit_status, term_signal);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QUEUE_FOREACH(q, &pending) {
|
||||||
|
process = QUEUE_DATA(q, uv_process_t, queue);
|
||||||
|
QUEUE_REMOVE(q);
|
||||||
|
uv__handle_stop(process);
|
||||||
|
|
||||||
|
if (process->exit_cb == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
exit_status = 0;
|
||||||
|
if (WIFEXITED(process->status))
|
||||||
|
exit_status = WEXITSTATUS(process->status);
|
||||||
|
|
||||||
|
term_signal = 0;
|
||||||
|
if (WIFSIGNALED(process->status))
|
||||||
|
term_signal = WTERMSIG(process->status);
|
||||||
|
|
||||||
|
process->exit_cb(process, exit_status, term_signal);
|
||||||
|
}
|
||||||
|
assert(QUEUE_EMPTY(&pending));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -369,7 +357,6 @@ int uv_spawn(uv_loop_t* loop,
|
|||||||
int signal_pipe[2] = { -1, -1 };
|
int signal_pipe[2] = { -1, -1 };
|
||||||
int (*pipes)[2];
|
int (*pipes)[2];
|
||||||
int stdio_count;
|
int stdio_count;
|
||||||
QUEUE* q;
|
|
||||||
ssize_t r;
|
ssize_t r;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int err;
|
int err;
|
||||||
@ -483,8 +470,7 @@ int uv_spawn(uv_loop_t* loop,
|
|||||||
|
|
||||||
/* Only activate this handle if exec() happened successfully */
|
/* Only activate this handle if exec() happened successfully */
|
||||||
if (exec_errorno == 0) {
|
if (exec_errorno == 0) {
|
||||||
q = uv__process_queue(loop, pid);
|
QUEUE_INSERT_TAIL(&loop->process_handles, &process->queue);
|
||||||
QUEUE_INSERT_TAIL(q, &process->queue);
|
|
||||||
uv__handle_start(process);
|
uv__handle_start(process);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,7 +512,8 @@ int uv_kill(int pid, int signum) {
|
|||||||
|
|
||||||
|
|
||||||
void uv__process_close(uv_process_t* handle) {
|
void uv__process_close(uv_process_t* handle) {
|
||||||
/* TODO stop signal watcher when this is the last handle */
|
|
||||||
QUEUE_REMOVE(&handle->queue);
|
QUEUE_REMOVE(&handle->queue);
|
||||||
uv__handle_stop(handle);
|
uv__handle_stop(handle);
|
||||||
|
if (QUEUE_EMPTY(&handle->loop->process_handles))
|
||||||
|
uv_signal_stop(&handle->loop->child_watcher);
|
||||||
}
|
}
|
||||||
|
153
deps/uv/src/unix/stream.c
vendored
@ -53,6 +53,10 @@ struct uv__stream_select_s {
|
|||||||
int fake_fd;
|
int fake_fd;
|
||||||
int int_fd;
|
int int_fd;
|
||||||
int fd;
|
int fd;
|
||||||
|
fd_set* sread;
|
||||||
|
size_t sread_sz;
|
||||||
|
fd_set* swrite;
|
||||||
|
size_t swrite_sz;
|
||||||
};
|
};
|
||||||
#endif /* defined(__APPLE__) */
|
#endif /* defined(__APPLE__) */
|
||||||
|
|
||||||
@ -127,8 +131,6 @@ static void uv__stream_osx_select(void* arg) {
|
|||||||
uv_stream_t* stream;
|
uv_stream_t* stream;
|
||||||
uv__stream_select_t* s;
|
uv__stream_select_t* s;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
fd_set sread;
|
|
||||||
fd_set swrite;
|
|
||||||
int events;
|
int events;
|
||||||
int fd;
|
int fd;
|
||||||
int r;
|
int r;
|
||||||
@ -149,17 +151,17 @@ static void uv__stream_osx_select(void* arg) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* Watch fd using select(2) */
|
/* Watch fd using select(2) */
|
||||||
FD_ZERO(&sread);
|
memset(s->sread, 0, s->sread_sz);
|
||||||
FD_ZERO(&swrite);
|
memset(s->swrite, 0, s->swrite_sz);
|
||||||
|
|
||||||
if (uv__io_active(&stream->io_watcher, UV__POLLIN))
|
if (uv__io_active(&stream->io_watcher, UV__POLLIN))
|
||||||
FD_SET(fd, &sread);
|
FD_SET(fd, s->sread);
|
||||||
if (uv__io_active(&stream->io_watcher, UV__POLLOUT))
|
if (uv__io_active(&stream->io_watcher, UV__POLLOUT))
|
||||||
FD_SET(fd, &swrite);
|
FD_SET(fd, s->swrite);
|
||||||
FD_SET(s->int_fd, &sread);
|
FD_SET(s->int_fd, s->sread);
|
||||||
|
|
||||||
/* Wait indefinitely for fd events */
|
/* Wait indefinitely for fd events */
|
||||||
r = select(max_fd + 1, &sread, &swrite, NULL, NULL);
|
r = select(max_fd + 1, s->sread, s->swrite, NULL, NULL);
|
||||||
if (r == -1) {
|
if (r == -1) {
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
@ -173,7 +175,7 @@ static void uv__stream_osx_select(void* arg) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Empty socketpair's buffer in case of interruption */
|
/* Empty socketpair's buffer in case of interruption */
|
||||||
if (FD_ISSET(s->int_fd, &sread))
|
if (FD_ISSET(s->int_fd, s->sread))
|
||||||
while (1) {
|
while (1) {
|
||||||
r = read(s->int_fd, buf, sizeof(buf));
|
r = read(s->int_fd, buf, sizeof(buf));
|
||||||
|
|
||||||
@ -194,12 +196,12 @@ static void uv__stream_osx_select(void* arg) {
|
|||||||
|
|
||||||
/* Handle events */
|
/* Handle events */
|
||||||
events = 0;
|
events = 0;
|
||||||
if (FD_ISSET(fd, &sread))
|
if (FD_ISSET(fd, s->sread))
|
||||||
events |= UV__POLLIN;
|
events |= UV__POLLIN;
|
||||||
if (FD_ISSET(fd, &swrite))
|
if (FD_ISSET(fd, s->swrite))
|
||||||
events |= UV__POLLOUT;
|
events |= UV__POLLOUT;
|
||||||
|
|
||||||
assert(events != 0 || FD_ISSET(s->int_fd, &sread));
|
assert(events != 0 || FD_ISSET(s->int_fd, s->sread));
|
||||||
if (events != 0) {
|
if (events != 0) {
|
||||||
ACCESS_ONCE(int, s->events) = events;
|
ACCESS_ONCE(int, s->events) = events;
|
||||||
|
|
||||||
@ -261,6 +263,9 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
|
|||||||
int ret;
|
int ret;
|
||||||
int kq;
|
int kq;
|
||||||
int old_fd;
|
int old_fd;
|
||||||
|
int max_fd;
|
||||||
|
size_t sread_sz;
|
||||||
|
size_t swrite_sz;
|
||||||
|
|
||||||
kq = kqueue();
|
kq = kqueue();
|
||||||
if (kq == -1) {
|
if (kq == -1) {
|
||||||
@ -284,31 +289,48 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* At this point we definitely know that this fd won't work with kqueue */
|
/* At this point we definitely know that this fd won't work with kqueue */
|
||||||
s = malloc(sizeof(*s));
|
|
||||||
if (s == NULL)
|
/*
|
||||||
return -ENOMEM;
|
* Create fds for io watcher and to interrupt the select() loop.
|
||||||
|
* NOTE: do it ahead of malloc below to allocate enough space for fd_sets
|
||||||
|
*/
|
||||||
|
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
max_fd = *fd;
|
||||||
|
if (fds[1] > max_fd)
|
||||||
|
max_fd = fds[1];
|
||||||
|
|
||||||
|
sread_sz = (max_fd + NBBY) / NBBY;
|
||||||
|
swrite_sz = sread_sz;
|
||||||
|
|
||||||
|
s = malloc(sizeof(*s) + sread_sz + swrite_sz);
|
||||||
|
if (s == NULL) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto failed_malloc;
|
||||||
|
}
|
||||||
|
|
||||||
s->events = 0;
|
s->events = 0;
|
||||||
s->fd = *fd;
|
s->fd = *fd;
|
||||||
|
s->sread = (fd_set*) ((char*) s + sizeof(*s));
|
||||||
|
s->sread_sz = sread_sz;
|
||||||
|
s->swrite = (fd_set*) ((char*) s->sread + sread_sz);
|
||||||
|
s->swrite_sz = swrite_sz;
|
||||||
|
|
||||||
err = uv_async_init(stream->loop, &s->async, uv__stream_osx_select_cb);
|
err = uv_async_init(stream->loop, &s->async, uv__stream_osx_select_cb);
|
||||||
if (err) {
|
if (err)
|
||||||
free(s);
|
goto failed_async_init;
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
s->async.flags |= UV__HANDLE_INTERNAL;
|
s->async.flags |= UV__HANDLE_INTERNAL;
|
||||||
uv__handle_unref(&s->async);
|
uv__handle_unref(&s->async);
|
||||||
|
|
||||||
if (uv_sem_init(&s->close_sem, 0))
|
err = uv_sem_init(&s->close_sem, 0);
|
||||||
goto fatal1;
|
if (err != 0)
|
||||||
|
goto failed_close_sem_init;
|
||||||
|
|
||||||
if (uv_sem_init(&s->async_sem, 0))
|
err = uv_sem_init(&s->async_sem, 0);
|
||||||
goto fatal2;
|
if (err != 0)
|
||||||
|
goto failed_async_sem_init;
|
||||||
/* Create fds for io watcher and to interrupt the select() loop. */
|
|
||||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
|
|
||||||
goto fatal3;
|
|
||||||
|
|
||||||
s->fake_fd = fds[0];
|
s->fake_fd = fds[0];
|
||||||
s->int_fd = fds[1];
|
s->int_fd = fds[1];
|
||||||
@ -318,26 +340,36 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
|
|||||||
stream->select = s;
|
stream->select = s;
|
||||||
*fd = s->fake_fd;
|
*fd = s->fake_fd;
|
||||||
|
|
||||||
if (uv_thread_create(&s->thread, uv__stream_osx_select, stream))
|
err = uv_thread_create(&s->thread, uv__stream_osx_select, stream);
|
||||||
goto fatal4;
|
if (err != 0)
|
||||||
|
goto failed_thread_create;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fatal4:
|
failed_thread_create:
|
||||||
s->stream = NULL;
|
s->stream = NULL;
|
||||||
stream->select = NULL;
|
stream->select = NULL;
|
||||||
*fd = old_fd;
|
*fd = old_fd;
|
||||||
uv__close(s->fake_fd);
|
|
||||||
uv__close(s->int_fd);
|
|
||||||
s->fake_fd = -1;
|
|
||||||
s->int_fd = -1;
|
|
||||||
fatal3:
|
|
||||||
uv_sem_destroy(&s->async_sem);
|
uv_sem_destroy(&s->async_sem);
|
||||||
fatal2:
|
|
||||||
|
failed_async_sem_init:
|
||||||
uv_sem_destroy(&s->close_sem);
|
uv_sem_destroy(&s->close_sem);
|
||||||
fatal1:
|
|
||||||
|
failed_close_sem_init:
|
||||||
|
uv__close(fds[0]);
|
||||||
|
uv__close(fds[1]);
|
||||||
uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close);
|
uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close);
|
||||||
return -errno;
|
return err;
|
||||||
|
|
||||||
|
failed_async_init:
|
||||||
|
free(s);
|
||||||
|
|
||||||
|
failed_malloc:
|
||||||
|
uv__close(fds[0]);
|
||||||
|
uv__close(fds[1]);
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
#endif /* defined(__APPLE__) */
|
#endif /* defined(__APPLE__) */
|
||||||
|
|
||||||
@ -361,10 +393,22 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void uv__stream_destroy(uv_stream_t* stream) {
|
void uv__stream_flush_write_queue(uv_stream_t* stream, int error) {
|
||||||
uv_write_t* req;
|
uv_write_t* req;
|
||||||
QUEUE* q;
|
QUEUE* q;
|
||||||
|
while (!QUEUE_EMPTY(&stream->write_queue)) {
|
||||||
|
q = QUEUE_HEAD(&stream->write_queue);
|
||||||
|
QUEUE_REMOVE(q);
|
||||||
|
|
||||||
|
req = QUEUE_DATA(q, uv_write_t, queue);
|
||||||
|
req->error = error;
|
||||||
|
|
||||||
|
QUEUE_INSERT_TAIL(&stream->write_completed_queue, &req->queue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uv__stream_destroy(uv_stream_t* stream) {
|
||||||
assert(!uv__io_active(&stream->io_watcher, UV__POLLIN | UV__POLLOUT));
|
assert(!uv__io_active(&stream->io_watcher, UV__POLLIN | UV__POLLOUT));
|
||||||
assert(stream->flags & UV_CLOSED);
|
assert(stream->flags & UV_CLOSED);
|
||||||
|
|
||||||
@ -374,16 +418,7 @@ void uv__stream_destroy(uv_stream_t* stream) {
|
|||||||
stream->connect_req = NULL;
|
stream->connect_req = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!QUEUE_EMPTY(&stream->write_queue)) {
|
uv__stream_flush_write_queue(stream, -ECANCELED);
|
||||||
q = QUEUE_HEAD(&stream->write_queue);
|
|
||||||
QUEUE_REMOVE(q);
|
|
||||||
|
|
||||||
req = QUEUE_DATA(q, uv_write_t, queue);
|
|
||||||
req->error = -ECANCELED;
|
|
||||||
|
|
||||||
QUEUE_INSERT_TAIL(&stream->write_completed_queue, &req->queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
uv__write_callbacks(stream);
|
uv__write_callbacks(stream);
|
||||||
|
|
||||||
if (stream->shutdown_req) {
|
if (stream->shutdown_req) {
|
||||||
@ -537,7 +572,7 @@ int uv_accept(uv_stream_t* server, uv_stream_t* client) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0);
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
@ -573,7 +608,6 @@ done:
|
|||||||
int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
|
int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = -EINVAL;
|
|
||||||
switch (stream->type) {
|
switch (stream->type) {
|
||||||
case UV_TCP:
|
case UV_TCP:
|
||||||
err = uv_tcp_listen((uv_tcp_t*)stream, backlog, cb);
|
err = uv_tcp_listen((uv_tcp_t*)stream, backlog, cb);
|
||||||
@ -584,7 +618,7 @@ int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0);
|
err = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err == 0)
|
if (err == 0)
|
||||||
@ -1163,7 +1197,7 @@ static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
|||||||
assert(uv__stream_fd(stream) >= 0);
|
assert(uv__stream_fd(stream) >= 0);
|
||||||
|
|
||||||
/* Ignore POLLHUP here. Even it it's set, there may still be data to read. */
|
/* Ignore POLLHUP here. Even it it's set, there may still be data to read. */
|
||||||
if (events & (UV__POLLIN | UV__POLLERR))
|
if (events & (UV__POLLIN | UV__POLLERR | UV__POLLHUP))
|
||||||
uv__read(stream);
|
uv__read(stream);
|
||||||
|
|
||||||
if (uv__stream_fd(stream) == -1)
|
if (uv__stream_fd(stream) == -1)
|
||||||
@ -1233,10 +1267,21 @@ static void uv__stream_connect(uv_stream_t* stream) {
|
|||||||
|
|
||||||
stream->connect_req = NULL;
|
stream->connect_req = NULL;
|
||||||
uv__req_unregister(stream->loop, req);
|
uv__req_unregister(stream->loop, req);
|
||||||
uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT);
|
|
||||||
|
if (error < 0 || QUEUE_EMPTY(&stream->write_queue)) {
|
||||||
|
uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT);
|
||||||
|
}
|
||||||
|
|
||||||
if (req->cb)
|
if (req->cb)
|
||||||
req->cb(req, error);
|
req->cb(req, error);
|
||||||
|
|
||||||
|
if (uv__stream_fd(stream) == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (error < 0) {
|
||||||
|
uv__stream_flush_write_queue(stream, -ECANCELED);
|
||||||
|
uv__write_callbacks(stream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
3
deps/uv/src/unix/timer.c
vendored
@ -65,6 +65,9 @@ int uv_timer_start(uv_timer_t* handle,
|
|||||||
uint64_t repeat) {
|
uint64_t repeat) {
|
||||||
uint64_t clamped_timeout;
|
uint64_t clamped_timeout;
|
||||||
|
|
||||||
|
if (cb == NULL)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
if (uv__is_active(handle))
|
if (uv__is_active(handle))
|
||||||
uv_timer_stop(handle);
|
uv_timer_stop(handle);
|
||||||
|
|
||||||
|
2
deps/uv/src/unix/udp.c
vendored
@ -340,8 +340,6 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
|
|||||||
unsigned char taddr[sizeof(struct sockaddr_in6)];
|
unsigned char taddr[sizeof(struct sockaddr_in6)];
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
|
|
||||||
assert(domain == AF_INET || domain == AF_INET6);
|
|
||||||
|
|
||||||
if (handle->io_watcher.fd != -1)
|
if (handle->io_watcher.fd != -1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
142
deps/uv/src/uv-common.c
vendored
@ -19,13 +19,6 @@
|
|||||||
* IN THE SOFTWARE.
|
* IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* 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 "uv.h"
|
||||||
#include "uv-common.h"
|
#include "uv-common.h"
|
||||||
|
|
||||||
@ -39,13 +32,6 @@
|
|||||||
# include <net/if.h> /* if_nametoindex */
|
# include <net/if.h> /* if_nametoindex */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* EAI_* constants. */
|
|
||||||
#if !defined(_WIN32)
|
|
||||||
# include <sys/types.h>
|
|
||||||
# include <sys/socket.h>
|
|
||||||
# include <netdb.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define XX(uc, lc) case UV_##uc: return sizeof(uv_##lc##_t);
|
#define XX(uc, lc) case UV_##uc: return sizeof(uv_##lc##_t);
|
||||||
|
|
||||||
size_t uv_handle_size(uv_handle_type type) {
|
size_t uv_handle_size(uv_handle_type type) {
|
||||||
@ -410,62 +396,6 @@ uint64_t uv_now(const uv_loop_t* loop) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int uv__getaddrinfo_translate_error(int sys_err) {
|
|
||||||
switch (sys_err) {
|
|
||||||
case 0: return 0;
|
|
||||||
#if defined(EAI_ADDRFAMILY)
|
|
||||||
case EAI_ADDRFAMILY: return UV_EAI_ADDRFAMILY;
|
|
||||||
#endif
|
|
||||||
#if defined(EAI_AGAIN)
|
|
||||||
case EAI_AGAIN: return UV_EAI_AGAIN;
|
|
||||||
#endif
|
|
||||||
#if defined(EAI_BADFLAGS)
|
|
||||||
case EAI_BADFLAGS: return UV_EAI_BADFLAGS;
|
|
||||||
#endif
|
|
||||||
#if defined(EAI_BADHINTS)
|
|
||||||
case EAI_BADHINTS: return UV_EAI_BADHINTS;
|
|
||||||
#endif
|
|
||||||
#if defined(EAI_CANCELED)
|
|
||||||
case EAI_CANCELED: return UV_EAI_CANCELED;
|
|
||||||
#endif
|
|
||||||
#if defined(EAI_FAIL)
|
|
||||||
case EAI_FAIL: return UV_EAI_FAIL;
|
|
||||||
#endif
|
|
||||||
#if defined(EAI_FAMILY)
|
|
||||||
case EAI_FAMILY: return UV_EAI_FAMILY;
|
|
||||||
#endif
|
|
||||||
#if defined(EAI_MEMORY)
|
|
||||||
case EAI_MEMORY: return UV_EAI_MEMORY;
|
|
||||||
#endif
|
|
||||||
#if defined(EAI_NODATA)
|
|
||||||
case EAI_NODATA: return UV_EAI_NODATA;
|
|
||||||
#endif
|
|
||||||
#if defined(EAI_NONAME)
|
|
||||||
# if !defined(EAI_NODATA) || EAI_NODATA != EAI_NONAME
|
|
||||||
case EAI_NONAME: return UV_EAI_NONAME;
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#if defined(EAI_OVERFLOW)
|
|
||||||
case EAI_OVERFLOW: return UV_EAI_OVERFLOW;
|
|
||||||
#endif
|
|
||||||
#if defined(EAI_PROTOCOL)
|
|
||||||
case EAI_PROTOCOL: return UV_EAI_PROTOCOL;
|
|
||||||
#endif
|
|
||||||
#if defined(EAI_SERVICE)
|
|
||||||
case EAI_SERVICE: return UV_EAI_SERVICE;
|
|
||||||
#endif
|
|
||||||
#if defined(EAI_SOCKTYPE)
|
|
||||||
case EAI_SOCKTYPE: return UV_EAI_SOCKTYPE;
|
|
||||||
#endif
|
|
||||||
#if defined(EAI_SYSTEM)
|
|
||||||
case EAI_SYSTEM: return -errno;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
assert(!"unknown EAI_* error code");
|
|
||||||
abort();
|
|
||||||
return 0; /* Pacify compiler. */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs) {
|
size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@ -478,6 +408,13 @@ size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs) {
|
|||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int uv_recv_buffer_size(uv_handle_t* handle, int* value) {
|
||||||
|
return uv__socket_sockopt(handle, SO_RCVBUF, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int uv_send_buffer_size(uv_handle_t* handle, int *value) {
|
||||||
|
return uv__socket_sockopt(handle, SO_SNDBUF, value);
|
||||||
|
}
|
||||||
|
|
||||||
int uv_fs_event_getpath(uv_fs_event_t* handle, char* buf, size_t* len) {
|
int uv_fs_event_getpath(uv_fs_event_t* handle, char* buf, size_t* len) {
|
||||||
size_t required_len;
|
size_t required_len;
|
||||||
@ -498,3 +435,68 @@ int uv_fs_event_getpath(uv_fs_event_t* handle, char* buf, size_t* len) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uv__fs_readdir_cleanup(uv_fs_t* req) {
|
||||||
|
uv__dirent_t** dents;
|
||||||
|
|
||||||
|
dents = req->ptr;
|
||||||
|
if (req->nbufs > 0 && req->nbufs != (unsigned int) req->result)
|
||||||
|
req->nbufs--;
|
||||||
|
for (; req->nbufs < (unsigned int) req->result; req->nbufs++)
|
||||||
|
free(dents[req->nbufs]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int uv_fs_readdir_next(uv_fs_t* req, uv_dirent_t* ent) {
|
||||||
|
uv__dirent_t** dents;
|
||||||
|
uv__dirent_t* dent;
|
||||||
|
|
||||||
|
dents = req->ptr;
|
||||||
|
|
||||||
|
/* Free previous entity */
|
||||||
|
if (req->nbufs > 0)
|
||||||
|
free(dents[req->nbufs - 1]);
|
||||||
|
|
||||||
|
/* End was already reached */
|
||||||
|
if (req->nbufs == (unsigned int) req->result) {
|
||||||
|
free(dents);
|
||||||
|
req->ptr = NULL;
|
||||||
|
return UV_EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
dent = dents[req->nbufs++];
|
||||||
|
|
||||||
|
ent->name = dent->d_name;
|
||||||
|
#ifdef HAVE_DIRENT_TYPES
|
||||||
|
switch (dent->d_type) {
|
||||||
|
case UV__DT_DIR:
|
||||||
|
ent->type = UV_DIRENT_DIR;
|
||||||
|
break;
|
||||||
|
case UV__DT_FILE:
|
||||||
|
ent->type = UV_DIRENT_FILE;
|
||||||
|
break;
|
||||||
|
case UV__DT_LINK:
|
||||||
|
ent->type = UV_DIRENT_LINK;
|
||||||
|
break;
|
||||||
|
case UV__DT_FIFO:
|
||||||
|
ent->type = UV_DIRENT_FIFO;
|
||||||
|
break;
|
||||||
|
case UV__DT_SOCKET:
|
||||||
|
ent->type = UV_DIRENT_SOCKET;
|
||||||
|
break;
|
||||||
|
case UV__DT_CHAR:
|
||||||
|
ent->type = UV_DIRENT_CHAR;
|
||||||
|
break;
|
||||||
|
case UV__DT_BLOCK:
|
||||||
|
ent->type = UV_DIRENT_BLOCK;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ent->type = UV_DIRENT_UNKNOWN;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
ent->type = UV_DIRENT_UNKNOWN;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
4
deps/uv/src/uv-common.h
vendored
@ -107,6 +107,10 @@ void uv__work_done(uv_async_t* handle);
|
|||||||
|
|
||||||
size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs);
|
size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs);
|
||||||
|
|
||||||
|
int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value);
|
||||||
|
|
||||||
|
void uv__fs_readdir_cleanup(uv_fs_t* req);
|
||||||
|
|
||||||
#define uv__has_active_reqs(loop) \
|
#define uv__has_active_reqs(loop) \
|
||||||
(QUEUE_EMPTY(&(loop)->active_reqs) == 0)
|
(QUEUE_EMPTY(&(loop)->active_reqs) == 0)
|
||||||
|
|
||||||
|
2
deps/uv/src/version.c
vendored
@ -35,7 +35,7 @@
|
|||||||
#if UV_VERSION_IS_RELEASE
|
#if UV_VERSION_IS_RELEASE
|
||||||
# define UV_VERSION_STRING UV_VERSION_STRING_BASE
|
# define UV_VERSION_STRING UV_VERSION_STRING_BASE
|
||||||
#else
|
#else
|
||||||
# define UV_VERSION_STRING UV_VERSION_STRING_BASE "-pre"
|
# define UV_VERSION_STRING UV_VERSION_STRING_BASE "-" UV_VERSION_SUFFIX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
138
deps/uv/src/win/core.c
vendored
@ -36,12 +36,11 @@
|
|||||||
#include "req-inl.h"
|
#include "req-inl.h"
|
||||||
|
|
||||||
|
|
||||||
/* The only event loop we support right now */
|
static uv_loop_t default_loop_struct;
|
||||||
static uv_loop_t uv_default_loop_;
|
static uv_loop_t* default_loop_ptr;
|
||||||
|
|
||||||
/* uv_once intialization guards */
|
/* uv_once intialization guards */
|
||||||
static uv_once_t uv_init_guard_ = UV_ONCE_INIT;
|
static uv_once_t uv_init_guard_ = UV_ONCE_INIT;
|
||||||
static uv_once_t uv_default_loop_init_guard_ = UV_ONCE_INIT;
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(_DEBUG) && (defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR))
|
#if defined(_DEBUG) && (defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR))
|
||||||
@ -138,7 +137,6 @@ int uv_loop_init(uv_loop_t* loop) {
|
|||||||
* to zero before calling uv_update_time for the first time.
|
* to zero before calling uv_update_time for the first time.
|
||||||
*/
|
*/
|
||||||
loop->time = 0;
|
loop->time = 0;
|
||||||
loop->last_tick_count = 0;
|
|
||||||
uv_update_time(loop);
|
uv_update_time(loop);
|
||||||
|
|
||||||
QUEUE_INIT(&loop->wq);
|
QUEUE_INIT(&loop->wq);
|
||||||
@ -181,48 +179,45 @@ int uv_loop_init(uv_loop_t* loop) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void uv_default_loop_init(void) {
|
|
||||||
/* Initialize libuv itself first */
|
|
||||||
uv__once_init();
|
|
||||||
|
|
||||||
/* Initialize the main loop */
|
|
||||||
uv_loop_init(&uv_default_loop_);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void uv__once_init(void) {
|
void uv__once_init(void) {
|
||||||
uv_once(&uv_init_guard_, uv_init);
|
uv_once(&uv_init_guard_, uv_init);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uv_loop_t* uv_default_loop(void) {
|
uv_loop_t* uv_default_loop(void) {
|
||||||
uv_once(&uv_default_loop_init_guard_, uv_default_loop_init);
|
if (default_loop_ptr != NULL)
|
||||||
return &uv_default_loop_;
|
return default_loop_ptr;
|
||||||
|
|
||||||
|
if (uv_loop_init(&default_loop_struct))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
default_loop_ptr = &default_loop_struct;
|
||||||
|
return default_loop_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void uv__loop_close(uv_loop_t* loop) {
|
static void uv__loop_close(uv_loop_t* loop) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
/* close the async handle without needeing an extra loop iteration */
|
/* close the async handle without needeing an extra loop iteration */
|
||||||
assert(!loop->wq_async.async_sent);
|
assert(!loop->wq_async.async_sent);
|
||||||
loop->wq_async.close_cb = NULL;
|
loop->wq_async.close_cb = NULL;
|
||||||
uv__handle_closing(&loop->wq_async);
|
uv__handle_closing(&loop->wq_async);
|
||||||
uv__handle_close(&loop->wq_async);
|
uv__handle_close(&loop->wq_async);
|
||||||
|
|
||||||
if (loop != &uv_default_loop_) {
|
for (i = 0; i < ARRAY_SIZE(loop->poll_peer_sockets); i++) {
|
||||||
size_t i;
|
SOCKET sock = loop->poll_peer_sockets[i];
|
||||||
for (i = 0; i < ARRAY_SIZE(loop->poll_peer_sockets); i++) {
|
if (sock != 0 && sock != INVALID_SOCKET)
|
||||||
SOCKET sock = loop->poll_peer_sockets[i];
|
closesocket(sock);
|
||||||
if (sock != 0 && sock != INVALID_SOCKET)
|
|
||||||
closesocket(sock);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* TODO: cleanup default loop*/
|
|
||||||
|
|
||||||
uv_mutex_lock(&loop->wq_mutex);
|
uv_mutex_lock(&loop->wq_mutex);
|
||||||
assert(QUEUE_EMPTY(&loop->wq) && "thread pool work queue not empty!");
|
assert(QUEUE_EMPTY(&loop->wq) && "thread pool work queue not empty!");
|
||||||
assert(!uv__has_active_reqs(loop));
|
assert(!uv__has_active_reqs(loop));
|
||||||
uv_mutex_unlock(&loop->wq_mutex);
|
uv_mutex_unlock(&loop->wq_mutex);
|
||||||
uv_mutex_destroy(&loop->wq_mutex);
|
uv_mutex_destroy(&loop->wq_mutex);
|
||||||
|
|
||||||
|
CloseHandle(loop->iocp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -242,6 +237,8 @@ int uv_loop_close(uv_loop_t* loop) {
|
|||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
memset(loop, -1, sizeof(*loop));
|
memset(loop, -1, sizeof(*loop));
|
||||||
#endif
|
#endif
|
||||||
|
if (loop == default_loop_ptr)
|
||||||
|
default_loop_ptr = NULL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -265,9 +262,12 @@ uv_loop_t* uv_loop_new(void) {
|
|||||||
|
|
||||||
|
|
||||||
void uv_loop_delete(uv_loop_t* loop) {
|
void uv_loop_delete(uv_loop_t* loop) {
|
||||||
int err = uv_loop_close(loop);
|
uv_loop_t* default_loop;
|
||||||
|
int err;
|
||||||
|
default_loop = default_loop_ptr;
|
||||||
|
err = uv_loop_close(loop);
|
||||||
assert(err == 0);
|
assert(err == 0);
|
||||||
if (loop != &uv_default_loop_)
|
if (loop != default_loop)
|
||||||
free(loop);
|
free(loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,13 +313,17 @@ static void uv_poll(uv_loop_t* loop, DWORD timeout) {
|
|||||||
/* Package was dequeued */
|
/* Package was dequeued */
|
||||||
req = uv_overlapped_to_req(overlapped);
|
req = uv_overlapped_to_req(overlapped);
|
||||||
uv_insert_pending_req(loop, req);
|
uv_insert_pending_req(loop, req);
|
||||||
|
|
||||||
|
/* Some time might have passed waiting for I/O,
|
||||||
|
* so update the loop time here.
|
||||||
|
*/
|
||||||
|
uv_update_time(loop);
|
||||||
} else if (GetLastError() != WAIT_TIMEOUT) {
|
} else if (GetLastError() != WAIT_TIMEOUT) {
|
||||||
/* Serious error */
|
/* Serious error */
|
||||||
uv_fatal_error(GetLastError(), "GetQueuedCompletionStatus");
|
uv_fatal_error(GetLastError(), "GetQueuedCompletionStatus");
|
||||||
} else {
|
} else if (timeout > 0) {
|
||||||
/* We're sure that at least `timeout` milliseconds have expired, but
|
/* GetQueuedCompletionStatus can occasionally return a little early.
|
||||||
* this may not be reflected yet in the GetTickCount() return value.
|
* Make sure that the desired timeout is reflected in the loop time.
|
||||||
* Therefore we ensure it's taken into account here.
|
|
||||||
*/
|
*/
|
||||||
uv__time_forward(loop, timeout);
|
uv__time_forward(loop, timeout);
|
||||||
}
|
}
|
||||||
@ -346,13 +350,17 @@ static void uv_poll_ex(uv_loop_t* loop, DWORD timeout) {
|
|||||||
req = uv_overlapped_to_req(overlappeds[i].lpOverlapped);
|
req = uv_overlapped_to_req(overlappeds[i].lpOverlapped);
|
||||||
uv_insert_pending_req(loop, req);
|
uv_insert_pending_req(loop, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Some time might have passed waiting for I/O,
|
||||||
|
* so update the loop time here.
|
||||||
|
*/
|
||||||
|
uv_update_time(loop);
|
||||||
} else if (GetLastError() != WAIT_TIMEOUT) {
|
} else if (GetLastError() != WAIT_TIMEOUT) {
|
||||||
/* Serious error */
|
/* Serious error */
|
||||||
uv_fatal_error(GetLastError(), "GetQueuedCompletionStatusEx");
|
uv_fatal_error(GetLastError(), "GetQueuedCompletionStatusEx");
|
||||||
} else if (timeout > 0) {
|
} else if (timeout > 0) {
|
||||||
/* We're sure that at least `timeout` milliseconds have expired, but
|
/* GetQueuedCompletionStatus can occasionally return a little early.
|
||||||
* this may not be reflected yet in the GetTickCount() return value.
|
* Make sure that the desired timeout is reflected in the loop time.
|
||||||
* Therefore we ensure it's taken into account here.
|
|
||||||
*/
|
*/
|
||||||
uv__time_forward(loop, timeout);
|
uv__time_forward(loop, timeout);
|
||||||
}
|
}
|
||||||
@ -411,7 +419,6 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
|
|||||||
* UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from
|
* UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from
|
||||||
* the check.
|
* the check.
|
||||||
*/
|
*/
|
||||||
uv_update_time(loop);
|
|
||||||
uv_process_timers(loop);
|
uv_process_timers(loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,3 +435,68 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
|
|||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) {
|
||||||
|
uv_os_fd_t fd_out;
|
||||||
|
|
||||||
|
switch (handle->type) {
|
||||||
|
case UV_TCP:
|
||||||
|
fd_out = (uv_os_fd_t)((uv_tcp_t*) handle)->socket;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UV_NAMED_PIPE:
|
||||||
|
fd_out = ((uv_pipe_t*) handle)->handle;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UV_TTY:
|
||||||
|
fd_out = ((uv_tty_t*) handle)->handle;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UV_UDP:
|
||||||
|
fd_out = (uv_os_fd_t)((uv_udp_t*) handle)->socket;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case UV_POLL:
|
||||||
|
fd_out = (uv_os_fd_t)((uv_poll_t*) handle)->socket;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return UV_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uv_is_closing(handle) || fd_out == INVALID_HANDLE_VALUE)
|
||||||
|
return UV_EBADF;
|
||||||
|
|
||||||
|
*fd = fd_out;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) {
|
||||||
|
int r;
|
||||||
|
int len;
|
||||||
|
SOCKET socket;
|
||||||
|
|
||||||
|
if (handle == NULL || value == NULL)
|
||||||
|
return UV_EINVAL;
|
||||||
|
|
||||||
|
if (handle->type == UV_TCP)
|
||||||
|
socket = ((uv_tcp_t*) handle)->socket;
|
||||||
|
else if (handle->type == UV_UDP)
|
||||||
|
socket = ((uv_udp_t*) handle)->socket;
|
||||||
|
else
|
||||||
|
return UV_ENOTSUP;
|
||||||
|
|
||||||
|
len = sizeof(*value);
|
||||||
|
|
||||||
|
if (*value == 0)
|
||||||
|
r = getsockopt(socket, SOL_SOCKET, optname, (char*) value, &len);
|
||||||
|
else
|
||||||
|
r = setsockopt(socket, SOL_SOCKET, optname, (const char*) value, len);
|
||||||
|
|
||||||
|
if (r == SOCKET_ERROR)
|
||||||
|
return uv_translate_sys_error(WSAGetLastError());
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
226
deps/uv/src/win/fs.c
vendored
@ -36,11 +36,15 @@
|
|||||||
#include "req-inl.h"
|
#include "req-inl.h"
|
||||||
#include "handle-inl.h"
|
#include "handle-inl.h"
|
||||||
|
|
||||||
|
#include <wincrypt.h>
|
||||||
|
|
||||||
|
|
||||||
#define UV_FS_FREE_PATHS 0x0002
|
#define UV_FS_FREE_PATHS 0x0002
|
||||||
#define UV_FS_FREE_PTR 0x0008
|
#define UV_FS_FREE_PTR 0x0008
|
||||||
#define UV_FS_CLEANEDUP 0x0010
|
#define UV_FS_CLEANEDUP 0x0010
|
||||||
|
|
||||||
|
static const int uv__fs_dirent_slide = 0x20;
|
||||||
|
|
||||||
|
|
||||||
#define QUEUE_FS_TP_JOB(loop, req) \
|
#define QUEUE_FS_TP_JOB(loop, req) \
|
||||||
do { \
|
do { \
|
||||||
@ -721,88 +725,75 @@ void fs__mkdir(uv_fs_t* req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Some parts of the implementation were borrowed from glibc. */
|
/* OpenBSD original: lib/libc/stdio/mktemp.c */
|
||||||
void fs__mkdtemp(uv_fs_t* req) {
|
void fs__mkdtemp(uv_fs_t* req) {
|
||||||
static const WCHAR letters[] =
|
static const WCHAR *tempchars =
|
||||||
L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||||
|
static const size_t num_chars = 62;
|
||||||
|
static const size_t num_x = 6;
|
||||||
|
WCHAR *cp, *ep;
|
||||||
|
unsigned int tries, i;
|
||||||
size_t len;
|
size_t len;
|
||||||
WCHAR* template_part;
|
HCRYPTPROV h_crypt_prov;
|
||||||
static uint64_t value;
|
uint64_t v;
|
||||||
unsigned int count;
|
BOOL released;
|
||||||
int fd;
|
|
||||||
|
|
||||||
/* A lower bound on the number of temporary files to attempt to
|
|
||||||
generate. The maximum total number of temporary file names that
|
|
||||||
can exist for a given template is 62**6. It should never be
|
|
||||||
necessary to try all these combinations. Instead if a reasonable
|
|
||||||
number of names is tried (we define reasonable as 62**3) fail to
|
|
||||||
give the system administrator the chance to remove the problems. */
|
|
||||||
#define ATTEMPTS_MIN (62 * 62 * 62)
|
|
||||||
|
|
||||||
/* The number of times to attempt to generate a temporary file. To
|
|
||||||
conform to POSIX, this must be no smaller than TMP_MAX. */
|
|
||||||
#if ATTEMPTS_MIN < TMP_MAX
|
|
||||||
unsigned int attempts = TMP_MAX;
|
|
||||||
#else
|
|
||||||
unsigned int attempts = ATTEMPTS_MIN;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
len = wcslen(req->pathw);
|
len = wcslen(req->pathw);
|
||||||
if (len < 6 || wcsncmp(&req->pathw[len - 6], L"XXXXXX", 6)) {
|
ep = req->pathw + len;
|
||||||
|
if (len < num_x || wcsncmp(ep - num_x, L"XXXXXX", num_x)) {
|
||||||
SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
|
SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is where the Xs start. */
|
if (!CryptAcquireContext(&h_crypt_prov, NULL, NULL, PROV_RSA_FULL,
|
||||||
template_part = &req->pathw[len - 6];
|
CRYPT_VERIFYCONTEXT)) {
|
||||||
|
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||||
/* Get some random data. */
|
return;
|
||||||
value += uv_hrtime() ^ _getpid();
|
|
||||||
|
|
||||||
for (count = 0; count < attempts; value += 7777, ++count) {
|
|
||||||
uint64_t v = value;
|
|
||||||
|
|
||||||
/* Fill in the random bits. */
|
|
||||||
template_part[0] = letters[v % 62];
|
|
||||||
v /= 62;
|
|
||||||
template_part[1] = letters[v % 62];
|
|
||||||
v /= 62;
|
|
||||||
template_part[2] = letters[v % 62];
|
|
||||||
v /= 62;
|
|
||||||
template_part[3] = letters[v % 62];
|
|
||||||
v /= 62;
|
|
||||||
template_part[4] = letters[v % 62];
|
|
||||||
v /= 62;
|
|
||||||
template_part[5] = letters[v % 62];
|
|
||||||
|
|
||||||
fd = _wmkdir(req->pathw);
|
|
||||||
|
|
||||||
if (fd >= 0) {
|
|
||||||
len = strlen(req->path);
|
|
||||||
wcstombs((char*) req->path + len - 6, template_part, 6);
|
|
||||||
SET_REQ_RESULT(req, 0);
|
|
||||||
return;
|
|
||||||
} else if (errno != EEXIST) {
|
|
||||||
SET_REQ_RESULT(req, -1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We got out of the loop because we ran out of combinations to try. */
|
tries = TMP_MAX;
|
||||||
SET_REQ_RESULT(req, -1);
|
do {
|
||||||
|
if (!CryptGenRandom(h_crypt_prov, sizeof(v), (BYTE*) &v)) {
|
||||||
|
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cp = ep - num_x;
|
||||||
|
for (i = 0; i < num_x; i++) {
|
||||||
|
*cp++ = tempchars[v % num_chars];
|
||||||
|
v /= num_chars;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_wmkdir(req->pathw) == 0) {
|
||||||
|
len = strlen(req->path);
|
||||||
|
wcstombs((char*) req->path + len - num_x, ep - num_x, num_x);
|
||||||
|
SET_REQ_RESULT(req, 0);
|
||||||
|
break;
|
||||||
|
} else if (errno != EEXIST) {
|
||||||
|
SET_REQ_RESULT(req, -1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (--tries);
|
||||||
|
|
||||||
|
released = CryptReleaseContext(h_crypt_prov, 0);
|
||||||
|
assert(released);
|
||||||
|
if (tries == 0) {
|
||||||
|
SET_REQ_RESULT(req, -1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void fs__readdir(uv_fs_t* req) {
|
void fs__readdir(uv_fs_t* req) {
|
||||||
WCHAR* pathw = req->pathw;
|
WCHAR* pathw = req->pathw;
|
||||||
size_t len = wcslen(pathw);
|
size_t len = wcslen(pathw);
|
||||||
int result, size;
|
int result;
|
||||||
WCHAR* buf = NULL, *ptr, *name;
|
WCHAR* name;
|
||||||
HANDLE dir;
|
HANDLE dir;
|
||||||
WIN32_FIND_DATAW ent = { 0 };
|
WIN32_FIND_DATAW ent = { 0 };
|
||||||
size_t buf_char_len = 4096;
|
|
||||||
WCHAR* path2;
|
WCHAR* path2;
|
||||||
const WCHAR* fmt;
|
const WCHAR* fmt;
|
||||||
|
uv__dirent_t** dents;
|
||||||
|
int dent_size;
|
||||||
|
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
fmt = L"./*";
|
fmt = L"./*";
|
||||||
@ -821,7 +812,8 @@ void fs__readdir(uv_fs_t* req) {
|
|||||||
|
|
||||||
path2 = (WCHAR*)malloc(sizeof(WCHAR) * (len + 4));
|
path2 = (WCHAR*)malloc(sizeof(WCHAR) * (len + 4));
|
||||||
if (!path2) {
|
if (!path2) {
|
||||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_snwprintf(path2, len + 3, fmt, pathw);
|
_snwprintf(path2, len + 3, fmt, pathw);
|
||||||
@ -834,71 +826,81 @@ void fs__readdir(uv_fs_t* req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = 0;
|
result = 0;
|
||||||
|
dents = NULL;
|
||||||
|
dent_size = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
uv__dirent_t* dent;
|
||||||
|
int utf8_len;
|
||||||
|
|
||||||
name = ent.cFileName;
|
name = ent.cFileName;
|
||||||
|
|
||||||
if (name[0] != L'.' || (name[1] && (name[1] != L'.' || name[2]))) {
|
if (!(name[0] != L'.' || (name[1] && (name[1] != L'.' || name[2]))))
|
||||||
len = wcslen(name);
|
continue;
|
||||||
|
|
||||||
if (!buf) {
|
/* Grow dents buffer, if needed */
|
||||||
buf = (WCHAR*)malloc(buf_char_len * sizeof(WCHAR));
|
if (result >= dent_size) {
|
||||||
if (!buf) {
|
uv__dirent_t** tmp;
|
||||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr = buf;
|
dent_size += uv__fs_dirent_slide;
|
||||||
|
tmp = realloc(dents, dent_size * sizeof(*dents));
|
||||||
|
if (tmp == NULL) {
|
||||||
|
SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
|
||||||
|
goto fatal;
|
||||||
}
|
}
|
||||||
|
dents = tmp;
|
||||||
while ((ptr - buf) + len + 1 > buf_char_len) {
|
|
||||||
buf_char_len *= 2;
|
|
||||||
path2 = buf;
|
|
||||||
buf = (WCHAR*)realloc(buf, buf_char_len * sizeof(WCHAR));
|
|
||||||
if (!buf) {
|
|
||||||
uv_fatal_error(ERROR_OUTOFMEMORY, "realloc");
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr = buf + (ptr - path2);
|
|
||||||
}
|
|
||||||
|
|
||||||
wcscpy(ptr, name);
|
|
||||||
ptr += len + 1;
|
|
||||||
result++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allocate enough space to fit utf8 encoding of file name */
|
||||||
|
len = wcslen(name);
|
||||||
|
utf8_len = uv_utf16_to_utf8(name, len, NULL, 0);
|
||||||
|
if (!utf8_len) {
|
||||||
|
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||||
|
goto fatal;
|
||||||
|
}
|
||||||
|
|
||||||
|
dent = malloc(sizeof(*dent) + utf8_len + 1);
|
||||||
|
if (dent == NULL) {
|
||||||
|
SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
|
||||||
|
goto fatal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy file name */
|
||||||
|
utf8_len = uv_utf16_to_utf8(name, len, dent->d_name, utf8_len);
|
||||||
|
if (!utf8_len) {
|
||||||
|
free(dent);
|
||||||
|
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||||
|
goto fatal;
|
||||||
|
}
|
||||||
|
dent->d_name[utf8_len] = '\0';
|
||||||
|
|
||||||
|
/* Copy file type */
|
||||||
|
if ((ent.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
|
||||||
|
dent->d_type = UV__DT_DIR;
|
||||||
|
else if ((ent.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0)
|
||||||
|
dent->d_type = UV__DT_LINK;
|
||||||
|
else
|
||||||
|
dent->d_type = UV__DT_FILE;
|
||||||
|
|
||||||
|
dents[result++] = dent;
|
||||||
} while(FindNextFileW(dir, &ent));
|
} while(FindNextFileW(dir, &ent));
|
||||||
|
|
||||||
FindClose(dir);
|
FindClose(dir);
|
||||||
|
|
||||||
if (buf) {
|
if (dents != NULL)
|
||||||
/* Convert result to UTF8. */
|
|
||||||
size = uv_utf16_to_utf8(buf, buf_char_len, NULL, 0);
|
|
||||||
if (!size) {
|
|
||||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
req->ptr = (char*)malloc(size + 1);
|
|
||||||
if (!req->ptr) {
|
|
||||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
|
||||||
}
|
|
||||||
|
|
||||||
size = uv_utf16_to_utf8(buf, buf_char_len, (char*)req->ptr, size);
|
|
||||||
if (!size) {
|
|
||||||
free(buf);
|
|
||||||
free(req->ptr);
|
|
||||||
req->ptr = NULL;
|
|
||||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
free(buf);
|
|
||||||
|
|
||||||
((char*)req->ptr)[size] = '\0';
|
|
||||||
req->flags |= UV_FS_FREE_PTR;
|
req->flags |= UV_FS_FREE_PTR;
|
||||||
} else {
|
|
||||||
req->ptr = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* NOTE: nbufs will be used as index */
|
||||||
|
req->nbufs = 0;
|
||||||
|
req->ptr = dents;
|
||||||
SET_REQ_RESULT(req, result);
|
SET_REQ_RESULT(req, result);
|
||||||
|
return;
|
||||||
|
|
||||||
|
fatal:
|
||||||
|
/* Deallocate dents */
|
||||||
|
for (result--; result >= 0; result--)
|
||||||
|
free(dents[result]);
|
||||||
|
free(dents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
19
deps/uv/src/win/getaddrinfo.c
vendored
@ -26,6 +26,25 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "req-inl.h"
|
#include "req-inl.h"
|
||||||
|
|
||||||
|
/* EAI_* constants. */
|
||||||
|
#include <winsock2.h>
|
||||||
|
|
||||||
|
|
||||||
|
int uv__getaddrinfo_translate_error(int sys_err) {
|
||||||
|
switch (sys_err) {
|
||||||
|
case 0: return 0;
|
||||||
|
case WSATRY_AGAIN: return UV_EAI_AGAIN;
|
||||||
|
case WSAEINVAL: return UV_EAI_BADFLAGS;
|
||||||
|
case WSANO_RECOVERY: return UV_EAI_FAIL;
|
||||||
|
case WSAEAFNOSUPPORT: return UV_EAI_FAMILY;
|
||||||
|
case WSA_NOT_ENOUGH_MEMORY: return UV_EAI_MEMORY;
|
||||||
|
case WSAHOST_NOT_FOUND: return UV_EAI_NONAME;
|
||||||
|
case WSATYPE_NOT_FOUND: return UV_EAI_SERVICE;
|
||||||
|
case WSAESOCKTNOSUPPORT: return UV_EAI_SOCKTYPE;
|
||||||
|
default: return uv_translate_sys_error(sys_err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MinGW is missing this
|
* MinGW is missing this
|
||||||
|
16
deps/uv/src/win/getnameinfo.c
vendored
@ -46,13 +46,15 @@ static void uv__getnameinfo_work(struct uv__work* w) {
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
req = container_of(w, uv_getnameinfo_t, work_req);
|
req = container_of(w, uv_getnameinfo_t, work_req);
|
||||||
ret = GetNameInfoW((struct sockaddr*)&req->storage,
|
if (GetNameInfoW((struct sockaddr*)&req->storage,
|
||||||
sizeof(req->storage),
|
sizeof(req->storage),
|
||||||
host,
|
host,
|
||||||
ARRAY_SIZE(host),
|
ARRAY_SIZE(host),
|
||||||
service,
|
service,
|
||||||
ARRAY_SIZE(service),
|
ARRAY_SIZE(service),
|
||||||
req->flags);
|
req->flags)) {
|
||||||
|
ret = WSAGetLastError();
|
||||||
|
}
|
||||||
req->retcode = uv__getaddrinfo_translate_error(ret);
|
req->retcode = uv__getaddrinfo_translate_error(ret);
|
||||||
|
|
||||||
/* convert results to UTF-8 */
|
/* convert results to UTF-8 */
|
||||||
|
6
deps/uv/src/win/internal.h
vendored
@ -65,7 +65,6 @@ extern UV_THREAD_LOCAL int uv__crt_assert_enabled;
|
|||||||
/* Used by all handles. */
|
/* Used by all handles. */
|
||||||
#define UV_HANDLE_CLOSED 0x00000002
|
#define UV_HANDLE_CLOSED 0x00000002
|
||||||
#define UV_HANDLE_ENDGAME_QUEUED 0x00000004
|
#define UV_HANDLE_ENDGAME_QUEUED 0x00000004
|
||||||
#define UV_HANDLE_ACTIVE 0x00000010
|
|
||||||
|
|
||||||
/* uv-common.h: #define UV__HANDLE_CLOSING 0x00000001 */
|
/* uv-common.h: #define UV__HANDLE_CLOSING 0x00000001 */
|
||||||
/* uv-common.h: #define UV__HANDLE_ACTIVE 0x00000040 */
|
/* uv-common.h: #define UV__HANDLE_ACTIVE 0x00000040 */
|
||||||
@ -100,6 +99,7 @@ extern UV_THREAD_LOCAL int uv__crt_assert_enabled;
|
|||||||
/* Only used by uv_pipe_t handles. */
|
/* Only used by uv_pipe_t handles. */
|
||||||
#define UV_HANDLE_NON_OVERLAPPED_PIPE 0x01000000
|
#define UV_HANDLE_NON_OVERLAPPED_PIPE 0x01000000
|
||||||
#define UV_HANDLE_PIPESERVER 0x02000000
|
#define UV_HANDLE_PIPESERVER 0x02000000
|
||||||
|
#define UV_HANDLE_PIPE_READ_CANCELABLE 0x04000000
|
||||||
|
|
||||||
/* Only used by uv_tty_t handles. */
|
/* Only used by uv_tty_t handles. */
|
||||||
#define UV_HANDLE_TTY_READABLE 0x01000000
|
#define UV_HANDLE_TTY_READABLE 0x01000000
|
||||||
@ -181,6 +181,9 @@ int uv_pipe_write(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle,
|
|||||||
int uv_pipe_write2(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle,
|
int uv_pipe_write2(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle,
|
||||||
const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle,
|
const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle,
|
||||||
uv_write_cb cb);
|
uv_write_cb cb);
|
||||||
|
void uv__pipe_pause_read(uv_pipe_t* handle);
|
||||||
|
void uv__pipe_unpause_read(uv_pipe_t* handle);
|
||||||
|
void uv__pipe_stop_read(uv_pipe_t* handle);
|
||||||
|
|
||||||
void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
|
void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
|
||||||
uv_req_t* req);
|
uv_req_t* req);
|
||||||
@ -319,6 +322,7 @@ void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle);
|
|||||||
*/
|
*/
|
||||||
void uv__util_init();
|
void uv__util_init();
|
||||||
|
|
||||||
|
uint64_t uv__hrtime(double scale);
|
||||||
int uv_parent_pid();
|
int uv_parent_pid();
|
||||||
__declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall);
|
__declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall);
|
||||||
|
|
||||||
|
6
deps/uv/src/win/loop-watcher.c
vendored
@ -49,7 +49,7 @@ void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
|
|||||||
\
|
\
|
||||||
assert(handle->type == UV_##NAME); \
|
assert(handle->type == UV_##NAME); \
|
||||||
\
|
\
|
||||||
if (handle->flags & UV_HANDLE_ACTIVE) \
|
if (uv__is_active(handle)) \
|
||||||
return 0; \
|
return 0; \
|
||||||
\
|
\
|
||||||
if (cb == NULL) \
|
if (cb == NULL) \
|
||||||
@ -67,7 +67,6 @@ void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
|
|||||||
loop->name##_handles = handle; \
|
loop->name##_handles = handle; \
|
||||||
\
|
\
|
||||||
handle->name##_cb = cb; \
|
handle->name##_cb = cb; \
|
||||||
handle->flags |= UV_HANDLE_ACTIVE; \
|
|
||||||
uv__handle_start(handle); \
|
uv__handle_start(handle); \
|
||||||
\
|
\
|
||||||
return 0; \
|
return 0; \
|
||||||
@ -79,7 +78,7 @@ void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
|
|||||||
\
|
\
|
||||||
assert(handle->type == UV_##NAME); \
|
assert(handle->type == UV_##NAME); \
|
||||||
\
|
\
|
||||||
if (!(handle->flags & UV_HANDLE_ACTIVE)) \
|
if (!uv__is_active(handle)) \
|
||||||
return 0; \
|
return 0; \
|
||||||
\
|
\
|
||||||
/* Update loop head if needed */ \
|
/* Update loop head if needed */ \
|
||||||
@ -99,7 +98,6 @@ void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
|
|||||||
handle->name##_next->name##_prev = handle->name##_prev; \
|
handle->name##_next->name##_prev = handle->name##_prev; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
handle->flags &= ~UV_HANDLE_ACTIVE; \
|
|
||||||
uv__handle_stop(handle); \
|
uv__handle_stop(handle); \
|
||||||
\
|
\
|
||||||
return 0; \
|
return 0; \
|
||||||
|
105
deps/uv/src/win/pipe.c
vendored
@ -101,6 +101,7 @@ int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
|
|||||||
handle->pending_ipc_info.queue_len = 0;
|
handle->pending_ipc_info.queue_len = 0;
|
||||||
handle->ipc = ipc;
|
handle->ipc = ipc;
|
||||||
handle->non_overlapped_writes_tail = NULL;
|
handle->non_overlapped_writes_tail = NULL;
|
||||||
|
handle->readfile_thread = NULL;
|
||||||
|
|
||||||
uv_req_init(loop, (uv_req_t*) &handle->ipc_header_write_req);
|
uv_req_init(loop, (uv_req_t*) &handle->ipc_header_write_req);
|
||||||
|
|
||||||
@ -112,6 +113,12 @@ static void uv_pipe_connection_init(uv_pipe_t* handle) {
|
|||||||
uv_connection_init((uv_stream_t*) handle);
|
uv_connection_init((uv_stream_t*) handle);
|
||||||
handle->read_req.data = handle;
|
handle->read_req.data = handle;
|
||||||
handle->eof_timer = NULL;
|
handle->eof_timer = NULL;
|
||||||
|
assert(!(handle->flags & UV_HANDLE_PIPESERVER));
|
||||||
|
if (pCancelSynchronousIo &&
|
||||||
|
handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
|
||||||
|
uv_mutex_init(&handle->readfile_mutex);
|
||||||
|
handle->flags |= UV_HANDLE_PIPE_READ_CANCELABLE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -321,6 +328,11 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
|
|||||||
FILE_PIPE_LOCAL_INFORMATION pipe_info;
|
FILE_PIPE_LOCAL_INFORMATION pipe_info;
|
||||||
uv__ipc_queue_item_t* item;
|
uv__ipc_queue_item_t* item;
|
||||||
|
|
||||||
|
if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
|
||||||
|
handle->flags &= ~UV_HANDLE_PIPE_READ_CANCELABLE;
|
||||||
|
uv_mutex_destroy(&handle->readfile_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
if ((handle->flags & UV_HANDLE_CONNECTION) &&
|
if ((handle->flags & UV_HANDLE_CONNECTION) &&
|
||||||
handle->shutdown_req != NULL &&
|
handle->shutdown_req != NULL &&
|
||||||
handle->write_reqs_pending == 0) {
|
handle->write_reqs_pending == 0) {
|
||||||
@ -658,12 +670,49 @@ error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uv__pipe_pause_read(uv_pipe_t* handle) {
|
||||||
|
if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
|
||||||
|
/* Pause the ReadFile task briefly, to work
|
||||||
|
around the Windows kernel bug that causes
|
||||||
|
any access to a NamedPipe to deadlock if
|
||||||
|
any process has called ReadFile */
|
||||||
|
HANDLE h;
|
||||||
|
uv_mutex_lock(&handle->readfile_mutex);
|
||||||
|
h = handle->readfile_thread;
|
||||||
|
while (h) {
|
||||||
|
/* spinlock: we expect this to finish quickly,
|
||||||
|
or we are probably about to deadlock anyways
|
||||||
|
(in the kernel), so it doesn't matter */
|
||||||
|
pCancelSynchronousIo(h);
|
||||||
|
SwitchToThread(); /* yield thread control briefly */
|
||||||
|
h = handle->readfile_thread;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uv__pipe_unpause_read(uv_pipe_t* handle) {
|
||||||
|
if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
|
||||||
|
uv_mutex_unlock(&handle->readfile_mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uv__pipe_stop_read(uv_pipe_t* handle) {
|
||||||
|
handle->flags &= ~UV_HANDLE_READING;
|
||||||
|
uv__pipe_pause_read((uv_pipe_t*)handle);
|
||||||
|
uv__pipe_unpause_read((uv_pipe_t*)handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Cleans up uv_pipe_t (server or connection) and all resources associated */
|
/* Cleans up uv_pipe_t (server or connection) and all resources associated */
|
||||||
/* with it. */
|
/* with it. */
|
||||||
void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) {
|
void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) {
|
||||||
int i;
|
int i;
|
||||||
HANDLE pipeHandle;
|
HANDLE pipeHandle;
|
||||||
|
|
||||||
|
uv__pipe_stop_read(handle);
|
||||||
|
|
||||||
if (handle->name) {
|
if (handle->name) {
|
||||||
free(handle->name);
|
free(handle->name);
|
||||||
handle->name = NULL;
|
handle->name = NULL;
|
||||||
@ -689,6 +738,7 @@ void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) {
|
|||||||
CloseHandle(handle->handle);
|
CloseHandle(handle->handle);
|
||||||
handle->handle = INVALID_HANDLE_VALUE;
|
handle->handle = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -867,19 +917,61 @@ static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) {
|
|||||||
uv_read_t* req = (uv_read_t*) parameter;
|
uv_read_t* req = (uv_read_t*) parameter;
|
||||||
uv_pipe_t* handle = (uv_pipe_t*) req->data;
|
uv_pipe_t* handle = (uv_pipe_t*) req->data;
|
||||||
uv_loop_t* loop = handle->loop;
|
uv_loop_t* loop = handle->loop;
|
||||||
|
HANDLE hThread = NULL;
|
||||||
|
DWORD err;
|
||||||
|
uv_mutex_t *m = &handle->readfile_mutex;
|
||||||
|
|
||||||
assert(req != NULL);
|
assert(req != NULL);
|
||||||
assert(req->type == UV_READ);
|
assert(req->type == UV_READ);
|
||||||
assert(handle->type == UV_NAMED_PIPE);
|
assert(handle->type == UV_NAMED_PIPE);
|
||||||
|
|
||||||
|
if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
|
||||||
|
uv_mutex_lock(m); /* mutex controls *setting* of readfile_thread */
|
||||||
|
if (DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
|
||||||
|
GetCurrentProcess(), &hThread,
|
||||||
|
0, TRUE, DUPLICATE_SAME_ACCESS)) {
|
||||||
|
handle->readfile_thread = hThread;
|
||||||
|
} else {
|
||||||
|
hThread = NULL;
|
||||||
|
}
|
||||||
|
uv_mutex_unlock(m);
|
||||||
|
}
|
||||||
|
restart_readfile:
|
||||||
result = ReadFile(handle->handle,
|
result = ReadFile(handle->handle,
|
||||||
&uv_zero_,
|
&uv_zero_,
|
||||||
0,
|
0,
|
||||||
&bytes,
|
&bytes,
|
||||||
NULL);
|
NULL);
|
||||||
|
if (!result) {
|
||||||
|
err = GetLastError();
|
||||||
|
if (err == ERROR_OPERATION_ABORTED &&
|
||||||
|
handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
|
||||||
|
if (handle->flags & UV_HANDLE_READING) {
|
||||||
|
/* just a brief break to do something else */
|
||||||
|
handle->readfile_thread = NULL;
|
||||||
|
/* resume after it is finished */
|
||||||
|
uv_mutex_lock(m);
|
||||||
|
handle->readfile_thread = hThread;
|
||||||
|
uv_mutex_unlock(m);
|
||||||
|
goto restart_readfile;
|
||||||
|
} else {
|
||||||
|
result = 1; /* successfully stopped reading */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hThread) {
|
||||||
|
assert(hThread == handle->readfile_thread);
|
||||||
|
/* mutex does not control clearing readfile_thread */
|
||||||
|
handle->readfile_thread = NULL;
|
||||||
|
uv_mutex_lock(m);
|
||||||
|
/* only when we hold the mutex lock is it safe to
|
||||||
|
open or close the handle */
|
||||||
|
CloseHandle(hThread);
|
||||||
|
uv_mutex_unlock(m);
|
||||||
|
}
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
SET_REQ_ERROR(req, GetLastError());
|
SET_REQ_ERROR(req, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
POST_COMPLETION_FOR_REQ(loop, req);
|
POST_COMPLETION_FOR_REQ(loop, req);
|
||||||
@ -1836,6 +1928,8 @@ int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len) {
|
|||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uv__pipe_pause_read((uv_pipe_t*)handle); /* cast away const warning */
|
||||||
|
|
||||||
nt_status = pNtQueryInformationFile(handle->handle,
|
nt_status = pNtQueryInformationFile(handle->handle,
|
||||||
&io_status,
|
&io_status,
|
||||||
&tmp_name_info,
|
&tmp_name_info,
|
||||||
@ -1846,7 +1940,8 @@ int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len) {
|
|||||||
name_info = malloc(name_size);
|
name_info = malloc(name_size);
|
||||||
if (!name_info) {
|
if (!name_info) {
|
||||||
*len = 0;
|
*len = 0;
|
||||||
return UV_ENOMEM;
|
err = UV_ENOMEM;
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
nt_status = pNtQueryInformationFile(handle->handle,
|
nt_status = pNtQueryInformationFile(handle->handle,
|
||||||
@ -1918,10 +2013,14 @@ int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len) {
|
|||||||
buf[addrlen++] = '\0';
|
buf[addrlen++] = '\0';
|
||||||
*len = addrlen;
|
*len = addrlen;
|
||||||
|
|
||||||
return 0;
|
err = 0;
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
free(name_info);
|
free(name_info);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
uv__pipe_unpause_read((uv_pipe_t*)handle); /* cast away const warning */
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
deps/uv/src/win/process.c
vendored
@ -171,8 +171,10 @@ static WCHAR* search_path_join_test(const WCHAR* dir,
|
|||||||
size_t cwd_len) {
|
size_t cwd_len) {
|
||||||
WCHAR *result, *result_pos;
|
WCHAR *result, *result_pos;
|
||||||
DWORD attrs;
|
DWORD attrs;
|
||||||
|
if (dir_len > 2 && dir[0] == L'\\' && dir[1] == L'\\') {
|
||||||
if (dir_len >= 1 && (dir[0] == L'/' || dir[0] == L'\\')) {
|
/* It's a UNC path so ignore cwd */
|
||||||
|
cwd_len = 0;
|
||||||
|
} else if (dir_len >= 1 && (dir[0] == L'/' || dir[0] == L'\\')) {
|
||||||
/* It's a full path without drive letter, use cwd's drive letter only */
|
/* It's a full path without drive letter, use cwd's drive letter only */
|
||||||
cwd_len = 2;
|
cwd_len = 2;
|
||||||
} else if (dir_len >= 2 && dir[1] == L':' &&
|
} else if (dir_len >= 2 && dir[1] == L':' &&
|
||||||
@ -331,7 +333,11 @@ static WCHAR* path_search_walk_ext(const WCHAR *dir,
|
|||||||
* file that is not readable/executable; if the spawn fails it will not
|
* file that is not readable/executable; if the spawn fails it will not
|
||||||
* continue searching.
|
* continue searching.
|
||||||
*
|
*
|
||||||
* TODO: correctly interpret UNC paths
|
* UNC path support: we are dealing with UNC paths in both the path and the
|
||||||
|
* filename. This is a deviation from what cmd.exe does (it does not let you
|
||||||
|
* start a program by specifying an UNC path on the command line) but this is
|
||||||
|
* really a pointless restriction.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
static WCHAR* search_path(const WCHAR *file,
|
static WCHAR* search_path(const WCHAR *file,
|
||||||
WCHAR *cwd,
|
WCHAR *cwd,
|
||||||
@ -794,10 +800,8 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
|
|||||||
i++;
|
i++;
|
||||||
} else {
|
} else {
|
||||||
/* copy var from env_block */
|
/* copy var from env_block */
|
||||||
DWORD r;
|
|
||||||
len = wcslen(*ptr_copy) + 1;
|
len = wcslen(*ptr_copy) + 1;
|
||||||
r = wmemcpy_s(ptr, (env_len - (ptr - dst)), *ptr_copy, len);
|
wmemcpy(ptr, *ptr_copy, len);
|
||||||
assert(!r);
|
|
||||||
ptr_copy++;
|
ptr_copy++;
|
||||||
if (cmp == 0)
|
if (cmp == 0)
|
||||||
i++;
|
i++;
|
||||||
|
6
deps/uv/src/win/stream.c
vendored
@ -106,7 +106,11 @@ int uv_read_stop(uv_stream_t* handle) {
|
|||||||
if (handle->type == UV_TTY) {
|
if (handle->type == UV_TTY) {
|
||||||
err = uv_tty_read_stop((uv_tty_t*) handle);
|
err = uv_tty_read_stop((uv_tty_t*) handle);
|
||||||
} else {
|
} else {
|
||||||
handle->flags &= ~UV_HANDLE_READING;
|
if (handle->type == UV_NAMED_PIPE) {
|
||||||
|
uv__pipe_stop_read((uv_pipe_t*) handle);
|
||||||
|
} else {
|
||||||
|
handle->flags &= ~UV_HANDLE_READING;
|
||||||
|
}
|
||||||
DECREASE_ACTIVE_COUNT(handle->loop, handle);
|
DECREASE_ACTIVE_COUNT(handle->loop, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
deps/uv/src/win/tcp.c
vendored
@ -196,6 +196,7 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
|
|||||||
|
|
||||||
if (!(handle->flags & UV_HANDLE_TCP_SOCKET_CLOSED)) {
|
if (!(handle->flags & UV_HANDLE_TCP_SOCKET_CLOSED)) {
|
||||||
closesocket(handle->socket);
|
closesocket(handle->socket);
|
||||||
|
handle->socket = INVALID_SOCKET;
|
||||||
handle->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
|
handle->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1368,6 +1369,7 @@ void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
|
|||||||
|
|
||||||
if (close_socket) {
|
if (close_socket) {
|
||||||
closesocket(tcp->socket);
|
closesocket(tcp->socket);
|
||||||
|
tcp->socket = INVALID_SOCKET;
|
||||||
tcp->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
|
tcp->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
100
deps/uv/src/win/timer.c
vendored
@ -28,39 +28,17 @@
|
|||||||
#include "handle-inl.h"
|
#include "handle-inl.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* The number of milliseconds in one second. */
|
||||||
|
#define UV__MILLISEC 1000
|
||||||
|
|
||||||
|
|
||||||
void uv_update_time(uv_loop_t* loop) {
|
void uv_update_time(uv_loop_t* loop) {
|
||||||
DWORD ticks;
|
uint64_t new_time = uv__hrtime(UV__MILLISEC);
|
||||||
ULARGE_INTEGER time;
|
if (new_time > loop->time) {
|
||||||
|
loop->time = new_time;
|
||||||
ticks = GetTickCount();
|
}
|
||||||
|
|
||||||
time.QuadPart = loop->time;
|
|
||||||
|
|
||||||
/* GetTickCount() can conceivably wrap around, so when the current tick
|
|
||||||
* count is lower than the last tick count, we'll assume it has wrapped.
|
|
||||||
* uv_poll must make sure that the timer can never overflow more than
|
|
||||||
* once between two subsequent uv_update_time calls.
|
|
||||||
*/
|
|
||||||
time.LowPart = ticks;
|
|
||||||
if (ticks < loop->last_tick_count)
|
|
||||||
time.HighPart++;
|
|
||||||
|
|
||||||
/* Remember the last tick count. */
|
|
||||||
loop->last_tick_count = ticks;
|
|
||||||
|
|
||||||
/* The GetTickCount() resolution isn't too good. Sometimes it'll happen
|
|
||||||
* that GetQueuedCompletionStatus() or GetQueuedCompletionStatusEx() has
|
|
||||||
* waited for a couple of ms but this is not reflected in the GetTickCount
|
|
||||||
* result yet. Therefore whenever GetQueuedCompletionStatus times out
|
|
||||||
* we'll add the number of ms that it has waited to the current loop time.
|
|
||||||
* When that happened the loop time might be a little ms farther than what
|
|
||||||
* we've just computed, and we shouldn't update the loop time.
|
|
||||||
*/
|
|
||||||
if (loop->time < time.QuadPart)
|
|
||||||
loop->time = time.QuadPart;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void uv__time_forward(uv_loop_t* loop, uint64_t msecs) {
|
void uv__time_forward(uv_loop_t* loop, uint64_t msecs) {
|
||||||
loop->time += msecs;
|
loop->time += msecs;
|
||||||
}
|
}
|
||||||
@ -119,14 +97,15 @@ int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, uint64_t timeout,
|
|||||||
uv_loop_t* loop = handle->loop;
|
uv_loop_t* loop = handle->loop;
|
||||||
uv_timer_t* old;
|
uv_timer_t* old;
|
||||||
|
|
||||||
if (handle->flags & UV_HANDLE_ACTIVE) {
|
if (timer_cb == NULL)
|
||||||
RB_REMOVE(uv_timer_tree_s, &loop->timers, handle);
|
return UV_EINVAL;
|
||||||
}
|
|
||||||
|
if (uv__is_active(handle))
|
||||||
|
uv_timer_stop(handle);
|
||||||
|
|
||||||
handle->timer_cb = timer_cb;
|
handle->timer_cb = timer_cb;
|
||||||
handle->due = get_clamped_due_time(loop->time, timeout);
|
handle->due = get_clamped_due_time(loop->time, timeout);
|
||||||
handle->repeat = repeat;
|
handle->repeat = repeat;
|
||||||
handle->flags |= UV_HANDLE_ACTIVE;
|
|
||||||
uv__handle_start(handle);
|
uv__handle_start(handle);
|
||||||
|
|
||||||
/* start_id is the second index to be compared in uv__timer_cmp() */
|
/* start_id is the second index to be compared in uv__timer_cmp() */
|
||||||
@ -142,12 +121,10 @@ int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, uint64_t timeout,
|
|||||||
int uv_timer_stop(uv_timer_t* handle) {
|
int uv_timer_stop(uv_timer_t* handle) {
|
||||||
uv_loop_t* loop = handle->loop;
|
uv_loop_t* loop = handle->loop;
|
||||||
|
|
||||||
if (!(handle->flags & UV_HANDLE_ACTIVE))
|
if (!uv__is_active(handle))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
RB_REMOVE(uv_timer_tree_s, &loop->timers, handle);
|
RB_REMOVE(uv_timer_tree_s, &loop->timers, handle);
|
||||||
|
|
||||||
handle->flags &= ~UV_HANDLE_ACTIVE;
|
|
||||||
uv__handle_stop(handle);
|
uv__handle_stop(handle);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -155,28 +132,14 @@ int uv_timer_stop(uv_timer_t* handle) {
|
|||||||
|
|
||||||
|
|
||||||
int uv_timer_again(uv_timer_t* handle) {
|
int uv_timer_again(uv_timer_t* handle) {
|
||||||
uv_loop_t* loop = handle->loop;
|
|
||||||
|
|
||||||
/* If timer_cb is NULL that means that the timer was never started. */
|
/* If timer_cb is NULL that means that the timer was never started. */
|
||||||
if (!handle->timer_cb) {
|
if (!handle->timer_cb) {
|
||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle->flags & UV_HANDLE_ACTIVE) {
|
|
||||||
RB_REMOVE(uv_timer_tree_s, &loop->timers, handle);
|
|
||||||
handle->flags &= ~UV_HANDLE_ACTIVE;
|
|
||||||
uv__handle_stop(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handle->repeat) {
|
if (handle->repeat) {
|
||||||
handle->due = get_clamped_due_time(loop->time, handle->repeat);
|
uv_timer_stop(handle);
|
||||||
|
uv_timer_start(handle, handle->timer_cb, handle->repeat, handle->repeat);
|
||||||
if (RB_INSERT(uv_timer_tree_s, &loop->timers, handle) != NULL) {
|
|
||||||
uv_fatal_error(ERROR_INVALID_DATA, "RB_INSERT");
|
|
||||||
}
|
|
||||||
|
|
||||||
handle->flags |= UV_HANDLE_ACTIVE;
|
|
||||||
uv__handle_start(handle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -206,16 +169,9 @@ DWORD uv__next_timeout(const uv_loop_t* loop) {
|
|||||||
timer = RB_MIN(uv_timer_tree_s, &((uv_loop_t*)loop)->timers);
|
timer = RB_MIN(uv_timer_tree_s, &((uv_loop_t*)loop)->timers);
|
||||||
if (timer) {
|
if (timer) {
|
||||||
delta = timer->due - loop->time;
|
delta = timer->due - loop->time;
|
||||||
if (delta >= UINT_MAX >> 1) {
|
if (delta >= UINT_MAX - 1) {
|
||||||
/* A timeout value of UINT_MAX means infinite, so that's no good. But
|
/* A timeout value of UINT_MAX means infinite, so that's no good. */
|
||||||
* more importantly, there's always the risk that GetTickCount wraps.
|
return UINT_MAX - 1;
|
||||||
* uv_update_time can detect this, but we must make sure that the
|
|
||||||
* tick counter never overflows twice between two subsequent
|
|
||||||
* uv_update_time calls. We do this by never sleeping more than half
|
|
||||||
* the time it takes to wrap the counter - which is huge overkill,
|
|
||||||
* but hey, it's not so bad to wake up every 25 days.
|
|
||||||
*/
|
|
||||||
return UINT_MAX >> 1;
|
|
||||||
} else if (delta < 0) {
|
} else if (delta < 0) {
|
||||||
/* Negative timeout values are not allowed */
|
/* Negative timeout values are not allowed */
|
||||||
return 0;
|
return 0;
|
||||||
@ -236,23 +192,9 @@ void uv_process_timers(uv_loop_t* loop) {
|
|||||||
for (timer = RB_MIN(uv_timer_tree_s, &loop->timers);
|
for (timer = RB_MIN(uv_timer_tree_s, &loop->timers);
|
||||||
timer != NULL && timer->due <= loop->time;
|
timer != NULL && timer->due <= loop->time;
|
||||||
timer = RB_MIN(uv_timer_tree_s, &loop->timers)) {
|
timer = RB_MIN(uv_timer_tree_s, &loop->timers)) {
|
||||||
RB_REMOVE(uv_timer_tree_s, &loop->timers, timer);
|
|
||||||
|
|
||||||
if (timer->repeat != 0) {
|
|
||||||
/* If it is a repeating timer, reschedule with repeat timeout. */
|
|
||||||
timer->due = get_clamped_due_time(timer->due, timer->repeat);
|
|
||||||
if (timer->due < loop->time) {
|
|
||||||
timer->due = loop->time;
|
|
||||||
}
|
|
||||||
if (RB_INSERT(uv_timer_tree_s, &loop->timers, timer) != NULL) {
|
|
||||||
uv_fatal_error(ERROR_INVALID_DATA, "RB_INSERT");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* If non-repeating, mark the timer as inactive. */
|
|
||||||
timer->flags &= ~UV_HANDLE_ACTIVE;
|
|
||||||
uv__handle_stop(timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
uv_timer_stop(timer);
|
||||||
|
uv_timer_again(timer);
|
||||||
timer->timer_cb((uv_timer_t*) timer);
|
timer->timer_cb((uv_timer_t*) timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1
deps/uv/src/win/tty.c
vendored
@ -1903,6 +1903,7 @@ void uv_tty_close(uv_tty_t* handle) {
|
|||||||
if (handle->flags & UV_HANDLE_READING)
|
if (handle->flags & UV_HANDLE_READING)
|
||||||
uv_tty_read_stop(handle);
|
uv_tty_read_stop(handle);
|
||||||
|
|
||||||
|
handle->handle = INVALID_HANDLE_VALUE;
|
||||||
handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
|
handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
|
||||||
uv__handle_closing(handle);
|
uv__handle_closing(handle);
|
||||||
|
|
||||||
|
15
deps/uv/src/win/udp.c
vendored
@ -144,6 +144,7 @@ int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
|
|||||||
void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle) {
|
void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle) {
|
||||||
uv_udp_recv_stop(handle);
|
uv_udp_recv_stop(handle);
|
||||||
closesocket(handle->socket);
|
closesocket(handle->socket);
|
||||||
|
handle->socket = INVALID_SOCKET;
|
||||||
|
|
||||||
uv__handle_closing(handle);
|
uv__handle_closing(handle);
|
||||||
|
|
||||||
@ -505,9 +506,13 @@ void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle,
|
|||||||
} else if (err == WSAEWOULDBLOCK) {
|
} else if (err == WSAEWOULDBLOCK) {
|
||||||
/* Kernel buffer empty */
|
/* Kernel buffer empty */
|
||||||
handle->recv_cb(handle, 0, &buf, NULL, 0);
|
handle->recv_cb(handle, 0, &buf, NULL, 0);
|
||||||
} else if (err != WSAECONNRESET && err != WSAENETRESET) {
|
} else if (err == WSAECONNRESET || err == WSAENETRESET) {
|
||||||
/* Serious error. WSAECONNRESET/WSANETRESET is ignored because this */
|
/* WSAECONNRESET/WSANETRESET is ignored because this just indicates
|
||||||
/* just indicates that a previous sendto operation failed. */
|
* that a previous sendto operation failed.
|
||||||
|
*/
|
||||||
|
handle->recv_cb(handle, 0, &buf, NULL, 0);
|
||||||
|
} else {
|
||||||
|
/* Any other error that we want to report back to the user. */
|
||||||
uv_udp_recv_stop(handle);
|
uv_udp_recv_stop(handle);
|
||||||
handle->recv_cb(handle, uv_translate_sys_error(err), &buf, NULL, 0);
|
handle->recv_cb(handle, uv_translate_sys_error(err), &buf, NULL, 0);
|
||||||
}
|
}
|
||||||
@ -572,7 +577,9 @@ static int uv__udp_set_membership4(uv_udp_t* handle,
|
|||||||
memset(&mreq, 0, sizeof mreq);
|
memset(&mreq, 0, sizeof mreq);
|
||||||
|
|
||||||
if (interface_addr) {
|
if (interface_addr) {
|
||||||
mreq.imr_interface.s_addr = inet_addr(interface_addr);
|
err = uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
} else {
|
} else {
|
||||||
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||||
}
|
}
|
||||||
|
37
deps/uv/src/win/util.c
vendored
@ -52,16 +52,15 @@
|
|||||||
#define MAX_TITLE_LENGTH 8192
|
#define MAX_TITLE_LENGTH 8192
|
||||||
|
|
||||||
/* The number of nanoseconds in one second. */
|
/* The number of nanoseconds in one second. */
|
||||||
#undef NANOSEC
|
#define UV__NANOSEC 1000000000
|
||||||
#define NANOSEC 1000000000
|
|
||||||
|
|
||||||
|
|
||||||
/* Cached copy of the process title, plus a mutex guarding it. */
|
/* Cached copy of the process title, plus a mutex guarding it. */
|
||||||
static char *process_title;
|
static char *process_title;
|
||||||
static CRITICAL_SECTION process_title_lock;
|
static CRITICAL_SECTION process_title_lock;
|
||||||
|
|
||||||
/* Frequency (ticks per nanosecond) of the high-resolution clock. */
|
/* Interval (in seconds) of the high-resolution clock. */
|
||||||
static double hrtime_frequency_ = 0;
|
static double hrtime_interval_ = 0;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -73,11 +72,14 @@ void uv__util_init() {
|
|||||||
/* Initialize process title access mutex. */
|
/* Initialize process title access mutex. */
|
||||||
InitializeCriticalSection(&process_title_lock);
|
InitializeCriticalSection(&process_title_lock);
|
||||||
|
|
||||||
/* Retrieve high-resolution timer frequency. */
|
/* Retrieve high-resolution timer frequency
|
||||||
if (QueryPerformanceFrequency(&perf_frequency))
|
* and precompute its reciprocal.
|
||||||
hrtime_frequency_ = (double) perf_frequency.QuadPart / (double) NANOSEC;
|
*/
|
||||||
else
|
if (QueryPerformanceFrequency(&perf_frequency)) {
|
||||||
hrtime_frequency_= 0;
|
hrtime_interval_ = 1.0 / perf_frequency.QuadPart;
|
||||||
|
} else {
|
||||||
|
hrtime_interval_= 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -463,26 +465,27 @@ int uv_get_process_title(char* buffer, size_t size) {
|
|||||||
|
|
||||||
|
|
||||||
uint64_t uv_hrtime(void) {
|
uint64_t uv_hrtime(void) {
|
||||||
|
uv__once_init();
|
||||||
|
return uv__hrtime(UV__NANOSEC);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t uv__hrtime(double scale) {
|
||||||
LARGE_INTEGER counter;
|
LARGE_INTEGER counter;
|
||||||
|
|
||||||
uv__once_init();
|
/* If the performance interval is zero, there's no support. */
|
||||||
|
if (hrtime_interval_ == 0) {
|
||||||
/* If the performance frequency is zero, there's no support. */
|
|
||||||
if (hrtime_frequency_ == 0) {
|
|
||||||
/* uv__set_sys_error(loop, ERROR_NOT_SUPPORTED); */
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!QueryPerformanceCounter(&counter)) {
|
if (!QueryPerformanceCounter(&counter)) {
|
||||||
/* uv__set_sys_error(loop, GetLastError()); */
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Because we have no guarantee about the order of magnitude of the
|
/* Because we have no guarantee about the order of magnitude of the
|
||||||
* performance counter frequency, integer math could cause this computation
|
* performance counter interval, integer math could cause this computation
|
||||||
* to overflow. Therefore we resort to floating point math.
|
* to overflow. Therefore we resort to floating point math.
|
||||||
*/
|
*/
|
||||||
return (uint64_t) ((double) counter.QuadPart / hrtime_frequency_);
|
return (uint64_t) ((double) counter.QuadPart * hrtime_interval_ * scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
4
deps/uv/src/win/winapi.c
vendored
@ -51,6 +51,7 @@ sSleepConditionVariableCS pSleepConditionVariableCS;
|
|||||||
sSleepConditionVariableSRW pSleepConditionVariableSRW;
|
sSleepConditionVariableSRW pSleepConditionVariableSRW;
|
||||||
sWakeAllConditionVariable pWakeAllConditionVariable;
|
sWakeAllConditionVariable pWakeAllConditionVariable;
|
||||||
sWakeConditionVariable pWakeConditionVariable;
|
sWakeConditionVariable pWakeConditionVariable;
|
||||||
|
sCancelSynchronousIo pCancelSynchronousIo;
|
||||||
|
|
||||||
|
|
||||||
void uv_winapi_init() {
|
void uv_winapi_init() {
|
||||||
@ -156,4 +157,7 @@ void uv_winapi_init() {
|
|||||||
|
|
||||||
pWakeConditionVariable = (sWakeConditionVariable)
|
pWakeConditionVariable = (sWakeConditionVariable)
|
||||||
GetProcAddress(kernel32_module, "WakeConditionVariable");
|
GetProcAddress(kernel32_module, "WakeConditionVariable");
|
||||||
|
|
||||||
|
pCancelSynchronousIo = (sCancelSynchronousIo)
|
||||||
|
GetProcAddress(kernel32_module, "CancelSynchronousIo");
|
||||||
}
|
}
|
||||||
|
3
deps/uv/src/win/winapi.h
vendored
@ -4617,6 +4617,8 @@ typedef VOID (WINAPI* sWakeAllConditionVariable)
|
|||||||
typedef VOID (WINAPI* sWakeConditionVariable)
|
typedef VOID (WINAPI* sWakeConditionVariable)
|
||||||
(PCONDITION_VARIABLE ConditionVariable);
|
(PCONDITION_VARIABLE ConditionVariable);
|
||||||
|
|
||||||
|
typedef BOOL (WINAPI* sCancelSynchronousIo)
|
||||||
|
(HANDLE hThread);
|
||||||
|
|
||||||
/* Ntdll function pointers */
|
/* Ntdll function pointers */
|
||||||
extern sRtlNtStatusToDosError pRtlNtStatusToDosError;
|
extern sRtlNtStatusToDosError pRtlNtStatusToDosError;
|
||||||
@ -4644,5 +4646,6 @@ extern sSleepConditionVariableCS pSleepConditionVariableCS;
|
|||||||
extern sSleepConditionVariableSRW pSleepConditionVariableSRW;
|
extern sSleepConditionVariableSRW pSleepConditionVariableSRW;
|
||||||
extern sWakeAllConditionVariable pWakeAllConditionVariable;
|
extern sWakeAllConditionVariable pWakeAllConditionVariable;
|
||||||
extern sWakeConditionVariable pWakeConditionVariable;
|
extern sWakeConditionVariable pWakeConditionVariable;
|
||||||
|
extern sCancelSynchronousIo pCancelSynchronousIo;
|
||||||
|
|
||||||
#endif /* UV_WIN_WINAPI_H_ */
|
#endif /* UV_WIN_WINAPI_H_ */
|
||||||
|
22
deps/uv/test/echo-server.c
vendored
@ -51,20 +51,21 @@ static void after_write(uv_write_t* req, int status) {
|
|||||||
/* Free the read/write buffer and the request */
|
/* Free the read/write buffer and the request */
|
||||||
wr = (write_req_t*) req;
|
wr = (write_req_t*) req;
|
||||||
free(wr->buf.base);
|
free(wr->buf.base);
|
||||||
|
free(wr);
|
||||||
|
|
||||||
if (status == 0) {
|
if (status == 0)
|
||||||
free(wr);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"uv_write error: %s - %s\n",
|
"uv_write error: %s - %s\n",
|
||||||
uv_err_name(status),
|
uv_err_name(status),
|
||||||
uv_strerror(status));
|
uv_strerror(status));
|
||||||
|
}
|
||||||
|
|
||||||
if (!uv_is_closing((uv_handle_t*) req->handle))
|
|
||||||
uv_close((uv_handle_t*) req->handle, on_close);
|
static void after_shutdown(uv_shutdown_t* req, int status) {
|
||||||
free(wr);
|
uv_close((uv_handle_t*) req->handle, on_close);
|
||||||
|
free(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -73,16 +74,15 @@ static void after_read(uv_stream_t* handle,
|
|||||||
const uv_buf_t* buf) {
|
const uv_buf_t* buf) {
|
||||||
int i;
|
int i;
|
||||||
write_req_t *wr;
|
write_req_t *wr;
|
||||||
|
uv_shutdown_t* sreq;
|
||||||
|
|
||||||
if (nread < 0) {
|
if (nread < 0) {
|
||||||
/* Error or EOF */
|
/* Error or EOF */
|
||||||
ASSERT(nread == UV_EOF);
|
ASSERT(nread == UV_EOF);
|
||||||
|
|
||||||
if (buf->base) {
|
free(buf->base);
|
||||||
free(buf->base);
|
sreq = malloc(sizeof* sreq);
|
||||||
}
|
ASSERT(0 == uv_shutdown(sreq, handle, after_shutdown));
|
||||||
|
|
||||||
uv_close((uv_handle_t*) handle, on_close);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
59
deps/uv/test/test-default-loop-close.c
vendored
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
* deal in the Software without restriction, including without limitation the
|
||||||
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
* sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
* IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uv.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
|
||||||
|
static int timer_cb_called;
|
||||||
|
|
||||||
|
|
||||||
|
static void timer_cb(uv_timer_t* timer) {
|
||||||
|
timer_cb_called++;
|
||||||
|
uv_close((uv_handle_t*) timer, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_IMPL(default_loop_close) {
|
||||||
|
uv_loop_t* loop;
|
||||||
|
uv_timer_t timer_handle;
|
||||||
|
|
||||||
|
loop = uv_default_loop();
|
||||||
|
ASSERT(loop != NULL);
|
||||||
|
|
||||||
|
ASSERT(0 == uv_timer_init(loop, &timer_handle));
|
||||||
|
ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0));
|
||||||
|
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
|
||||||
|
ASSERT(1 == timer_cb_called);
|
||||||
|
ASSERT(0 == uv_loop_close(loop));
|
||||||
|
|
||||||
|
loop = uv_default_loop();
|
||||||
|
ASSERT(loop != NULL);
|
||||||
|
|
||||||
|
ASSERT(0 == uv_timer_init(loop, &timer_handle));
|
||||||
|
ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0));
|
||||||
|
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
|
||||||
|
ASSERT(2 == timer_cb_called);
|
||||||
|
ASSERT(0 == uv_loop_close(loop));
|
||||||
|
|
||||||
|
MAKE_VALGRIND_HAPPY();
|
||||||
|
return 0;
|
||||||
|
}
|
28
deps/uv/test/test-fs.c
vendored
@ -417,12 +417,16 @@ static void rmdir_cb(uv_fs_t* req) {
|
|||||||
|
|
||||||
|
|
||||||
static void readdir_cb(uv_fs_t* req) {
|
static void readdir_cb(uv_fs_t* req) {
|
||||||
|
uv_dirent_t dent;
|
||||||
ASSERT(req == &readdir_req);
|
ASSERT(req == &readdir_req);
|
||||||
ASSERT(req->fs_type == UV_FS_READDIR);
|
ASSERT(req->fs_type == UV_FS_READDIR);
|
||||||
ASSERT(req->result == 2);
|
ASSERT(req->result == 2);
|
||||||
ASSERT(req->ptr);
|
ASSERT(req->ptr);
|
||||||
ASSERT(memcmp(req->ptr, "file1\0file2\0", 12) == 0
|
|
||||||
|| memcmp(req->ptr, "file2\0file1\0", 12) == 0);
|
while (UV_EOF != uv_fs_readdir_next(req, &dent)) {
|
||||||
|
ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
|
||||||
|
ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN);
|
||||||
|
}
|
||||||
readdir_cb_count++;
|
readdir_cb_count++;
|
||||||
ASSERT(req->path);
|
ASSERT(req->path);
|
||||||
ASSERT(memcmp(req->path, "test_dir\0", 9) == 0);
|
ASSERT(memcmp(req->path, "test_dir\0", 9) == 0);
|
||||||
@ -802,6 +806,7 @@ TEST_IMPL(fs_file_write_null_buffer) {
|
|||||||
|
|
||||||
TEST_IMPL(fs_async_dir) {
|
TEST_IMPL(fs_async_dir) {
|
||||||
int r;
|
int r;
|
||||||
|
uv_dirent_t dent;
|
||||||
|
|
||||||
/* Setup */
|
/* Setup */
|
||||||
unlink("test_dir/file1");
|
unlink("test_dir/file1");
|
||||||
@ -844,8 +849,10 @@ TEST_IMPL(fs_async_dir) {
|
|||||||
ASSERT(r == 2);
|
ASSERT(r == 2);
|
||||||
ASSERT(readdir_req.result == 2);
|
ASSERT(readdir_req.result == 2);
|
||||||
ASSERT(readdir_req.ptr);
|
ASSERT(readdir_req.ptr);
|
||||||
ASSERT(memcmp(readdir_req.ptr, "file1\0file2\0", 12) == 0
|
while (UV_EOF != uv_fs_readdir_next(&readdir_req, &dent)) {
|
||||||
|| memcmp(readdir_req.ptr, "file2\0file1\0", 12) == 0);
|
ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
|
||||||
|
ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN);
|
||||||
|
}
|
||||||
uv_fs_req_cleanup(&readdir_req);
|
uv_fs_req_cleanup(&readdir_req);
|
||||||
ASSERT(!readdir_req.ptr);
|
ASSERT(!readdir_req.ptr);
|
||||||
|
|
||||||
@ -1521,6 +1528,7 @@ TEST_IMPL(fs_symlink_dir) {
|
|||||||
uv_fs_t req;
|
uv_fs_t req;
|
||||||
int r;
|
int r;
|
||||||
char* test_dir;
|
char* test_dir;
|
||||||
|
uv_dirent_t dent;
|
||||||
|
|
||||||
/* set-up */
|
/* set-up */
|
||||||
unlink("test_dir/file1");
|
unlink("test_dir/file1");
|
||||||
@ -1597,8 +1605,10 @@ TEST_IMPL(fs_symlink_dir) {
|
|||||||
ASSERT(r == 2);
|
ASSERT(r == 2);
|
||||||
ASSERT(readdir_req.result == 2);
|
ASSERT(readdir_req.result == 2);
|
||||||
ASSERT(readdir_req.ptr);
|
ASSERT(readdir_req.ptr);
|
||||||
ASSERT(memcmp(readdir_req.ptr, "file1\0file2\0", 12) == 0
|
while (UV_EOF != uv_fs_readdir_next(&readdir_req, &dent)) {
|
||||||
|| memcmp(readdir_req.ptr, "file2\0file1\0", 12) == 0);
|
ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
|
||||||
|
ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN);
|
||||||
|
}
|
||||||
uv_fs_req_cleanup(&readdir_req);
|
uv_fs_req_cleanup(&readdir_req);
|
||||||
ASSERT(!readdir_req.ptr);
|
ASSERT(!readdir_req.ptr);
|
||||||
|
|
||||||
@ -1615,8 +1625,10 @@ TEST_IMPL(fs_symlink_dir) {
|
|||||||
ASSERT(r == 2);
|
ASSERT(r == 2);
|
||||||
ASSERT(readdir_req.result == 2);
|
ASSERT(readdir_req.result == 2);
|
||||||
ASSERT(readdir_req.ptr);
|
ASSERT(readdir_req.ptr);
|
||||||
ASSERT(memcmp(readdir_req.ptr, "file1\0file2\0", 12) == 0
|
while (UV_EOF != uv_fs_readdir_next(&readdir_req, &dent)) {
|
||||||
|| memcmp(readdir_req.ptr, "file2\0file1\0", 12) == 0);
|
ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
|
||||||
|
ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN);
|
||||||
|
}
|
||||||
uv_fs_req_cleanup(&readdir_req);
|
uv_fs_req_cleanup(&readdir_req);
|
||||||
ASSERT(!readdir_req.ptr);
|
ASSERT(!readdir_req.ptr);
|
||||||
|
|
||||||
|
120
deps/uv/test/test-handle-fileno.c
vendored
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
* deal in the Software without restriction, including without limitation the
|
||||||
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
* sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
* IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uv.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
|
||||||
|
static int get_tty_fd(void) {
|
||||||
|
/* Make sure we have an FD that refers to a tty */
|
||||||
|
#ifdef _WIN32
|
||||||
|
HANDLE handle;
|
||||||
|
handle = CreateFileA("conout$",
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
NULL);
|
||||||
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
|
return -1;
|
||||||
|
return _open_osfhandle((intptr_t) handle, 0);
|
||||||
|
#else /* unix */
|
||||||
|
return open("/dev/tty", O_RDONLY, 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_IMPL(handle_fileno) {
|
||||||
|
int r;
|
||||||
|
int tty_fd;
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
uv_os_fd_t fd;
|
||||||
|
uv_tcp_t tcp;
|
||||||
|
uv_udp_t udp;
|
||||||
|
uv_pipe_t pipe;
|
||||||
|
uv_tty_t tty;
|
||||||
|
uv_idle_t idle;
|
||||||
|
uv_loop_t* loop;
|
||||||
|
|
||||||
|
loop = uv_default_loop();
|
||||||
|
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
|
||||||
|
|
||||||
|
r = uv_idle_init(loop, &idle);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
r = uv_fileno((uv_handle_t*) &idle, &fd);
|
||||||
|
ASSERT(r == UV_EINVAL);
|
||||||
|
uv_close((uv_handle_t*) &idle, NULL);
|
||||||
|
|
||||||
|
r = uv_tcp_init(loop, &tcp);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
r = uv_fileno((uv_handle_t*) &tcp, &fd);
|
||||||
|
ASSERT(r == UV_EBADF);
|
||||||
|
r = uv_tcp_bind(&tcp, (const struct sockaddr*) &addr, 0);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
r = uv_fileno((uv_handle_t*) &tcp, &fd);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
uv_close((uv_handle_t*) &tcp, NULL);
|
||||||
|
r = uv_fileno((uv_handle_t*) &tcp, &fd);
|
||||||
|
ASSERT(r == UV_EBADF);
|
||||||
|
|
||||||
|
r = uv_udp_init(loop, &udp);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
r = uv_fileno((uv_handle_t*) &udp, &fd);
|
||||||
|
ASSERT(r == UV_EBADF);
|
||||||
|
r = uv_udp_bind(&udp, (const struct sockaddr*) &addr, 0);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
r = uv_fileno((uv_handle_t*) &udp, &fd);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
uv_close((uv_handle_t*) &udp, NULL);
|
||||||
|
r = uv_fileno((uv_handle_t*) &udp, &fd);
|
||||||
|
ASSERT(r == UV_EBADF);
|
||||||
|
|
||||||
|
r = uv_pipe_init(loop, &pipe, 0);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
r = uv_fileno((uv_handle_t*) &pipe, &fd);
|
||||||
|
ASSERT(r == UV_EBADF);
|
||||||
|
r = uv_pipe_bind(&pipe, TEST_PIPENAME);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
r = uv_fileno((uv_handle_t*) &pipe, &fd);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
uv_close((uv_handle_t*) &pipe, NULL);
|
||||||
|
r = uv_fileno((uv_handle_t*) &pipe, &fd);
|
||||||
|
ASSERT(r == UV_EBADF);
|
||||||
|
|
||||||
|
tty_fd = get_tty_fd();
|
||||||
|
if (tty_fd < 0) {
|
||||||
|
LOGF("Cannot open a TTY fd");
|
||||||
|
} else {
|
||||||
|
r = uv_tty_init(loop, &tty, tty_fd, 0);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
r = uv_fileno((uv_handle_t*) &tty, &fd);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
uv_close((uv_handle_t*) &tty, NULL);
|
||||||
|
r = uv_fileno((uv_handle_t*) &tty, &fd);
|
||||||
|
ASSERT(r == UV_EBADF);
|
||||||
|
}
|
||||||
|
|
||||||
|
uv_run(loop, UV_RUN_DEFAULT);
|
||||||
|
|
||||||
|
MAKE_VALGRIND_HAPPY();
|
||||||
|
return 0;
|
||||||
|
}
|
29
deps/uv/test/test-list.h
vendored
@ -29,6 +29,7 @@ TEST_DECLARE (loop_close)
|
|||||||
TEST_DECLARE (loop_stop)
|
TEST_DECLARE (loop_stop)
|
||||||
TEST_DECLARE (loop_update_time)
|
TEST_DECLARE (loop_update_time)
|
||||||
TEST_DECLARE (loop_backend_timeout)
|
TEST_DECLARE (loop_backend_timeout)
|
||||||
|
TEST_DECLARE (default_loop_close)
|
||||||
TEST_DECLARE (barrier_1)
|
TEST_DECLARE (barrier_1)
|
||||||
TEST_DECLARE (barrier_2)
|
TEST_DECLARE (barrier_2)
|
||||||
TEST_DECLARE (barrier_3)
|
TEST_DECLARE (barrier_3)
|
||||||
@ -55,6 +56,9 @@ TEST_DECLARE (tcp_ping_pong_v6)
|
|||||||
TEST_DECLARE (pipe_ping_pong)
|
TEST_DECLARE (pipe_ping_pong)
|
||||||
TEST_DECLARE (delayed_accept)
|
TEST_DECLARE (delayed_accept)
|
||||||
TEST_DECLARE (multiple_listen)
|
TEST_DECLARE (multiple_listen)
|
||||||
|
#ifndef _WIN32
|
||||||
|
TEST_DECLARE (tcp_write_after_connect)
|
||||||
|
#endif
|
||||||
TEST_DECLARE (tcp_writealot)
|
TEST_DECLARE (tcp_writealot)
|
||||||
TEST_DECLARE (tcp_try_write)
|
TEST_DECLARE (tcp_try_write)
|
||||||
TEST_DECLARE (tcp_write_queue_order)
|
TEST_DECLARE (tcp_write_queue_order)
|
||||||
@ -89,6 +93,7 @@ TEST_DECLARE (udp_bind)
|
|||||||
TEST_DECLARE (udp_bind_reuseaddr)
|
TEST_DECLARE (udp_bind_reuseaddr)
|
||||||
TEST_DECLARE (udp_send_and_recv)
|
TEST_DECLARE (udp_send_and_recv)
|
||||||
TEST_DECLARE (udp_send_immediate)
|
TEST_DECLARE (udp_send_immediate)
|
||||||
|
TEST_DECLARE (udp_send_unreachable)
|
||||||
TEST_DECLARE (udp_multicast_join)
|
TEST_DECLARE (udp_multicast_join)
|
||||||
TEST_DECLARE (udp_multicast_join6)
|
TEST_DECLARE (udp_multicast_join6)
|
||||||
TEST_DECLARE (udp_multicast_ttl)
|
TEST_DECLARE (udp_multicast_ttl)
|
||||||
@ -109,6 +114,7 @@ TEST_DECLARE (pipe_connect_bad_name)
|
|||||||
TEST_DECLARE (pipe_connect_to_file)
|
TEST_DECLARE (pipe_connect_to_file)
|
||||||
TEST_DECLARE (pipe_getsockname)
|
TEST_DECLARE (pipe_getsockname)
|
||||||
TEST_DECLARE (pipe_getsockname_abstract)
|
TEST_DECLARE (pipe_getsockname_abstract)
|
||||||
|
TEST_DECLARE (pipe_getsockname_blocking)
|
||||||
TEST_DECLARE (pipe_sendmsg)
|
TEST_DECLARE (pipe_sendmsg)
|
||||||
TEST_DECLARE (pipe_server_close)
|
TEST_DECLARE (pipe_server_close)
|
||||||
TEST_DECLARE (connection_fail)
|
TEST_DECLARE (connection_fail)
|
||||||
@ -128,6 +134,7 @@ TEST_DECLARE (timer_huge_timeout)
|
|||||||
TEST_DECLARE (timer_huge_repeat)
|
TEST_DECLARE (timer_huge_repeat)
|
||||||
TEST_DECLARE (timer_run_once)
|
TEST_DECLARE (timer_run_once)
|
||||||
TEST_DECLARE (timer_from_check)
|
TEST_DECLARE (timer_from_check)
|
||||||
|
TEST_DECLARE (timer_null_callback)
|
||||||
TEST_DECLARE (idle_starvation)
|
TEST_DECLARE (idle_starvation)
|
||||||
TEST_DECLARE (loop_handles)
|
TEST_DECLARE (loop_handles)
|
||||||
TEST_DECLARE (get_loadavg)
|
TEST_DECLARE (get_loadavg)
|
||||||
@ -155,6 +162,9 @@ TEST_DECLARE (pipe_ref)
|
|||||||
TEST_DECLARE (pipe_ref2)
|
TEST_DECLARE (pipe_ref2)
|
||||||
TEST_DECLARE (pipe_ref3)
|
TEST_DECLARE (pipe_ref3)
|
||||||
TEST_DECLARE (pipe_ref4)
|
TEST_DECLARE (pipe_ref4)
|
||||||
|
#ifndef _WIN32
|
||||||
|
TEST_DECLARE (pipe_close_stdout_read_stdin)
|
||||||
|
#endif
|
||||||
TEST_DECLARE (process_ref)
|
TEST_DECLARE (process_ref)
|
||||||
TEST_DECLARE (has_ref)
|
TEST_DECLARE (has_ref)
|
||||||
TEST_DECLARE (active)
|
TEST_DECLARE (active)
|
||||||
@ -165,6 +175,7 @@ TEST_DECLARE (get_currentexe)
|
|||||||
TEST_DECLARE (process_title)
|
TEST_DECLARE (process_title)
|
||||||
TEST_DECLARE (cwd_and_chdir)
|
TEST_DECLARE (cwd_and_chdir)
|
||||||
TEST_DECLARE (get_memory)
|
TEST_DECLARE (get_memory)
|
||||||
|
TEST_DECLARE (handle_fileno)
|
||||||
TEST_DECLARE (hrtime)
|
TEST_DECLARE (hrtime)
|
||||||
TEST_DECLARE (getaddrinfo_fail)
|
TEST_DECLARE (getaddrinfo_fail)
|
||||||
TEST_DECLARE (getaddrinfo_basic)
|
TEST_DECLARE (getaddrinfo_basic)
|
||||||
@ -175,6 +186,7 @@ TEST_DECLARE (getsockname_tcp)
|
|||||||
TEST_DECLARE (getsockname_udp)
|
TEST_DECLARE (getsockname_udp)
|
||||||
TEST_DECLARE (fail_always)
|
TEST_DECLARE (fail_always)
|
||||||
TEST_DECLARE (pass_always)
|
TEST_DECLARE (pass_always)
|
||||||
|
TEST_DECLARE (socket_buffer_size)
|
||||||
TEST_DECLARE (spawn_fails)
|
TEST_DECLARE (spawn_fails)
|
||||||
TEST_DECLARE (spawn_exit_code)
|
TEST_DECLARE (spawn_exit_code)
|
||||||
TEST_DECLARE (spawn_stdout)
|
TEST_DECLARE (spawn_stdout)
|
||||||
@ -275,6 +287,7 @@ TEST_DECLARE (closed_fd_events)
|
|||||||
#endif
|
#endif
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
TEST_DECLARE (osx_select)
|
TEST_DECLARE (osx_select)
|
||||||
|
TEST_DECLARE (osx_select_many_fds)
|
||||||
#endif
|
#endif
|
||||||
HELPER_DECLARE (tcp4_echo_server)
|
HELPER_DECLARE (tcp4_echo_server)
|
||||||
HELPER_DECLARE (tcp6_echo_server)
|
HELPER_DECLARE (tcp6_echo_server)
|
||||||
@ -296,6 +309,7 @@ TASK_LIST_START
|
|||||||
TEST_ENTRY (loop_stop)
|
TEST_ENTRY (loop_stop)
|
||||||
TEST_ENTRY (loop_update_time)
|
TEST_ENTRY (loop_update_time)
|
||||||
TEST_ENTRY (loop_backend_timeout)
|
TEST_ENTRY (loop_backend_timeout)
|
||||||
|
TEST_ENTRY (default_loop_close)
|
||||||
TEST_ENTRY (barrier_1)
|
TEST_ENTRY (barrier_1)
|
||||||
TEST_ENTRY (barrier_2)
|
TEST_ENTRY (barrier_2)
|
||||||
TEST_ENTRY (barrier_3)
|
TEST_ENTRY (barrier_3)
|
||||||
@ -312,6 +326,9 @@ TASK_LIST_START
|
|||||||
TEST_ENTRY (pipe_connect_to_file)
|
TEST_ENTRY (pipe_connect_to_file)
|
||||||
|
|
||||||
TEST_ENTRY (pipe_server_close)
|
TEST_ENTRY (pipe_server_close)
|
||||||
|
#ifndef _WIN32
|
||||||
|
TEST_ENTRY (pipe_close_stdout_read_stdin)
|
||||||
|
#endif
|
||||||
TEST_ENTRY (tty)
|
TEST_ENTRY (tty)
|
||||||
TEST_ENTRY (stdio_over_pipes)
|
TEST_ENTRY (stdio_over_pipes)
|
||||||
TEST_ENTRY (ip6_pton)
|
TEST_ENTRY (ip6_pton)
|
||||||
@ -335,6 +352,10 @@ TASK_LIST_START
|
|||||||
TEST_ENTRY (delayed_accept)
|
TEST_ENTRY (delayed_accept)
|
||||||
TEST_ENTRY (multiple_listen)
|
TEST_ENTRY (multiple_listen)
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
TEST_ENTRY (tcp_write_after_connect)
|
||||||
|
#endif
|
||||||
|
|
||||||
TEST_ENTRY (tcp_writealot)
|
TEST_ENTRY (tcp_writealot)
|
||||||
TEST_HELPER (tcp_writealot, tcp4_echo_server)
|
TEST_HELPER (tcp_writealot, tcp4_echo_server)
|
||||||
|
|
||||||
@ -381,6 +402,7 @@ TASK_LIST_START
|
|||||||
TEST_ENTRY (udp_bind_reuseaddr)
|
TEST_ENTRY (udp_bind_reuseaddr)
|
||||||
TEST_ENTRY (udp_send_and_recv)
|
TEST_ENTRY (udp_send_and_recv)
|
||||||
TEST_ENTRY (udp_send_immediate)
|
TEST_ENTRY (udp_send_immediate)
|
||||||
|
TEST_ENTRY (udp_send_unreachable)
|
||||||
TEST_ENTRY (udp_dgram_too_big)
|
TEST_ENTRY (udp_dgram_too_big)
|
||||||
TEST_ENTRY (udp_dual_stack)
|
TEST_ENTRY (udp_dual_stack)
|
||||||
TEST_ENTRY (udp_ipv6_only)
|
TEST_ENTRY (udp_ipv6_only)
|
||||||
@ -402,6 +424,7 @@ TASK_LIST_START
|
|||||||
TEST_ENTRY (pipe_listen_without_bind)
|
TEST_ENTRY (pipe_listen_without_bind)
|
||||||
TEST_ENTRY (pipe_getsockname)
|
TEST_ENTRY (pipe_getsockname)
|
||||||
TEST_ENTRY (pipe_getsockname_abstract)
|
TEST_ENTRY (pipe_getsockname_abstract)
|
||||||
|
TEST_ENTRY (pipe_getsockname_blocking)
|
||||||
TEST_ENTRY (pipe_sendmsg)
|
TEST_ENTRY (pipe_sendmsg)
|
||||||
|
|
||||||
TEST_ENTRY (connection_fail)
|
TEST_ENTRY (connection_fail)
|
||||||
@ -432,6 +455,7 @@ TASK_LIST_START
|
|||||||
TEST_ENTRY (timer_huge_repeat)
|
TEST_ENTRY (timer_huge_repeat)
|
||||||
TEST_ENTRY (timer_run_once)
|
TEST_ENTRY (timer_run_once)
|
||||||
TEST_ENTRY (timer_from_check)
|
TEST_ENTRY (timer_from_check)
|
||||||
|
TEST_ENTRY (timer_null_callback)
|
||||||
|
|
||||||
TEST_ENTRY (idle_starvation)
|
TEST_ENTRY (idle_starvation)
|
||||||
|
|
||||||
@ -487,6 +511,8 @@ TASK_LIST_START
|
|||||||
|
|
||||||
TEST_ENTRY (get_loadavg)
|
TEST_ENTRY (get_loadavg)
|
||||||
|
|
||||||
|
TEST_ENTRY (handle_fileno)
|
||||||
|
|
||||||
TEST_ENTRY (hrtime)
|
TEST_ENTRY (hrtime)
|
||||||
|
|
||||||
TEST_ENTRY_CUSTOM (getaddrinfo_fail, 0, 0, 10000)
|
TEST_ENTRY_CUSTOM (getaddrinfo_fail, 0, 0, 10000)
|
||||||
@ -504,6 +530,8 @@ TASK_LIST_START
|
|||||||
TEST_ENTRY (poll_unidirectional)
|
TEST_ENTRY (poll_unidirectional)
|
||||||
TEST_ENTRY (poll_close)
|
TEST_ENTRY (poll_close)
|
||||||
|
|
||||||
|
TEST_ENTRY (socket_buffer_size)
|
||||||
|
|
||||||
TEST_ENTRY (spawn_fails)
|
TEST_ENTRY (spawn_fails)
|
||||||
TEST_ENTRY (spawn_exit_code)
|
TEST_ENTRY (spawn_exit_code)
|
||||||
TEST_ENTRY (spawn_stdout)
|
TEST_ENTRY (spawn_stdout)
|
||||||
@ -549,6 +577,7 @@ TASK_LIST_START
|
|||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
TEST_ENTRY (osx_select)
|
TEST_ENTRY (osx_select)
|
||||||
|
TEST_ENTRY (osx_select_many_fds)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TEST_ENTRY (fs_file_noent)
|
TEST_ENTRY (fs_file_noent)
|
||||||
|
48
deps/uv/test/test-osx-select.c
vendored
@ -79,4 +79,52 @@ TEST_IMPL(osx_select) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_IMPL(osx_select_many_fds) {
|
||||||
|
int r;
|
||||||
|
int fd;
|
||||||
|
size_t i;
|
||||||
|
size_t len;
|
||||||
|
const char* str;
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
uv_tty_t tty;
|
||||||
|
uv_tcp_t tcps[1500];
|
||||||
|
|
||||||
|
r = uv_ip4_addr("127.0.0.1", 0, &addr);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(tcps); i++) {
|
||||||
|
r = uv_tcp_init(uv_default_loop(), &tcps[i]);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
r = uv_tcp_bind(&tcps[i], (const struct sockaddr *) &addr, 0);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
uv_unref((uv_handle_t*) &tcps[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = open("/dev/tty", O_RDONLY);
|
||||||
|
ASSERT(fd >= 0);
|
||||||
|
|
||||||
|
r = uv_tty_init(uv_default_loop(), &tty, fd, 1);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
|
||||||
|
r = uv_read_start((uv_stream_t*) &tty, alloc_cb, read_cb);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
|
||||||
|
/* Emulate user-input */
|
||||||
|
str = "got some input\n"
|
||||||
|
"with a couple of lines\n"
|
||||||
|
"feel pretty happy\n";
|
||||||
|
for (i = 0, len = strlen(str); i < len; i++) {
|
||||||
|
r = ioctl(fd, TIOCSTI, str + i);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||||
|
|
||||||
|
ASSERT(read_count == 3);
|
||||||
|
|
||||||
|
MAKE_VALGRIND_HAPPY();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* __APPLE__ */
|
#endif /* __APPLE__ */
|
||||||
|
103
deps/uv/test/test-pipe-close-stdout-read-stdin.c
vendored
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
* deal in the Software without restriction, including without limitation the
|
||||||
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
* sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
* IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "uv.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t* buf)
|
||||||
|
{
|
||||||
|
static char buffer[1024];
|
||||||
|
|
||||||
|
buf->base = buffer;
|
||||||
|
buf->len = sizeof(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void read_stdin(uv_stream_t *stream, ssize_t nread, const uv_buf_t* buf)
|
||||||
|
{
|
||||||
|
if (nread < 0) {
|
||||||
|
uv_close((uv_handle_t*)stream, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This test is a reproduction of joyent/libuv#1419 .
|
||||||
|
*/
|
||||||
|
TEST_IMPL(pipe_close_stdout_read_stdin) {
|
||||||
|
int r = -1;
|
||||||
|
int pid;
|
||||||
|
int fd[2];
|
||||||
|
int status;
|
||||||
|
|
||||||
|
pipe(fd);
|
||||||
|
|
||||||
|
if ((pid = fork()) == 0) {
|
||||||
|
/*
|
||||||
|
* Make the read side of the pipe our stdin.
|
||||||
|
* The write side will be closed by the parent process.
|
||||||
|
*/
|
||||||
|
close(fd[1]);
|
||||||
|
close(0);
|
||||||
|
dup(fd[0]);
|
||||||
|
|
||||||
|
/* Create a stream that reads from the pipe. */
|
||||||
|
uv_pipe_t stdin_pipe;
|
||||||
|
|
||||||
|
r = uv_pipe_init(uv_default_loop(), (uv_pipe_t *)&stdin_pipe, 0);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
|
||||||
|
r = uv_pipe_open((uv_pipe_t *)&stdin_pipe, 0);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
|
||||||
|
r = uv_read_start((uv_stream_t *)&stdin_pipe, alloc_buffer, read_stdin);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Because the other end of the pipe was closed, there should
|
||||||
|
* be no event left to process after one run of the event loop.
|
||||||
|
* Otherwise, it means that events were not processed correctly.
|
||||||
|
*/
|
||||||
|
ASSERT(uv_run(uv_default_loop(), UV_RUN_NOWAIT) == 0);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Close both ends of the pipe so that the child
|
||||||
|
* get a POLLHUP event when it tries to read from
|
||||||
|
* the other end.
|
||||||
|
*/
|
||||||
|
close(fd[1]);
|
||||||
|
close(fd[0]);
|
||||||
|
|
||||||
|
waitpid(pid, &status, 0);
|
||||||
|
ASSERT(WIFEXITED(status) && WEXITSTATUS(status) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
MAKE_VALGRIND_HAPPY();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ifndef _WIN32 */
|
58
deps/uv/test/test-pipe-getsockname.c
vendored
@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
# include <unistd.h> /* close */
|
# include <unistd.h> /* close */
|
||||||
|
#else
|
||||||
|
# include <fcntl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -120,3 +122,59 @@ TEST_IMPL(pipe_getsockname_abstract) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_IMPL(pipe_getsockname_blocking) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
uv_pipe_t reader;
|
||||||
|
HANDLE readh, writeh;
|
||||||
|
int readfd;
|
||||||
|
char buf1[1024], buf2[1024];
|
||||||
|
size_t len1, len2;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = CreatePipe(&readh, &writeh, NULL, 65536);
|
||||||
|
ASSERT(r != 0);
|
||||||
|
|
||||||
|
r = uv_pipe_init(uv_default_loop(), &reader, 0);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
readfd = _open_osfhandle((intptr_t)readh, _O_RDONLY);
|
||||||
|
ASSERT(r != -1);
|
||||||
|
r = uv_pipe_open(&reader, readfd);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
r = uv_read_start((uv_stream_t*)&reader, NULL, NULL);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
Sleep(100);
|
||||||
|
r = uv_read_stop((uv_stream_t*)&reader);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
|
||||||
|
len1 = sizeof buf1;
|
||||||
|
r = uv_pipe_getsockname(&reader, buf1, &len1);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
|
||||||
|
r = uv_read_start((uv_stream_t*)&reader, NULL, NULL);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
Sleep(100);
|
||||||
|
|
||||||
|
len2 = sizeof buf2;
|
||||||
|
r = uv_pipe_getsockname(&reader, buf2, &len2);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
|
||||||
|
r = uv_read_stop((uv_stream_t*)&reader);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
|
||||||
|
ASSERT(len1 == len2);
|
||||||
|
ASSERT(memcmp(buf1, buf2, len1) == 0);
|
||||||
|
|
||||||
|
close_cb_called = 0;
|
||||||
|
uv_close((uv_handle_t*)&reader, close_cb);
|
||||||
|
|
||||||
|
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||||
|
|
||||||
|
ASSERT(close_cb_called == 1);
|
||||||
|
|
||||||
|
_close(readfd);
|
||||||
|
CloseHandle(writeh);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MAKE_VALGRIND_HAPPY();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
77
deps/uv/test/test-socket-buffer-size.c
vendored
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
* deal in the Software without restriction, including without limitation the
|
||||||
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
* sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
* IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uv.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static uv_udp_t udp;
|
||||||
|
static uv_tcp_t tcp;
|
||||||
|
static int close_cb_called;
|
||||||
|
|
||||||
|
|
||||||
|
static void close_cb(uv_handle_t* handle) {
|
||||||
|
close_cb_called++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void check_buffer_size(uv_handle_t* handle) {
|
||||||
|
int value;
|
||||||
|
|
||||||
|
value = 0;
|
||||||
|
ASSERT(0 == uv_recv_buffer_size(handle, &value));
|
||||||
|
ASSERT(value > 0);
|
||||||
|
|
||||||
|
value = 10000;
|
||||||
|
ASSERT(0 == uv_recv_buffer_size(handle, &value));
|
||||||
|
|
||||||
|
value = 0;
|
||||||
|
ASSERT(0 == uv_recv_buffer_size(handle, &value));
|
||||||
|
/* linux sets double the value */
|
||||||
|
ASSERT(value == 10000 || value == 20000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_IMPL(socket_buffer_size) {
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
|
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
|
||||||
|
|
||||||
|
ASSERT(0 == uv_tcp_init(uv_default_loop(), &tcp));
|
||||||
|
ASSERT(0 == uv_tcp_bind(&tcp, (struct sockaddr*) &addr, 0));
|
||||||
|
check_buffer_size((uv_handle_t*) &tcp);
|
||||||
|
uv_close((uv_handle_t*) &tcp, close_cb);
|
||||||
|
|
||||||
|
ASSERT(0 == uv_udp_init(uv_default_loop(), &udp));
|
||||||
|
ASSERT(0 == uv_udp_bind(&udp, (struct sockaddr*) &addr, 0));
|
||||||
|
check_buffer_size((uv_handle_t*) &udp);
|
||||||
|
uv_close((uv_handle_t*) &udp, close_cb);
|
||||||
|
|
||||||
|
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
|
||||||
|
|
||||||
|
ASSERT(close_cb_called == 2);
|
||||||
|
|
||||||
|
MAKE_VALGRIND_HAPPY();
|
||||||
|
return 0;
|
||||||
|
}
|