Browse Source

deps: update uv to v1.0.0-rc1

v0.11.14-release
Fedor Indutny 10 years ago
committed by Timothy J Fontaine
parent
commit
c5f5d4cd11
  1. 6
      deps/uv/.gitignore
  2. 2
      deps/uv/.mailmap
  3. 2
      deps/uv/AUTHORS
  4. 99
      deps/uv/ChangeLog
  5. 10
      deps/uv/Makefile.am
  6. 35
      deps/uv/README.md
  7. 4
      deps/uv/configure.ac
  8. 243
      deps/uv/docs/make.bat
  9. 56
      deps/uv/docs/src/async.rst
  10. 46
      deps/uv/docs/src/check.rst
  11. 348
      deps/uv/docs/src/conf.py
  12. 137
      deps/uv/docs/src/design.rst
  13. 44
      deps/uv/docs/src/dll.rst
  14. 83
      deps/uv/docs/src/dns.rst
  15. 329
      deps/uv/docs/src/errors.rst
  16. 259
      deps/uv/docs/src/fs.rst
  17. 102
      deps/uv/docs/src/fs_event.rst
  18. 65
      deps/uv/docs/src/fs_poll.rst
  19. 172
      deps/uv/docs/src/handle.rst
  20. 54
      deps/uv/docs/src/idle.rst
  21. 84
      deps/uv/docs/src/index.rst
  22. 137
      deps/uv/docs/src/loop.rst
  23. 228
      deps/uv/docs/src/misc.rst
  24. 86
      deps/uv/docs/src/pipe.rst
  25. 99
      deps/uv/docs/src/poll.rst
  26. 46
      deps/uv/docs/src/prepare.rst
  27. 215
      deps/uv/docs/src/process.rst
  28. 82
      deps/uv/docs/src/request.rst
  29. 77
      deps/uv/docs/src/signal.rst
  30. BIN
      deps/uv/docs/src/static/architecture.png
  31. BIN
      deps/uv/docs/src/static/diagrams.key/Data/st0-311.jpg
  32. BIN
      deps/uv/docs/src/static/diagrams.key/Data/st1-475.jpg
  33. BIN
      deps/uv/docs/src/static/diagrams.key/Index.zip
  34. 8
      deps/uv/docs/src/static/diagrams.key/Metadata/BuildVersionHistory.plist
  35. 1
      deps/uv/docs/src/static/diagrams.key/Metadata/DocumentIdentifier
  36. BIN
      deps/uv/docs/src/static/diagrams.key/Metadata/Properties.plist
  37. BIN
      deps/uv/docs/src/static/diagrams.key/preview-micro.jpg
  38. BIN
      deps/uv/docs/src/static/diagrams.key/preview-web.jpg
  39. BIN
      deps/uv/docs/src/static/diagrams.key/preview.jpg
  40. BIN
      deps/uv/docs/src/static/favicon.ico
  41. BIN
      deps/uv/docs/src/static/logo.png
  42. BIN
      deps/uv/docs/src/static/loop_iteration.png
  43. 189
      deps/uv/docs/src/stream.rst
  44. 97
      deps/uv/docs/src/tcp.rst
  45. 156
      deps/uv/docs/src/threading.rst
  46. 59
      deps/uv/docs/src/threadpool.rst
  47. 68
      deps/uv/docs/src/timer.rst
  48. 63
      deps/uv/docs/src/tty.rst
  49. 280
      deps/uv/docs/src/udp.rst
  50. 6
      deps/uv/include/uv-errno.h
  51. 47
      deps/uv/include/uv-unix.h
  52. 13
      deps/uv/include/uv-version.h
  53. 34
      deps/uv/include/uv-win.h
  54. 1281
      deps/uv/include/uv.h
  55. 3
      deps/uv/m4/.gitignore
  56. 21
      deps/uv/m4/as_case.m4
  57. 66
      deps/uv/m4/dtrace.m4
  58. 319
      deps/uv/m4/libuv-check-flags.m4
  59. 15
      deps/uv/src/fs-poll.c
  60. 57
      deps/uv/src/unix/core.c
  61. 24
      deps/uv/src/unix/darwin-proctitle.c
  62. 41
      deps/uv/src/unix/fs.c
  63. 2
      deps/uv/src/unix/fsevents.c
  64. 67
      deps/uv/src/unix/getaddrinfo.c
  65. 2
      deps/uv/src/unix/internal.h
  66. 21
      deps/uv/src/unix/linux-core.c
  67. 5
      deps/uv/src/unix/loop.c
  68. 1
      deps/uv/src/unix/netbsd.c
  69. 85
      deps/uv/src/unix/process.c
  70. 153
      deps/uv/src/unix/stream.c
  71. 3
      deps/uv/src/unix/timer.c
  72. 2
      deps/uv/src/unix/udp.c
  73. 142
      deps/uv/src/uv-common.c
  74. 4
      deps/uv/src/uv-common.h
  75. 2
      deps/uv/src/version.c
  76. 138
      deps/uv/src/win/core.c
  77. 202
      deps/uv/src/win/fs.c
  78. 19
      deps/uv/src/win/getaddrinfo.c
  79. 16
      deps/uv/src/win/getnameinfo.c
  80. 6
      deps/uv/src/win/internal.h
  81. 6
      deps/uv/src/win/loop-watcher.c
  82. 105
      deps/uv/src/win/pipe.c
  83. 16
      deps/uv/src/win/process.c
  84. 6
      deps/uv/src/win/stream.c
  85. 2
      deps/uv/src/win/tcp.c
  86. 98
      deps/uv/src/win/timer.c
  87. 1
      deps/uv/src/win/tty.c
  88. 15
      deps/uv/src/win/udp.c
  89. 37
      deps/uv/src/win/util.c
  90. 4
      deps/uv/src/win/winapi.c
  91. 3
      deps/uv/src/win/winapi.h
  92. 22
      deps/uv/test/echo-server.c
  93. 59
      deps/uv/test/test-default-loop-close.c
  94. 28
      deps/uv/test/test-fs.c
  95. 120
      deps/uv/test/test-handle-fileno.c
  96. 29
      deps/uv/test/test-list.h
  97. 48
      deps/uv/test/test-osx-select.c
  98. 103
      deps/uv/test/test-pipe-close-stdout-read-stdin.c
  99. 58
      deps/uv/test/test-pipe-getsockname.c
  100. 77
      deps/uv/test/test-socket-buffer-size.c

6
deps/uv/.gitignore

@ -61,3 +61,9 @@ UpgradeLog*.XML
Debug Debug
Release Release
ipch ipch
# sphinx generated files
/docs/build/
*.xcodeproj
*.xcworkspace

2
deps/uv/.mailmap

@ -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

@ -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

@ -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

@ -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

@ -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
&mdash; 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/)
&mdash; An overview of libuv with tutorials. &mdash; 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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

BIN
deps/uv/docs/src/static/diagrams.key/Data/st0-311.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
deps/uv/docs/src/static/diagrams.key/Data/st1-475.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
deps/uv/docs/src/static/diagrams.key/Index.zip

Binary file not shown.

8
deps/uv/docs/src/static/diagrams.key/Metadata/BuildVersionHistory.plist

@ -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

@ -0,0 +1 @@
F69E9CD9-EEF1-4223-9DA4-A1EA7FE112BA

BIN
deps/uv/docs/src/static/diagrams.key/Metadata/Properties.plist

Binary file not shown.

BIN
deps/uv/docs/src/static/diagrams.key/preview-micro.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
deps/uv/docs/src/static/diagrams.key/preview-web.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

BIN
deps/uv/docs/src/static/diagrams.key/preview.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

BIN
deps/uv/docs/src/static/favicon.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
deps/uv/docs/src/static/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
deps/uv/docs/src/static/loop_iteration.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

189
deps/uv/docs/src/stream.rst

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

File diff suppressed because it is too large

3
deps/uv/m4/.gitignore

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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;
for (i = 0; i < n; i++) req->nbufs = 0;
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; return n;
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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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>

85
deps/uv/src/unix/process.c

@ -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)
continue;
if (pid == -1) {
if (errno != ECHILD)
abort();
continue;
}
process->status = status; if (pid == -1) {
QUEUE_REMOVE(&process->queue); if (errno != ECHILD)
QUEUE_INSERT_TAIL(&pending, &process->queue); abort();
continue;
} }
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); QUEUE_FOREACH(q, &pending) {
uv__handle_stop(process); process = QUEUE_DATA(q, uv_process_t, queue);
QUEUE_REMOVE(q);
uv__handle_stop(process);
if (process->exit_cb == NULL) if (process->exit_cb == NULL)
continue; continue;
exit_status = 0; exit_status = 0;
if (WIFEXITED(process->status)) if (WIFEXITED(process->status))
exit_status = WEXITSTATUS(process->status); exit_status = WEXITSTATUS(process->status);
term_signal = 0; term_signal = 0;
if (WIFSIGNALED(process->status)) if (WIFSIGNALED(process->status))
term_signal = WTERMSIG(process->status); term_signal = WTERMSIG(process->status);
process->exit_cb(process, exit_status, term_signal); 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

@ -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))
goto fatal2;
/* Create fds for io watcher and to interrupt the select() loop. */ err = uv_sem_init(&s->async_sem, 0);
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) if (err != 0)
goto fatal3; goto failed_async_sem_init;
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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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;
}

202
deps/uv/src/win/fs.c

@ -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. */ tries = TMP_MAX;
template_part[0] = letters[v % 62]; do {
v /= 62; if (!CryptGenRandom(h_crypt_prov, sizeof(v), (BYTE*) &v)) {
template_part[1] = letters[v % 62]; SET_REQ_WIN32_ERROR(req, GetLastError());
v /= 62; break;
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); cp = ep - num_x;
for (i = 0; i < num_x; i++) {
*cp++ = tempchars[v % num_chars];
v /= num_chars;
}
if (fd >= 0) { if (_wmkdir(req->pathw) == 0) {
len = strlen(req->path); len = strlen(req->path);
wcstombs((char*) req->path + len - 6, template_part, 6); wcstombs((char*) req->path + len - num_x, ep - num_x, num_x);
SET_REQ_RESULT(req, 0); SET_REQ_RESULT(req, 0);
return; break;
} else if (errno != EEXIST) { } else if (errno != EEXIST) {
SET_REQ_RESULT(req, -1); SET_REQ_RESULT(req, -1);
return; break;
} }
} } while (--tries);
/* We got out of the loop because we ran out of combinations to try. */ released = CryptReleaseContext(h_crypt_prov, 0);
SET_REQ_RESULT(req, -1); 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 {
name = ent.cFileName; uv__dirent_t* dent;
int utf8_len;
if (name[0] != L'.' || (name[1] && (name[1] != L'.' || name[2]))) {
len = wcslen(name);
if (!buf) { name = ent.cFileName;
buf = (WCHAR*)malloc(buf_char_len * sizeof(WCHAR));
if (!buf) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
ptr = buf; if (!(name[0] != L'.' || (name[1] && (name[1] != L'.' || name[2]))))
} continue;
while ((ptr - buf) + len + 1 > buf_char_len) { /* Grow dents buffer, if needed */
buf_char_len *= 2; if (result >= dent_size) {
path2 = buf; uv__dirent_t** tmp;
buf = (WCHAR*)realloc(buf, buf_char_len * sizeof(WCHAR));
if (!buf) {
uv_fatal_error(ERROR_OUTOFMEMORY, "realloc");
}
ptr = buf + (ptr - path2); 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;
wcscpy(ptr, name);
ptr += len + 1;
result++;
} }
} while(FindNextFileW(dir, &ent));
FindClose(dir); /* Allocate enough space to fit utf8 encoding of file name */
len = wcslen(name);
if (buf) { utf8_len = uv_utf16_to_utf8(name, len, NULL, 0);
/* Convert result to UTF8. */ if (!utf8_len) {
size = uv_utf16_to_utf8(buf, buf_char_len, NULL, 0);
if (!size) {
SET_REQ_WIN32_ERROR(req, GetLastError()); SET_REQ_WIN32_ERROR(req, GetLastError());
return; goto fatal;
} }
req->ptr = (char*)malloc(size + 1); dent = malloc(sizeof(*dent) + utf8_len + 1);
if (!req->ptr) { if (dent == NULL) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
goto fatal;
} }
size = uv_utf16_to_utf8(buf, buf_char_len, (char*)req->ptr, size); /* Copy file name */
if (!size) { utf8_len = uv_utf16_to_utf8(name, len, dent->d_name, utf8_len);
free(buf); if (!utf8_len) {
free(req->ptr); free(dent);
req->ptr = NULL;
SET_REQ_WIN32_ERROR(req, GetLastError()); SET_REQ_WIN32_ERROR(req, GetLastError());
return; goto fatal;
} }
free(buf); dent->d_name[utf8_len] = '\0';
((char*)req->ptr)[size] = '\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));
FindClose(dir);
if (dents != NULL)
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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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;
} }

98
deps/uv/src/win/timer.c

@ -28,39 +28,17 @@
#include "handle-inl.h" #include "handle-inl.h"
void uv_update_time(uv_loop_t* loop) { /* The number of milliseconds in one second. */
DWORD ticks; #define UV__MILLISEC 1000
ULARGE_INTEGER time;
ticks = GetTickCount();
time.QuadPart = loop->time;
/* GetTickCount() can conceivably wrap around, so when the current tick void uv_update_time(uv_loop_t* loop) {
* count is lower than the last tick count, we'll assume it has wrapped. uint64_t new_time = uv__hrtime(UV__MILLISEC);
* uv_poll must make sure that the timer can never overflow more than if (new_time > loop->time) {
* once between two subsequent uv_update_time calls. loop->time = new_time;
*/ }
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

@ -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

@ -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

@ -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) {
LARGE_INTEGER counter;
uv__once_init(); uv__once_init();
return uv__hrtime(UV__NANOSEC);
}
uint64_t uv__hrtime(double scale) {
LARGE_INTEGER counter;
/* If the performance frequency is zero, there's no support. */ /* If the performance interval is zero, there's no support. */
if (hrtime_frequency_ == 0) { if (hrtime_interval_ == 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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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;
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save