Browse Source

Upgrade libuv to ea4271f

Required adding uv_default_loop() in many places.
Ryan Dahl 14 years ago
parent
commit
21cc4c4985
  1. 2
      deps/uv/Makefile
  2. 50
      deps/uv/config-unix.mk
  3. 4
      deps/uv/include/uv-private/eio.h
  4. 0
      deps/uv/include/uv-private/ev.h
  5. 0
      deps/uv/include/uv-private/ngx-queue.h
  6. 0
      deps/uv/include/uv-private/tree.h
  7. 10
      deps/uv/include/uv-private/uv-unix.h
  8. 40
      deps/uv/include/uv-private/uv-win.h
  9. 160
      deps/uv/include/uv.h
  10. 0
      deps/uv/src/unix/cygwin.c
  11. 0
      deps/uv/src/unix/darwin.c
  12. 0
      deps/uv/src/unix/eio/Changes
  13. 0
      deps/uv/src/unix/eio/LICENSE
  14. 0
      deps/uv/src/unix/eio/Makefile.am
  15. 0
      deps/uv/src/unix/eio/aclocal.m4
  16. 0
      deps/uv/src/unix/eio/autogen.sh
  17. 0
      deps/uv/src/unix/eio/config.h.in
  18. 0
      deps/uv/src/unix/eio/config_cygwin.h
  19. 0
      deps/uv/src/unix/eio/config_darwin.h
  20. 0
      deps/uv/src/unix/eio/config_freebsd.h
  21. 0
      deps/uv/src/unix/eio/config_linux.h
  22. 0
      deps/uv/src/unix/eio/config_sunos.h
  23. 0
      deps/uv/src/unix/eio/configure.ac
  24. 0
      deps/uv/src/unix/eio/demo.c
  25. 0
      deps/uv/src/unix/eio/ecb.h
  26. 0
      deps/uv/src/unix/eio/eio.3
  27. 0
      deps/uv/src/unix/eio/eio.c
  28. 0
      deps/uv/src/unix/eio/eio.pod
  29. 0
      deps/uv/src/unix/eio/libeio.m4
  30. 0
      deps/uv/src/unix/eio/xthread.h
  31. 0
      deps/uv/src/unix/ev/Changes
  32. 0
      deps/uv/src/unix/ev/LICENSE
  33. 0
      deps/uv/src/unix/ev/Makefile.am
  34. 0
      deps/uv/src/unix/ev/Makefile.in
  35. 0
      deps/uv/src/unix/ev/README
  36. 0
      deps/uv/src/unix/ev/aclocal.m4
  37. 0
      deps/uv/src/unix/ev/autogen.sh
  38. 0
      deps/uv/src/unix/ev/config.guess
  39. 0
      deps/uv/src/unix/ev/config.h.in
  40. 0
      deps/uv/src/unix/ev/config.sub
  41. 0
      deps/uv/src/unix/ev/config_cygwin.h
  42. 0
      deps/uv/src/unix/ev/config_darwin.h
  43. 0
      deps/uv/src/unix/ev/config_freebsd.h
  44. 0
      deps/uv/src/unix/ev/config_linux.h
  45. 0
      deps/uv/src/unix/ev/config_sunos.h
  46. 0
      deps/uv/src/unix/ev/configure
  47. 0
      deps/uv/src/unix/ev/configure.ac
  48. 0
      deps/uv/src/unix/ev/depcomp
  49. 0
      deps/uv/src/unix/ev/ev++.h
  50. 0
      deps/uv/src/unix/ev/ev.3
  51. 0
      deps/uv/src/unix/ev/ev.c
  52. 0
      deps/uv/src/unix/ev/ev.pod
  53. 0
      deps/uv/src/unix/ev/ev_epoll.c
  54. 0
      deps/uv/src/unix/ev/ev_kqueue.c
  55. 0
      deps/uv/src/unix/ev/ev_poll.c
  56. 0
      deps/uv/src/unix/ev/ev_port.c
  57. 0
      deps/uv/src/unix/ev/ev_select.c
  58. 0
      deps/uv/src/unix/ev/ev_vars.h
  59. 0
      deps/uv/src/unix/ev/ev_win32.c
  60. 0
      deps/uv/src/unix/ev/ev_wrap.h
  61. 0
      deps/uv/src/unix/ev/event.c
  62. 0
      deps/uv/src/unix/ev/event.h
  63. 0
      deps/uv/src/unix/ev/install-sh
  64. 0
      deps/uv/src/unix/ev/libev.m4
  65. 0
      deps/uv/src/unix/ev/ltmain.sh
  66. 0
      deps/uv/src/unix/ev/missing
  67. 0
      deps/uv/src/unix/ev/mkinstalldirs
  68. 0
      deps/uv/src/unix/freebsd.c
  69. 210
      deps/uv/src/unix/fs.c
  70. 2
      deps/uv/src/unix/internal.h
  71. 0
      deps/uv/src/unix/linux.c
  72. 0
      deps/uv/src/unix/sunos.c
  73. 75
      deps/uv/src/unix/uv-eio.c
  74. 2
      deps/uv/src/unix/uv-eio.h
  75. 30
      deps/uv/src/uv-common.c
  76. 14
      deps/uv/src/uv-common.h
  77. 468
      deps/uv/src/uv-unix.c
  78. 24
      deps/uv/src/win/async.c
  79. 128
      deps/uv/src/win/cares.c
  80. 108
      deps/uv/src/win/core.c
  81. 30
      deps/uv/src/win/error.c
  82. 240
      deps/uv/src/win/fs.c
  83. 97
      deps/uv/src/win/getaddrinfo.c
  84. 56
      deps/uv/src/win/handle.c
  85. 166
      deps/uv/src/win/internal.h
  86. 38
      deps/uv/src/win/loop-watcher.c
  87. 248
      deps/uv/src/win/pipe.c
  88. 111
      deps/uv/src/win/process.c
  89. 75
      deps/uv/src/win/req.c
  90. 10
      deps/uv/src/win/stdio.c
  91. 32
      deps/uv/src/win/stream.c
  92. 194
      deps/uv/src/win/tcp.c
  93. 22
      deps/uv/src/win/threadpool.c
  94. 80
      deps/uv/src/win/timer.c
  95. 117
      deps/uv/src/win/udp.c
  96. 26
      deps/uv/src/win/util.c
  97. 16
      deps/uv/test/benchmark-ares.c
  98. 17
      deps/uv/test/benchmark-getaddrinfo.c
  99. 14
      deps/uv/test/benchmark-ping-pongs.c
  100. 25
      deps/uv/test/benchmark-pound.c

2
deps/uv/Makefile

@ -24,7 +24,7 @@ ifdef MSVC
uname_S := MINGW uname_S := MINGW
endif endif
CPPFLAGS += -Iinclude CPPFLAGS += -Iinclude -Iinclude/uv-private
CARES_OBJS = CARES_OBJS =
CARES_OBJS += src/ares/ares__close_sockets.o CARES_OBJS += src/ares/ares__close_sockets.o

50
deps/uv/config-unix.mk

@ -23,7 +23,7 @@ AR = $(PREFIX)ar
E= E=
CSTDFLAG=--std=c89 -pedantic -Wall -Wextra -Wno-unused-parameter CSTDFLAG=--std=c89 -pedantic -Wall -Wextra -Wno-unused-parameter
CFLAGS=-g CFLAGS=-g
CPPFLAGS += -Isrc/ev CPPFLAGS += -Isrc/unix/ev
LINKFLAGS=-lm LINKFLAGS=-lm
CPPFLAGS += -D_LARGEFILE_SOURCE CPPFLAGS += -D_LARGEFILE_SOURCE
@ -34,7 +34,7 @@ EV_CONFIG=config_sunos.h
EIO_CONFIG=config_sunos.h EIO_CONFIG=config_sunos.h
CPPFLAGS += -Isrc/ares/config_sunos -D__EXTENSIONS__ -D_XOPEN_SOURCE=500 CPPFLAGS += -Isrc/ares/config_sunos -D__EXTENSIONS__ -D_XOPEN_SOURCE=500
LINKFLAGS+=-lsocket -lnsl LINKFLAGS+=-lsocket -lnsl
UV_OS_FILE=uv-sunos.c UV_OS_FILE=sunos.c
endif endif
ifeq (Darwin,$(uname_S)) ifeq (Darwin,$(uname_S))
@ -42,7 +42,7 @@ EV_CONFIG=config_darwin.h
EIO_CONFIG=config_darwin.h EIO_CONFIG=config_darwin.h
CPPFLAGS += -Isrc/ares/config_darwin CPPFLAGS += -Isrc/ares/config_darwin
LINKFLAGS+=-framework CoreServices LINKFLAGS+=-framework CoreServices
UV_OS_FILE=uv-darwin.c UV_OS_FILE=darwin.c
endif endif
ifeq (Linux,$(uname_S)) ifeq (Linux,$(uname_S))
@ -51,7 +51,7 @@ EIO_CONFIG=config_linux.h
CSTDFLAG += -D_XOPEN_SOURCE=600 CSTDFLAG += -D_XOPEN_SOURCE=600
CPPFLAGS += -Isrc/ares/config_linux CPPFLAGS += -Isrc/ares/config_linux
LINKFLAGS+=-lrt LINKFLAGS+=-lrt
UV_OS_FILE=uv-linux.c UV_OS_FILE=linux.c
endif endif
ifeq (FreeBSD,$(uname_S)) ifeq (FreeBSD,$(uname_S))
@ -59,7 +59,7 @@ EV_CONFIG=config_freebsd.h
EIO_CONFIG=config_freebsd.h EIO_CONFIG=config_freebsd.h
CPPFLAGS += -Isrc/ares/config_freebsd CPPFLAGS += -Isrc/ares/config_freebsd
LINKFLAGS+= LINKFLAGS+=
UV_OS_FILE=uv-freebsd.c UV_OS_FILE=freebsd.c
endif endif
ifneq (,$(findstring CYGWIN,$(uname_S))) ifneq (,$(findstring CYGWIN,$(uname_S)))
@ -69,7 +69,7 @@ EIO_CONFIG=config_cygwin.h
CSTDFLAG = -D_GNU_SOURCE CSTDFLAG = -D_GNU_SOURCE
CPPFLAGS += -Isrc/ares/config_cygwin CPPFLAGS += -Isrc/ares/config_cygwin
LINKFLAGS+= LINKFLAGS+=
UV_OS_FILE=uv-cygwin.c UV_OS_FILE=cygwin.c
endif endif
# Need _GNU_SOURCE for strdup? # Need _GNU_SOURCE for strdup?
@ -85,24 +85,24 @@ endif
RUNNER_LIBS= RUNNER_LIBS=
RUNNER_SRC=test/runner-unix.c RUNNER_SRC=test/runner-unix.c
uv.a: src/uv-unix.o src/unix/fs.o src/uv-common.o src/uv-platform.o src/ev/ev.o src/uv-eio.o src/eio/eio.o $(CARES_OBJS) uv.a: src/uv-unix.o src/unix/fs.o src/uv-common.o src/uv-platform.o src/unix/ev/ev.o src/unix/uv-eio.o src/unix/eio/eio.o $(CARES_OBJS)
$(AR) rcs uv.a src/uv-unix.o src/unix/fs.o src/uv-platform.o src/uv-common.o src/uv-eio.o src/ev/ev.o \ $(AR) rcs uv.a src/uv-unix.o src/unix/fs.o src/uv-platform.o src/uv-common.o src/unix/uv-eio.o src/unix/ev/ev.o \
src/eio/eio.o $(CARES_OBJS) src/unix/eio/eio.o $(CARES_OBJS)
src/uv-platform.o: src/$(UV_OS_FILE) include/uv.h include/uv-unix.h src/uv-platform.o: src/unix/$(UV_OS_FILE) include/uv.h include/uv-private/uv-unix.h
$(CC) $(CSTDFLAG) $(CPPFLAGS) $(CFLAGS) -c src/$(UV_OS_FILE) -o src/uv-platform.o $(CC) $(CSTDFLAG) $(CPPFLAGS) $(CFLAGS) -c src/unix/$(UV_OS_FILE) -o src/uv-platform.o
src/uv-unix.o: src/uv-unix.c include/uv.h include/uv-unix.h src/unix/internal.h src/uv-unix.o: src/uv-unix.c include/uv.h include/uv-private/uv-unix.h src/unix/internal.h
$(CC) $(CSTDFLAG) $(CPPFLAGS) -Isrc $(CFLAGS) -c src/uv-unix.c -o src/uv-unix.o $(CC) $(CSTDFLAG) $(CPPFLAGS) -Isrc $(CFLAGS) -c src/uv-unix.c -o src/uv-unix.o
src/unix/fs.o: src/unix/fs.c include/uv.h include/uv-unix.h src/unix/internal.h src/unix/fs.o: src/unix/fs.c include/uv.h include/uv-private/uv-unix.h src/unix/internal.h
$(CC) $(CSTDFLAG) $(CPPFLAGS) -Isrc/ $(CFLAGS) -c src/unix/fs.c -o src/unix/fs.o $(CC) $(CSTDFLAG) $(CPPFLAGS) -Isrc/ $(CFLAGS) -c src/unix/fs.c -o src/unix/fs.o
src/uv-common.o: src/uv-common.c include/uv.h include/uv-unix.h src/uv-common.o: src/uv-common.c include/uv.h include/uv-private/uv-unix.h
$(CC) $(CSTDFLAG) $(CPPFLAGS) $(CFLAGS) -c src/uv-common.c -o src/uv-common.o $(CC) $(CSTDFLAG) $(CPPFLAGS) $(CFLAGS) -c src/uv-common.c -o src/uv-common.o
src/ev/ev.o: src/ev/ev.c src/unix/ev/ev.o: src/unix/ev/ev.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c src/ev/ev.c -o src/ev/ev.o -DEV_CONFIG_H=\"$(EV_CONFIG)\" $(CC) $(CPPFLAGS) $(CFLAGS) -c src/unix/ev/ev.c -o src/unix/ev/ev.o -DEV_CONFIG_H=\"$(EV_CONFIG)\"
EIO_CPPFLAGS += $(CPPFLAGS) EIO_CPPFLAGS += $(CPPFLAGS)
@ -110,21 +110,23 @@ EIO_CPPFLAGS += -DEIO_CONFIG_H=\"$(EIO_CONFIG)\"
EIO_CPPFLAGS += -DEIO_STACKSIZE=262144 EIO_CPPFLAGS += -DEIO_STACKSIZE=262144
EIO_CPPFLAGS += -D_GNU_SOURCE EIO_CPPFLAGS += -D_GNU_SOURCE
src/eio/eio.o: src/eio/eio.c src/unix/eio/eio.o: src/unix/eio/eio.c
$(CC) $(EIO_CPPFLAGS) $(CFLAGS) -c src/eio/eio.c -o src/eio/eio.o $(CC) $(EIO_CPPFLAGS) $(CFLAGS) -c src/unix/eio/eio.c -o src/unix/eio/eio.o
src/uv-eio.o: src/uv-eio.c src/unix/uv-eio.o: src/unix/uv-eio.c
$(CC) $(CPPFLAGS) -Isrc/eio/ $(CSTDFLAG) $(CFLAGS) -c src/uv-eio.c -o src/uv-eio.o $(CC) $(CPPFLAGS) -Isrc/unix/eio/ $(CSTDFLAG) $(CFLAGS) -c src/unix/uv-eio.c -o src/unix/uv-eio.o
clean-platform: clean-platform:
-rm -f src/ares/*.o -rm -f src/ares/*.o
-rm -f src/ev/*.o -rm -f src/unix/ev/*.o
-rm -f src/eio/*.o -rm -f src/unix/eio/*.o
-rm -f src/unix/*.o
-rm -rf test/run-tests.dSYM run-benchmarks.dSYM -rm -rf test/run-tests.dSYM run-benchmarks.dSYM
distclean-platform: distclean-platform:
-rm -f src/ares/*.o -rm -f src/ares/*.o
-rm -f src/ev/*.o -rm -f src/unix/ev/*.o
-rm -f src/eio/*.o -rm -f src/unix/*.o
-rm -f src/unix/eio/*.o
-rm -rf test/run-tests.dSYM run-benchmarks.dSYM -rm -rf test/run-tests.dSYM run-benchmarks.dSYM

4
deps/uv/include/eio.h → deps/uv/include/uv-private/eio.h

@ -195,7 +195,7 @@ enum
enum enum
{ {
EIO_MCL_CURRENT = 1, EIO_MCL_CURRENT = 1,
EIO_MCL_FUTURE = 2, EIO_MCL_FUTURE = 2
}; };
/* request priorities */ /* request priorities */
@ -203,7 +203,7 @@ enum
enum { enum {
EIO_PRI_MIN = -4, EIO_PRI_MIN = -4,
EIO_PRI_MAX = 4, EIO_PRI_MAX = 4,
EIO_PRI_DEFAULT = 0, EIO_PRI_DEFAULT = 0
}; };
/* eio request structure */ /* eio request structure */

0
deps/uv/include/ev.h → deps/uv/include/uv-private/ev.h

0
deps/uv/include/ngx-queue.h → deps/uv/include/uv-private/ngx-queue.h

0
deps/uv/include/tree.h → deps/uv/include/uv-private/tree.h

10
deps/uv/include/uv-unix.h → deps/uv/include/uv-private/uv-unix.h

@ -42,6 +42,16 @@ typedef struct {
typedef int uv_file; typedef int uv_file;
#define UV_LOOP_PRIVATE_FIELDS \
ares_channel channel; \
/* \
* While the channel is active this timer is called once per second to be \
* sure that we're always calling ares_process. See the warning above the \
* definition of ares_timeout(). \
*/ \
ev_timer timer; \
struct ev_loop* ev;
#define UV_REQ_BUFSML_SIZE (4) #define UV_REQ_BUFSML_SIZE (4)
#define UV_REQ_PRIVATE_FIELDS /* empty */ #define UV_REQ_PRIVATE_FIELDS /* empty */

40
deps/uv/include/uv-win.h → deps/uv/include/uv-private/uv-win.h

@ -44,6 +44,40 @@ typedef struct uv_buf_t {
typedef int uv_file; typedef int uv_file;
RB_HEAD(uv_timer_tree_s, uv_timer_s);
#define UV_LOOP_PRIVATE_FIELDS \
/* The loop's I/O completion port */ \
HANDLE iocp; \
/* Reference count that keeps the event loop alive */ \
int refs; \
/* The current time according to the event loop. in msecs. */ \
int64_t time; \
/* Tail of a single-linked circular queue of pending reqs. If the queue */ \
/* is empty, tail_ is NULL. If there is only one item, */ \
/* tail_->next_req == tail_ */ \
uv_req_t* pending_reqs_tail; \
/* Head of a single-linked list of closed handles */ \
uv_handle_t* endgame_handles; \
/* The head of the timers tree */ \
struct uv_timer_tree_s timers; \
/* Lists of active loop (prepare / check / idle) watchers */ \
uv_prepare_t* prepare_handles; \
uv_check_t* check_handles; \
uv_idle_t* idle_handles; \
/* This pointer will refer to the prepare/check/idle handle whose */ \
/* callback is scheduled to be called next. This is needed to allow */ \
/* safe removal from one of the lists above while that list being */ \
/* iterated over. */ \
uv_prepare_t* next_prepare_handle; \
uv_check_t* next_check_handle; \
uv_idle_t* next_idle_handle; \
ares_channel ares_channel; \
int ares_active_sockets; \
uv_timer_t ares_polling_timer; \
/* Last error code */ \
uv_err_t last_error;
#define UV_REQ_TYPE_PRIVATE \ #define UV_REQ_TYPE_PRIVATE \
/* TODO: remove the req suffix */ \ /* TODO: remove the req suffix */ \
UV_ARES_EVENT_REQ, \ UV_ARES_EVENT_REQ, \
@ -227,5 +261,7 @@ typedef int uv_file;
#define UV_WORK_PRIVATE_FIELDS \ #define UV_WORK_PRIVATE_FIELDS \
int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size, char* utf8Buffer, size_t utf8Size); int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size,
int uv_utf8_to_utf16(const char* utf8Buffer, wchar_t* utf16Buffer, size_t utf16Size); char* utf8Buffer, size_t utf8Size);
int uv_utf8_to_utf16(const char* utf8Buffer, wchar_t* utf16Buffer,
size_t utf16Size);

160
deps/uv/include/uv.h

@ -19,7 +19,7 @@
* IN THE SOFTWARE. * IN THE SOFTWARE.
*/ */
/* See uv_init for an introduction. */ /* See uv_loop_new for an introduction. */
#ifndef UV_H #ifndef UV_H
#define UV_H #define UV_H
@ -41,6 +41,8 @@ extern "C" {
typedef intptr_t ssize_t; typedef intptr_t ssize_t;
#endif #endif
typedef struct uv_loop_s uv_loop_t;
typedef struct uv_ares_task_s uv_ares_task_t;
typedef struct uv_err_s uv_err_t; typedef struct uv_err_s uv_err_t;
typedef struct uv_handle_s uv_handle_t; typedef struct uv_handle_s uv_handle_t;
typedef struct uv_stream_s uv_stream_t; typedef struct uv_stream_s uv_stream_t;
@ -54,6 +56,7 @@ typedef struct uv_idle_s uv_idle_t;
typedef struct uv_async_s uv_async_t; typedef struct uv_async_s uv_async_t;
typedef struct uv_getaddrinfo_s uv_getaddrinfo_t; typedef struct uv_getaddrinfo_s uv_getaddrinfo_t;
typedef struct uv_process_s uv_process_t; typedef struct uv_process_s uv_process_t;
typedef struct uv_counters_s uv_counters_t;
/* Request types */ /* Request types */
typedef struct uv_req_s uv_req_t; typedef struct uv_req_s uv_req_t;
typedef struct uv_shutdown_s uv_shutdown_t; typedef struct uv_shutdown_s uv_shutdown_t;
@ -64,41 +67,45 @@ typedef struct uv_fs_s uv_fs_t;
typedef struct uv_work_s uv_work_t; typedef struct uv_work_s uv_work_t;
#if defined(__unix__) || defined(__POSIX__) || defined(__APPLE__) #if defined(__unix__) || defined(__POSIX__) || defined(__APPLE__)
# include "uv-unix.h" # include "uv-private/uv-unix.h"
#else #else
# include "uv-win.h" # include "uv-private/uv-win.h"
#endif #endif
/* /*
* This function must be called before any other functions in libuv. * This function must be called before any other functions in libuv.
* *
* At the moment libuv is single threaded but this will likely change in the
* near future. Basically it will change by uv_init() taking a 'loop'
* argument and all other _init having a first argument as the the 'loop'.
*
* All functions besides uv_run() are non-blocking. * All functions besides uv_run() are non-blocking.
* *
* All callbacks in libuv are made asynchronously. That is they are never * All callbacks in libuv are made asynchronously. That is they are never
* made by the function that takes them as a parameter. * made by the function that takes them as a parameter.
*/ */
void uv_init(); void uv_init();
uv_loop_t* uv_loop_new();
void uv_loop_delete(uv_loop_t*);
/*
* Returns the default loop.
*/
uv_loop_t* uv_default_loop();
/* /*
* This function starts the event loop. It blocks until the reference count * This function starts the event loop. It blocks until the reference count
* of the loop drops to zero. * of the loop drops to zero.
*/ */
int uv_run(); int uv_run(uv_loop_t*);
/* /*
* Manually modify the event loop's reference count. Useful if the user wants * Manually modify the event loop's reference count. Useful if the user wants
* to have a handle or timeout that doesn't keep the loop alive. * to have a handle or timeout that doesn't keep the loop alive.
*/ */
void uv_ref(); void uv_ref(uv_loop_t*);
void uv_unref(); void uv_unref(uv_loop_t*);
void uv_update_time(); void uv_update_time(uv_loop_t*);
int64_t uv_now(); int64_t uv_now(uv_loop_t*);
/* /*
@ -123,7 +130,8 @@ typedef void (*uv_async_cb)(uv_async_t* handle, int status);
typedef void (*uv_prepare_cb)(uv_prepare_t* handle, int status); typedef void (*uv_prepare_cb)(uv_prepare_t* handle, int status);
typedef void (*uv_check_cb)(uv_check_t* handle, int status); typedef void (*uv_check_cb)(uv_check_t* handle, int status);
typedef void (*uv_idle_cb)(uv_idle_t* handle, int status); typedef void (*uv_idle_cb)(uv_idle_t* handle, int status);
typedef void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* handle, int status, struct addrinfo* res); typedef void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* handle, int status,
struct addrinfo* res);
typedef void (*uv_exit_cb)(uv_process_t*, int exit_status, int term_signal); typedef void (*uv_exit_cb)(uv_process_t*, int exit_status, int term_signal);
typedef void (*uv_fs_cb)(uv_fs_t* req); typedef void (*uv_fs_cb)(uv_fs_t* req);
typedef void (*uv_work_cb)(uv_work_t* req); typedef void (*uv_work_cb)(uv_work_t* req);
@ -223,7 +231,7 @@ struct uv_err_s {
* On error the user should then call uv_last_error() to determine * On error the user should then call uv_last_error() to determine
* the error code. * the error code.
*/ */
uv_err_t uv_last_error(); uv_err_t uv_last_error(uv_loop_t*);
char* uv_strerror(uv_err_t err); char* uv_strerror(uv_err_t err);
const char* uv_err_name(uv_err_t err); const char* uv_err_name(uv_err_t err);
@ -266,6 +274,7 @@ struct uv_shutdown_s {
#define UV_HANDLE_FIELDS \ #define UV_HANDLE_FIELDS \
/* read-only */ \ /* read-only */ \
uv_loop_t* loop; \
uv_handle_type type; \ uv_handle_type type; \
/* public */ \ /* public */ \
uv_close_cb close_cb; \ uv_close_cb close_cb; \
@ -358,7 +367,7 @@ typedef enum {
UV_STDERR UV_STDERR
} uv_std_type; } uv_std_type;
uv_stream_t* uv_std_handle(uv_std_type type); uv_stream_t* uv_std_handle(uv_loop_t*, uv_std_type type);
/* /*
* Write data to stream. Buffers are written in order. Example: * Write data to stream. Buffers are written in order. Example:
@ -402,7 +411,7 @@ struct uv_tcp_s {
UV_TCP_PRIVATE_FIELDS UV_TCP_PRIVATE_FIELDS
}; };
int uv_tcp_init(uv_tcp_t* handle); int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle);
int uv_tcp_bind(uv_tcp_t* handle, struct sockaddr_in); int uv_tcp_bind(uv_tcp_t* handle, struct sockaddr_in);
int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6); int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6);
@ -485,7 +494,7 @@ struct uv_udp_send_s {
* Initialize a new UDP handle. The actual socket is created lazily. * Initialize a new UDP handle. The actual socket is created lazily.
* Returns 0 on success. * Returns 0 on success.
*/ */
int uv_udp_init(uv_udp_t* handle); int uv_udp_init(uv_loop_t*, uv_udp_t* handle);
/* /*
* Bind to a IPv4 address and port. * Bind to a IPv4 address and port.
@ -590,7 +599,7 @@ struct uv_pipe_s {
UV_PIPE_PRIVATE_FIELDS UV_PIPE_PRIVATE_FIELDS
}; };
int uv_pipe_init(uv_pipe_t* handle); int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle);
int uv_pipe_bind(uv_pipe_t* handle, const char* name); int uv_pipe_bind(uv_pipe_t* handle, const char* name);
@ -610,7 +619,7 @@ struct uv_prepare_s {
UV_PREPARE_PRIVATE_FIELDS UV_PREPARE_PRIVATE_FIELDS
}; };
int uv_prepare_init(uv_prepare_t* prepare); int uv_prepare_init(uv_loop_t*, uv_prepare_t* prepare);
int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb); int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb);
@ -628,7 +637,7 @@ struct uv_check_s {
UV_CHECK_PRIVATE_FIELDS UV_CHECK_PRIVATE_FIELDS
}; };
int uv_check_init(uv_check_t* check); int uv_check_init(uv_loop_t*, uv_check_t* check);
int uv_check_start(uv_check_t* check, uv_check_cb cb); int uv_check_start(uv_check_t* check, uv_check_cb cb);
@ -648,7 +657,7 @@ struct uv_idle_s {
UV_IDLE_PRIVATE_FIELDS UV_IDLE_PRIVATE_FIELDS
}; };
int uv_idle_init(uv_idle_t* idle); int uv_idle_init(uv_loop_t*, uv_idle_t* idle);
int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb); int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb);
@ -670,7 +679,7 @@ struct uv_async_s {
UV_ASYNC_PRIVATE_FIELDS UV_ASYNC_PRIVATE_FIELDS
}; };
int uv_async_init(uv_async_t* async, uv_async_cb async_cb); int uv_async_init(uv_loop_t*, uv_async_t* async, uv_async_cb async_cb);
/* /*
* This can be called from other threads to wake up a libuv thread. * This can be called from other threads to wake up a libuv thread.
@ -691,7 +700,7 @@ struct uv_timer_s {
UV_TIMER_PRIVATE_FIELDS UV_TIMER_PRIVATE_FIELDS
}; };
int uv_timer_init(uv_timer_t* timer); int uv_timer_init(uv_loop_t*, uv_timer_t* timer);
int uv_timer_start(uv_timer_t* timer, uv_timer_cb cb, int64_t timeout, int uv_timer_start(uv_timer_t* timer, uv_timer_cb cb, int64_t timeout,
int64_t repeat); int64_t repeat);
@ -717,11 +726,13 @@ int64_t uv_timer_get_repeat(uv_timer_t* timer);
/* c-ares integration initialize and terminate */ /* c-ares integration initialize and terminate */
int uv_ares_init_options(ares_channel *channelptr, int uv_ares_init_options(uv_loop_t*,
ares_channel *channelptr,
struct ares_options *options, struct ares_options *options,
int optmask); int optmask);
void uv_ares_destroy(ares_channel channel); /* TODO remove the loop argument from this function? */
void uv_ares_destroy(uv_loop_t*, ares_channel channel);
/* /*
@ -745,7 +756,8 @@ struct uv_getaddrinfo_s {
* Input arguments may be released after return from this call. Callback * Input arguments may be released after return from this call. Callback
* must not call freeaddrinfo. * must not call freeaddrinfo.
*/ */
int uv_getaddrinfo(uv_getaddrinfo_t* handle, int uv_getaddrinfo(uv_loop_t*,
uv_getaddrinfo_t* handle,
uv_getaddrinfo_cb getaddrinfo_cb, uv_getaddrinfo_cb getaddrinfo_cb,
const char* node, const char* node,
const char* service, const char* service,
@ -799,7 +811,7 @@ struct uv_process_s {
}; };
/* Initializes uv_process_t and starts the process. */ /* Initializes uv_process_t and starts the process. */
int uv_spawn(uv_process_t*, uv_process_options_t options); int uv_spawn(uv_loop_t*, uv_process_t*, uv_process_options_t options);
/* /*
* Kills the process with the specified signal. The user must still * Kills the process with the specified signal. The user must still
@ -813,13 +825,14 @@ int uv_process_kill(uv_process_t*, int signum);
*/ */
struct uv_work_s { struct uv_work_s {
UV_REQ_FIELDS UV_REQ_FIELDS
uv_loop_t* loop;
uv_work_cb work_cb; uv_work_cb work_cb;
uv_after_work_cb after_work_cb; uv_after_work_cb after_work_cb;
UV_WORK_PRIVATE_FIELDS UV_WORK_PRIVATE_FIELDS
}; };
/* Queues a work request to execute asynchronously on the thread pool. */ /* Queues a work request to execute asynchronously on the thread pool. */
int uv_queue_work(uv_work_t* req, uv_work_cb work_cb, int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb,
uv_after_work_cb after_work_cb); uv_after_work_cb after_work_cb);
@ -858,6 +871,7 @@ typedef enum {
*/ */
struct uv_fs_s { struct uv_fs_s {
UV_REQ_FIELDS UV_REQ_FIELDS
uv_loop_t* loop;
uv_fs_type fs_type; uv_fs_type fs_type;
uv_fs_cb cb; uv_fs_cb cb;
ssize_t result; ssize_t result;
@ -867,31 +881,48 @@ struct uv_fs_s {
}; };
void uv_fs_req_cleanup(uv_fs_t* req); void uv_fs_req_cleanup(uv_fs_t* req);
int uv_fs_close(uv_fs_t* req, uv_file file, uv_fs_cb cb); int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb);
int uv_fs_open(uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb); int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
int uv_fs_read(uv_fs_t* req, uv_file file, void* buf, size_t length, off_t offset, uv_fs_cb cb); int mode, uv_fs_cb cb);
int uv_fs_unlink(uv_fs_t* req, const char* path, uv_fs_cb cb); int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
int uv_fs_write(uv_fs_t* req, uv_file file, void* buf, size_t length, off_t offset, uv_fs_cb cb); size_t length, off_t offset, uv_fs_cb cb);
int uv_fs_mkdir(uv_fs_t* req, const char* path, int mode, uv_fs_cb cb); int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb);
int uv_fs_rmdir(uv_fs_t* req, const char* path, uv_fs_cb cb); int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
int uv_fs_readdir(uv_fs_t* req, const char* path, int flags, uv_fs_cb cb); size_t length, off_t offset, uv_fs_cb cb);
int uv_fs_stat(uv_fs_t* req, const char* path, uv_fs_cb cb); int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
int uv_fs_fstat(uv_fs_t* req, uv_file file, uv_fs_cb cb); uv_fs_cb cb);
int uv_fs_rename(uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb); int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb);
int uv_fs_fsync(uv_fs_t* req, uv_file file, uv_fs_cb cb); int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
int uv_fs_fdatasync(uv_fs_t* req, uv_file file, uv_fs_cb cb); uv_fs_cb cb);
int uv_fs_ftruncate(uv_fs_t* req, uv_file file, off_t offset, uv_fs_cb cb); int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb);
int uv_fs_sendfile(uv_fs_t* req, uv_file out_fd, uv_file in_fd, off_t in_offset, size_t length, uv_fs_cb cb); int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb);
int uv_fs_chmod(uv_fs_t* req, const char* path, int mode, uv_fs_cb cb); int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path,
int uv_fs_utime(uv_fs_t* req, const char* path, double atime, double mtime, uv_fs_cb cb); const char* new_path, uv_fs_cb cb);
int uv_fs_futime(uv_fs_t* req, uv_file file, double atime, double mtime, uv_fs_cb cb); int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb);
int uv_fs_lstat(uv_fs_t* req, const char* path, uv_fs_cb cb); int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb);
int uv_fs_link(uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb); int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file,
int uv_fs_symlink(uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb); off_t offset, uv_fs_cb cb);
int uv_fs_readlink(uv_fs_t* req, const char* path, uv_fs_cb cb); int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd,
int uv_fs_fchmod(uv_fs_t* req, uv_file file, int mode, uv_fs_cb cb); uv_file in_fd, off_t in_offset, size_t length, uv_fs_cb cb);
int uv_fs_chown(uv_fs_t* req, const char* path, int uid, int gid, uv_fs_cb cb); int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
int uv_fs_fchown(uv_fs_t* req, uv_file file, int uid, int gid, uv_fs_cb cb); uv_fs_cb cb);
int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
double mtime, uv_fs_cb cb);
int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime,
double mtime, uv_fs_cb cb);
int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb);
int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb);
int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb);
int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_cb cb);
int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode,
uv_fs_cb cb);
int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, int uid,
int gid, uv_fs_cb cb);
int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, int uid,
int gid, uv_fs_cb cb);
/* Utility */ /* Utility */
@ -941,8 +972,8 @@ union uv_any_req {
}; };
/* Diagnostic counters */ struct uv_counters_s {
typedef struct { uint64_t eio_init;
uint64_t req_init; uint64_t req_init;
uint64_t handle_init; uint64_t handle_init;
uint64_t stream_init; uint64_t stream_init;
@ -955,9 +986,24 @@ typedef struct {
uint64_t async_init; uint64_t async_init;
uint64_t timer_init; uint64_t timer_init;
uint64_t process_init; uint64_t process_init;
} uv_counters_t; };
uv_counters_t* uv_counters();
struct uv_loop_s {
UV_LOOP_PRIVATE_FIELDS
/* list used for ares task handles */
uv_ares_task_t* uv_ares_handles_;
/* Various thing for libeio. */
uv_async_t uv_eio_want_poll_notifier;
uv_async_t uv_eio_done_poll_notifier;
uv_idle_t uv_eio_poller;
/* Diagnostic counters */
uv_counters_t counters;
/* The last error */
uv_err_t last_err;
/* User data - use this for whatever. */
void* data;
};
/* Don't export the private CPP symbols. */ /* Don't export the private CPP symbols. */

0
deps/uv/src/uv-cygwin.c → deps/uv/src/unix/cygwin.c

0
deps/uv/src/uv-darwin.c → deps/uv/src/unix/darwin.c

0
deps/uv/src/eio/Changes → deps/uv/src/unix/eio/Changes

0
deps/uv/src/eio/LICENSE → deps/uv/src/unix/eio/LICENSE

0
deps/uv/src/eio/Makefile.am → deps/uv/src/unix/eio/Makefile.am

0
deps/uv/src/eio/aclocal.m4 → deps/uv/src/unix/eio/aclocal.m4

0
deps/uv/src/eio/autogen.sh → deps/uv/src/unix/eio/autogen.sh

0
deps/uv/src/eio/config.h.in → deps/uv/src/unix/eio/config.h.in

0
deps/uv/src/eio/config_cygwin.h → deps/uv/src/unix/eio/config_cygwin.h

0
deps/uv/src/eio/config_darwin.h → deps/uv/src/unix/eio/config_darwin.h

0
deps/uv/src/eio/config_freebsd.h → deps/uv/src/unix/eio/config_freebsd.h

0
deps/uv/src/eio/config_linux.h → deps/uv/src/unix/eio/config_linux.h

0
deps/uv/src/eio/config_sunos.h → deps/uv/src/unix/eio/config_sunos.h

0
deps/uv/src/eio/configure.ac → deps/uv/src/unix/eio/configure.ac

0
deps/uv/src/eio/demo.c → deps/uv/src/unix/eio/demo.c

0
deps/uv/src/eio/ecb.h → deps/uv/src/unix/eio/ecb.h

0
deps/uv/src/eio/eio.3 → deps/uv/src/unix/eio/eio.3

0
deps/uv/src/eio/eio.c → deps/uv/src/unix/eio/eio.c

0
deps/uv/src/eio/eio.pod → deps/uv/src/unix/eio/eio.pod

0
deps/uv/src/eio/libeio.m4 → deps/uv/src/unix/eio/libeio.m4

0
deps/uv/src/eio/xthread.h → deps/uv/src/unix/eio/xthread.h

0
deps/uv/src/ev/Changes → deps/uv/src/unix/ev/Changes

0
deps/uv/src/ev/LICENSE → deps/uv/src/unix/ev/LICENSE

0
deps/uv/src/ev/Makefile.am → deps/uv/src/unix/ev/Makefile.am

0
deps/uv/src/ev/Makefile.in → deps/uv/src/unix/ev/Makefile.in

0
deps/uv/src/ev/README → deps/uv/src/unix/ev/README

0
deps/uv/src/ev/aclocal.m4 → deps/uv/src/unix/ev/aclocal.m4

0
deps/uv/src/ev/autogen.sh → deps/uv/src/unix/ev/autogen.sh

0
deps/uv/src/ev/config.guess → deps/uv/src/unix/ev/config.guess

0
deps/uv/src/ev/config.h.in → deps/uv/src/unix/ev/config.h.in

0
deps/uv/src/ev/config.sub → deps/uv/src/unix/ev/config.sub

0
deps/uv/src/ev/config_cygwin.h → deps/uv/src/unix/ev/config_cygwin.h

0
deps/uv/src/ev/config_darwin.h → deps/uv/src/unix/ev/config_darwin.h

0
deps/uv/src/ev/config_freebsd.h → deps/uv/src/unix/ev/config_freebsd.h

0
deps/uv/src/ev/config_linux.h → deps/uv/src/unix/ev/config_linux.h

0
deps/uv/src/ev/config_sunos.h → deps/uv/src/unix/ev/config_sunos.h

0
deps/uv/src/ev/configure → deps/uv/src/unix/ev/configure

0
deps/uv/src/ev/configure.ac → deps/uv/src/unix/ev/configure.ac

0
deps/uv/src/ev/depcomp → deps/uv/src/unix/ev/depcomp

0
deps/uv/src/ev/ev++.h → deps/uv/src/unix/ev/ev++.h

0
deps/uv/src/ev/ev.3 → deps/uv/src/unix/ev/ev.3

0
deps/uv/src/ev/ev.c → deps/uv/src/unix/ev/ev.c

0
deps/uv/src/ev/ev.pod → deps/uv/src/unix/ev/ev.pod

0
deps/uv/src/ev/ev_epoll.c → deps/uv/src/unix/ev/ev_epoll.c

0
deps/uv/src/ev/ev_kqueue.c → deps/uv/src/unix/ev/ev_kqueue.c

0
deps/uv/src/ev/ev_poll.c → deps/uv/src/unix/ev/ev_poll.c

0
deps/uv/src/ev/ev_port.c → deps/uv/src/unix/ev/ev_port.c

0
deps/uv/src/ev/ev_select.c → deps/uv/src/unix/ev/ev_select.c

0
deps/uv/src/ev/ev_vars.h → deps/uv/src/unix/ev/ev_vars.h

0
deps/uv/src/ev/ev_win32.c → deps/uv/src/unix/ev/ev_win32.c

0
deps/uv/src/ev/ev_wrap.h → deps/uv/src/unix/ev/ev_wrap.h

0
deps/uv/src/ev/event.c → deps/uv/src/unix/ev/event.c

0
deps/uv/src/ev/event.h → deps/uv/src/unix/ev/event.h

0
deps/uv/src/ev/install-sh → deps/uv/src/unix/ev/install-sh

0
deps/uv/src/ev/libev.m4 → deps/uv/src/unix/ev/libev.m4

0
deps/uv/src/ev/ltmain.sh → deps/uv/src/unix/ev/ltmain.sh

0
deps/uv/src/ev/missing → deps/uv/src/unix/ev/missing

0
deps/uv/src/ev/mkinstalldirs → deps/uv/src/unix/ev/mkinstalldirs

0
deps/uv/src/uv-freebsd.c → deps/uv/src/unix/freebsd.c

210
deps/uv/src/unix/fs.c

@ -33,12 +33,14 @@
#include <unistd.h> #include <unistd.h>
static void uv_fs_req_init(uv_fs_t* req, uv_fs_type fs_type, uv_fs_cb cb) { static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req, uv_fs_type fs_type,
uv_fs_cb cb) {
/* Make sure the thread pool is initialized. */ /* Make sure the thread pool is initialized. */
uv_eio_init(); uv_eio_init(loop);
uv__req_init((uv_req_t*) req); uv__req_init((uv_req_t*) req);
req->type = UV_FS; req->type = UV_FS;
req->loop = loop;
req->fs_type = fs_type; req->fs_type = fs_type;
req->cb = cb; req->cb = cb;
req->result = 0; req->result = 0;
@ -103,7 +105,7 @@ static int uv__fs_after(eio_req* eio) {
req->ptr = req->eio->ptr2; req->ptr = req->eio->ptr2;
} }
uv_unref(); uv_unref(req->loop);
req->eio = NULL; /* Freed by libeio */ req->eio = NULL; /* Freed by libeio */
req->cb(req); req->cb(req);
@ -111,20 +113,20 @@ static int uv__fs_after(eio_req* eio) {
} }
int uv_fs_close(uv_fs_t* req, uv_file file, uv_fs_cb cb) { int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
uv_fs_req_init(req, UV_FS_CLOSE, cb); uv_fs_req_init(loop, req, UV_FS_CLOSE, cb);
if (cb) { if (cb) {
/* async */ /* async */
uv_ref(); uv_ref(loop);
req->eio = eio_close(file, EIO_PRI_DEFAULT, uv__fs_after, req); req->eio = eio_close(file, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) { if (!req->eio) {
uv_err_new(NULL, ENOMEM); uv_err_new(loop, ENOMEM);
return -1; return -1;
} }
} else { } else {
/* sync */ /* sync */
if ((req->result = uv__close(file))) { if ((req->result = uv__close(file))) {
uv_err_new(NULL, errno); uv_err_new(loop, errno);
return -1; return -1;
} }
} }
@ -133,16 +135,16 @@ int uv_fs_close(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
} }
int uv_fs_open(uv_fs_t* req, const char* path, int flags, int mode, int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
uv_fs_cb cb) { int mode, uv_fs_cb cb) {
uv_fs_req_init(req, UV_FS_OPEN, cb); uv_fs_req_init(loop, req, UV_FS_OPEN, cb);
if (cb) { if (cb) {
/* async */ /* async */
uv_ref(); uv_ref(loop);
req->eio = eio_open(path, flags, mode, EIO_PRI_DEFAULT, uv__fs_after, req); req->eio = eio_open(path, flags, mode, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) { if (!req->eio) {
uv_err_new(NULL, ENOMEM); uv_err_new(loop, ENOMEM);
return -1; return -1;
} }
@ -150,7 +152,7 @@ int uv_fs_open(uv_fs_t* req, const char* path, int flags, int mode,
/* sync */ /* sync */
req->result = open(path, flags, mode); req->result = open(path, flags, mode);
if (req->result < 0) { if (req->result < 0) {
uv_err_new(NULL, errno); uv_err_new(loop, errno);
return -1; return -1;
} }
@ -161,18 +163,18 @@ int uv_fs_open(uv_fs_t* req, const char* path, int flags, int mode,
} }
int uv_fs_read(uv_fs_t* req, uv_file fd, void* buf, size_t length, int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file fd, void* buf,
off_t offset, uv_fs_cb cb) { size_t length, off_t offset, uv_fs_cb cb) {
uv_fs_req_init(req, UV_FS_READ, cb); uv_fs_req_init(loop, req, UV_FS_READ, cb);
if (cb) { if (cb) {
/* async */ /* async */
uv_ref(); uv_ref(loop);
req->eio = eio_read(fd, buf, length, offset, EIO_PRI_DEFAULT, req->eio = eio_read(fd, buf, length, offset, EIO_PRI_DEFAULT,
uv__fs_after, req); uv__fs_after, req);
if (!req->eio) { if (!req->eio) {
uv_err_new(NULL, ENOMEM); uv_err_new(loop, ENOMEM);
return -1; return -1;
} }
@ -183,7 +185,7 @@ int uv_fs_read(uv_fs_t* req, uv_file fd, void* buf, size_t length,
pread(fd, buf, length, offset); pread(fd, buf, length, offset);
if (req->result < 0) { if (req->result < 0) {
uv_err_new(NULL, errno); uv_err_new(loop, errno);
return -1; return -1;
} }
} }
@ -192,15 +194,15 @@ int uv_fs_read(uv_fs_t* req, uv_file fd, void* buf, size_t length,
} }
int uv_fs_unlink(uv_fs_t* req, const char* path, uv_fs_cb cb) { int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
uv_fs_req_init(req, UV_FS_UNLINK, cb); uv_fs_req_init(loop, req, UV_FS_UNLINK, cb);
if (cb) { if (cb) {
/* async */ /* async */
uv_ref(); uv_ref(loop);
req->eio = eio_unlink(path, EIO_PRI_DEFAULT, uv__fs_after, req); req->eio = eio_unlink(path, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) { if (!req->eio) {
uv_err_new(NULL, ENOMEM); uv_err_new(loop, ENOMEM);
return -1; return -1;
} }
@ -209,7 +211,7 @@ int uv_fs_unlink(uv_fs_t* req, const char* path, uv_fs_cb cb) {
req->result = unlink(path); req->result = unlink(path);
if (req->result) { if (req->result) {
uv_err_new(NULL, errno); uv_err_new(loop, errno);
return -1; return -1;
} }
} }
@ -218,17 +220,17 @@ int uv_fs_unlink(uv_fs_t* req, const char* path, uv_fs_cb cb) {
} }
int uv_fs_write(uv_fs_t* req, uv_file file, void* buf, size_t length, int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
off_t offset, uv_fs_cb cb) { size_t length, off_t offset, uv_fs_cb cb) {
uv_fs_req_init(req, UV_FS_WRITE, cb); uv_fs_req_init(loop, req, UV_FS_WRITE, cb);
if (cb) { if (cb) {
/* async */ /* async */
uv_ref(); uv_ref(loop);
req->eio = eio_write(file, buf, length, offset, EIO_PRI_DEFAULT, req->eio = eio_write(file, buf, length, offset, EIO_PRI_DEFAULT,
uv__fs_after, req); uv__fs_after, req);
if (!req->eio) { if (!req->eio) {
uv_err_new(NULL, ENOMEM); uv_err_new(loop, ENOMEM);
return -1; return -1;
} }
@ -239,7 +241,7 @@ int uv_fs_write(uv_fs_t* req, uv_file file, void* buf, size_t length,
pwrite(file, buf, length, offset); pwrite(file, buf, length, offset);
if (req->result < 0) { if (req->result < 0) {
uv_err_new(NULL, errno); uv_err_new(loop, errno);
return -1; return -1;
} }
} }
@ -248,15 +250,16 @@ int uv_fs_write(uv_fs_t* req, uv_file file, void* buf, size_t length,
} }
int uv_fs_mkdir(uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) { int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
uv_fs_req_init(req, UV_FS_MKDIR, cb); uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_MKDIR, cb);
if (cb) { if (cb) {
/* async */ /* async */
uv_ref(); uv_ref(loop);
req->eio = eio_mkdir(path, mode, EIO_PRI_DEFAULT, uv__fs_after, req); req->eio = eio_mkdir(path, mode, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) { if (!req->eio) {
uv_err_new(NULL, ENOMEM); uv_err_new(loop, ENOMEM);
return -1; return -1;
} }
@ -265,7 +268,7 @@ int uv_fs_mkdir(uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) {
req->result = mkdir(path, mode); req->result = mkdir(path, mode);
if (req->result < 0) { if (req->result < 0) {
uv_err_new(NULL, errno); uv_err_new(loop, errno);
return -1; return -1;
} }
} }
@ -274,15 +277,15 @@ int uv_fs_mkdir(uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) {
} }
int uv_fs_rmdir(uv_fs_t* req, const char* path, uv_fs_cb cb) { int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
uv_fs_req_init(req, UV_FS_RMDIR, cb); uv_fs_req_init(loop, req, UV_FS_RMDIR, cb);
if (cb) { if (cb) {
/* async */ /* async */
uv_ref(); uv_ref(loop);
req->eio = eio_rmdir(path, EIO_PRI_DEFAULT, uv__fs_after, req); req->eio = eio_rmdir(path, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) { if (!req->eio) {
uv_err_new(NULL, ENOMEM); uv_err_new(loop, ENOMEM);
return -1; return -1;
} }
@ -291,7 +294,7 @@ int uv_fs_rmdir(uv_fs_t* req, const char* path, uv_fs_cb cb) {
req->result = rmdir(path); req->result = rmdir(path);
if (req->result < 0) { if (req->result < 0) {
uv_err_new(NULL, errno); uv_err_new(loop, errno);
return -1; return -1;
} }
} }
@ -300,20 +303,21 @@ int uv_fs_rmdir(uv_fs_t* req, const char* path, uv_fs_cb cb) {
} }
int uv_fs_readdir(uv_fs_t* req, const char* path, int flags, uv_fs_cb cb) { int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
uv_fs_cb cb) {
int r; int r;
struct dirent* entry; struct dirent* entry;
size_t size = 0; size_t size = 0;
size_t d_namlen = 0; size_t d_namlen = 0;
uv_fs_req_init(req, UV_FS_READDIR, cb); uv_fs_req_init(loop, req, UV_FS_READDIR, cb);
if (cb) { if (cb) {
/* async */ /* async */
uv_ref(); uv_ref(loop);
req->eio = eio_readdir(path, flags, EIO_PRI_DEFAULT, uv__fs_after, req); req->eio = eio_readdir(path, flags, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) { if (!req->eio) {
uv_err_new(NULL, ENOMEM); uv_err_new(loop, ENOMEM);
return -1; return -1;
} }
@ -321,7 +325,7 @@ int uv_fs_readdir(uv_fs_t* req, const char* path, int flags, uv_fs_cb cb) {
/* sync */ /* sync */
DIR* dir = opendir(path); DIR* dir = opendir(path);
if (!dir) { if (!dir) {
uv_err_new(NULL, errno); uv_err_new(loop, errno);
return -1; return -1;
} }
@ -338,7 +342,7 @@ int uv_fs_readdir(uv_fs_t* req, const char* path, int flags, uv_fs_cb cb) {
r = closedir(dir); r = closedir(dir);
if (r) { if (r) {
uv_err_new(NULL, errno); uv_err_new(loop, errno);
return -1; return -1;
} }
} }
@ -347,11 +351,11 @@ int uv_fs_readdir(uv_fs_t* req, const char* path, int flags, uv_fs_cb cb) {
} }
int uv_fs_stat(uv_fs_t* req, const char* path, uv_fs_cb cb) { int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
char* pathdup = path; char* pathdup = path;
int pathlen; int pathlen;
uv_fs_req_init(req, UV_FS_STAT, cb); uv_fs_req_init(loop, req, UV_FS_STAT, cb);
/* TODO do this without duplicating the string. */ /* TODO do this without duplicating the string. */
/* TODO security */ /* TODO security */
@ -365,13 +369,13 @@ int uv_fs_stat(uv_fs_t* req, const char* path, uv_fs_cb cb) {
if (cb) { if (cb) {
/* async */ /* async */
uv_ref(); uv_ref(loop);
req->eio = eio_stat(pathdup, EIO_PRI_DEFAULT, uv__fs_after, req); req->eio = eio_stat(pathdup, EIO_PRI_DEFAULT, uv__fs_after, req);
free(pathdup); free(pathdup);
if (!req->eio) { if (!req->eio) {
uv_err_new(NULL, ENOMEM); uv_err_new(loop, ENOMEM);
return -1; return -1;
} }
@ -382,7 +386,7 @@ int uv_fs_stat(uv_fs_t* req, const char* path, uv_fs_cb cb) {
free(pathdup); free(pathdup);
if (req->result < 0) { if (req->result < 0) {
uv_err_new(NULL, errno); uv_err_new(loop, errno);
return -1; return -1;
} }
@ -393,22 +397,22 @@ int uv_fs_stat(uv_fs_t* req, const char* path, uv_fs_cb cb) {
} }
int uv_fs_fstat(uv_fs_t* req, uv_file file, uv_fs_cb cb) { int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
assert(0 && "implement me"); assert(0 && "implement me");
return -1; return -1;
} }
int uv_fs_rename(uv_fs_t* req, const char* path, const char* new_path, int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path,
uv_fs_cb cb) { uv_fs_cb cb) {
uv_fs_req_init(req, UV_FS_RENAME, cb); uv_fs_req_init(loop, req, UV_FS_RENAME, cb);
if (cb) { if (cb) {
/* async */ /* async */
uv_ref(); uv_ref(loop);
req->eio = eio_rename(path, new_path, EIO_PRI_DEFAULT, uv__fs_after, req); req->eio = eio_rename(path, new_path, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) { if (!req->eio) {
uv_err_new(NULL, ENOMEM); uv_err_new(loop, ENOMEM);
return -1; return -1;
} }
@ -417,7 +421,7 @@ int uv_fs_rename(uv_fs_t* req, const char* path, const char* new_path,
req->result = rename(path, new_path); req->result = rename(path, new_path);
if (req->result) { if (req->result) {
uv_err_new(NULL, errno); uv_err_new(loop, errno);
return -1; return -1;
} }
} }
@ -426,15 +430,15 @@ int uv_fs_rename(uv_fs_t* req, const char* path, const char* new_path,
} }
int uv_fs_fsync(uv_fs_t* req, uv_file file, uv_fs_cb cb) { int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
uv_fs_req_init(req, UV_FS_FSYNC, cb); uv_fs_req_init(loop, req, UV_FS_FSYNC, cb);
if (cb) { if (cb) {
/* async */ /* async */
uv_ref(); uv_ref(loop);
req->eio = eio_fsync(file, EIO_PRI_DEFAULT, uv__fs_after, req); req->eio = eio_fsync(file, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) { if (!req->eio) {
uv_err_new(NULL, ENOMEM); uv_err_new(loop, ENOMEM);
return -1; return -1;
} }
@ -443,7 +447,7 @@ int uv_fs_fsync(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
req->result = fsync(file); req->result = fsync(file);
if (req->result) { if (req->result) {
uv_err_new(NULL, errno); uv_err_new(loop, errno);
return -1; return -1;
} }
} }
@ -452,15 +456,15 @@ int uv_fs_fsync(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
} }
int uv_fs_fdatasync(uv_fs_t* req, uv_file file, uv_fs_cb cb) { int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
uv_fs_req_init(req, UV_FS_FDATASYNC, cb); uv_fs_req_init(loop, req, UV_FS_FDATASYNC, cb);
if (cb) { if (cb) {
/* async */ /* async */
uv_ref(); uv_ref(loop);
req->eio = eio_fdatasync(file, EIO_PRI_DEFAULT, uv__fs_after, req); req->eio = eio_fdatasync(file, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) { if (!req->eio) {
uv_err_new(NULL, ENOMEM); uv_err_new(loop, ENOMEM);
return -1; return -1;
} }
@ -469,7 +473,7 @@ int uv_fs_fdatasync(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
req->result = fdatasync(file); req->result = fdatasync(file);
if (req->result) { if (req->result) {
uv_err_new(NULL, errno); uv_err_new(loop, errno);
return -1; return -1;
} }
} }
@ -478,15 +482,16 @@ int uv_fs_fdatasync(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
} }
int uv_fs_ftruncate(uv_fs_t* req, uv_file file, off_t offset, uv_fs_cb cb) { int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file, off_t offset,
uv_fs_req_init(req, UV_FS_FTRUNCATE, cb); uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_FTRUNCATE, cb);
if (cb) { if (cb) {
/* async */ /* async */
uv_ref(); uv_ref(loop);
req->eio = eio_ftruncate(file, offset, EIO_PRI_DEFAULT, uv__fs_after, req); req->eio = eio_ftruncate(file, offset, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) { if (!req->eio) {
uv_err_new(NULL, ENOMEM); uv_err_new(loop, ENOMEM);
return -1; return -1;
} }
@ -495,7 +500,7 @@ int uv_fs_ftruncate(uv_fs_t* req, uv_file file, off_t offset, uv_fs_cb cb) {
req->result = ftruncate(file, offset); req->result = ftruncate(file, offset);
if (req->result) { if (req->result) {
uv_err_new(NULL, errno); uv_err_new(loop, errno);
return -1; return -1;
} }
} }
@ -504,17 +509,17 @@ int uv_fs_ftruncate(uv_fs_t* req, uv_file file, off_t offset, uv_fs_cb cb) {
} }
int uv_fs_sendfile(uv_fs_t* req, uv_file out_fd, uv_file in_fd, int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd, uv_file in_fd,
off_t in_offset, size_t length, uv_fs_cb cb) { off_t in_offset, size_t length, uv_fs_cb cb) {
uv_fs_req_init(req, UV_FS_SENDFILE, cb); uv_fs_req_init(loop, req, UV_FS_SENDFILE, cb);
if (cb) { if (cb) {
/* async */ /* async */
uv_ref(); uv_ref(loop);
req->eio = eio_sendfile(out_fd, in_fd, in_offset, length, EIO_PRI_DEFAULT, req->eio = eio_sendfile(out_fd, in_fd, in_offset, length, EIO_PRI_DEFAULT,
uv__fs_after, req); uv__fs_after, req);
if (!req->eio) { if (!req->eio) {
uv_err_new(NULL, ENOMEM); uv_err_new(loop, ENOMEM);
return -1; return -1;
} }
@ -523,7 +528,7 @@ int uv_fs_sendfile(uv_fs_t* req, uv_file out_fd, uv_file in_fd,
req->result = eio_sendfile_sync(out_fd, in_fd, in_offset, length); req->result = eio_sendfile_sync(out_fd, in_fd, in_offset, length);
if (req->result) { if (req->result) {
uv_err_new(NULL, errno); uv_err_new(loop, errno);
return -1; return -1;
} }
} }
@ -532,29 +537,32 @@ int uv_fs_sendfile(uv_fs_t* req, uv_file out_fd, uv_file in_fd,
} }
int uv_fs_chmod(uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) { int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
uv_fs_cb cb) {
assert(0 && "implement me"); assert(0 && "implement me");
return -1; return -1;
} }
int uv_fs_utime(uv_fs_t* req, const char* path, double atime, double mtime, uv_fs_cb cb) { int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
double mtime, uv_fs_cb cb) {
assert(0 && "implement me"); assert(0 && "implement me");
return -1; return -1;
} }
int uv_fs_futime(uv_fs_t* req, uv_file file, double atime, double mtime, uv_fs_cb cb) { int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime,
double mtime, uv_fs_cb cb) {
assert(0 && "implement me"); assert(0 && "implement me");
return -1; return -1;
} }
int uv_fs_lstat(uv_fs_t* req, const char* path, uv_fs_cb cb) { int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
char* pathdup = path; char* pathdup = path;
int pathlen; int pathlen;
uv_fs_req_init(req, UV_FS_LSTAT, cb); uv_fs_req_init(loop, req, UV_FS_LSTAT, cb);
/* TODO do this without duplicating the string. */ /* TODO do this without duplicating the string. */
/* TODO security */ /* TODO security */
@ -568,13 +576,13 @@ int uv_fs_lstat(uv_fs_t* req, const char* path, uv_fs_cb cb) {
if (cb) { if (cb) {
/* async */ /* async */
uv_ref(); uv_ref(loop);
req->eio = eio_lstat(pathdup, EIO_PRI_DEFAULT, uv__fs_after, req); req->eio = eio_lstat(pathdup, EIO_PRI_DEFAULT, uv__fs_after, req);
free(pathdup); free(pathdup);
if (!req->eio) { if (!req->eio) {
uv_err_new(NULL, ENOMEM); uv_err_new(loop, ENOMEM);
return -1; return -1;
} }
@ -585,7 +593,7 @@ int uv_fs_lstat(uv_fs_t* req, const char* path, uv_fs_cb cb) {
free(pathdup); free(pathdup);
if (req->result < 0) { if (req->result < 0) {
uv_err_new(NULL, errno); uv_err_new(loop, errno);
return -1; return -1;
} }
@ -596,38 +604,43 @@ int uv_fs_lstat(uv_fs_t* req, const char* path, uv_fs_cb cb) {
} }
int uv_fs_link(uv_fs_t* req, const char* path, const char* new_path, int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_cb cb) { const char* new_path, uv_fs_cb cb) {
assert(0 && "implement me"); assert(0 && "implement me");
return -1; return -1;
} }
int uv_fs_symlink(uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb) { int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb) {
assert(0 && "implement me"); assert(0 && "implement me");
return -1; return -1;
} }
int uv_fs_readlink(uv_fs_t* req, const char* path, uv_fs_cb cb) { int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_cb cb) {
assert(0 && "implement me"); assert(0 && "implement me");
return -1; return -1;
} }
int uv_fs_fchmod(uv_fs_t* req, uv_file file, int mode, uv_fs_cb cb) { int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode,
uv_fs_cb cb) {
assert(0 && "implement me"); assert(0 && "implement me");
return -1; return -1;
} }
int uv_fs_chown(uv_fs_t* req, const char* path, int uid, int gid, uv_fs_cb cb) { int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, int uid,
int gid, uv_fs_cb cb) {
assert(0 && "implement me"); assert(0 && "implement me");
return -1; return -1;
} }
int uv_fs_fchown(uv_fs_t* req, uv_file file, int uid, int gid, uv_fs_cb cb) { int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, int uid, int gid,
uv_fs_cb cb) {
assert(0 && "implement me"); assert(0 && "implement me");
return -1; return -1;
} }
@ -643,7 +656,7 @@ static void uv__work(eio_req* eio) {
static int uv__after_work(eio_req *eio) { static int uv__after_work(eio_req *eio) {
uv_work_t* req = eio->data; uv_work_t* req = eio->data;
uv_unref(); uv_unref(req->loop);
if (req->after_work_cb) { if (req->after_work_cb) {
req->after_work_cb(req); req->after_work_cb(req);
} }
@ -651,14 +664,15 @@ static int uv__after_work(eio_req *eio) {
} }
int uv_queue_work(uv_work_t* req, uv_work_cb work_cb, int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb,
uv_after_work_cb after_work_cb) { uv_after_work_cb after_work_cb) {
void* data = req->data; void* data = req->data;
uv_eio_init(); uv_eio_init(loop);
uv__req_init((uv_req_t*) req); uv__req_init((uv_req_t*) req);
uv_ref(); uv_ref(loop);
req->loop = loop;
req->data = data; req->data = data;
req->work_cb = work_cb; req->work_cb = work_cb;
req->after_work_cb = after_work_cb; req->after_work_cb = after_work_cb;
@ -666,7 +680,7 @@ int uv_queue_work(uv_work_t* req, uv_work_cb work_cb,
req->eio = eio_custom(uv__work, EIO_PRI_DEFAULT, uv__after_work, req); req->eio = eio_custom(uv__work, EIO_PRI_DEFAULT, uv__after_work, req);
if (!req->eio) { if (!req->eio) {
uv_err_new(NULL, ENOMEM); uv_err_new(loop, ENOMEM);
return -1; return -1;
} }

2
deps/uv/src/unix/internal.h

@ -27,7 +27,7 @@
int uv__close(int fd); int uv__close(int fd);
void uv__req_init(uv_req_t*); void uv__req_init(uv_req_t*);
uv_err_t uv_err_new(uv_handle_t* handle, int sys_error); uv_err_t uv_err_new(uv_loop_t* loop, int sys_error);
int uv__nonblock(int fd, int set) __attribute__((unused)); int uv__nonblock(int fd, int set) __attribute__((unused));
int uv__cloexec(int fd, int set) __attribute__((unused)); int uv__cloexec(int fd, int set) __attribute__((unused));

0
deps/uv/src/uv-linux.c → deps/uv/src/unix/linux.c

0
deps/uv/src/uv-sunos.c → deps/uv/src/unix/sunos.c

75
deps/uv/src/uv-eio.c → deps/uv/src/unix/uv-eio.c

@ -22,51 +22,55 @@
#include "uv.h" #include "uv.h"
#include "eio.h" #include "eio.h"
#include <assert.h> #include <assert.h>
#include <stdio.h>
static uv_async_t uv_eio_want_poll_notifier; /* TODO remove me! */
static uv_async_t uv_eio_done_poll_notifier; static uv_loop_t* main_loop;
static uv_idle_t uv_eio_poller;
static int uv_eio_init_count;
static void uv_eio_do_poll(uv_idle_t* watcher, int status) { static void uv_eio_do_poll(uv_idle_t* watcher, int status) {
assert(watcher == &uv_eio_poller); assert(watcher == &(watcher->loop->uv_eio_poller));
/* printf("uv_eio_poller\n"); */ /* printf("uv_eio_poller\n"); */
if (eio_poll() != -1 && uv_is_active((uv_handle_t*) &uv_eio_poller)) { if (eio_poll() != -1 && uv_is_active((uv_handle_t*) watcher)) {
/* printf("uv_eio_poller stop\n"); */ /* printf("uv_eio_poller stop\n"); */
uv_idle_stop(&uv_eio_poller); uv_idle_stop(watcher);
uv_unref(); uv_unref(watcher->loop);
} }
} }
/* Called from the main thread. */ /* Called from the main thread. */
static void uv_eio_want_poll_notifier_cb(uv_async_t* watcher, int status) { static void uv_eio_want_poll_notifier_cb(uv_async_t* watcher, int status) {
assert(watcher == &uv_eio_want_poll_notifier); uv_loop_t* loop = watcher->loop;
assert(watcher == &loop->uv_eio_want_poll_notifier);
/* printf("want poll notifier\n"); */ /* printf("want poll notifier\n"); */
if (eio_poll() == -1 && !uv_is_active((uv_handle_t*) &uv_eio_poller)) { if (eio_poll() == -1 && !uv_is_active((uv_handle_t*) &loop->uv_eio_poller)) {
/* printf("uv_eio_poller start\n"); */ /* printf("uv_eio_poller start\n"); */
uv_idle_start(&uv_eio_poller, uv_eio_do_poll); uv_idle_start(&loop->uv_eio_poller, uv_eio_do_poll);
uv_ref(); uv_ref(loop);
} }
} }
static void uv_eio_done_poll_notifier_cb(uv_async_t* watcher, int revents) { static void uv_eio_done_poll_notifier_cb(uv_async_t* watcher, int revents) {
assert(watcher == &uv_eio_done_poll_notifier); uv_loop_t* loop = watcher->loop;
assert(watcher == &loop->uv_eio_done_poll_notifier);
/* printf("done poll notifier\n"); */ /* printf("done poll notifier\n"); */
if (eio_poll() != -1 && uv_is_active((uv_handle_t*) &uv_eio_poller)) { if (eio_poll() != -1 && uv_is_active((uv_handle_t*) &loop->uv_eio_poller)) {
/* printf("uv_eio_poller stop\n"); */ /* printf("uv_eio_poller stop\n"); */
uv_idle_stop(&uv_eio_poller); uv_idle_stop(&loop->uv_eio_poller);
uv_unref(); uv_unref(loop);
} }
} }
@ -77,7 +81,13 @@ static void uv_eio_done_poll_notifier_cb(uv_async_t* watcher, int revents) {
*/ */
static void uv_eio_want_poll(void) { static void uv_eio_want_poll(void) {
/* Signal the main thread that eio_poll need to be processed. */ /* Signal the main thread that eio_poll need to be processed. */
uv_async_send(&uv_eio_want_poll_notifier);
/*
* TODO need to select the correct uv_loop_t and async_send to
* uv_eio_want_poll_notifier.
*/
uv_async_send(&main_loop->uv_eio_want_poll_notifier);
} }
@ -86,22 +96,27 @@ static void uv_eio_done_poll(void) {
* Signal the main thread that we should stop calling eio_poll(). * Signal the main thread that we should stop calling eio_poll().
* from the idle watcher. * from the idle watcher.
*/ */
uv_async_send(&uv_eio_done_poll_notifier); uv_async_send(&main_loop->uv_eio_done_poll_notifier);
} }
void uv_eio_init() { void uv_eio_init(uv_loop_t* loop) {
if (uv_eio_init_count == 0) { if (loop->counters.eio_init == 0) {
uv_eio_init_count++; loop->counters.eio_init++;
main_loop = loop;
uv_idle_init(&uv_eio_poller); uv_idle_init(loop, &loop->uv_eio_poller);
uv_idle_start(&uv_eio_poller, uv_eio_do_poll); uv_idle_start(&loop->uv_eio_poller, uv_eio_do_poll);
uv_async_init(&uv_eio_want_poll_notifier, uv_eio_want_poll_notifier_cb); loop->uv_eio_want_poll_notifier.data = loop;
uv_unref(); uv_async_init(loop, &loop->uv_eio_want_poll_notifier,
uv_eio_want_poll_notifier_cb);
uv_unref(loop);
uv_async_init(&uv_eio_done_poll_notifier, uv_eio_done_poll_notifier_cb); uv_async_init(loop, &loop->uv_eio_done_poll_notifier,
uv_unref(); uv_eio_done_poll_notifier_cb);
uv_unref(loop);
eio_init(uv_eio_want_poll, uv_eio_done_poll); eio_init(uv_eio_want_poll, uv_eio_done_poll);
/* /*
@ -109,5 +124,11 @@ void uv_eio_init() {
* race conditions. See Node's test/simple/test-eio-race.js * race conditions. See Node's test/simple/test-eio-race.js
*/ */
eio_set_max_poll_reqs(10); eio_set_max_poll_reqs(10);
} else {
/*
* If this assertion breaks then Ryan hasn't implemented support for
* receiving thread pool requests back to multiple threads.
*/
assert(main_loop == loop);
} }
} }

2
deps/uv/src/uv-eio.h → deps/uv/src/unix/uv-eio.h

@ -9,5 +9,5 @@
* safe to call more than once. * safe to call more than once.
* TODO: uv_eio_deinit * TODO: uv_eio_deinit
*/ */
void uv_eio_init(void); void uv_eio_init(uv_loop_t*);
#endif #endif

30
deps/uv/src/uv-common.c

@ -31,9 +31,6 @@
#include "ares/inet_net_pton.h" #include "ares/inet_net_pton.h"
#include "ares/inet_ntop.h" #include "ares/inet_ntop.h"
/* list used for ares task handles */
static uv_ares_task_t* uv_ares_handles_ = NULL;
static uv_counters_t counters; static uv_counters_t counters;
@ -135,20 +132,23 @@ int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size) {
/* find matching ares handle in list */ /* find matching ares handle in list */
void uv_add_ares_handle(uv_ares_task_t* handle) { void uv_add_ares_handle(uv_loop_t* loop, uv_ares_task_t* handle) {
handle->ares_next = uv_ares_handles_; handle->loop = loop;
handle->ares_next = loop->uv_ares_handles_;
handle->ares_prev = NULL; handle->ares_prev = NULL;
if (uv_ares_handles_) { if (loop->uv_ares_handles_) {
uv_ares_handles_->ares_prev = handle; loop->uv_ares_handles_->ares_prev = handle;
} }
uv_ares_handles_ = handle;
loop->uv_ares_handles_ = handle;
} }
/* find matching ares handle in list */ /* find matching ares handle in list */
/* TODO: faster lookup */ /* TODO: faster lookup */
uv_ares_task_t* uv_find_ares_handle(ares_socket_t sock) { uv_ares_task_t* uv_find_ares_handle(uv_loop_t* loop, ares_socket_t sock) {
uv_ares_task_t* handle = uv_ares_handles_; uv_ares_task_t* handle = loop->uv_ares_handles_;
while (handle != NULL) { while (handle != NULL) {
if (handle->sock == sock) { if (handle->sock == sock) {
break; break;
@ -161,8 +161,10 @@ uv_ares_task_t* uv_find_ares_handle(ares_socket_t sock) {
/* remove ares handle in list */ /* remove ares handle in list */
void uv_remove_ares_handle(uv_ares_task_t* handle) { void uv_remove_ares_handle(uv_ares_task_t* handle) {
if (handle == uv_ares_handles_) { uv_loop_t* loop = handle->loop;
uv_ares_handles_ = handle->ares_next;
if (handle == loop->uv_ares_handles_) {
loop->uv_ares_handles_ = handle->ares_next;
} }
if (handle->ares_next) { if (handle->ares_next) {
@ -176,6 +178,6 @@ void uv_remove_ares_handle(uv_ares_task_t* handle) {
/* Returns 1 if the uv_ares_handles_ list is empty. 0 otherwise. */ /* Returns 1 if the uv_ares_handles_ list is empty. 0 otherwise. */
int uv_ares_handles_empty() { int uv_ares_handles_empty(uv_loop_t* loop) {
return uv_ares_handles_ ? 0 : 1; return loop->uv_ares_handles_ ? 0 : 1;
} }

14
deps/uv/src/uv-common.h

@ -38,11 +38,6 @@
req->errorno = errno; \ req->errorno = errno; \
} }
/*
* Subclass of uv_handle_t. Used for integration of c-ares.
*/
typedef struct uv_ares_task_s uv_ares_task_t;
struct uv_ares_task_s { struct uv_ares_task_s {
UV_HANDLE_FIELDS UV_HANDLE_FIELDS
UV_ARES_TASK_PRIVATE_FIELDS UV_ARES_TASK_PRIVATE_FIELDS
@ -52,9 +47,12 @@ struct uv_ares_task_s {
void uv_remove_ares_handle(uv_ares_task_t* handle); void uv_remove_ares_handle(uv_ares_task_t* handle);
uv_ares_task_t* uv_find_ares_handle(ares_socket_t sock); uv_ares_task_t* uv_find_ares_handle(uv_loop_t*, ares_socket_t sock);
void uv_add_ares_handle(uv_ares_task_t* handle);
int uv_ares_handles_empty(); /* TODO Rename to uv_ares_task_init? */
void uv_add_ares_handle(uv_loop_t* loop, uv_ares_task_t* handle);
int uv_ares_handles_empty(uv_loop_t* loop);
#endif /* UV_COMMON_H_ */ #endif /* UV_COMMON_H_ */

468
deps/uv/src/uv-unix.c

File diff suppressed because it is too large

24
deps/uv/src/win/async.c

@ -54,7 +54,7 @@ static inline char uv_atomic_exchange_set(char volatile* target) {
#endif #endif
void uv_async_endgame(uv_async_t* handle) { void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle) {
if (handle->flags & UV_HANDLE_CLOSING && if (handle->flags & UV_HANDLE_CLOSING &&
!handle->async_sent) { !handle->async_sent) {
assert(!(handle->flags & UV_HANDLE_CLOSED)); assert(!(handle->flags & UV_HANDLE_CLOSED));
@ -64,34 +64,37 @@ void uv_async_endgame(uv_async_t* handle) {
handle->close_cb((uv_handle_t*)handle); handle->close_cb((uv_handle_t*)handle);
} }
uv_unref(); uv_unref(loop);
} }
} }
int uv_async_init(uv_async_t* handle, uv_async_cb async_cb) { int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
uv_req_t* req; uv_req_t* req;
uv_counters()->handle_init++; loop->counters.handle_init++;
uv_counters()->async_init++; loop->counters.async_init++;
handle->type = UV_ASYNC; handle->type = UV_ASYNC;
handle->loop = loop;
handle->flags = 0; handle->flags = 0;
handle->async_sent = 0; handle->async_sent = 0;
handle->async_cb = async_cb; handle->async_cb = async_cb;
req = &handle->async_req; req = &handle->async_req;
uv_req_init(req); uv_req_init(loop, req);
req->type = UV_WAKEUP; req->type = UV_WAKEUP;
req->data = handle; req->data = handle;
uv_ref(); uv_ref(loop);
return 0; return 0;
} }
int uv_async_send(uv_async_t* handle) { int uv_async_send(uv_async_t* handle) {
uv_loop_t* loop = handle->loop;
if (handle->type != UV_ASYNC) { if (handle->type != UV_ASYNC) {
/* Can't set errno because that's not thread-safe. */ /* Can't set errno because that's not thread-safe. */
return -1; return -1;
@ -102,14 +105,15 @@ int uv_async_send(uv_async_t* handle) {
assert(!(handle->flags & UV_HANDLE_CLOSING)); assert(!(handle->flags & UV_HANDLE_CLOSING));
if (!uv_atomic_exchange_set(&handle->async_sent)) { if (!uv_atomic_exchange_set(&handle->async_sent)) {
POST_COMPLETION_FOR_REQ(&handle->async_req); POST_COMPLETION_FOR_REQ(loop, &handle->async_req);
} }
return 0; return 0;
} }
void uv_process_async_wakeup_req(uv_async_t* handle, uv_req_t* req) { void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle,
uv_req_t* req) {
assert(handle->type == UV_ASYNC); assert(handle->type == UV_ASYNC);
assert(req->type == UV_WAKEUP); assert(req->type == UV_WAKEUP);
@ -118,6 +122,6 @@ void uv_process_async_wakeup_req(uv_async_t* handle, uv_req_t* req) {
handle->async_cb((uv_async_t*) handle, 0); handle->async_cb((uv_async_t*) handle, 0);
} }
if (handle->flags & UV_HANDLE_CLOSING) { if (handle->flags & UV_HANDLE_CLOSING) {
uv_want_endgame((uv_handle_t*)handle); uv_want_endgame(loop, (uv_handle_t*)handle);
} }
} }

128
deps/uv/src/win/cares.c

@ -38,41 +38,34 @@ struct uv_ares_action_s {
}; };
/* memory used per ares_channel */
typedef struct uv_ares_channel_s {
ares_channel channel;
int activesockets;
uv_timer_t pollingtimer;
} uv_ares_channel_t;
/* static data to hold single ares_channel */
static uv_ares_channel_t uv_ares_data = { NULL, 0 };
/* default timeout per socket request if ares does not specify value */ /* default timeout per socket request if ares does not specify value */
/* use 20 sec */ /* use 20 sec */
#define ARES_TIMEOUT_MS 20000 #define ARES_TIMEOUT_MS 20000
/* thread pool callback when socket is signalled */ /* thread pool callback when socket is signalled */
static void CALLBACK uv_ares_socksignal_tp(void* parameter, BOOLEAN timerfired) { static void CALLBACK uv_ares_socksignal_tp(void* parameter,
BOOLEAN timerfired) {
WSANETWORKEVENTS network_events; WSANETWORKEVENTS network_events;
uv_ares_task_t* sockhandle; uv_ares_task_t* sockhandle;
uv_ares_action_t* selhandle; uv_ares_action_t* selhandle;
uv_req_t* uv_ares_req; uv_req_t* uv_ares_req;
uv_loop_t* loop;
assert(parameter != NULL); assert(parameter != NULL);
if (parameter != NULL) { if (parameter != NULL) {
sockhandle = (uv_ares_task_t*)parameter; sockhandle = (uv_ares_task_t*) parameter;
loop = sockhandle->loop;
/* clear socket status for this event */ /* clear socket status for this event */
/* do not fail if error, thread may run after socket close */ /* do not fail if error, thread may run after socket close */
/* The code assumes that c-ares will write all pending data in the callback, /* The code assumes that c-ares will write all pending data in the */
unless the socket would block. We can clear the state here to avoid unecessary /* callback, unless the socket would block. We can clear the state here */
signals. */ /* to avoid unecessary signals. */
WSAEnumNetworkEvents(sockhandle->sock, sockhandle->h_event, &network_events); WSAEnumNetworkEvents(sockhandle->sock,
sockhandle->h_event,
&network_events);
/* setup new handle */ /* setup new handle */
selhandle = (uv_ares_action_t*)malloc(sizeof(uv_ares_action_t)); selhandle = (uv_ares_action_t*)malloc(sizeof(uv_ares_action_t));
@ -83,47 +76,53 @@ static void CALLBACK uv_ares_socksignal_tp(void* parameter, BOOLEAN timerfired)
selhandle->close_cb = NULL; selhandle->close_cb = NULL;
selhandle->data = sockhandle->data; selhandle->data = sockhandle->data;
selhandle->sock = sockhandle->sock; selhandle->sock = sockhandle->sock;
selhandle->read = (network_events.lNetworkEvents & (FD_READ | FD_CONNECT)) ? 1 : 0; selhandle->read =
selhandle->write = (network_events.lNetworkEvents & (FD_WRITE | FD_CONNECT)) ? 1 : 0; (network_events.lNetworkEvents & (FD_READ | FD_CONNECT)) ? 1 : 0;
selhandle->write =
(network_events.lNetworkEvents & (FD_WRITE | FD_CONNECT)) ? 1 : 0;
uv_ares_req = &selhandle->ares_req; uv_ares_req = &selhandle->ares_req;
uv_req_init(uv_ares_req); uv_req_init(loop, uv_ares_req);
uv_ares_req->type = UV_ARES_EVENT_REQ; uv_ares_req->type = UV_ARES_EVENT_REQ;
uv_ares_req->data = selhandle; uv_ares_req->data = selhandle;
/* post ares needs to called */ /* post ares needs to called */
POST_COMPLETION_FOR_REQ(uv_ares_req); POST_COMPLETION_FOR_REQ(loop, uv_ares_req);
} }
} }
/* periodically call ares to check for timeouts */ /* periodically call ares to check for timeouts */
static void uv_ares_poll(uv_timer_t* handle, int status) { static void uv_ares_poll(uv_timer_t* handle, int status) {
if (uv_ares_data.channel != NULL && uv_ares_data.activesockets > 0) { uv_loop_t* loop = handle->loop;
ares_process_fd(uv_ares_data.channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD); if (loop->ares_channel != NULL && loop->ares_active_sockets > 0) {
ares_process_fd(loop->ares_channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
} }
} }
/* callback from ares when socket operation is started */ /* callback from ares when socket operation is started */
static void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read, int write) { static void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read,
int write) {
/* look to see if we have a handle for this socket in our list */ /* look to see if we have a handle for this socket in our list */
uv_ares_task_t* uv_handle_ares = uv_find_ares_handle(sock); uv_loop_t* loop = (uv_loop_t*) data;
uv_ares_channel_t* uv_ares_data_ptr = (uv_ares_channel_t*)data; uv_ares_task_t* uv_handle_ares = uv_find_ares_handle(loop, sock);
int timeoutms = 0; int timeoutms = 0;
if (read == 0 && write == 0) { if (read == 0 && write == 0) {
/* if read and write are 0, cleanup existing data */ /* if read and write are 0, cleanup existing data */
/* The code assumes that c-ares does a callback with read = 0 and write = 0 /* The code assumes that c-ares does a callback with read = 0 and */
when the socket is closed. After we recieve this we stop monitoring the socket. */ /* write = 0 when the socket is closed. After we recieve this we stop */
/* monitoring the socket. */
if (uv_handle_ares != NULL) { if (uv_handle_ares != NULL) {
uv_req_t* uv_ares_req; uv_req_t* uv_ares_req;
uv_handle_ares->h_close_event = CreateEvent(NULL, FALSE, FALSE, NULL); uv_handle_ares->h_close_event = CreateEvent(NULL, FALSE, FALSE, NULL);
/* remove Wait */ /* remove Wait */
if (uv_handle_ares->h_wait) { if (uv_handle_ares->h_wait) {
UnregisterWaitEx(uv_handle_ares->h_wait, uv_handle_ares->h_close_event); UnregisterWaitEx(uv_handle_ares->h_wait,
uv_handle_ares->h_close_event);
uv_handle_ares->h_wait = NULL; uv_handle_ares->h_wait = NULL;
} }
@ -138,12 +137,12 @@ static void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read, int w
/* Post request to cleanup the Task */ /* Post request to cleanup the Task */
uv_ares_req = &uv_handle_ares->ares_req; uv_ares_req = &uv_handle_ares->ares_req;
uv_req_init(uv_ares_req); uv_req_init(loop, uv_ares_req);
uv_ares_req->type = UV_ARES_CLEANUP_REQ; uv_ares_req->type = UV_ARES_CLEANUP_REQ;
uv_ares_req->data = uv_handle_ares; uv_ares_req->data = uv_handle_ares;
/* post ares done with socket - finish cleanup when all threads done. */ /* post ares done with socket - finish cleanup when all threads done. */
POST_COMPLETION_FOR_REQ(uv_ares_req); POST_COMPLETION_FOR_REQ(loop, uv_ares_req);
} else { } else {
assert(0); assert(0);
uv_fatal_error(ERROR_INVALID_DATA, "ares_SockStateCB"); uv_fatal_error(ERROR_INVALID_DATA, "ares_SockStateCB");
@ -160,7 +159,7 @@ static void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read, int w
} }
uv_handle_ares->type = UV_ARES_TASK; uv_handle_ares->type = UV_ARES_TASK;
uv_handle_ares->close_cb = NULL; uv_handle_ares->close_cb = NULL;
uv_handle_ares->data = uv_ares_data_ptr; uv_handle_ares->data = loop;
uv_handle_ares->sock = sock; uv_handle_ares->sock = sock;
uv_handle_ares->h_wait = NULL; uv_handle_ares->h_wait = NULL;
uv_handle_ares->flags = 0; uv_handle_ares->flags = 0;
@ -172,24 +171,26 @@ static void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read, int w
} }
/* tie event to socket */ /* tie event to socket */
if (SOCKET_ERROR == WSAEventSelect(sock, uv_handle_ares->h_event, FD_READ | FD_WRITE | FD_CONNECT)) { if (SOCKET_ERROR == WSAEventSelect(sock,
uv_handle_ares->h_event,
FD_READ | FD_WRITE | FD_CONNECT)) {
uv_fatal_error(WSAGetLastError(), "WSAEventSelect"); uv_fatal_error(WSAGetLastError(), "WSAEventSelect");
} }
/* add handle to list */ /* add handle to list */
uv_add_ares_handle(uv_handle_ares); uv_add_ares_handle(loop, uv_handle_ares);
uv_ref(); uv_ref(loop);
/* /*
* we have a single polling timer for all ares sockets. * we have a single polling timer for all ares sockets.
* This is preferred to using ares_timeout. See ares_timeout.c warning. * This is preferred to using ares_timeout. See ares_timeout.c warning.
* if timer is not running start it, and keep socket count * if timer is not running start it, and keep socket count
*/ */
if (uv_ares_data_ptr->activesockets == 0) { if (loop->ares_active_sockets == 0) {
uv_timer_init(&uv_ares_data_ptr->pollingtimer); uv_timer_init(loop, &loop->ares_polling_timer);
uv_timer_start(&uv_ares_data_ptr->pollingtimer, uv_ares_poll, 1000L, 1000L); uv_timer_start(&loop->ares_polling_timer, uv_ares_poll, 1000L, 1000L);
} }
uv_ares_data_ptr->activesockets++; loop->ares_active_sockets++;
/* specify thread pool function to call when event is signaled */ /* specify thread pool function to call when event is signaled */
if (RegisterWaitForSingleObject(&uv_handle_ares->h_wait, if (RegisterWaitForSingleObject(&uv_handle_ares->h_wait,
@ -211,12 +212,11 @@ static void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read, int w
/* called via uv_poll when ares completion port signaled */ /* called via uv_poll when ares completion port signaled */
void uv_process_ares_event_req(uv_ares_action_t* handle, uv_req_t* req) { void uv_process_ares_event_req(uv_loop_t* loop, uv_ares_action_t* handle,
uv_ares_channel_t* uv_ares_data_ptr = (uv_ares_channel_t*)handle->data; uv_req_t* req) {
ares_process_fd(loop->ares_channel,
ares_process_fd(uv_ares_data_ptr->channel, handle->read ? handle->sock : INVALID_SOCKET,
handle->read ? handle->sock : INVALID_SOCKET, handle->write ? handle->sock : INVALID_SOCKET);
handle->write ? handle->sock : INVALID_SOCKET);
/* release handle for select here */ /* release handle for select here */
free(handle); free(handle);
@ -224,47 +224,47 @@ void uv_process_ares_event_req(uv_ares_action_t* handle, uv_req_t* req) {
/* called via uv_poll when ares is finished with socket */ /* called via uv_poll when ares is finished with socket */
void uv_process_ares_cleanup_req(uv_ares_task_t* handle, uv_req_t* req) { void uv_process_ares_cleanup_req(uv_loop_t* loop, uv_ares_task_t* handle,
uv_req_t* req) {
/* check for event complete without waiting */ /* check for event complete without waiting */
unsigned int signaled = WaitForSingleObject(handle->h_close_event, 0); unsigned int signaled = WaitForSingleObject(handle->h_close_event, 0);
if (signaled != WAIT_TIMEOUT) { if (signaled != WAIT_TIMEOUT) {
uv_ares_channel_t* uv_ares_data_ptr = (uv_ares_channel_t*)handle->data; uv_unref(loop);
uv_unref();
/* close event handle and free uv handle memory */ /* close event handle and free uv handle memory */
CloseHandle(handle->h_close_event); CloseHandle(handle->h_close_event);
free(handle); free(handle);
/* decrement active count. if it becomes 0 stop polling */ /* decrement active count. if it becomes 0 stop polling */
if (uv_ares_data_ptr->activesockets > 0) { if (loop->ares_active_sockets > 0) {
uv_ares_data_ptr->activesockets--; loop->ares_active_sockets--;
if (uv_ares_data_ptr->activesockets == 0) { if (loop->ares_active_sockets == 0) {
uv_close((uv_handle_t*)&uv_ares_data_ptr->pollingtimer, NULL); uv_close((uv_handle_t*) &loop->ares_polling_timer, NULL);
} }
} }
} else { } else {
/* stil busy - repost and try again */ /* stil busy - repost and try again */
POST_COMPLETION_FOR_REQ(req); POST_COMPLETION_FOR_REQ(loop, req);
} }
} }
/* set ares SOCK_STATE callback to our handler */ /* set ares SOCK_STATE callback to our handler */
int uv_ares_init_options(ares_channel *channelptr, int uv_ares_init_options(uv_loop_t* loop,
struct ares_options *options, ares_channel *channelptr,
int optmask) { struct ares_options *options,
int optmask) {
int rc; int rc;
/* only allow single init at a time */ /* only allow single init at a time */
if (uv_ares_data.channel != NULL) { if (loop->ares_channel != NULL) {
return UV_EALREADY; return UV_EALREADY;
} }
/* set our callback as an option */ /* set our callback as an option */
options->sock_state_cb = uv_ares_sockstate_cb; options->sock_state_cb = uv_ares_sockstate_cb;
options->sock_state_cb_data = &uv_ares_data; options->sock_state_cb_data = loop;
optmask |= ARES_OPT_SOCK_STATE_CB; optmask |= ARES_OPT_SOCK_STATE_CB;
/* We do the call to ares_init_option for caller. */ /* We do the call to ares_init_option for caller. */
@ -272,7 +272,7 @@ int uv_ares_init_options(ares_channel *channelptr,
/* if success, save channel */ /* if success, save channel */
if (rc == ARES_SUCCESS) { if (rc == ARES_SUCCESS) {
uv_ares_data.channel = *channelptr; loop->ares_channel = *channelptr;
} }
return rc; return rc;
@ -280,10 +280,10 @@ int uv_ares_init_options(ares_channel *channelptr,
/* release memory */ /* release memory */
void uv_ares_destroy(ares_channel channel) { void uv_ares_destroy(uv_loop_t* loop, ares_channel channel) {
/* only allow destroy if did init */ /* only allow destroy if did init */
if (uv_ares_data.channel != NULL) { if (loop->ares_channel != NULL) {
ares_destroy(channel); ares_destroy(channel);
uv_ares_data.channel = NULL; loop->ares_channel = NULL;
} }
} }

108
deps/uv/src/win/core.c

@ -32,37 +32,49 @@
/* The only event loop we support right now */ /* The only event loop we support right now */
uv_loop_t uv_main_loop_; static uv_loop_t uv_default_loop_;
static int uv_default_loop_initialized_ = 0;
static void uv_loop_init() { static void uv_loop_init(uv_loop_t* loop) {
/* Create an I/O completion port */ /* Create an I/O completion port */
LOOP->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1); loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
if (LOOP->iocp == NULL) { if (loop->iocp == NULL) {
uv_fatal_error(GetLastError(), "CreateIoCompletionPort"); uv_fatal_error(GetLastError(), "CreateIoCompletionPort");
} }
LOOP->refs = 0; loop->refs = 0;
uv_update_time(); uv_update_time(loop);
LOOP->pending_reqs_tail = NULL; loop->pending_reqs_tail = NULL;
LOOP->endgame_handles = NULL; loop->endgame_handles = NULL;
RB_INIT(&LOOP->timers); RB_INIT(&loop->timers);
LOOP->check_handles = NULL; loop->check_handles = NULL;
LOOP->prepare_handles = NULL; loop->prepare_handles = NULL;
LOOP->idle_handles = NULL; loop->idle_handles = NULL;
LOOP->next_prepare_handle = NULL; loop->next_prepare_handle = NULL;
LOOP->next_check_handle = NULL; loop->next_check_handle = NULL;
LOOP->next_idle_handle = NULL; loop->next_idle_handle = NULL;
LOOP->last_error = uv_ok_; loop->ares_active_sockets = 0;
loop->ares_channel = NULL;
LOOP->err_str = NULL; loop->last_error = uv_ok_;
}
uv_loop_t* uv_default_loop() {
if (!uv_default_loop_initialized_) {
uv_loop_init(&uv_default_loop_);
uv_default_loop_initialized_ = 1;
}
return &uv_default_loop_;
} }
@ -75,23 +87,20 @@ void uv_init() {
/* Initialize FS */ /* Initialize FS */
uv_fs_init(); uv_fs_init();
/* Intialize event loop */
uv_loop_init();
} }
void uv_ref() { void uv_ref(uv_loop_t* loop) {
LOOP->refs++; loop->refs++;
} }
void uv_unref() { void uv_unref(uv_loop_t* loop) {
LOOP->refs--; loop->refs--;
} }
static void uv_poll(int block) { static void uv_poll(uv_loop_t* loop, int block) {
BOOL success; BOOL success;
DWORD bytes, timeout; DWORD bytes, timeout;
ULONG_PTR key; ULONG_PTR key;
@ -99,12 +108,12 @@ static void uv_poll(int block) {
uv_req_t* req; uv_req_t* req;
if (block) { if (block) {
timeout = uv_get_poll_timeout(); timeout = uv_get_poll_timeout(loop);
} else { } else {
timeout = 0; timeout = 0;
} }
success = GetQueuedCompletionStatus(LOOP->iocp, success = GetQueuedCompletionStatus(loop->iocp,
&bytes, &bytes,
&key, &key,
&overlapped, &overlapped,
@ -114,7 +123,7 @@ static void uv_poll(int block) {
/* Package was dequeued */ /* Package was dequeued */
req = uv_overlapped_to_req(overlapped); req = uv_overlapped_to_req(overlapped);
uv_insert_pending_req(req); uv_insert_pending_req(loop, req);
} else if (GetLastError() != WAIT_TIMEOUT) { } else if (GetLastError() != WAIT_TIMEOUT) {
/* Serious error */ /* Serious error */
@ -123,7 +132,7 @@ static void uv_poll(int block) {
} }
static void uv_poll_ex(int block) { static void uv_poll_ex(uv_loop_t* loop, int block) {
BOOL success; BOOL success;
DWORD timeout; DWORD timeout;
uv_req_t* req; uv_req_t* req;
@ -132,14 +141,14 @@ static void uv_poll_ex(int block) {
ULONG i; ULONG i;
if (block) { if (block) {
timeout = uv_get_poll_timeout(); timeout = uv_get_poll_timeout(loop);
} else { } else {
timeout = 0; timeout = 0;
} }
assert(pGetQueuedCompletionStatusEx); assert(pGetQueuedCompletionStatusEx);
success = pGetQueuedCompletionStatusEx(LOOP->iocp, success = pGetQueuedCompletionStatusEx(loop->iocp,
overlappeds, overlappeds,
COUNTOF(overlappeds), COUNTOF(overlappeds),
&count, &count,
@ -149,7 +158,7 @@ static void uv_poll_ex(int block) {
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
/* Package was dequeued */ /* Package was dequeued */
req = uv_overlapped_to_req(overlappeds[i].lpOverlapped); req = uv_overlapped_to_req(overlappeds[i].lpOverlapped);
uv_insert_pending_req(req); uv_insert_pending_req(loop, req);
} }
} else if (GetLastError() != WAIT_TIMEOUT) { } else if (GetLastError() != WAIT_TIMEOUT) {
/* Serious error */ /* Serious error */
@ -158,43 +167,44 @@ static void uv_poll_ex(int block) {
} }
#define UV_LOOP(poll) \ #define UV_LOOP(loop, poll) \
while (LOOP->refs > 0) { \ while ((loop)->refs > 0) { \
uv_update_time(); \ uv_update_time((loop)); \
uv_process_timers(); \ uv_process_timers((loop)); \
\ \
/* Call idle callbacks if nothing to do. */ \ /* Call idle callbacks if nothing to do. */ \
if (LOOP->pending_reqs_tail == NULL && LOOP->endgame_handles == NULL) { \ if ((loop)->pending_reqs_tail == NULL && \
uv_idle_invoke(); \ (loop)->endgame_handles == NULL) { \
uv_idle_invoke((loop)); \
} \ } \
\ \
/* Completely flush all pending reqs and endgames. */ \ /* Completely flush all pending reqs and endgames. */ \
/* We do even when we just called the idle callbacks because those may */ \ /* We do even when we just called the idle callbacks because those may */ \
/* have closed handles or started requests that short-circuited. */ \ /* have closed handles or started requests that short-circuited. */ \
while (LOOP->pending_reqs_tail || LOOP->endgame_handles) { \ while ((loop)->pending_reqs_tail || (loop)->endgame_handles) { \
uv_process_endgames(); \ uv_process_endgames((loop)); \
uv_process_reqs(); \ uv_process_reqs((loop)); \
} \ } \
\ \
if (LOOP->refs <= 0) { \ if ((loop)->refs <= 0) { \
break; \ break; \
} \ } \
\ \
uv_prepare_invoke(); \ uv_prepare_invoke((loop)); \
\ \
poll(LOOP->idle_handles == NULL && LOOP->refs > 0); \ poll((loop), (loop)->idle_handles == NULL && (loop)->refs > 0); \
\ \
uv_check_invoke(); \ uv_check_invoke((loop)); \
} }
int uv_run() { int uv_run(uv_loop_t* loop) {
if (pGetQueuedCompletionStatusEx) { if (pGetQueuedCompletionStatusEx) {
UV_LOOP(uv_poll_ex); UV_LOOP(loop, uv_poll_ex);
} else { } else {
UV_LOOP(uv_poll); UV_LOOP(loop, uv_poll);
} }
assert(LOOP->refs == 0); assert(loop->refs == 0);
return 0; return 0;
} }

30
deps/uv/src/win/error.c

@ -67,22 +67,26 @@ void uv_fatal_error(const int errorno, const char* syscall) {
} }
uv_err_t uv_last_error() { uv_err_t uv_last_error(uv_loop_t* loop) {
return LOOP->last_error; return loop->last_error;
} }
/* TODO: thread safety */
static char* last_err_str_ = NULL;
char* uv_strerror(uv_err_t err) { char* uv_strerror(uv_err_t err) {
if (LOOP->err_str != NULL) { if (last_err_str_ != NULL) {
LocalFree(LOOP->err_str); LocalFree(last_err_str_);
} }
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err.sys_errno_, FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err.sys_errno_,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&LOOP->err_str, 0, NULL); MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR) &last_err_str_, 0,
NULL);
if (LOOP->err_str) { if (last_err_str_) {
return LOOP->err_str; return last_err_str_;
} else { } else {
return "Unknown error"; return "Unknown error";
} }
@ -134,13 +138,13 @@ uv_err_t uv_new_sys_error(int sys_errno) {
} }
void uv_set_sys_error(int sys_errno) { void uv_set_sys_error(uv_loop_t* loop, int sys_errno) {
LOOP->last_error.code = uv_translate_sys_error(sys_errno); loop->last_error.code = uv_translate_sys_error(sys_errno);
LOOP->last_error.sys_errno_ = sys_errno; loop->last_error.sys_errno_ = sys_errno;
} }
void uv_set_error(uv_err_code code, int sys_errno) { void uv_set_error(uv_loop_t* loop, uv_err_code code, int sys_errno) {
LOOP->last_error.code = code; loop->last_error.code = code;
LOOP->last_error.sys_errno_ = sys_errno; loop->last_error.sys_errno_ = sys_errno;
} }

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

@ -59,13 +59,15 @@
WRAP_REQ_ARGS3(req, a0, a1, a2) \ WRAP_REQ_ARGS3(req, a0, a1, a2) \
req->arg3 = (void*)a3; req->arg3 = (void*)a3;
#define QUEUE_FS_TP_JOB(req) \ #define QUEUE_FS_TP_JOB(loop, req) \
if (!QueueUserWorkItem(&uv_fs_thread_proc, req, WT_EXECUTELONGFUNCTION)) {\ if (!QueueUserWorkItem(&uv_fs_thread_proc, \
uv_set_sys_error(GetLastError()); \ req, \
WT_EXECUTELONGFUNCTION)) { \
uv_set_sys_error((loop), GetLastError()); \
return -1; \ return -1; \
} \ } \
req->flags |= UV_FS_ASYNC_QUEUED; \ req->flags |= UV_FS_ASYNC_QUEUED; \
uv_ref(); uv_ref((loop));
void uv_fs_init() { void uv_fs_init() {
@ -73,9 +75,11 @@ void uv_fs_init() {
} }
static void uv_fs_req_init_async(uv_fs_t* req, uv_fs_type fs_type, uv_fs_cb cb) { static void uv_fs_req_init_async(uv_loop_t* loop, uv_fs_t* req,
uv_req_init((uv_req_t*) req); uv_fs_type fs_type, uv_fs_cb cb) {
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_FS; req->type = UV_FS;
req->loop = loop;
req->flags = 0; req->flags = 0;
req->fs_type = fs_type; req->fs_type = fs_type;
req->cb = cb; req->cb = cb;
@ -86,9 +90,11 @@ static void uv_fs_req_init_async(uv_fs_t* req, uv_fs_type fs_type, uv_fs_cb cb)
} }
static void uv_fs_req_init_sync(uv_fs_t* req, uv_fs_type fs_type) { static void uv_fs_req_init_sync(uv_loop_t* loop, uv_fs_t* req,
uv_req_init((uv_req_t*) req); uv_fs_type fs_type) {
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_FS; req->type = UV_FS;
req->loop = loop;
req->flags = 0; req->flags = 0;
req->fs_type = fs_type; req->fs_type = fs_type;
req->result = 0; req->result = 0;
@ -109,7 +115,8 @@ void fs__close(uv_fs_t* req, uv_file file) {
} }
void fs__read(uv_fs_t* req, uv_file file, void *buf, size_t length, off_t offset) { void fs__read(uv_fs_t* req, uv_file file, void *buf, size_t length,
off_t offset) {
int result = 0; int result = 0;
if (offset != -1) { if (offset != -1) {
@ -124,7 +131,8 @@ void fs__read(uv_fs_t* req, uv_file file, void *buf, size_t length, off_t offset
} }
void fs__write(uv_fs_t* req, uv_file file, void *buf, size_t length, off_t offset) { void fs__write(uv_fs_t* req, uv_file file, void *buf, size_t length,
off_t offset) {
int result = 0; int result = 0;
if (offset != -1) { if (offset != -1) {
@ -281,7 +289,8 @@ void fs__ftruncate(uv_fs_t* req, uv_file file, off_t offset) {
} }
void fs__sendfile(uv_fs_t* req, uv_file out_file, uv_file in_file, off_t in_offset, size_t length) { void fs__sendfile(uv_fs_t* req, uv_file out_file, uv_file in_file,
off_t in_offset, size_t length) {
const size_t max_buf_size = 65536; const size_t max_buf_size = 65536;
size_t buf_size = length < max_buf_size ? length : max_buf_size; size_t buf_size = length < max_buf_size ? length : max_buf_size;
int n, result = 0; int n, result = 0;
@ -293,7 +302,7 @@ void fs__sendfile(uv_fs_t* req, uv_file out_file, uv_file in_file, off_t in_offs
if (in_offset != -1) { if (in_offset != -1) {
result = _lseek(in_file, in_offset, SEEK_SET); result = _lseek(in_file, in_offset, SEEK_SET);
} }
if (result != -1) { if (result != -1) {
while (length > 0) { while (length > 0) {
n = _read(in_file, buf, length < buf_size ? length : buf_size); n = _read(in_file, buf, length < buf_size ? length : buf_size);
@ -343,7 +352,8 @@ void fs__futime(uv_fs_t* req, uv_file file, double atime, double mtime) {
static DWORD WINAPI uv_fs_thread_proc(void* parameter) { static DWORD WINAPI uv_fs_thread_proc(void* parameter) {
uv_fs_t* req = (uv_fs_t*)parameter; uv_fs_t* req = (uv_fs_t*) parameter;
uv_loop_t* loop = req->loop;
assert(req != NULL); assert(req != NULL);
assert(req->type == UV_FS); assert(req->type == UV_FS);
@ -356,10 +366,18 @@ static DWORD WINAPI uv_fs_thread_proc(void* parameter) {
fs__close(req, (uv_file)req->arg0); fs__close(req, (uv_file)req->arg0);
break; break;
case UV_FS_READ: case UV_FS_READ:
fs__read(req, (uv_file)req->arg0, req->arg1, (size_t)req->arg2, (off_t)req->arg3); fs__read(req,
(uv_file) req->arg0,
req->arg1,
(size_t) req->arg2,
(off_t) req->arg3);
break; break;
case UV_FS_WRITE: case UV_FS_WRITE:
fs__write(req, (uv_file)req->arg0, req->arg1, (size_t)req->arg2, (off_t)req->arg3); fs__write(req,
(uv_file)req->arg0,
req->arg1,
(size_t) req->arg2,
(off_t) req->arg3);
break; break;
case UV_FS_UNLINK: case UV_FS_UNLINK:
fs__unlink(req, (const char*)req->arg0); fs__unlink(req, (const char*)req->arg0);
@ -390,7 +408,11 @@ static DWORD WINAPI uv_fs_thread_proc(void* parameter) {
fs__ftruncate(req, (uv_file)req->arg0, (off_t)req->arg1); fs__ftruncate(req, (uv_file)req->arg0, (off_t)req->arg1);
break; break;
case UV_FS_SENDFILE: case UV_FS_SENDFILE:
fs__sendfile(req, (uv_file)req->arg0, (uv_file)req->arg1, (off_t)req->arg2, (size_t)req->arg3); fs__sendfile(req,
(uv_file) req->arg0,
(uv_file) req->arg1,
(off_t) req->arg2,
(size_t) req->arg3);
break; break;
case UV_FS_CHMOD: case UV_FS_CHMOD:
fs__chmod(req, (const char*)req->arg0, (int)req->arg1); fs__chmod(req, (const char*)req->arg0, (int)req->arg1);
@ -405,20 +427,21 @@ static DWORD WINAPI uv_fs_thread_proc(void* parameter) {
assert(!"bad uv_fs_type"); assert(!"bad uv_fs_type");
} }
POST_COMPLETION_FOR_REQ(req); POST_COMPLETION_FOR_REQ(loop, req);
return 0; return 0;
} }
int uv_fs_open(uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb) { int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
int mode, uv_fs_cb cb) {
if (cb) { if (cb) {
uv_fs_req_init_async(req, UV_FS_OPEN, cb); uv_fs_req_init_async(loop, req, UV_FS_OPEN, cb);
WRAP_REQ_ARGS3(req, path, flags, mode); WRAP_REQ_ARGS3(req, path, flags, mode);
STRDUP_ARG(req, 0); STRDUP_ARG(req, 0);
QUEUE_FS_TP_JOB(req); QUEUE_FS_TP_JOB(loop, req);
} else { } else {
uv_fs_req_init_sync(req, UV_FS_OPEN); uv_fs_req_init_sync(loop, req, UV_FS_OPEN);
fs__open(req, path, flags, mode); fs__open(req, path, flags, mode);
} }
@ -426,13 +449,13 @@ int uv_fs_open(uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb)
} }
int uv_fs_close(uv_fs_t* req, uv_file file, uv_fs_cb cb) { int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
if (cb) { if (cb) {
uv_fs_req_init_async(req, UV_FS_CLOSE, cb); uv_fs_req_init_async(loop, req, UV_FS_CLOSE, cb);
WRAP_REQ_ARGS1(req, file); WRAP_REQ_ARGS1(req, file);
QUEUE_FS_TP_JOB(req); QUEUE_FS_TP_JOB(loop, req);
} else { } else {
uv_fs_req_init_sync(req, UV_FS_CLOSE); uv_fs_req_init_sync(loop, req, UV_FS_CLOSE);
fs__close(req, file); fs__close(req, file);
} }
@ -440,13 +463,14 @@ int uv_fs_close(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
} }
int uv_fs_read(uv_fs_t* req, uv_file file, void* buf, size_t length, off_t offset, uv_fs_cb cb) { int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
size_t length, off_t offset, uv_fs_cb cb) {
if (cb) { if (cb) {
uv_fs_req_init_async(req, UV_FS_READ, cb); uv_fs_req_init_async(loop, req, UV_FS_READ, cb);
WRAP_REQ_ARGS4(req, file, buf, length, offset); WRAP_REQ_ARGS4(req, file, buf, length, offset);
QUEUE_FS_TP_JOB(req); QUEUE_FS_TP_JOB(loop, req);
} else { } else {
uv_fs_req_init_sync(req, UV_FS_READ); uv_fs_req_init_sync(loop, req, UV_FS_READ);
fs__read(req, file, buf, length, offset); fs__read(req, file, buf, length, offset);
} }
@ -454,13 +478,14 @@ int uv_fs_read(uv_fs_t* req, uv_file file, void* buf, size_t length, off_t offse
} }
int uv_fs_write(uv_fs_t* req, uv_file file, void* buf, size_t length, off_t offset, uv_fs_cb cb) { int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
size_t length, off_t offset, uv_fs_cb cb) {
if (cb) { if (cb) {
uv_fs_req_init_async(req, UV_FS_WRITE, cb); uv_fs_req_init_async(loop, req, UV_FS_WRITE, cb);
WRAP_REQ_ARGS4(req, file, buf, length, offset); WRAP_REQ_ARGS4(req, file, buf, length, offset);
QUEUE_FS_TP_JOB(req); QUEUE_FS_TP_JOB(loop, req);
} else { } else {
uv_fs_req_init_sync(req, UV_FS_WRITE); uv_fs_req_init_sync(loop, req, UV_FS_WRITE);
fs__write(req, file, buf, length, offset); fs__write(req, file, buf, length, offset);
} }
@ -468,14 +493,15 @@ int uv_fs_write(uv_fs_t* req, uv_file file, void* buf, size_t length, off_t offs
} }
int uv_fs_unlink(uv_fs_t* req, const char* path, uv_fs_cb cb) { int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_cb cb) {
if (cb) { if (cb) {
uv_fs_req_init_async(req, UV_FS_UNLINK, cb); uv_fs_req_init_async(loop, req, UV_FS_UNLINK, cb);
WRAP_REQ_ARGS1(req, path); WRAP_REQ_ARGS1(req, path);
STRDUP_ARG(req, 0); STRDUP_ARG(req, 0);
QUEUE_FS_TP_JOB(req); QUEUE_FS_TP_JOB(loop, req);
} else { } else {
uv_fs_req_init_sync(req, UV_FS_UNLINK); uv_fs_req_init_sync(loop, req, UV_FS_UNLINK);
fs__unlink(req, path); fs__unlink(req, path);
} }
@ -483,14 +509,15 @@ int uv_fs_unlink(uv_fs_t* req, const char* path, uv_fs_cb cb) {
} }
int uv_fs_mkdir(uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) { int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
uv_fs_cb cb) {
if (cb) { if (cb) {
uv_fs_req_init_async(req, UV_FS_MKDIR, cb); uv_fs_req_init_async(loop, req, UV_FS_MKDIR, cb);
WRAP_REQ_ARGS2(req, path, mode); WRAP_REQ_ARGS2(req, path, mode);
STRDUP_ARG(req, 0); STRDUP_ARG(req, 0);
QUEUE_FS_TP_JOB(req); QUEUE_FS_TP_JOB(loop, req);
} else { } else {
uv_fs_req_init_sync(req, UV_FS_MKDIR); uv_fs_req_init_sync(loop, req, UV_FS_MKDIR);
fs__mkdir(req, path, mode); fs__mkdir(req, path, mode);
} }
@ -498,14 +525,14 @@ int uv_fs_mkdir(uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) {
} }
int uv_fs_rmdir(uv_fs_t* req, const char* path, uv_fs_cb cb) { int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
if (cb) { if (cb) {
uv_fs_req_init_async(req, UV_FS_RMDIR, cb); uv_fs_req_init_async(loop, req, UV_FS_RMDIR, cb);
WRAP_REQ_ARGS1(req, path); WRAP_REQ_ARGS1(req, path);
STRDUP_ARG(req, 0); STRDUP_ARG(req, 0);
QUEUE_FS_TP_JOB(req); QUEUE_FS_TP_JOB(loop, req);
} else { } else {
uv_fs_req_init_sync(req, UV_FS_RMDIR); uv_fs_req_init_sync(loop, req, UV_FS_RMDIR);
fs__rmdir(req, path); fs__rmdir(req, path);
} }
@ -513,14 +540,15 @@ int uv_fs_rmdir(uv_fs_t* req, const char* path, uv_fs_cb cb) {
} }
int uv_fs_readdir(uv_fs_t* req, const char* path, int flags, uv_fs_cb cb) { int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
uv_fs_cb cb) {
if (cb) { if (cb) {
uv_fs_req_init_async(req, UV_FS_READDIR, cb); uv_fs_req_init_async(loop, req, UV_FS_READDIR, cb);
WRAP_REQ_ARGS2(req, path, flags); WRAP_REQ_ARGS2(req, path, flags);
STRDUP_ARG(req, 0); STRDUP_ARG(req, 0);
QUEUE_FS_TP_JOB(req); QUEUE_FS_TP_JOB(loop, req);
} else { } else {
uv_fs_req_init_sync(req, UV_FS_READDIR); uv_fs_req_init_sync(loop, req, UV_FS_READDIR);
fs__readdir(req, path, flags); fs__readdir(req, path, flags);
} }
@ -528,50 +556,56 @@ int uv_fs_readdir(uv_fs_t* req, const char* path, int flags, uv_fs_cb cb) {
} }
int uv_fs_lstat(uv_fs_t* req, const char* path, uv_fs_cb cb) { int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
assert(0 && "implement me"); assert(0 && "implement me");
return -1; return -1;
} }
// uv_fs_readlink, uv_fs_fchmod, uv_fs_chown, uv_fs_fchown // uv_fs_readlink, uv_fs_fchmod, uv_fs_chown, uv_fs_fchown
int uv_fs_link(uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb) { int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb) {
assert(0 && "implement me"); assert(0 && "implement me");
return -1; return -1;
} }
int uv_fs_symlink(uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb) { int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb) {
assert(0 && "implement me"); assert(0 && "implement me");
return -1; return -1;
} }
int uv_fs_readlink(uv_fs_t* req, const char* path, uv_fs_cb cb) { int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_cb cb) {
assert(0 && "implement me"); assert(0 && "implement me");
return -1; return -1;
} }
int uv_fs_fchmod(uv_fs_t* req, uv_file file, int mode, uv_fs_cb cb) { int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode,
uv_fs_cb cb) {
assert(0 && "implement me"); assert(0 && "implement me");
return -1; return -1;
} }
int uv_fs_chown(uv_fs_t* req, const char* path, int uid, int gid, uv_fs_cb cb) { int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, int uid,
int gid, uv_fs_cb cb) {
assert(0 && "implement me"); assert(0 && "implement me");
return -1; return -1;
} }
int uv_fs_fchown(uv_fs_t* req, uv_file file, int uid, int gid, uv_fs_cb cb) { int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, int uid,
int gid, uv_fs_cb cb) {
assert(0 && "implement me"); assert(0 && "implement me");
return -1; return -1;
} }
int uv_fs_stat(uv_fs_t* req, const char* path, uv_fs_cb cb) { int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
int len = strlen(path); int len = strlen(path);
char* path2 = NULL; char* path2 = NULL;
int has_backslash = (path[len - 1] == '\\' || path[len - 1] == '/'); int has_backslash = (path[len - 1] == '\\' || path[len - 1] == '/');
@ -586,7 +620,7 @@ int uv_fs_stat(uv_fs_t* req, const char* path, uv_fs_cb cb) {
} }
if (cb) { if (cb) {
uv_fs_req_init_async(req, UV_FS_STAT, cb); uv_fs_req_init_async(loop, req, UV_FS_STAT, cb);
if (path2) { if (path2) {
WRAP_REQ_ARGS1(req, path2); WRAP_REQ_ARGS1(req, path2);
req->flags |= UV_FS_FREE_ARG0; req->flags |= UV_FS_FREE_ARG0;
@ -594,10 +628,10 @@ int uv_fs_stat(uv_fs_t* req, const char* path, uv_fs_cb cb) {
WRAP_REQ_ARGS1(req, path); WRAP_REQ_ARGS1(req, path);
STRDUP_ARG(req, 0); STRDUP_ARG(req, 0);
} }
QUEUE_FS_TP_JOB(req); QUEUE_FS_TP_JOB(loop, req);
} else { } else {
uv_fs_req_init_sync(req, UV_FS_STAT); uv_fs_req_init_sync(loop, req, UV_FS_STAT);
fs__stat(req, path2 ? path2 : path); fs__stat(req, path2 ? path2 : path);
if (path2) { if (path2) {
free(path2); free(path2);
@ -608,13 +642,13 @@ int uv_fs_stat(uv_fs_t* req, const char* path, uv_fs_cb cb) {
} }
int uv_fs_fstat(uv_fs_t* req, uv_file file, uv_fs_cb cb) { int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
if (cb) { if (cb) {
uv_fs_req_init_async(req, UV_FS_FSTAT, cb); uv_fs_req_init_async(loop, req, UV_FS_FSTAT, cb);
WRAP_REQ_ARGS1(req, file); WRAP_REQ_ARGS1(req, file);
QUEUE_FS_TP_JOB(req); QUEUE_FS_TP_JOB(loop, req);
} else { } else {
uv_fs_req_init_sync(req, UV_FS_FSTAT); uv_fs_req_init_sync(loop, req, UV_FS_FSTAT);
fs__fstat(req, file); fs__fstat(req, file);
} }
@ -622,15 +656,16 @@ int uv_fs_fstat(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
} }
int uv_fs_rename(uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb) { int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb) {
if (cb) { if (cb) {
uv_fs_req_init_async(req, UV_FS_RENAME, cb); uv_fs_req_init_async(loop, req, UV_FS_RENAME, cb);
WRAP_REQ_ARGS2(req, path, new_path); WRAP_REQ_ARGS2(req, path, new_path);
STRDUP_ARG(req, 0); STRDUP_ARG(req, 0);
STRDUP_ARG(req, 1); STRDUP_ARG(req, 1);
QUEUE_FS_TP_JOB(req); QUEUE_FS_TP_JOB(loop, req);
} else { } else {
uv_fs_req_init_sync(req, UV_FS_RENAME); uv_fs_req_init_sync(loop, req, UV_FS_RENAME);
fs__rename(req, path, new_path); fs__rename(req, path, new_path);
} }
@ -638,13 +673,13 @@ int uv_fs_rename(uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb
} }
int uv_fs_fdatasync(uv_fs_t* req, uv_file file, uv_fs_cb cb) { int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
if (cb) { if (cb) {
uv_fs_req_init_async(req, UV_FS_FDATASYNC, cb); uv_fs_req_init_async(loop, req, UV_FS_FDATASYNC, cb);
WRAP_REQ_ARGS1(req, file); WRAP_REQ_ARGS1(req, file);
QUEUE_FS_TP_JOB(req); QUEUE_FS_TP_JOB(loop, req);
} else { } else {
uv_fs_req_init_sync(req, UV_FS_FDATASYNC); uv_fs_req_init_sync(loop, req, UV_FS_FDATASYNC);
fs__fsync(req, file); fs__fsync(req, file);
} }
@ -652,13 +687,13 @@ int uv_fs_fdatasync(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
} }
int uv_fs_fsync(uv_fs_t* req, uv_file file, uv_fs_cb cb) { int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
if (cb) { if (cb) {
uv_fs_req_init_async(req, UV_FS_FSYNC, cb); uv_fs_req_init_async(loop, req, UV_FS_FSYNC, cb);
WRAP_REQ_ARGS1(req, file); WRAP_REQ_ARGS1(req, file);
QUEUE_FS_TP_JOB(req); QUEUE_FS_TP_JOB(loop, req);
} else { } else {
uv_fs_req_init_sync(req, UV_FS_FSYNC); uv_fs_req_init_sync(loop, req, UV_FS_FSYNC);
fs__fsync(req, file); fs__fsync(req, file);
} }
@ -666,13 +701,14 @@ int uv_fs_fsync(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
} }
int uv_fs_ftruncate(uv_fs_t* req, uv_file file, off_t offset, uv_fs_cb cb) { int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file,
off_t offset, uv_fs_cb cb) {
if (cb) { if (cb) {
uv_fs_req_init_async(req, UV_FS_FTRUNCATE, cb); uv_fs_req_init_async(loop, req, UV_FS_FTRUNCATE, cb);
WRAP_REQ_ARGS2(req, file, offset); WRAP_REQ_ARGS2(req, file, offset);
QUEUE_FS_TP_JOB(req); QUEUE_FS_TP_JOB(loop, req);
} else { } else {
uv_fs_req_init_sync(req, UV_FS_FTRUNCATE); uv_fs_req_init_sync(loop, req, UV_FS_FTRUNCATE);
fs__ftruncate(req, file, offset); fs__ftruncate(req, file, offset);
} }
@ -680,13 +716,14 @@ int uv_fs_ftruncate(uv_fs_t* req, uv_file file, off_t offset, uv_fs_cb cb) {
} }
int uv_fs_sendfile(uv_fs_t* req, uv_file out_fd, uv_file in_fd, off_t in_offset, size_t length, uv_fs_cb cb) { int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd,
uv_file in_fd, off_t in_offset, size_t length, uv_fs_cb cb) {
if (cb) { if (cb) {
uv_fs_req_init_async(req, UV_FS_SENDFILE, cb); uv_fs_req_init_async(loop, req, UV_FS_SENDFILE, cb);
WRAP_REQ_ARGS4(req, out_fd, in_fd, in_offset, length); WRAP_REQ_ARGS4(req, out_fd, in_fd, in_offset, length);
QUEUE_FS_TP_JOB(req); QUEUE_FS_TP_JOB(loop, req);
} else { } else {
uv_fs_req_init_sync(req, UV_FS_SENDFILE); uv_fs_req_init_sync(loop, req, UV_FS_SENDFILE);
fs__sendfile(req, out_fd, in_fd, in_offset, length); fs__sendfile(req, out_fd, in_fd, in_offset, length);
} }
@ -694,14 +731,15 @@ int uv_fs_sendfile(uv_fs_t* req, uv_file out_fd, uv_file in_fd, off_t in_offset,
} }
int uv_fs_chmod(uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) { int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
uv_fs_cb cb) {
if (cb) { if (cb) {
uv_fs_req_init_async(req, UV_FS_CHMOD, cb); uv_fs_req_init_async(loop, req, UV_FS_CHMOD, cb);
WRAP_REQ_ARGS2(req, path, mode); WRAP_REQ_ARGS2(req, path, mode);
STRDUP_ARG(req, 0); STRDUP_ARG(req, 0);
QUEUE_FS_TP_JOB(req); QUEUE_FS_TP_JOB(loop, req);
} else { } else {
uv_fs_req_init_sync(req, UV_FS_CHMOD); uv_fs_req_init_sync(loop, req, UV_FS_CHMOD);
fs__chmod(req, path, mode); fs__chmod(req, path, mode);
} }
@ -709,16 +747,17 @@ int uv_fs_chmod(uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) {
} }
int uv_fs_utime(uv_fs_t* req, const char* path, double atime, double mtime, uv_fs_cb cb) { int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
double mtime, uv_fs_cb cb) {
if (cb) { if (cb) {
uv_fs_req_init_async(req, UV_FS_UTIME, cb); uv_fs_req_init_async(loop, req, UV_FS_UTIME, cb);
WRAP_REQ_ARGS1(req, path); WRAP_REQ_ARGS1(req, path);
STRDUP_ARG(req, 0); STRDUP_ARG(req, 0);
req->arg4 = (ssize_t)atime; req->arg4 = (ssize_t)atime;
req->arg5 = (ssize_t)mtime; req->arg5 = (ssize_t)mtime;
QUEUE_FS_TP_JOB(req); QUEUE_FS_TP_JOB(loop, req);
} else { } else {
uv_fs_req_init_sync(req, UV_FS_UTIME); uv_fs_req_init_sync(loop, req, UV_FS_UTIME);
fs__utime(req, path, atime, mtime); fs__utime(req, path, atime, mtime);
} }
@ -726,15 +765,16 @@ int uv_fs_utime(uv_fs_t* req, const char* path, double atime, double mtime, uv_f
} }
int uv_fs_futime(uv_fs_t* req, uv_file file, double atime, double mtime, uv_fs_cb cb) { int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime,
double mtime, uv_fs_cb cb) {
if (cb) { if (cb) {
uv_fs_req_init_async(req, UV_FS_FUTIME, cb); uv_fs_req_init_async(loop, req, UV_FS_FUTIME, cb);
WRAP_REQ_ARGS1(req, file); WRAP_REQ_ARGS1(req, file);
req->arg4 = (ssize_t)atime; req->arg4 = (ssize_t)atime;
req->arg5 = (ssize_t)mtime; req->arg5 = (ssize_t)mtime;
QUEUE_FS_TP_JOB(req); QUEUE_FS_TP_JOB(loop, req);
} else { } else {
uv_fs_req_init_sync(req, UV_FS_FUTIME); uv_fs_req_init_sync(loop, req, UV_FS_FUTIME);
fs__futime(req, file, atime, mtime); fs__futime(req, file, atime, mtime);
} }
@ -742,13 +782,15 @@ int uv_fs_futime(uv_fs_t* req, uv_file file, double atime, double mtime, uv_fs_c
} }
void uv_process_fs_req(uv_fs_t* req) { void uv_process_fs_req(uv_loop_t* loop, uv_fs_t* req) {
assert(req->cb); assert(req->cb);
req->cb(req); req->cb(req);
} }
void uv_fs_req_cleanup(uv_fs_t* req) { void uv_fs_req_cleanup(uv_fs_t* req) {
uv_loop_t* loop = req->loop;
if (req->flags & UV_FS_CLEANEDUP) { if (req->flags & UV_FS_CLEANEDUP) {
return; return;
} }
@ -769,7 +811,7 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
} }
if (req->flags & UV_FS_ASYNC_QUEUED) { if (req->flags & UV_FS_ASYNC_QUEUED) {
uv_unref(); uv_unref(loop);
} }
req->flags |= UV_FS_CLEANEDUP; req->flags |= UV_FS_CLEANEDUP;

97
deps/uv/src/win/getaddrinfo.c

@ -61,34 +61,38 @@
*/ */
static uv_err_code uv_translate_eai_error(int eai_errno) { static uv_err_code uv_translate_eai_error(int eai_errno) {
switch (eai_errno) { switch (eai_errno) {
case ERROR_SUCCESS: return UV_OK; case ERROR_SUCCESS: return UV_OK;
case EAI_BADFLAGS: return UV_EBADF; case EAI_BADFLAGS: return UV_EBADF;
case EAI_FAIL: return UV_EFAULT; case EAI_FAIL: return UV_EFAULT;
case EAI_FAMILY: return UV_EAIFAMNOSUPPORT; case EAI_FAMILY: return UV_EAIFAMNOSUPPORT;
case EAI_MEMORY: return UV_ENOMEM; case EAI_MEMORY: return UV_ENOMEM;
case EAI_NONAME: return UV_EAINONAME; case EAI_NONAME: return UV_EAINONAME;
case EAI_AGAIN: return UV_EAGAIN; case EAI_AGAIN: return UV_EAGAIN;
case EAI_SERVICE: return UV_EAISERVICE; case EAI_SERVICE: return UV_EAISERVICE;
case EAI_SOCKTYPE: return UV_EAISOCKTYPE; case EAI_SOCKTYPE: return UV_EAISOCKTYPE;
default: return uv_translate_sys_error(eai_errno); default: return uv_translate_sys_error(eai_errno);
} }
} }
/* getaddrinfo worker thread implementation */ /* getaddrinfo worker thread implementation */
static DWORD WINAPI getaddrinfo_thread_proc(void* parameter) { static DWORD WINAPI getaddrinfo_thread_proc(void* parameter) {
uv_getaddrinfo_t* handle = (uv_getaddrinfo_t*)parameter; uv_getaddrinfo_t* handle = (uv_getaddrinfo_t*) parameter;
uv_loop_t* loop = handle->loop;
int ret; int ret;
assert(handle != NULL); assert(handle != NULL);
if (handle != NULL) { if (handle != NULL) {
/* call OS function on this thread */ /* call OS function on this thread */
ret = GetAddrInfoW(handle->node, handle->service, handle->hints, &handle->res); ret = GetAddrInfoW(handle->node,
handle->service,
handle->hints,
&handle->res);
handle->retcode = ret; handle->retcode = ret;
/* post getaddrinfo completed */ /* post getaddrinfo completed */
POST_COMPLETION_FOR_REQ(&handle->getadddrinfo_req); POST_COMPLETION_FOR_REQ(loop, &handle->getadddrinfo_req);
} }
return 0; return 0;
@ -104,7 +108,8 @@ static DWORD WINAPI getaddrinfo_thread_proc(void* parameter) {
* and copy all structs and referenced strings into the one block. * and copy all structs and referenced strings into the one block.
* Each size calculation is adjusted to avoid unaligned pointers. * Each size calculation is adjusted to avoid unaligned pointers.
*/ */
void uv_process_getaddrinfo_req(uv_getaddrinfo_t* handle, uv_req_t* req) { void uv_process_getaddrinfo_req(uv_loop_t* loop, uv_getaddrinfo_t* handle,
uv_req_t* req) {
int addrinfo_len = 0; int addrinfo_len = 0;
int name_len = 0; int name_len = 0;
size_t addrinfo_struct_len = ALIGNED_SIZE(sizeof(struct addrinfo)); size_t addrinfo_struct_len = ALIGNED_SIZE(sizeof(struct addrinfo));
@ -126,7 +131,8 @@ void uv_process_getaddrinfo_req(uv_getaddrinfo_t* handle, uv_req_t* req) {
/* first calculate required length */ /* first calculate required length */
addrinfow_ptr = handle->res; addrinfow_ptr = handle->res;
while (addrinfow_ptr != NULL) { while (addrinfow_ptr != NULL) {
addrinfo_len += addrinfo_struct_len + ALIGNED_SIZE(addrinfow_ptr->ai_addrlen); addrinfo_len += addrinfo_struct_len +
ALIGNED_SIZE(addrinfow_ptr->ai_addrlen);
if (addrinfow_ptr->ai_canonname != NULL) { if (addrinfow_ptr->ai_canonname != NULL) {
name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, -1, NULL, 0); name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, -1, NULL, 0);
if (name_len == 0) { if (name_len == 0) {
@ -163,7 +169,8 @@ void uv_process_getaddrinfo_req(uv_getaddrinfo_t* handle, uv_req_t* req) {
/* copy sockaddr */ /* copy sockaddr */
if (addrinfo_ptr->ai_addrlen > 0) { if (addrinfo_ptr->ai_addrlen > 0) {
assert(cur_ptr + addrinfo_ptr->ai_addrlen <= alloc_ptr + addrinfo_len); assert(cur_ptr + addrinfo_ptr->ai_addrlen <=
alloc_ptr + addrinfo_len);
memcpy(cur_ptr, addrinfow_ptr->ai_addr, addrinfo_ptr->ai_addrlen); memcpy(cur_ptr, addrinfow_ptr->ai_addr, addrinfo_ptr->ai_addrlen);
addrinfo_ptr->ai_addr = (struct sockaddr*)cur_ptr; addrinfo_ptr->ai_addr = (struct sockaddr*)cur_ptr;
cur_ptr += ALIGNED_SIZE(addrinfo_ptr->ai_addrlen); cur_ptr += ALIGNED_SIZE(addrinfo_ptr->ai_addrlen);
@ -171,10 +178,16 @@ void uv_process_getaddrinfo_req(uv_getaddrinfo_t* handle, uv_req_t* req) {
/* convert canonical name to UTF-8 */ /* convert canonical name to UTF-8 */
if (addrinfow_ptr->ai_canonname != NULL) { if (addrinfow_ptr->ai_canonname != NULL) {
name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, -1, NULL, 0); name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname,
-1,
NULL,
0);
assert(name_len > 0); assert(name_len > 0);
assert(cur_ptr + name_len <= alloc_ptr + addrinfo_len); assert(cur_ptr + name_len <= alloc_ptr + addrinfo_len);
name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, -1, cur_ptr, name_len); name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname,
-1,
cur_ptr,
name_len);
assert(name_len > 0); assert(name_len > 0);
addrinfo_ptr->ai_canonname = cur_ptr; addrinfo_ptr->ai_canonname = cur_ptr;
cur_ptr += ALIGNED_SIZE(name_len); cur_ptr += ALIGNED_SIZE(name_len);
@ -208,7 +221,7 @@ complete:
free(alloc_ptr); free(alloc_ptr);
} }
uv_unref(); uv_unref(loop);
} }
@ -216,7 +229,8 @@ complete:
* Entry point for getaddrinfo * Entry point for getaddrinfo
* we convert the UTF-8 strings to UNICODE * we convert the UTF-8 strings to UNICODE
* and save the UNICODE string pointers in the handle * and save the UNICODE string pointers in the handle
* We also copy hints so that caller does not need to keep memory until the callback. * We also copy hints so that caller does not need to keep memory until the
* callback.
* return UV_OK if a callback will be made * return UV_OK if a callback will be made
* return error code if validation fails * return error code if validation fails
* *
@ -224,7 +238,8 @@ complete:
* and copy all structs and referenced strings into the one block. * and copy all structs and referenced strings into the one block.
* Each size calculation is adjusted to avoid unaligned pointers. * Each size calculation is adjusted to avoid unaligned pointers.
*/ */
int uv_getaddrinfo(uv_getaddrinfo_t* handle, int uv_getaddrinfo(uv_loop_t* loop,
uv_getaddrinfo_t* handle,
uv_getaddrinfo_cb getaddrinfo_cb, uv_getaddrinfo_cb getaddrinfo_cb,
const char* node, const char* node,
const char* service, const char* service,
@ -236,27 +251,29 @@ int uv_getaddrinfo(uv_getaddrinfo_t* handle,
if (handle == NULL || getaddrinfo_cb == NULL || if (handle == NULL || getaddrinfo_cb == NULL ||
(node == NULL && service == NULL)) { (node == NULL && service == NULL)) {
uv_set_sys_error(WSAEINVAL); uv_set_sys_error(loop, WSAEINVAL);
goto error; goto error;
} }
handle->getaddrinfo_cb = getaddrinfo_cb; handle->getaddrinfo_cb = getaddrinfo_cb;
handle->res = NULL; handle->res = NULL;
handle->type = UV_GETADDRINFO; handle->type = UV_GETADDRINFO;
handle->loop = loop;
/* calculate required memory size for all input values */ /* calculate required memory size for all input values */
if (node != NULL) { if (node != NULL) {
nodesize = ALIGNED_SIZE(uv_utf8_to_utf16(node, NULL, 0) * sizeof(wchar_t)); nodesize = ALIGNED_SIZE(uv_utf8_to_utf16(node, NULL, 0) * sizeof(wchar_t));
if (nodesize == 0) { if (nodesize == 0) {
uv_set_sys_error(GetLastError()); uv_set_sys_error(loop, GetLastError());
goto error; goto error;
} }
} }
if (service != NULL) { if (service != NULL) {
servicesize = ALIGNED_SIZE(uv_utf8_to_utf16(service, NULL, 0) * sizeof(wchar_t)); servicesize = ALIGNED_SIZE(uv_utf8_to_utf16(service, NULL, 0) *
sizeof(wchar_t));
if (servicesize == 0) { if (servicesize == 0) {
uv_set_sys_error(GetLastError()); uv_set_sys_error(loop, GetLastError());
goto error; goto error;
} }
} }
@ -267,18 +284,21 @@ int uv_getaddrinfo(uv_getaddrinfo_t* handle,
/* allocate memory for inputs, and partition it as needed */ /* allocate memory for inputs, and partition it as needed */
alloc_ptr = (char*)malloc(nodesize + servicesize + hintssize); alloc_ptr = (char*)malloc(nodesize + servicesize + hintssize);
if (!alloc_ptr) { if (!alloc_ptr) {
uv_set_sys_error(WSAENOBUFS); uv_set_sys_error(loop, WSAENOBUFS);
goto error; goto error;
} }
/* save alloc_ptr now so we can free if error */ /* save alloc_ptr now so we can free if error */
handle->alloc = (void*)alloc_ptr; handle->alloc = (void*)alloc_ptr;
/* convert node string to UTF16 into allocated memory and save pointer in handle */ /* convert node string to UTF16 into allocated memory and save pointer in */
/* handle */
if (node != NULL) { if (node != NULL) {
handle->node = (wchar_t*)alloc_ptr; handle->node = (wchar_t*)alloc_ptr;
if (uv_utf8_to_utf16(node, (wchar_t*)alloc_ptr, nodesize / sizeof(wchar_t)) == 0) { if (uv_utf8_to_utf16(node,
uv_set_sys_error(GetLastError()); (wchar_t*) alloc_ptr,
nodesize / sizeof(wchar_t)) == 0) {
uv_set_sys_error(loop, GetLastError());
goto error; goto error;
} }
alloc_ptr += nodesize; alloc_ptr += nodesize;
@ -286,11 +306,14 @@ int uv_getaddrinfo(uv_getaddrinfo_t* handle,
handle->node = NULL; handle->node = NULL;
} }
/* convert service string to UTF16 into allocated memory and save pointer in handle */ /* convert service string to UTF16 into allocated memory and save pointer */
/* in handle */
if (service != NULL) { if (service != NULL) {
handle->service = (wchar_t*)alloc_ptr; handle->service = (wchar_t*)alloc_ptr;
if (uv_utf8_to_utf16(service, (wchar_t*)alloc_ptr, servicesize / sizeof(wchar_t)) == 0) { if (uv_utf8_to_utf16(service,
uv_set_sys_error(GetLastError()); (wchar_t*) alloc_ptr,
servicesize / sizeof(wchar_t)) == 0) {
uv_set_sys_error(loop, GetLastError());
goto error; goto error;
} }
alloc_ptr += servicesize; alloc_ptr += servicesize;
@ -314,17 +337,19 @@ int uv_getaddrinfo(uv_getaddrinfo_t* handle,
} }
/* init request for Post handling */ /* init request for Post handling */
uv_req_init(&handle->getadddrinfo_req); uv_req_init(loop, &handle->getadddrinfo_req);
handle->getadddrinfo_req.data = handle; handle->getadddrinfo_req.data = handle;
handle->getadddrinfo_req.type = UV_GETADDRINFO_REQ; handle->getadddrinfo_req.type = UV_GETADDRINFO_REQ;
/* Ask thread to run. Treat this as a long operation */ /* Ask thread to run. Treat this as a long operation */
if (QueueUserWorkItem(&getaddrinfo_thread_proc, handle, WT_EXECUTELONGFUNCTION) == 0) { if (QueueUserWorkItem(&getaddrinfo_thread_proc,
uv_set_sys_error(GetLastError()); handle,
WT_EXECUTELONGFUNCTION) == 0) {
uv_set_sys_error(loop, GetLastError());
goto error; goto error;
} }
uv_ref(); uv_ref(loop);
return 0; return 0;

56
deps/uv/src/win/handle.c

@ -40,15 +40,17 @@ int uv_is_active(uv_handle_t* handle) {
int uv_getsockname(uv_handle_t* handle, struct sockaddr* name, int* namelen) { int uv_getsockname(uv_handle_t* handle, struct sockaddr* name, int* namelen) {
uv_loop_t* loop = handle->loop;
switch (handle->type) { switch (handle->type) {
case UV_TCP: case UV_TCP:
return uv_tcp_getsockname((uv_tcp_t*) handle, name, namelen); return uv_tcp_getsockname(loop, (uv_tcp_t*) handle, name, namelen);
case UV_UDP: case UV_UDP:
return uv_udp_getsockname((uv_udp_t*) handle, name, namelen); return uv_udp_getsockname(loop, (uv_udp_t*) handle, name, namelen);
default: default:
uv_set_sys_error(WSAENOTSOCK); uv_set_sys_error(loop, WSAENOTSOCK);
return -1; return -1;
} }
} }
@ -60,6 +62,8 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
uv_udp_t* udp; uv_udp_t* udp;
uv_process_t* process; uv_process_t* process;
uv_loop_t* loop = handle->loop;
if (handle->flags & UV_HANDLE_CLOSING) { if (handle->flags & UV_HANDLE_CLOSING) {
return; return;
} }
@ -80,7 +84,7 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
tcp->flags &= ~(UV_HANDLE_READING | UV_HANDLE_LISTENING); tcp->flags &= ~(UV_HANDLE_READING | UV_HANDLE_LISTENING);
closesocket(tcp->socket); closesocket(tcp->socket);
if (tcp->reqs_pending == 0) { if (tcp->reqs_pending == 0) {
uv_want_endgame(handle); uv_want_endgame(loop, handle);
} }
return; return;
@ -89,7 +93,7 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
pipe->flags &= ~(UV_HANDLE_READING | UV_HANDLE_LISTENING); pipe->flags &= ~(UV_HANDLE_READING | UV_HANDLE_LISTENING);
close_pipe(pipe, NULL, NULL); close_pipe(pipe, NULL, NULL);
if (pipe->reqs_pending == 0) { if (pipe->reqs_pending == 0) {
uv_want_endgame(handle); uv_want_endgame(loop, handle);
} }
return; return;
@ -98,39 +102,39 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
uv_udp_recv_stop(udp); uv_udp_recv_stop(udp);
closesocket(udp->socket); closesocket(udp->socket);
if (udp->reqs_pending == 0) { if (udp->reqs_pending == 0) {
uv_want_endgame(handle); uv_want_endgame(loop, handle);
} }
return; return;
case UV_TIMER: case UV_TIMER:
uv_timer_stop((uv_timer_t*)handle); uv_timer_stop((uv_timer_t*)handle);
uv_want_endgame(handle); uv_want_endgame(loop, handle);
return; return;
case UV_PREPARE: case UV_PREPARE:
uv_prepare_stop((uv_prepare_t*)handle); uv_prepare_stop((uv_prepare_t*)handle);
uv_want_endgame(handle); uv_want_endgame(loop, handle);
return; return;
case UV_CHECK: case UV_CHECK:
uv_check_stop((uv_check_t*)handle); uv_check_stop((uv_check_t*)handle);
uv_want_endgame(handle); uv_want_endgame(loop, handle);
return; return;
case UV_IDLE: case UV_IDLE:
uv_idle_stop((uv_idle_t*)handle); uv_idle_stop((uv_idle_t*)handle);
uv_want_endgame(handle); uv_want_endgame(loop, handle);
return; return;
case UV_ASYNC: case UV_ASYNC:
if (!((uv_async_t*)handle)->async_sent) { if (!((uv_async_t*)handle)->async_sent) {
uv_want_endgame(handle); uv_want_endgame(loop, handle);
} }
return; return;
case UV_PROCESS: case UV_PROCESS:
process = (uv_process_t*)handle; process = (uv_process_t*)handle;
uv_process_close(process); uv_process_close(loop, process);
return; return;
default: default:
@ -140,54 +144,54 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
} }
void uv_want_endgame(uv_handle_t* handle) { void uv_want_endgame(uv_loop_t* loop, uv_handle_t* handle) {
if (!(handle->flags & UV_HANDLE_ENDGAME_QUEUED)) { if (!(handle->flags & UV_HANDLE_ENDGAME_QUEUED)) {
handle->flags |= UV_HANDLE_ENDGAME_QUEUED; handle->flags |= UV_HANDLE_ENDGAME_QUEUED;
handle->endgame_next = LOOP->endgame_handles; handle->endgame_next = loop->endgame_handles;
LOOP->endgame_handles = handle; loop->endgame_handles = handle;
} }
} }
void uv_process_endgames() { void uv_process_endgames(uv_loop_t* loop) {
uv_handle_t* handle; uv_handle_t* handle;
while (LOOP->endgame_handles) { while (loop->endgame_handles) {
handle = LOOP->endgame_handles; handle = loop->endgame_handles;
LOOP->endgame_handles = handle->endgame_next; loop->endgame_handles = handle->endgame_next;
handle->flags &= ~UV_HANDLE_ENDGAME_QUEUED; handle->flags &= ~UV_HANDLE_ENDGAME_QUEUED;
switch (handle->type) { switch (handle->type) {
case UV_TCP: case UV_TCP:
uv_tcp_endgame((uv_tcp_t*)handle); uv_tcp_endgame(loop, (uv_tcp_t*) handle);
break; break;
case UV_NAMED_PIPE: case UV_NAMED_PIPE:
uv_pipe_endgame((uv_pipe_t*)handle); uv_pipe_endgame(loop, (uv_pipe_t*) handle);
break; break;
case UV_UDP: case UV_UDP:
uv_udp_endgame((uv_udp_t*) handle); uv_udp_endgame(loop, (uv_udp_t*) handle);
break; break;
case UV_TIMER: case UV_TIMER:
uv_timer_endgame((uv_timer_t*)handle); uv_timer_endgame(loop, (uv_timer_t*) handle);
break; break;
case UV_PREPARE: case UV_PREPARE:
case UV_CHECK: case UV_CHECK:
case UV_IDLE: case UV_IDLE:
uv_loop_watcher_endgame(handle); uv_loop_watcher_endgame(loop, handle);
break; break;
case UV_ASYNC: case UV_ASYNC:
uv_async_endgame((uv_async_t*)handle); uv_async_endgame(loop, (uv_async_t*) handle);
break; break;
case UV_PROCESS: case UV_PROCESS:
uv_process_endgame((uv_process_t*)handle); uv_process_endgame(loop, (uv_process_t*) handle);
break; break;
default: default:

166
deps/uv/src/win/internal.h

@ -33,55 +33,10 @@
/* /*
* Timers * Timers
*/ */
RB_HEAD(uv_timer_tree_s, uv_timer_s); void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle);
void uv_timer_endgame(uv_timer_t* handle); DWORD uv_get_poll_timeout(uv_loop_t* loop);
void uv_process_timers(uv_loop_t* loop);
DWORD uv_get_poll_timeout();
void uv_process_timers();
/*
* Core
*/
/* Loop state struct. We don't support multiplicity right now, but this */
/* should help when we get to that. */
typedef struct uv_loop_s {
/* The loop's I/O completion port */
HANDLE iocp;
/* Reference count that keeps the event loop alive */
int refs;
/* The current time according to the event loop. in msecs. */
int64_t time;
/* Tail of a single-linked circular queue of pending reqs. If the queue */
/* is empty, tail_ is NULL. If there is only one item, */
/* tail_->next_req == tail_ */
uv_req_t* pending_reqs_tail;
/* Head of a single-linked list of closed handles */
uv_handle_t* endgame_handles;
/* The head of the timers tree */
struct uv_timer_tree_s timers;
/* Lists of active loop (prepare / check / idle) watchers */
uv_prepare_t* prepare_handles;
uv_check_t* check_handles;
uv_idle_t* idle_handles;
/* This pointer will refer to the prepare/check/idle handle whose */
/* callback is scheduled to be called next. This is needed to allow */
/* safe removal from one of the lists above while that list being */
/* iterated over. */
uv_prepare_t* next_prepare_handle;
uv_check_t* next_check_handle;
uv_idle_t* next_idle_handle;
/* Last error code */
uv_err_t last_error;
/* Error string most recently returned by uv_strerror() */
char* err_str;
} uv_loop_t;
extern uv_loop_t uv_main_loop_;
#define LOOP (&uv_main_loop_)
/* /*
@ -110,8 +65,8 @@ extern uv_loop_t uv_main_loop_;
#define UV_HANDLE_SYNC_BYPASS_IOCP 0x40000 #define UV_HANDLE_SYNC_BYPASS_IOCP 0x40000
#define UV_HANDLE_ZERO_READ 0x80000 #define UV_HANDLE_ZERO_READ 0x80000
void uv_want_endgame(uv_handle_t* handle); void uv_want_endgame(uv_loop_t* loop, uv_handle_t* handle);
void uv_process_endgames(); void uv_process_endgames(uv_loop_t* loop);
#define DECREASE_PENDING_REQ_COUNT(handle) \ #define DECREASE_PENDING_REQ_COUNT(handle) \
do { \ do { \
@ -120,7 +75,7 @@ void uv_process_endgames();
\ \
if (handle->flags & UV_HANDLE_CLOSING && \ if (handle->flags & UV_HANDLE_CLOSING && \
handle->reqs_pending == 0) { \ handle->reqs_pending == 0) { \
uv_want_endgame((uv_handle_t*)handle); \ uv_want_endgame(loop, (uv_handle_t*)handle); \
} \ } \
} while (0) } while (0)
@ -134,15 +89,15 @@ void uv_process_endgames();
/* /*
* Requests * Requests
*/ */
void uv_req_init(uv_req_t* req); void uv_req_init(uv_loop_t* loop, uv_req_t* req);
uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped); uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped);
void uv_insert_pending_req(uv_req_t* req); void uv_insert_pending_req(uv_loop_t* loop, uv_req_t* req);
void uv_process_reqs(); void uv_process_reqs(uv_loop_t* loop);
#define POST_COMPLETION_FOR_REQ(req) \ #define POST_COMPLETION_FOR_REQ(loop, req) \
if (!PostQueuedCompletionStatus(LOOP->iocp, \ if (!PostQueuedCompletionStatus((loop)->iocp, \
0, \ 0, \
0, \ 0, \
&((req)->overlapped))) { \ &((req)->overlapped))) { \
@ -153,7 +108,7 @@ void uv_process_reqs();
/* /*
* Streams * Streams
*/ */
void uv_stream_init(uv_stream_t* handle); void uv_stream_init(uv_loop_t* loop, uv_stream_t* handle);
void uv_connection_init(uv_stream_t* handle); void uv_connection_init(uv_stream_t* handle);
size_t uv_count_bufs(uv_buf_t bufs[], int count); size_t uv_count_bufs(uv_buf_t bufs[], int count);
@ -166,75 +121,89 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb);
int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client); int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client);
int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb, int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb,
uv_read_cb read_cb); uv_read_cb read_cb);
int uv_tcp_write(uv_write_t* req, uv_tcp_t* handle, uv_buf_t bufs[], int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle,
int bufcnt, uv_write_cb cb); uv_buf_t bufs[], int bufcnt, uv_write_cb cb);
int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name, int* namelen); int uv_tcp_getsockname(uv_loop_t* loop, uv_tcp_t* handle,
struct sockaddr* name, int* namelen);
void uv_process_tcp_read_req(uv_tcp_t* handle, uv_req_t* req); void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, uv_req_t* req);
void uv_process_tcp_write_req(uv_tcp_t* handle, uv_write_t* req); void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
void uv_process_tcp_accept_req(uv_tcp_t* handle, uv_req_t* req); uv_write_t* req);
void uv_process_tcp_connect_req(uv_tcp_t* handle, uv_connect_t* req); void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle,
uv_req_t* req);
void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
uv_connect_t* req);
void uv_tcp_endgame(uv_tcp_t* handle); void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle);
/* /*
* UDP * UDP
*/ */
int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, int* namelen); int uv_udp_getsockname(uv_loop_t* loop, uv_udp_t* handle,
struct sockaddr* name, int* namelen);
void uv_process_udp_recv_req(uv_udp_t* handle, uv_req_t* req); void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, uv_req_t* req);
void uv_process_udp_send_req(uv_udp_t* handle, uv_udp_send_t* req); void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle,
uv_udp_send_t* req);
void uv_udp_endgame(uv_udp_t* handle); void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle);
/* /*
* Pipes * Pipes
*/ */
int uv_pipe_init_with_handle(uv_pipe_t* handle, HANDLE pipeHandle); int uv_pipe_init_with_handle(uv_loop_t* loop, uv_pipe_t* handle,
int uv_stdio_pipe_server(uv_pipe_t* handle, DWORD access, char* name, size_t nameSize); HANDLE pipeHandle);
int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
char* name, size_t nameSize);
void close_pipe(uv_pipe_t* handle, int* status, uv_err_t* err); void close_pipe(uv_pipe_t* handle, int* status, uv_err_t* err);
void uv_pipe_endgame(uv_pipe_t* handle); void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle);
int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb); int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
int uv_pipe_accept(uv_pipe_t* server, uv_pipe_t* client); int uv_pipe_accept(uv_pipe_t* server, uv_pipe_t* client);
int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb, int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb,
uv_read_cb read_cb); uv_read_cb read_cb);
int uv_pipe_write(uv_write_t* req, uv_pipe_t* handle, uv_buf_t bufs[], int uv_pipe_write(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle,
int bufcnt, uv_write_cb cb); uv_buf_t bufs[], int bufcnt, uv_write_cb cb);
void uv_process_pipe_read_req(uv_pipe_t* handle, uv_req_t* req); void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
void uv_process_pipe_write_req(uv_pipe_t* handle, uv_write_t* req); uv_req_t* req);
void uv_process_pipe_accept_req(uv_pipe_t* handle, uv_req_t* raw_req); void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
void uv_process_pipe_connect_req(uv_pipe_t* handle, uv_connect_t* req); uv_write_t* req);
void uv_process_pipe_shutdown_req(uv_pipe_t* handle, uv_shutdown_t* req); void uv_process_pipe_accept_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_req_t* raw_req);
void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_connect_t* req);
void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_shutdown_t* req);
/* /*
* Loop watchers * Loop watchers
*/ */
void uv_loop_watcher_endgame(uv_handle_t* handle); void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle);
void uv_prepare_invoke(); void uv_prepare_invoke(uv_loop_t* loop);
void uv_check_invoke(); void uv_check_invoke(uv_loop_t* loop);
void uv_idle_invoke(); void uv_idle_invoke(uv_loop_t* loop);
/* /*
* Async watcher * Async watcher
*/ */
void uv_async_endgame(uv_async_t* handle); void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle);
void uv_process_async_wakeup_req(uv_async_t* handle, uv_req_t* req); void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle,
uv_req_t* req);
/* /*
* Spawn * Spawn
*/ */
void uv_process_proc_exit(uv_process_t* handle); void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle);
void uv_process_proc_close(uv_process_t* handle); void uv_process_proc_close(uv_loop_t* loop, uv_process_t* handle);
void uv_process_close(uv_process_t* handle); void uv_process_close(uv_loop_t* loop, uv_process_t* handle);
void uv_process_endgame(uv_process_t* handle); void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle);
/* /*
@ -242,26 +211,29 @@ void uv_process_endgame(uv_process_t* handle);
*/ */
typedef struct uv_ares_action_s uv_ares_action_t; typedef struct uv_ares_action_s uv_ares_action_t;
void uv_process_ares_event_req(uv_ares_action_t* handle, uv_req_t* req); void uv_process_ares_event_req(uv_loop_t* loop, uv_ares_action_t* handle,
void uv_process_ares_cleanup_req(uv_ares_task_t* handle, uv_req_t* req); uv_req_t* req);
void uv_process_ares_cleanup_req(uv_loop_t* loop, uv_ares_task_t* handle,
uv_req_t* req);
/* /*
* Getaddrinfo * Getaddrinfo
*/ */
void uv_process_getaddrinfo_req(uv_getaddrinfo_t* handle, uv_req_t* req); void uv_process_getaddrinfo_req(uv_loop_t* loop, uv_getaddrinfo_t* handle,
uv_req_t* req);
/* /*
* FS * FS
*/ */
void uv_fs_init(); void uv_fs_init();
void uv_process_fs_req(uv_fs_t* req); void uv_process_fs_req(uv_loop_t* loop, uv_fs_t* req);
/* /*
* Threadpool * Threadpool
*/ */
void uv_process_work_req(uv_work_t* req); void uv_process_work_req(uv_loop_t* loop, uv_work_t* req);
/* /*
@ -273,8 +245,8 @@ void uv_fatal_error(const int errorno, const char* syscall);
uv_err_code uv_translate_sys_error(int sys_errno); uv_err_code uv_translate_sys_error(int sys_errno);
uv_err_t uv_new_sys_error(int sys_errno); uv_err_t uv_new_sys_error(int sys_errno);
void uv_set_sys_error(int sys_errno); void uv_set_sys_error(uv_loop_t* loop, int sys_errno);
void uv_set_error(uv_err_code code, int sys_errno); void uv_set_error(uv_loop_t* loop, uv_err_code code, int sys_errno);
#define SET_REQ_STATUS(req, status) \ #define SET_REQ_STATUS(req, status) \
(req)->overlapped.Internal = (ULONG_PTR) (status) (req)->overlapped.Internal = (ULONG_PTR) (status)

38
deps/uv/src/win/loop-watcher.c

@ -26,7 +26,7 @@
#include "internal.h" #include "internal.h"
void uv_loop_watcher_endgame(uv_handle_t* handle) { void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
if (handle->flags & UV_HANDLE_CLOSING) { if (handle->flags & UV_HANDLE_CLOSING) {
assert(!(handle->flags & UV_HANDLE_CLOSED)); assert(!(handle->flags & UV_HANDLE_CLOSED));
handle->flags |= UV_HANDLE_CLOSED; handle->flags |= UV_HANDLE_CLOSED;
@ -35,26 +35,28 @@ void uv_loop_watcher_endgame(uv_handle_t* handle) {
handle->close_cb(handle); handle->close_cb(handle);
} }
uv_unref(); uv_unref(loop);
} }
} }
#define UV_LOOP_WATCHER_DEFINE(name, NAME) \ #define UV_LOOP_WATCHER_DEFINE(name, NAME) \
int uv_##name##_init(uv_##name##_t* handle) { \ int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) { \
handle->type = UV_##NAME; \ handle->type = UV_##NAME; \
handle->loop = loop; \
handle->flags = 0; \ handle->flags = 0; \
\ \
uv_ref(); \ uv_ref(loop); \
\ \
uv_counters()->handle_init++; \ loop->counters.handle_init++; \
uv_counters()->prepare_init++; \ loop->counters.##name##_init++; \
\ \
return 0; \ return 0; \
} \ } \
\ \
\ \
int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) { \ int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) { \
uv_loop_t* loop = handle->loop; \
uv_##name##_t* old_head; \ uv_##name##_t* old_head; \
\ \
assert(handle->type == UV_##NAME); \ assert(handle->type == UV_##NAME); \
@ -62,7 +64,7 @@ void uv_loop_watcher_endgame(uv_handle_t* handle) {
if (handle->flags & UV_HANDLE_ACTIVE) \ if (handle->flags & UV_HANDLE_ACTIVE) \
return 0; \ return 0; \
\ \
old_head = LOOP->name##_handles; \ old_head = loop->name##_handles; \
\ \
handle->name##_next = old_head; \ handle->name##_next = old_head; \
handle->name##_prev = NULL; \ handle->name##_prev = NULL; \
@ -71,7 +73,7 @@ void uv_loop_watcher_endgame(uv_handle_t* handle) {
old_head->name##_prev = handle; \ old_head->name##_prev = handle; \
} \ } \
\ \
LOOP->name##_handles = handle; \ loop->name##_handles = handle; \
\ \
handle->name##_cb = cb; \ handle->name##_cb = cb; \
handle->flags |= UV_HANDLE_ACTIVE; \ handle->flags |= UV_HANDLE_ACTIVE; \
@ -81,19 +83,21 @@ void uv_loop_watcher_endgame(uv_handle_t* handle) {
\ \
\ \
int uv_##name##_stop(uv_##name##_t* handle) { \ int uv_##name##_stop(uv_##name##_t* handle) { \
uv_loop_t* loop = handle->loop; \
\
assert(handle->type == UV_##NAME); \ assert(handle->type == UV_##NAME); \
\ \
if (!(handle->flags & UV_HANDLE_ACTIVE)) \ if (!(handle->flags & UV_HANDLE_ACTIVE)) \
return 0; \ return 0; \
\ \
/* Update loop head if needed */ \ /* Update loop head if needed */ \
if (LOOP->name##_handles == handle) { \ if (loop->name##_handles == handle) { \
LOOP->name##_handles = handle->name##_next; \ loop->name##_handles = handle->name##_next; \
} \ } \
\ \
/* Update the iterator-next pointer of needed */ \ /* Update the iterator-next pointer of needed */ \
if (LOOP->next_##name##_handle == handle) { \ if (loop->next_##name##_handle == handle) { \
LOOP->next_##name##_handle = handle->name##_next; \ loop->next_##name##_handle = handle->name##_next; \
} \ } \
\ \
if (handle->name##_prev) { \ if (handle->name##_prev) { \
@ -109,14 +113,14 @@ void uv_loop_watcher_endgame(uv_handle_t* handle) {
} \ } \
\ \
\ \
void uv_##name##_invoke() { \ void uv_##name##_invoke(uv_loop_t* loop) { \
uv_##name##_t* handle; \ uv_##name##_t* handle; \
\ \
LOOP->next_##name##_handle = LOOP->name##_handles; \ (loop)->next_##name##_handle = (loop)->name##_handles; \
\ \
while (LOOP->next_##name##_handle != NULL) { \ while ((loop)->next_##name##_handle != NULL) { \
handle = LOOP->next_##name##_handle; \ handle = (loop)->next_##name##_handle; \
LOOP->next_##name##_handle = handle->name##_next; \ (loop)->next_##name##_handle = handle->name##_next; \
\ \
handle->name##_cb(handle, 0); \ handle->name##_cb(handle, 0); \
} \ } \

248
deps/uv/src/win/pipe.c

@ -51,22 +51,23 @@ static void uv_unique_pipe_name(char* ptr, char* name, size_t size) {
} }
int uv_pipe_init(uv_pipe_t* handle) { int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle) {
uv_stream_init((uv_stream_t*)handle); uv_stream_init(loop, (uv_stream_t*)handle);
handle->type = UV_NAMED_PIPE; handle->type = UV_NAMED_PIPE;
handle->reqs_pending = 0; handle->reqs_pending = 0;
handle->handle = INVALID_HANDLE_VALUE; handle->handle = INVALID_HANDLE_VALUE;
handle->name = NULL; handle->name = NULL;
uv_counters()->pipe_init++; loop->counters.pipe_init++;
return 0; return 0;
} }
int uv_pipe_init_with_handle(uv_pipe_t* handle, HANDLE pipeHandle) { int uv_pipe_init_with_handle(uv_loop_t* loop, uv_pipe_t* handle,
int err = uv_pipe_init(handle); HANDLE pipeHandle) {
int err = uv_pipe_init(loop, handle);
if (!err) { if (!err) {
/* /*
@ -88,7 +89,8 @@ static void uv_pipe_connection_init(uv_pipe_t* handle) {
} }
int uv_stdio_pipe_server(uv_pipe_t* handle, DWORD access, char* name, size_t nameSize) { int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
char* name, size_t nameSize) {
HANDLE pipeHandle; HANDLE pipeHandle;
int errno; int errno;
int err; int err;
@ -98,13 +100,9 @@ int uv_stdio_pipe_server(uv_pipe_t* handle, DWORD access, char* name, size_t nam
uv_unique_pipe_name(ptr, name, nameSize); uv_unique_pipe_name(ptr, name, nameSize);
pipeHandle = CreateNamedPipeA(name, pipeHandle = CreateNamedPipeA(name,
access | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE, access | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 65536, 65536, 0,
1, NULL);
65536,
65536,
0,
NULL);
if (pipeHandle != INVALID_HANDLE_VALUE) { if (pipeHandle != INVALID_HANDLE_VALUE) {
/* No name collisions. We're done. */ /* No name collisions. We're done. */
@ -113,7 +111,7 @@ int uv_stdio_pipe_server(uv_pipe_t* handle, DWORD access, char* name, size_t nam
errno = GetLastError(); errno = GetLastError();
if (errno != ERROR_PIPE_BUSY && errno != ERROR_ACCESS_DENIED) { if (errno != ERROR_PIPE_BUSY && errno != ERROR_ACCESS_DENIED) {
uv_set_sys_error(errno); uv_set_sys_error(loop, errno);
err = -1; err = -1;
goto done; goto done;
} }
@ -123,10 +121,10 @@ int uv_stdio_pipe_server(uv_pipe_t* handle, DWORD access, char* name, size_t nam
} }
if (CreateIoCompletionPort(pipeHandle, if (CreateIoCompletionPort(pipeHandle,
LOOP->iocp, loop->iocp,
(ULONG_PTR)handle, (ULONG_PTR)handle,
0) == NULL) { 0) == NULL) {
uv_set_sys_error(GetLastError()); uv_set_sys_error(loop, GetLastError());
err = -1; err = -1;
goto done; goto done;
} }
@ -145,7 +143,8 @@ done:
} }
static int uv_set_pipe_handle(uv_pipe_t* handle, HANDLE pipeHandle) { static int uv_set_pipe_handle(uv_loop_t* loop, uv_pipe_t* handle,
HANDLE pipeHandle) {
DWORD mode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT; DWORD mode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT;
if (!SetNamedPipeHandleState(pipeHandle, &mode, NULL, NULL)) { if (!SetNamedPipeHandleState(pipeHandle, &mode, NULL, NULL)) {
@ -153,7 +152,7 @@ static int uv_set_pipe_handle(uv_pipe_t* handle, HANDLE pipeHandle) {
} }
if (CreateIoCompletionPort(pipeHandle, if (CreateIoCompletionPort(pipeHandle,
LOOP->iocp, loop->iocp,
(ULONG_PTR)handle, (ULONG_PTR)handle,
0) == NULL) { 0) == NULL) {
return -1; return -1;
@ -165,6 +164,7 @@ static int uv_set_pipe_handle(uv_pipe_t* handle, HANDLE pipeHandle) {
static DWORD WINAPI pipe_shutdown_thread_proc(void* parameter) { static DWORD WINAPI pipe_shutdown_thread_proc(void* parameter) {
int errno; int errno;
uv_loop_t* loop;
uv_pipe_t* handle; uv_pipe_t* handle;
uv_shutdown_t* req; uv_shutdown_t* req;
@ -172,17 +172,19 @@ static DWORD WINAPI pipe_shutdown_thread_proc(void* parameter) {
assert(req); assert(req);
handle = (uv_pipe_t*) req->handle; handle = (uv_pipe_t*) req->handle;
assert(handle); assert(handle);
loop = handle->loop;
assert(loop);
FlushFileBuffers(handle->handle); FlushFileBuffers(handle->handle);
/* Post completed */ /* Post completed */
POST_COMPLETION_FOR_REQ(req); POST_COMPLETION_FOR_REQ(loop, req);
return 0; return 0;
} }
void uv_pipe_endgame(uv_pipe_t* handle) { void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
unsigned int uv_alloced; unsigned int uv_alloced;
DWORD result; DWORD result;
uv_shutdown_t* req; uv_shutdown_t* req;
@ -207,7 +209,7 @@ void uv_pipe_endgame(uv_pipe_t* handle) {
/* Failure */ /* Failure */
handle->flags &= ~UV_HANDLE_SHUTTING; handle->flags &= ~UV_HANDLE_SHUTTING;
if (req->cb) { if (req->cb) {
uv_set_sys_error(pRtlNtStatusToDosError(nt_status)); uv_set_sys_error(loop, pRtlNtStatusToDosError(nt_status));
req->cb(req, -1); req->cb(req, -1);
} }
DECREASE_PENDING_REQ_COUNT(handle); DECREASE_PENDING_REQ_COUNT(handle);
@ -218,7 +220,7 @@ void uv_pipe_endgame(uv_pipe_t* handle) {
handle->flags |= UV_HANDLE_SHUT; handle->flags |= UV_HANDLE_SHUT;
/* Short-circuit, no need to call FlushFileBuffers. */ /* Short-circuit, no need to call FlushFileBuffers. */
uv_insert_pending_req((uv_req_t*) req); uv_insert_pending_req(loop, (uv_req_t*) req);
return; return;
} }
@ -234,7 +236,7 @@ void uv_pipe_endgame(uv_pipe_t* handle) {
/* Failure. */ /* Failure. */
handle->flags &= ~UV_HANDLE_SHUTTING; handle->flags &= ~UV_HANDLE_SHUTTING;
if (req->cb) { if (req->cb) {
uv_set_sys_error(GetLastError()); uv_set_sys_error(loop, GetLastError());
req->cb(req, -1); req->cb(req, -1);
} }
DECREASE_PENDING_REQ_COUNT(handle); DECREASE_PENDING_REQ_COUNT(handle);
@ -259,29 +261,30 @@ void uv_pipe_endgame(uv_pipe_t* handle) {
free(handle); free(handle);
} }
uv_unref(); uv_unref(loop);
} }
} }
/* Creates a pipe server. */ /* Creates a pipe server. */
int uv_pipe_bind(uv_pipe_t* handle, const char* name) { int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
uv_loop_t* loop = handle->loop;
int i, errno, nameSize; int i, errno, nameSize;
uv_pipe_accept_t* req; uv_pipe_accept_t* req;
if (handle->flags & UV_HANDLE_BOUND) { if (handle->flags & UV_HANDLE_BOUND) {
uv_set_sys_error(WSAEINVAL); uv_set_sys_error(loop, WSAEINVAL);
return -1; return -1;
} }
if (!name) { if (!name) {
uv_set_sys_error(WSAEINVAL); uv_set_sys_error(loop, WSAEINVAL);
return -1; return -1;
} }
for (i = 0; i < COUNTOF(handle->accept_reqs); i++) { for (i = 0; i < COUNTOF(handle->accept_reqs); i++) {
req = &handle->accept_reqs[i]; req = &handle->accept_reqs[i];
uv_req_init((uv_req_t*) req); uv_req_init(loop, (uv_req_t*) req);
req->type = UV_ACCEPT; req->type = UV_ACCEPT;
req->data = handle; req->data = handle;
req->pipeHandle = INVALID_HANDLE_VALUE; req->pipeHandle = INVALID_HANDLE_VALUE;
@ -296,7 +299,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
} }
if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(wchar_t))) { if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(wchar_t))) {
uv_set_sys_error(GetLastError()); uv_set_sys_error(loop, GetLastError());
return -1; return -1;
} }
@ -305,28 +308,25 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
* If this fails then there's already a pipe server for the given pipe name. * If this fails then there's already a pipe server for the given pipe name.
*/ */
handle->accept_reqs[0].pipeHandle = CreateNamedPipeW(handle->name, handle->accept_reqs[0].pipeHandle = CreateNamedPipeW(handle->name,
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_UNLIMITED_INSTANCES, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
65536, PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL);
65536,
0,
NULL);
if (handle->accept_reqs[0].pipeHandle == INVALID_HANDLE_VALUE) { if (handle->accept_reqs[0].pipeHandle == INVALID_HANDLE_VALUE) {
errno = GetLastError(); errno = GetLastError();
if (errno == ERROR_ACCESS_DENIED) { if (errno == ERROR_ACCESS_DENIED) {
uv_set_error(UV_EADDRINUSE, errno); uv_set_error(loop, UV_EADDRINUSE, errno);
} else if (errno == ERROR_PATH_NOT_FOUND || errno == ERROR_INVALID_NAME) { } else if (errno == ERROR_PATH_NOT_FOUND || errno == ERROR_INVALID_NAME) {
uv_set_error(UV_EACCESS, errno); uv_set_error(loop, UV_EACCESS, errno);
} else { } else {
uv_set_sys_error(errno); uv_set_sys_error(loop, errno);
} }
goto error; goto error;
} }
if (uv_set_pipe_handle(handle, handle->accept_reqs[0].pipeHandle)) { if (uv_set_pipe_handle(loop, handle, handle->accept_reqs[0].pipeHandle)) {
uv_set_sys_error(GetLastError()); uv_set_sys_error(loop, GetLastError());
goto error; goto error;
} }
@ -354,15 +354,19 @@ error:
static DWORD WINAPI pipe_connect_thread_proc(void* parameter) { static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
HANDLE pipeHandle = INVALID_HANDLE_VALUE; HANDLE pipeHandle = INVALID_HANDLE_VALUE;
int errno; int errno;
uv_loop_t* loop;
uv_pipe_t* handle; uv_pipe_t* handle;
uv_connect_t* req; uv_connect_t* req;
req = (uv_connect_t*)parameter; req = (uv_connect_t*) parameter;
assert(req); assert(req);
handle = (uv_pipe_t*)req->handle; handle = (uv_pipe_t*) req->handle;
assert(handle); assert(handle);
loop = handle->loop;
assert(loop);
/* We're here because CreateFile on a pipe returned ERROR_PIPE_BUSY. We wait for the pipe to become available with WaitNamedPipe. */ /* We're here because CreateFile on a pipe returned ERROR_PIPE_BUSY. */
/* We wait for the pipe to become available with WaitNamedPipe. */
while (WaitNamedPipeW(handle->name, 30000)) { while (WaitNamedPipeW(handle->name, 30000)) {
/* The pipe is now available, try to connect. */ /* The pipe is now available, try to connect. */
pipeHandle = CreateFileW(handle->name, pipeHandle = CreateFileW(handle->name,
@ -380,7 +384,8 @@ static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
SwitchToThread(); SwitchToThread();
} }
if (pipeHandle != INVALID_HANDLE_VALUE && !uv_set_pipe_handle(handle, pipeHandle)) { if (pipeHandle != INVALID_HANDLE_VALUE &&
!uv_set_pipe_handle(loop, handle, pipeHandle)) {
handle->handle = pipeHandle; handle->handle = pipeHandle;
SET_REQ_SUCCESS(req); SET_REQ_SUCCESS(req);
} else { } else {
@ -388,7 +393,7 @@ static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
} }
/* Post completed */ /* Post completed */
POST_COMPLETION_FOR_REQ(req); POST_COMPLETION_FOR_REQ(loop, req);
return 0; return 0;
} }
@ -396,12 +401,13 @@ static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
const char* name, uv_connect_cb cb) { const char* name, uv_connect_cb cb) {
uv_loop_t* loop = handle->loop;
int errno, nameSize; int errno, nameSize;
HANDLE pipeHandle; HANDLE pipeHandle;
handle->handle = INVALID_HANDLE_VALUE; handle->handle = INVALID_HANDLE_VALUE;
uv_req_init((uv_req_t*) req); uv_req_init(loop, (uv_req_t*) req);
req->type = UV_CONNECT; req->type = UV_CONNECT;
req->handle = (uv_stream_t*) handle; req->handle = (uv_stream_t*) handle;
req->cb = cb; req->cb = cb;
@ -429,7 +435,9 @@ int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
if (pipeHandle == INVALID_HANDLE_VALUE) { if (pipeHandle == INVALID_HANDLE_VALUE) {
if (GetLastError() == ERROR_PIPE_BUSY) { if (GetLastError() == ERROR_PIPE_BUSY) {
/* Wait for the server to make a pipe instance available. */ /* Wait for the server to make a pipe instance available. */
if (!QueueUserWorkItem(&pipe_connect_thread_proc, req, WT_EXECUTELONGFUNCTION)) { if (!QueueUserWorkItem(&pipe_connect_thread_proc,
req,
WT_EXECUTELONGFUNCTION)) {
errno = GetLastError(); errno = GetLastError();
goto error; goto error;
} }
@ -443,7 +451,7 @@ int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
goto error; goto error;
} }
if (uv_set_pipe_handle((uv_pipe_t*)req->handle, pipeHandle)) { if (uv_set_pipe_handle(loop, (uv_pipe_t*)req->handle, pipeHandle)) {
errno = GetLastError(); errno = GetLastError();
goto error; goto error;
} }
@ -451,7 +459,7 @@ int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
handle->handle = pipeHandle; handle->handle = pipeHandle;
SET_REQ_SUCCESS(req); SET_REQ_SUCCESS(req);
uv_insert_pending_req((uv_req_t*) req); uv_insert_pending_req(loop, (uv_req_t*) req);
handle->reqs_pending++; handle->reqs_pending++;
return 0; return 0;
@ -464,12 +472,13 @@ error:
if (pipeHandle != INVALID_HANDLE_VALUE) { if (pipeHandle != INVALID_HANDLE_VALUE) {
CloseHandle(pipeHandle); CloseHandle(pipeHandle);
} }
uv_set_sys_error(errno); uv_set_sys_error(loop, errno);
return -1; return -1;
} }
/* Cleans up uv_pipe_t (server or connection) and all resources associated with it */ /* Cleans up uv_pipe_t (server or connection) and all resources associated */
/* with it. */
void close_pipe(uv_pipe_t* handle, int* status, uv_err_t* err) { void close_pipe(uv_pipe_t* handle, int* status, uv_err_t* err) {
int i; int i;
HANDLE pipeHandle; HANDLE pipeHandle;
@ -504,33 +513,30 @@ void close_pipe(uv_pipe_t* handle, int* status, uv_err_t* err) {
} }
static void uv_pipe_queue_accept(uv_pipe_t* handle, uv_pipe_accept_t* req, BOOL firstInstance) { static void uv_pipe_queue_accept(uv_loop_t* loop, uv_pipe_t* handle,
uv_pipe_accept_t* req, BOOL firstInstance) {
assert(handle->flags & UV_HANDLE_LISTENING); assert(handle->flags & UV_HANDLE_LISTENING);
if (!firstInstance) { if (!firstInstance) {
assert(req->pipeHandle == INVALID_HANDLE_VALUE); assert(req->pipeHandle == INVALID_HANDLE_VALUE);
req->pipeHandle = CreateNamedPipeW(handle->name, req->pipeHandle = CreateNamedPipeW(handle->name,
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL);
65536,
65536,
0,
NULL);
if (req->pipeHandle == INVALID_HANDLE_VALUE) { if (req->pipeHandle == INVALID_HANDLE_VALUE) {
SET_REQ_ERROR(req, GetLastError()); SET_REQ_ERROR(req, GetLastError());
uv_insert_pending_req((uv_req_t*) req); uv_insert_pending_req(loop, (uv_req_t*) req);
handle->reqs_pending++; handle->reqs_pending++;
return; return;
} }
if (uv_set_pipe_handle(handle, req->pipeHandle)) { if (uv_set_pipe_handle(loop, handle, req->pipeHandle)) {
CloseHandle(req->pipeHandle); CloseHandle(req->pipeHandle);
req->pipeHandle = INVALID_HANDLE_VALUE; req->pipeHandle = INVALID_HANDLE_VALUE;
SET_REQ_ERROR(req, GetLastError()); SET_REQ_ERROR(req, GetLastError());
uv_insert_pending_req((uv_req_t*) req); uv_insert_pending_req(loop, (uv_req_t*) req);
handle->reqs_pending++; handle->reqs_pending++;
return; return;
} }
@ -541,7 +547,8 @@ static void uv_pipe_queue_accept(uv_pipe_t* handle, uv_pipe_accept_t* req, BOOL
/* Prepare the overlapped structure. */ /* Prepare the overlapped structure. */
memset(&(req->overlapped), 0, sizeof(req->overlapped)); memset(&(req->overlapped), 0, sizeof(req->overlapped));
if (!ConnectNamedPipe(req->pipeHandle, &req->overlapped) && GetLastError() != ERROR_IO_PENDING) { if (!ConnectNamedPipe(req->pipeHandle, &req->overlapped) &&
GetLastError() != ERROR_IO_PENDING) {
if (GetLastError() == ERROR_PIPE_CONNECTED) { if (GetLastError() == ERROR_PIPE_CONNECTED) {
SET_REQ_SUCCESS(req); SET_REQ_SUCCESS(req);
} else { } else {
@ -550,7 +557,7 @@ static void uv_pipe_queue_accept(uv_pipe_t* handle, uv_pipe_accept_t* req, BOOL
/* Make this req pending reporting an error. */ /* Make this req pending reporting an error. */
SET_REQ_ERROR(req, GetLastError()); SET_REQ_ERROR(req, GetLastError());
} }
uv_insert_pending_req((uv_req_t*) req); uv_insert_pending_req(loop, (uv_req_t*) req);
handle->reqs_pending++; handle->reqs_pending++;
return; return;
} }
@ -560,12 +567,14 @@ static void uv_pipe_queue_accept(uv_pipe_t* handle, uv_pipe_accept_t* req, BOOL
int uv_pipe_accept(uv_pipe_t* server, uv_pipe_t* client) { int uv_pipe_accept(uv_pipe_t* server, uv_pipe_t* client) {
/* Find a connection instance that has been connected, but not yet accepted. */ uv_loop_t* loop = server->loop;
/* Find a connection instance that has been connected, but not yet */
/* accepted. */
uv_pipe_accept_t* req = server->pending_accepts; uv_pipe_accept_t* req = server->pending_accepts;
if (!req) { if (!req) {
/* No valid connections found, so we error out. */ /* No valid connections found, so we error out. */
uv_set_sys_error(WSAEWOULDBLOCK); uv_set_sys_error(loop, WSAEWOULDBLOCK);
return -1; return -1;
} }
@ -580,7 +589,7 @@ int uv_pipe_accept(uv_pipe_t* server, uv_pipe_t* client) {
if (!(server->flags & UV_HANDLE_CLOSING) && if (!(server->flags & UV_HANDLE_CLOSING) &&
!(server->flags & UV_HANDLE_GIVEN_OS_HANDLE)) { !(server->flags & UV_HANDLE_GIVEN_OS_HANDLE)) {
uv_pipe_queue_accept(server, req, FALSE); uv_pipe_queue_accept(loop, server, req, FALSE);
} }
return 0; return 0;
@ -589,25 +598,27 @@ int uv_pipe_accept(uv_pipe_t* server, uv_pipe_t* client) {
/* Starts listening for connections for the given pipe. */ /* Starts listening for connections for the given pipe. */
int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) { int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
uv_loop_t* loop = handle->loop;
int i, errno; int i, errno;
uv_pipe_accept_t* req; uv_pipe_accept_t* req;
HANDLE pipeHandle; HANDLE pipeHandle;
if (!(handle->flags & UV_HANDLE_BOUND) && if (!(handle->flags & UV_HANDLE_BOUND) &&
!(handle->flags & UV_HANDLE_GIVEN_OS_HANDLE)) { !(handle->flags & UV_HANDLE_GIVEN_OS_HANDLE)) {
uv_set_error(UV_EINVAL, 0); uv_set_error(loop, UV_EINVAL, 0);
return -1; return -1;
} }
if (handle->flags & UV_HANDLE_LISTENING || if (handle->flags & UV_HANDLE_LISTENING ||
handle->flags & UV_HANDLE_READING) { handle->flags & UV_HANDLE_READING) {
uv_set_error(UV_EALREADY, 0); uv_set_error(loop, UV_EALREADY, 0);
return -1; return -1;
} }
if (!(handle->flags & UV_HANDLE_PIPESERVER) && if (!(handle->flags & UV_HANDLE_PIPESERVER) &&
!(handle->flags & UV_HANDLE_GIVEN_OS_HANDLE)) { !(handle->flags & UV_HANDLE_GIVEN_OS_HANDLE)) {
uv_set_error(UV_ENOTSUP, 0); uv_set_error(loop, UV_ENOTSUP, 0);
return -1; return -1;
} }
@ -619,24 +630,24 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
pipeHandle = handle->handle; pipeHandle = handle->handle;
assert(pipeHandle != INVALID_HANDLE_VALUE); assert(pipeHandle != INVALID_HANDLE_VALUE);
req = &handle->accept_reqs[0]; req = &handle->accept_reqs[0];
uv_req_init((uv_req_t*) req); uv_req_init(loop, (uv_req_t*) req);
req->pipeHandle = pipeHandle; req->pipeHandle = pipeHandle;
req->type = UV_ACCEPT; req->type = UV_ACCEPT;
req->data = handle; req->data = handle;
req->next_pending = NULL; req->next_pending = NULL;
if (uv_set_pipe_handle(handle, pipeHandle)) { if (uv_set_pipe_handle(loop, handle, pipeHandle)) {
uv_set_sys_error(GetLastError()); uv_set_sys_error(loop, GetLastError());
return -1; return -1;
} }
uv_pipe_queue_accept(handle, req, TRUE); uv_pipe_queue_accept(loop, handle, req, TRUE);
} else { } else {
/* First pipe handle should have already been created in uv_pipe_bind */ /* First pipe handle should have already been created in uv_pipe_bind */
assert(handle->accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE); assert(handle->accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE);
for (i = 0; i < COUNTOF(handle->accept_reqs); i++) { for (i = 0; i < COUNTOF(handle->accept_reqs); i++) {
uv_pipe_queue_accept(handle, &handle->accept_reqs[i], i == 0); uv_pipe_queue_accept(loop, handle, &handle->accept_reqs[i], i == 0);
} }
} }
@ -644,7 +655,7 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
} }
static void uv_pipe_queue_read(uv_pipe_t* handle) { static void uv_pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) {
uv_req_t* req; uv_req_t* req;
int result; int result;
@ -666,7 +677,7 @@ static void uv_pipe_queue_read(uv_pipe_t* handle) {
if (!result && GetLastError() != ERROR_IO_PENDING) { if (!result && GetLastError() != ERROR_IO_PENDING) {
/* Make this req pending reporting an error. */ /* Make this req pending reporting an error. */
SET_REQ_ERROR(req, WSAGetLastError()); SET_REQ_ERROR(req, WSAGetLastError());
uv_insert_pending_req(req); uv_insert_pending_req(loop, req);
handle->reqs_pending++; handle->reqs_pending++;
return; return;
} }
@ -679,19 +690,22 @@ static void uv_pipe_queue_read(uv_pipe_t* handle) {
} }
int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb) { int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb,
uv_read_cb read_cb) {
uv_loop_t* loop = handle->loop;
if (!(handle->flags & UV_HANDLE_CONNECTION)) { if (!(handle->flags & UV_HANDLE_CONNECTION)) {
uv_set_error(UV_EINVAL, 0); uv_set_error(loop, UV_EINVAL, 0);
return -1; return -1;
} }
if (handle->flags & UV_HANDLE_READING) { if (handle->flags & UV_HANDLE_READING) {
uv_set_error(UV_EALREADY, 0); uv_set_error(loop, UV_EALREADY, 0);
return -1; return -1;
} }
if (handle->flags & UV_HANDLE_EOF) { if (handle->flags & UV_HANDLE_EOF) {
uv_set_error(UV_EOF, 0); uv_set_error(loop, UV_EOF, 0);
return -1; return -1;
} }
@ -702,34 +716,34 @@ int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_
/* If reading was stopped and then started again, there could stell be a */ /* If reading was stopped and then started again, there could stell be a */
/* read request pending. */ /* read request pending. */
if (!(handle->flags & UV_HANDLE_READ_PENDING)) if (!(handle->flags & UV_HANDLE_READ_PENDING))
uv_pipe_queue_read(handle); uv_pipe_queue_read(loop, handle);
return 0; return 0;
} }
int uv_pipe_write(uv_write_t* req, uv_pipe_t* handle, uv_buf_t bufs[], int bufcnt, int uv_pipe_write(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle,
uv_write_cb cb) { uv_buf_t bufs[], int bufcnt, uv_write_cb cb) {
int result; int result;
if (bufcnt != 1) { if (bufcnt != 1) {
uv_set_error(UV_ENOTSUP, 0); uv_set_error(loop, UV_ENOTSUP, 0);
return -1; return -1;
} }
assert(handle->handle != INVALID_HANDLE_VALUE); assert(handle->handle != INVALID_HANDLE_VALUE);
if (!(handle->flags & UV_HANDLE_CONNECTION)) { if (!(handle->flags & UV_HANDLE_CONNECTION)) {
uv_set_error(UV_EINVAL, 0); uv_set_error(loop, UV_EINVAL, 0);
return -1; return -1;
} }
if (handle->flags & UV_HANDLE_SHUTTING) { if (handle->flags & UV_HANDLE_SHUTTING) {
uv_set_error(UV_EOF, 0); uv_set_error(loop, UV_EOF, 0);
return -1; return -1;
} }
uv_req_init((uv_req_t*) req); uv_req_init(loop, (uv_req_t*) req);
req->type = UV_WRITE; req->type = UV_WRITE;
req->handle = (uv_stream_t*) handle; req->handle = (uv_stream_t*) handle;
req->cb = cb; req->cb = cb;
@ -742,7 +756,7 @@ int uv_pipe_write(uv_write_t* req, uv_pipe_t* handle, uv_buf_t bufs[], int bufcn
&req->overlapped); &req->overlapped);
if (!result && GetLastError() != ERROR_IO_PENDING) { if (!result && GetLastError() != ERROR_IO_PENDING) {
uv_set_sys_error(GetLastError()); uv_set_sys_error(loop, GetLastError());
return -1; return -1;
} }
@ -762,7 +776,8 @@ int uv_pipe_write(uv_write_t* req, uv_pipe_t* handle, uv_buf_t bufs[], int bufcn
} }
static void uv_pipe_read_eof(uv_pipe_t* handle, uv_buf_t buf) { static void uv_pipe_read_eof(uv_loop_t* loop, uv_pipe_t* handle,
uv_buf_t buf) {
/* If there is an eof timer running, we don't need it any more, */ /* If there is an eof timer running, we don't need it any more, */
/* so discard it. */ /* so discard it. */
eof_timer_destroy(handle); eof_timer_destroy(handle);
@ -770,33 +785,36 @@ static void uv_pipe_read_eof(uv_pipe_t* handle, uv_buf_t buf) {
handle->flags |= UV_HANDLE_EOF; handle->flags |= UV_HANDLE_EOF;
uv_read_stop((uv_stream_t*) handle); uv_read_stop((uv_stream_t*) handle);
uv_set_error(UV_EOF, 0); uv_set_error(loop, UV_EOF, 0);
handle->read_cb((uv_stream_t*) handle, -1, uv_null_buf_); handle->read_cb((uv_stream_t*) handle, -1, uv_null_buf_);
} }
static void uv_pipe_read_error(uv_pipe_t* handle, int error, uv_buf_t buf) { static void uv_pipe_read_error(uv_loop_t* loop, uv_pipe_t* handle, int error,
uv_buf_t buf) {
/* If there is an eof timer running, we don't need it any more, */ /* If there is an eof timer running, we don't need it any more, */
/* so discard it. */ /* so discard it. */
eof_timer_destroy(handle); eof_timer_destroy(handle);
uv_read_stop((uv_stream_t*) handle); uv_read_stop((uv_stream_t*) handle);
uv_set_sys_error(error); uv_set_sys_error(loop, error);
handle->read_cb((uv_stream_t*)handle, -1, buf); handle->read_cb((uv_stream_t*)handle, -1, buf);
} }
static void uv_pipe_read_error_or_eof(uv_pipe_t* handle, int error, uv_buf_t buf) { static void uv_pipe_read_error_or_eof(uv_loop_t* loop, uv_pipe_t* handle,
int error, uv_buf_t buf) {
if (error == ERROR_BROKEN_PIPE) { if (error == ERROR_BROKEN_PIPE) {
uv_pipe_read_eof(handle, buf); uv_pipe_read_eof(loop, handle, buf);
} else { } else {
uv_pipe_read_error(handle, error, buf); uv_pipe_read_error(loop, handle, error, buf);
} }
} }
void uv_process_pipe_read_req(uv_pipe_t* handle, uv_req_t* req) { void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_req_t* req) {
DWORD bytes, avail; DWORD bytes, avail;
uv_buf_t buf; uv_buf_t buf;
@ -808,7 +826,10 @@ void uv_process_pipe_read_req(uv_pipe_t* handle, uv_req_t* req) {
if (!REQ_SUCCESS(req)) { if (!REQ_SUCCESS(req)) {
/* An error occurred doing the 0-read. */ /* An error occurred doing the 0-read. */
if (handle->flags & UV_HANDLE_READING) { if (handle->flags & UV_HANDLE_READING) {
uv_pipe_read_error_or_eof(handle, GET_REQ_ERROR(req), uv_null_buf_); uv_pipe_read_error_or_eof(loop,
handle,
GET_REQ_ERROR(req),
uv_null_buf_);
} }
} else { } else {
/* Do non-blocking reads until the buffer is empty */ /* Do non-blocking reads until the buffer is empty */
@ -819,7 +840,7 @@ void uv_process_pipe_read_req(uv_pipe_t* handle, uv_req_t* req) {
NULL, NULL,
&avail, &avail,
NULL)) { NULL)) {
uv_pipe_read_error_or_eof(handle, GetLastError(), uv_null_buf_); uv_pipe_read_error_or_eof(loop, handle, GetLastError(), uv_null_buf_);
break; break;
} }
@ -843,7 +864,7 @@ void uv_process_pipe_read_req(uv_pipe_t* handle, uv_req_t* req) {
break; break;
} }
} else { } else {
uv_pipe_read_error_or_eof(handle, GetLastError(), uv_null_buf_); uv_pipe_read_error_or_eof(loop, handle, GetLastError(), uv_null_buf_);
break; break;
} }
} }
@ -851,7 +872,7 @@ void uv_process_pipe_read_req(uv_pipe_t* handle, uv_req_t* req) {
/* Post another 0-read if still reading and not closing. */ /* Post another 0-read if still reading and not closing. */
if ((handle->flags & UV_HANDLE_READING) && if ((handle->flags & UV_HANDLE_READING) &&
!(handle->flags & UV_HANDLE_READ_PENDING)) { !(handle->flags & UV_HANDLE_READ_PENDING)) {
uv_pipe_queue_read(handle); uv_pipe_queue_read(loop, handle);
} }
} }
@ -859,14 +880,15 @@ void uv_process_pipe_read_req(uv_pipe_t* handle, uv_req_t* req) {
} }
void uv_process_pipe_write_req(uv_pipe_t* handle, uv_write_t* req) { void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_write_t* req) {
assert(handle->type == UV_NAMED_PIPE); assert(handle->type == UV_NAMED_PIPE);
handle->write_queue_size -= req->queued_bytes; handle->write_queue_size -= req->queued_bytes;
if (req->cb) { if (req->cb) {
if (!REQ_SUCCESS(req)) { if (!REQ_SUCCESS(req)) {
LOOP->last_error = GET_REQ_UV_ERROR(req); loop->last_error = GET_REQ_UV_ERROR(req);
((uv_write_cb)req->cb)(req, -1); ((uv_write_cb)req->cb)(req, -1);
} else { } else {
((uv_write_cb)req->cb)(req, 0); ((uv_write_cb)req->cb)(req, 0);
@ -876,14 +898,15 @@ void uv_process_pipe_write_req(uv_pipe_t* handle, uv_write_t* req) {
handle->write_reqs_pending--; handle->write_reqs_pending--;
if (handle->write_reqs_pending == 0 && if (handle->write_reqs_pending == 0 &&
handle->flags & UV_HANDLE_SHUTTING) { handle->flags & UV_HANDLE_SHUTTING) {
uv_want_endgame((uv_handle_t*)handle); uv_want_endgame(loop, (uv_handle_t*)handle);
} }
DECREASE_PENDING_REQ_COUNT(handle); DECREASE_PENDING_REQ_COUNT(handle);
} }
void uv_process_pipe_accept_req(uv_pipe_t* handle, uv_req_t* raw_req) { void uv_process_pipe_accept_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_req_t* raw_req) {
uv_pipe_accept_t* req = (uv_pipe_accept_t*) raw_req; uv_pipe_accept_t* req = (uv_pipe_accept_t*) raw_req;
assert(handle->type == UV_NAMED_PIPE); assert(handle->type == UV_NAMED_PIPE);
@ -903,7 +926,7 @@ void uv_process_pipe_accept_req(uv_pipe_t* handle, uv_req_t* raw_req) {
} }
if (!(handle->flags & UV_HANDLE_CLOSING) && if (!(handle->flags & UV_HANDLE_CLOSING) &&
!(handle->flags & UV_HANDLE_GIVEN_OS_HANDLE)) { !(handle->flags & UV_HANDLE_GIVEN_OS_HANDLE)) {
uv_pipe_queue_accept(handle, req, FALSE); uv_pipe_queue_accept(loop, handle, req, FALSE);
} }
} }
@ -911,7 +934,8 @@ void uv_process_pipe_accept_req(uv_pipe_t* handle, uv_req_t* raw_req) {
} }
void uv_process_pipe_connect_req(uv_pipe_t* handle, uv_connect_t* req) { void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_connect_t* req) {
assert(handle->type == UV_NAMED_PIPE); assert(handle->type == UV_NAMED_PIPE);
if (req->cb) { if (req->cb) {
@ -919,7 +943,7 @@ void uv_process_pipe_connect_req(uv_pipe_t* handle, uv_connect_t* req) {
uv_pipe_connection_init(handle); uv_pipe_connection_init(handle);
((uv_connect_cb)req->cb)(req, 0); ((uv_connect_cb)req->cb)(req, 0);
} else { } else {
LOOP->last_error = GET_REQ_UV_ERROR(req); loop->last_error = GET_REQ_UV_ERROR(req);
((uv_connect_cb)req->cb)(req, -1); ((uv_connect_cb)req->cb)(req, -1);
} }
} }
@ -928,7 +952,8 @@ void uv_process_pipe_connect_req(uv_pipe_t* handle, uv_connect_t* req) {
} }
void uv_process_pipe_shutdown_req(uv_pipe_t* handle, uv_shutdown_t* req) { void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_shutdown_t* req) {
assert(handle->type == UV_NAMED_PIPE); assert(handle->type == UV_NAMED_PIPE);
/* Initialize and optionally start the eof timer. */ /* Initialize and optionally start the eof timer. */
@ -959,7 +984,7 @@ static void eof_timer_init(uv_pipe_t* pipe) {
pipe->eof_timer = (uv_timer_t*) malloc(sizeof *pipe->eof_timer); pipe->eof_timer = (uv_timer_t*) malloc(sizeof *pipe->eof_timer);
r = uv_timer_init(pipe->eof_timer); r = uv_timer_init(pipe->loop, pipe->eof_timer);
assert(r == 0); /* timers can't fail */ assert(r == 0); /* timers can't fail */
pipe->eof_timer->data = pipe; pipe->eof_timer->data = pipe;
} }
@ -985,6 +1010,7 @@ static void eof_timer_stop(uv_pipe_t* pipe) {
static void eof_timer_cb(uv_timer_t* timer, int status) { static void eof_timer_cb(uv_timer_t* timer, int status) {
uv_pipe_t* pipe = (uv_pipe_t*) timer->data; uv_pipe_t* pipe = (uv_pipe_t*) timer->data;
uv_loop_t* loop = timer->loop;
assert(status == 0); /* timers can't fail */ assert(status == 0); /* timers can't fail */
assert(pipe->type == UV_NAMED_PIPE); assert(pipe->type == UV_NAMED_PIPE);
@ -1015,7 +1041,7 @@ static void eof_timer_cb(uv_timer_t* timer, int status) {
/* Report the eof and update flags. This will get reported even if the */ /* Report the eof and update flags. This will get reported even if the */
/* user stopped reading in the meantime. TODO: is that okay? */ /* user stopped reading in the meantime. TODO: is that okay? */
uv_pipe_read_eof(pipe, uv_null_buf_); uv_pipe_read_eof(loop, pipe, uv_null_buf_);
} }

111
deps/uv/src/win/process.c

@ -45,14 +45,15 @@ typedef struct env_var {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); \ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); \
} \ } \
if (!uv_utf8_to_utf16(s, t, size / sizeof(wchar_t))) { \ if (!uv_utf8_to_utf16(s, t, size / sizeof(wchar_t))) { \
uv_set_sys_error(GetLastError()); \ uv_set_sys_error(loop, GetLastError()); \
err = -1; \ err = -1; \
goto done; \ goto done; \
} }
static void uv_process_init(uv_process_t* handle) { static void uv_process_init(uv_loop_t* loop, uv_process_t* handle) {
handle->type = UV_PROCESS; handle->type = UV_PROCESS;
handle->loop = loop;
handle->flags = 0; handle->flags = 0;
handle->exit_cb = NULL; handle->exit_cb = NULL;
handle->pid = 0; handle->pid = 0;
@ -67,17 +68,17 @@ static void uv_process_init(uv_process_t* handle) {
handle->stdio_pipes[2].server_pipe = NULL; handle->stdio_pipes[2].server_pipe = NULL;
handle->stdio_pipes[2].child_pipe = INVALID_HANDLE_VALUE; handle->stdio_pipes[2].child_pipe = INVALID_HANDLE_VALUE;
uv_req_init((uv_req_t*)&handle->exit_req); uv_req_init(loop, (uv_req_t*)&handle->exit_req);
handle->exit_req.type = UV_PROCESS_EXIT; handle->exit_req.type = UV_PROCESS_EXIT;
handle->exit_req.data = handle; handle->exit_req.data = handle;
uv_req_init((uv_req_t*)&handle->close_req); uv_req_init(loop, (uv_req_t*)&handle->close_req);
handle->close_req.type = UV_PROCESS_CLOSE; handle->close_req.type = UV_PROCESS_CLOSE;
handle->close_req.data = handle; handle->close_req.data = handle;
uv_counters()->handle_init++; loop->counters.handle_init++;
uv_counters()->process_init++; loop->counters.process_init++;
uv_ref(); uv_ref(loop);
} }
@ -122,8 +123,8 @@ static wchar_t* search_path_join_test(const wchar_t* dir,
} }
/* Allocate buffer for output */ /* Allocate buffer for output */
result = result_pos = result = result_pos = (wchar_t*)malloc(sizeof(wchar_t) *
(wchar_t*)malloc(sizeof(wchar_t) * (cwd_len + 1 + dir_len + 1 + name_len + 1 + ext_len + 1)); (cwd_len + 1 + dir_len + 1 + name_len + 1 + ext_len + 1));
/* Copy cwd */ /* Copy cwd */
wcsncpy(result_pos, cwd, cwd_len); wcsncpy(result_pos, cwd, cwd_len);
@ -280,7 +281,8 @@ static wchar_t* search_path(const wchar_t *file,
return NULL; return NULL;
} }
/* Find the start of the filename so we can split the directory from the name */ /* Find the start of the filename so we can split the directory from the */
/* name. */
for (file_name_start = (wchar_t*)file + file_len; for (file_name_start = (wchar_t*)file + file_len;
file_name_start > file file_name_start > file
&& file_name_start[-1] != L'\\' && file_name_start[-1] != L'\\'
@ -489,7 +491,8 @@ error:
* issues associated with that solution; this is the caller's * issues associated with that solution; this is the caller's
* char**, and modifying it is rude. * char**, and modifying it is rude.
*/ */
static void check_required_vars_contains_var(env_var_t* required, int size, const char* var) { static void check_required_vars_contains_var(env_var_t* required, int size,
const char* var) {
int i; int i;
for (i = 0; i < size; ++i) { for (i = 0; i < size; ++i) {
if (_strnicmp(required[i].narrow, var, required[i].len) == 0) { if (_strnicmp(required[i].narrow, var, required[i].len) == 0) {
@ -527,7 +530,9 @@ wchar_t* make_program_env(char** env_block) {
}; };
for (env = env_block; *env; env++) { for (env = env_block; *env; env++) {
check_required_vars_contains_var(required_vars, COUNTOF(required_vars), *env); check_required_vars_contains_var(required_vars,
COUNTOF(required_vars),
*env);
env_len += (uv_utf8_to_utf16(*env, NULL, 0) * sizeof(wchar_t)); env_len += (uv_utf8_to_utf16(*env, NULL, 0) * sizeof(wchar_t));
} }
@ -563,7 +568,9 @@ wchar_t* make_program_env(char** env_block) {
wcscpy(ptr, required_vars[i].wide); wcscpy(ptr, required_vars[i].wide);
ptr += required_vars[i].len - 1; ptr += required_vars[i].len - 1;
*ptr++ = L'='; *ptr++ = L'=';
var_size = GetEnvironmentVariableW(required_vars[i].wide, ptr, required_vars[i].value_len); var_size = GetEnvironmentVariableW(required_vars[i].wide,
ptr,
required_vars[i].value_len);
if (var_size == 0) { if (var_size == 0) {
uv_fatal_error(GetLastError(), "GetEnvironmentVariableW"); uv_fatal_error(GetLastError(), "GetEnvironmentVariableW");
} }
@ -582,12 +589,13 @@ wchar_t* make_program_env(char** env_block) {
*/ */
static void CALLBACK exit_wait_callback(void* data, BOOLEAN didTimeout) { static void CALLBACK exit_wait_callback(void* data, BOOLEAN didTimeout) {
uv_process_t* process = (uv_process_t*)data; uv_process_t* process = (uv_process_t*)data;
uv_loop_t* loop = process->loop;
assert(didTimeout == FALSE); assert(didTimeout == FALSE);
assert(process); assert(process);
/* Post completed */ /* Post completed */
POST_COMPLETION_FOR_REQ(&process->exit_req); POST_COMPLETION_FOR_REQ(loop, &process->exit_req);
} }
@ -597,12 +605,13 @@ static void CALLBACK exit_wait_callback(void* data, BOOLEAN didTimeout) {
*/ */
static void CALLBACK close_wait_callback(void* data, BOOLEAN didTimeout) { static void CALLBACK close_wait_callback(void* data, BOOLEAN didTimeout) {
uv_process_t* process = (uv_process_t*)data; uv_process_t* process = (uv_process_t*)data;
uv_loop_t* loop = process->loop;
assert(didTimeout == FALSE); assert(didTimeout == FALSE);
assert(process); assert(process);
/* Post completed */ /* Post completed */
POST_COMPLETION_FOR_REQ(&process->close_req); POST_COMPLETION_FOR_REQ(loop, &process->close_req);
} }
@ -615,6 +624,7 @@ static DWORD WINAPI spawn_failure(void* data) {
char syscall[] = "CreateProcessW: "; char syscall[] = "CreateProcessW: ";
char unknown[] = "unknown error\n"; char unknown[] = "unknown error\n";
uv_process_t* process = (uv_process_t*) data; uv_process_t* process = (uv_process_t*) data;
uv_loop_t* loop = process->loop;
HANDLE child_stderr = process->stdio_pipes[2].child_pipe; HANDLE child_stderr = process->stdio_pipes[2].child_pipe;
char* buf = NULL; char* buf = NULL;
DWORD count, written; DWORD count, written;
@ -641,14 +651,14 @@ static DWORD WINAPI spawn_failure(void* data) {
FlushFileBuffers(child_stderr); FlushFileBuffers(child_stderr);
/* Post completed */ /* Post completed */
POST_COMPLETION_FOR_REQ(&process->exit_req); POST_COMPLETION_FOR_REQ(loop, &process->exit_req);
return 0; return 0;
} }
/* Called on main thread after a child process has exited. */ /* Called on main thread after a child process has exited. */
void uv_process_proc_exit(uv_process_t* handle) { void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
int i; int i;
DWORD exit_code; DWORD exit_code;
@ -688,12 +698,12 @@ void uv_process_proc_exit(uv_process_t* handle) {
/* Called on main thread after UnregisterWaitEx finishes. */ /* Called on main thread after UnregisterWaitEx finishes. */
void uv_process_proc_close(uv_process_t* handle) { void uv_process_proc_close(uv_loop_t* loop, uv_process_t* handle) {
uv_want_endgame((uv_handle_t*)handle); uv_want_endgame(loop, (uv_handle_t*)handle);
} }
void uv_process_endgame(uv_process_t* handle) { void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle) {
if (handle->flags & UV_HANDLE_CLOSING) { if (handle->flags & UV_HANDLE_CLOSING) {
assert(!(handle->flags & UV_HANDLE_CLOSED)); assert(!(handle->flags & UV_HANDLE_CLOSED));
handle->flags |= UV_HANDLE_CLOSED; handle->flags |= UV_HANDLE_CLOSED;
@ -702,12 +712,12 @@ void uv_process_endgame(uv_process_t* handle) {
handle->close_cb((uv_handle_t*)handle); handle->close_cb((uv_handle_t*)handle);
} }
uv_unref(); uv_unref(loop);
} }
} }
void uv_process_close(uv_process_t* handle) { void uv_process_close(uv_loop_t* loop, uv_process_t* handle) {
if (handle->wait_handle != INVALID_HANDLE_VALUE) { if (handle->wait_handle != INVALID_HANDLE_VALUE) {
handle->close_handle = CreateEvent(NULL, FALSE, FALSE, NULL); handle->close_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
UnregisterWaitEx(handle->wait_handle, handle->close_handle); UnregisterWaitEx(handle->wait_handle, handle->close_handle);
@ -717,25 +727,30 @@ void uv_process_close(uv_process_t* handle) {
close_wait_callback, (void*)handle, INFINITE, close_wait_callback, (void*)handle, INFINITE,
WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE); WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
} else { } else {
uv_want_endgame((uv_handle_t*)handle); uv_want_endgame(loop, (uv_handle_t*)handle);
} }
} }
static int uv_create_stdio_pipe_pair(uv_pipe_t* server_pipe, HANDLE* child_pipe, DWORD server_access, DWORD child_access) { static int uv_create_stdio_pipe_pair(uv_loop_t* loop, uv_pipe_t* server_pipe,
HANDLE* child_pipe, DWORD server_access, DWORD child_access) {
int err; int err;
SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
char pipe_name[64]; char pipe_name[64];
DWORD mode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT; DWORD mode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT;
if (server_pipe->type != UV_NAMED_PIPE) { if (server_pipe->type != UV_NAMED_PIPE) {
uv_set_error(UV_EINVAL, 0); uv_set_error(loop, UV_EINVAL, 0);
err = -1; err = -1;
goto done; goto done;
} }
/* Create server pipe handle. */ /* Create server pipe handle. */
err = uv_stdio_pipe_server(server_pipe, server_access, pipe_name, sizeof(pipe_name)); err = uv_stdio_pipe_server(loop,
server_pipe,
server_access,
pipe_name,
sizeof(pipe_name));
if (err) { if (err) {
goto done; goto done;
} }
@ -750,13 +765,13 @@ static int uv_create_stdio_pipe_pair(uv_pipe_t* server_pipe, HANDLE* child_pipe,
NULL); NULL);
if (*child_pipe == INVALID_HANDLE_VALUE) { if (*child_pipe == INVALID_HANDLE_VALUE) {
uv_set_sys_error(GetLastError()); uv_set_sys_error(loop, GetLastError());
err = -1; err = -1;
goto done; goto done;
} }
if (!SetNamedPipeHandleState(*child_pipe, &mode, NULL, NULL)) { if (!SetNamedPipeHandleState(*child_pipe, &mode, NULL, NULL)) {
uv_set_sys_error(GetLastError()); uv_set_sys_error(loop, GetLastError());
err = -1; err = -1;
goto done; goto done;
} }
@ -766,7 +781,7 @@ static int uv_create_stdio_pipe_pair(uv_pipe_t* server_pipe, HANDLE* child_pipe,
*/ */
if (!ConnectNamedPipe(server_pipe->handle, NULL)) { if (!ConnectNamedPipe(server_pipe->handle, NULL)) {
if (GetLastError() != ERROR_PIPE_CONNECTED) { if (GetLastError() != ERROR_PIPE_CONNECTED) {
uv_set_sys_error(GetLastError()); uv_set_sys_error(loop, GetLastError());
err = -1; err = -1;
goto done; goto done;
} }
@ -790,19 +805,22 @@ done:
} }
int uv_spawn(uv_process_t* process, uv_process_options_t options) { int uv_spawn(uv_loop_t* loop, uv_process_t* process,
uv_process_options_t options) {
int err = 0, i; int err = 0, i;
wchar_t* path; wchar_t* path;
int size; int size;
BOOL result;
wchar_t* application_path, *application, *arguments, *env, *cwd; wchar_t* application_path, *application, *arguments, *env, *cwd;
STARTUPINFOW startup; STARTUPINFOW startup;
PROCESS_INFORMATION info; PROCESS_INFORMATION info;
uv_process_init(process); uv_process_init(loop, process);
process->exit_cb = options.exit_cb; process->exit_cb = options.exit_cb;
UTF8_TO_UTF16(options.file, application); UTF8_TO_UTF16(options.file, application);
arguments = options.args ? make_program_args(options.args, options.windows_verbatim_arguments) : NULL; arguments = options.args ? make_program_args(options.args,
options.windows_verbatim_arguments) : NULL;
env = options.env ? make_program_env(options.env) : NULL; env = options.env ? make_program_env(options.env) : NULL;
if (options.cwd) { if (options.cwd) {
@ -816,7 +834,7 @@ int uv_spawn(uv_process_t* process, uv_process_options_t options) {
} }
GetCurrentDirectoryW(size, cwd); GetCurrentDirectoryW(size, cwd);
} else { } else {
uv_set_sys_error(GetLastError()); uv_set_sys_error(loop, GetLastError());
err = -1; err = -1;
goto done; goto done;
} }
@ -843,7 +861,12 @@ int uv_spawn(uv_process_t* process, uv_process_options_t options) {
/* Create stdio pipes. */ /* Create stdio pipes. */
if (options.stdin_stream) { if (options.stdin_stream) {
err = uv_create_stdio_pipe_pair(options.stdin_stream, &process->stdio_pipes[0].child_pipe, PIPE_ACCESS_OUTBOUND, GENERIC_READ | FILE_WRITE_ATTRIBUTES); err = uv_create_stdio_pipe_pair(
loop,
options.stdin_stream,
&process->stdio_pipes[0].child_pipe,
PIPE_ACCESS_OUTBOUND,
GENERIC_READ | FILE_WRITE_ATTRIBUTES);
if (err) { if (err) {
goto done; goto done;
} }
@ -852,7 +875,11 @@ int uv_spawn(uv_process_t* process, uv_process_options_t options) {
} }
if (options.stdout_stream) { if (options.stdout_stream) {
err = uv_create_stdio_pipe_pair(options.stdout_stream, &process->stdio_pipes[1].child_pipe, PIPE_ACCESS_INBOUND, GENERIC_WRITE); err = uv_create_stdio_pipe_pair(
loop, options.stdout_stream,
&process->stdio_pipes[1].child_pipe,
PIPE_ACCESS_INBOUND,
GENERIC_WRITE);
if (err) { if (err) {
goto done; goto done;
} }
@ -861,7 +888,12 @@ int uv_spawn(uv_process_t* process, uv_process_options_t options) {
} }
if (options.stderr_stream) { if (options.stderr_stream) {
err = uv_create_stdio_pipe_pair(options.stderr_stream, &process->stdio_pipes[2].child_pipe, PIPE_ACCESS_INBOUND, GENERIC_WRITE); err = uv_create_stdio_pipe_pair(
loop,
options.stderr_stream,
&process->stdio_pipes[2].child_pipe,
PIPE_ACCESS_INBOUND,
GENERIC_WRITE);
if (err) { if (err) {
goto done; goto done;
} }
@ -895,9 +927,10 @@ int uv_spawn(uv_process_t* process, uv_process_options_t options) {
process->pid = info.dwProcessId; process->pid = info.dwProcessId;
/* Setup notifications for when the child process exits. */ /* Setup notifications for when the child process exits. */
if (!RegisterWaitForSingleObject(&process->wait_handle, process->process_handle, result = RegisterWaitForSingleObject(&process->wait_handle,
exit_wait_callback, (void*)process, INFINITE, process->process_handle, exit_wait_callback, (void*)process, INFINITE,
WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)) { WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
if (!result) {
uv_fatal_error(GetLastError(), "RegisterWaitForSingleObject"); uv_fatal_error(GetLastError(), "RegisterWaitForSingleObject");
} }

75
deps/uv/src/win/req.c

@ -26,8 +26,8 @@
#include "internal.h" #include "internal.h"
void uv_req_init(uv_req_t* req) { void uv_req_init(uv_loop_t* loop, uv_req_t* req) {
uv_counters()->req_init++; loop->counters.req_init++;
req->type = UV_UNKNOWN_REQ; req->type = UV_UNKNOWN_REQ;
SET_REQ_SUCCESS(req); SET_REQ_SUCCESS(req);
} }
@ -38,29 +38,29 @@ uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped) {
} }
void uv_insert_pending_req(uv_req_t* req) { void uv_insert_pending_req(uv_loop_t* loop, uv_req_t* req) {
req->next_req = NULL; req->next_req = NULL;
if (LOOP->pending_reqs_tail) { if (loop->pending_reqs_tail) {
req->next_req = LOOP->pending_reqs_tail->next_req; req->next_req = loop->pending_reqs_tail->next_req;
LOOP->pending_reqs_tail->next_req = req; loop->pending_reqs_tail->next_req = req;
LOOP->pending_reqs_tail = req; loop->pending_reqs_tail = req;
} else { } else {
req->next_req = req; req->next_req = req;
LOOP->pending_reqs_tail = req; loop->pending_reqs_tail = req;
} }
} }
static uv_req_t* uv_remove_pending_req() { static uv_req_t* uv_remove_pending_req(uv_loop_t* loop) {
uv_req_t* req; uv_req_t* req;
if (LOOP->pending_reqs_tail) { if (loop->pending_reqs_tail) {
req = LOOP->pending_reqs_tail->next_req; req = loop->pending_reqs_tail->next_req;
if (req == LOOP->pending_reqs_tail) { if (req == loop->pending_reqs_tail) {
LOOP->pending_reqs_tail = NULL; loop->pending_reqs_tail = NULL;
} else { } else {
LOOP->pending_reqs_tail->next_req = req->next_req; loop->pending_reqs_tail->next_req = req->next_req;
} }
return req; return req;
@ -72,15 +72,19 @@ static uv_req_t* uv_remove_pending_req() {
} }
#define DELEGATE_STREAM_REQ(req, method, handle_at) \ #define DELEGATE_STREAM_REQ(loop, req, method, handle_at) \
do { \ do { \
switch (((uv_handle_t*) (req)->handle_at)->type) { \ switch (((uv_handle_t*) (req)->handle_at)->type) { \
case UV_TCP: \ case UV_TCP: \
uv_process_tcp_##method##_req((uv_tcp_t*) ((req)->handle_at), req); \ uv_process_tcp_##method##_req(loop, \
(uv_tcp_t*) ((req)->handle_at), \
req); \
break; \ break; \
\ \
case UV_NAMED_PIPE: \ case UV_NAMED_PIPE: \
uv_process_pipe_##method##_req((uv_pipe_t*) ((req)->handle_at), req); \ uv_process_pipe_##method##_req(loop, \
(uv_pipe_t*) ((req)->handle_at), \
req); \
break; \ break; \
\ \
default: \ default: \
@ -89,73 +93,76 @@ static uv_req_t* uv_remove_pending_req() {
} while (0) } while (0)
void uv_process_reqs() { void uv_process_reqs(uv_loop_t* loop) {
uv_req_t* req; uv_req_t* req;
while (req = uv_remove_pending_req()) { while (req = uv_remove_pending_req(loop)) {
switch (req->type) { switch (req->type) {
case UV_READ: case UV_READ:
DELEGATE_STREAM_REQ(req, read, data); DELEGATE_STREAM_REQ(loop, req, read, data);
break; break;
case UV_WRITE: case UV_WRITE:
DELEGATE_STREAM_REQ((uv_write_t*) req, write, handle); DELEGATE_STREAM_REQ(loop, (uv_write_t*) req, write, handle);
break; break;
case UV_ACCEPT: case UV_ACCEPT:
DELEGATE_STREAM_REQ(req, accept, data); DELEGATE_STREAM_REQ(loop, req, accept, data);
break; break;
case UV_CONNECT: case UV_CONNECT:
DELEGATE_STREAM_REQ((uv_connect_t*) req, connect, handle); DELEGATE_STREAM_REQ(loop, (uv_connect_t*) req, connect, handle);
break; break;
case UV_SHUTDOWN: case UV_SHUTDOWN:
/* Tcp shutdown requests don't come here. */ /* Tcp shutdown requests don't come here. */
assert(((uv_shutdown_t*) req)->handle->type == UV_NAMED_PIPE); assert(((uv_shutdown_t*) req)->handle->type == UV_NAMED_PIPE);
uv_process_pipe_shutdown_req( uv_process_pipe_shutdown_req(
(uv_pipe_t*) ((uv_shutdown_t*) req)->handle, (uv_shutdown_t*) req); loop,
(uv_pipe_t*) ((uv_shutdown_t*) req)->handle,
(uv_shutdown_t*) req);
break; break;
case UV_UDP_RECV: case UV_UDP_RECV:
uv_process_udp_recv_req((uv_udp_t*) req->data, req); uv_process_udp_recv_req(loop, (uv_udp_t*) req->data, req);
break; break;
case UV_UDP_SEND: case UV_UDP_SEND:
uv_process_udp_send_req(((uv_udp_send_t*) req)->handle, uv_process_udp_send_req(loop,
((uv_udp_send_t*) req)->handle,
(uv_udp_send_t*) req); (uv_udp_send_t*) req);
break; break;
case UV_WAKEUP: case UV_WAKEUP:
uv_process_async_wakeup_req((uv_async_t*) req->data, req); uv_process_async_wakeup_req(loop, (uv_async_t*) req->data, req);
break; break;
case UV_ARES_EVENT_REQ: case UV_ARES_EVENT_REQ:
uv_process_ares_event_req((uv_ares_action_t*) req->data, req); uv_process_ares_event_req(loop, (uv_ares_action_t*) req->data, req);
break; break;
case UV_ARES_CLEANUP_REQ: case UV_ARES_CLEANUP_REQ:
uv_process_ares_cleanup_req((uv_ares_task_t*) req->data, req); uv_process_ares_cleanup_req(loop, (uv_ares_task_t*) req->data, req);
break; break;
case UV_GETADDRINFO_REQ: case UV_GETADDRINFO_REQ:
uv_process_getaddrinfo_req((uv_getaddrinfo_t*) req->data, req); uv_process_getaddrinfo_req(loop, (uv_getaddrinfo_t*) req->data, req);
break; break;
case UV_PROCESS_EXIT: case UV_PROCESS_EXIT:
uv_process_proc_exit((uv_process_t*) req->data); uv_process_proc_exit(loop, (uv_process_t*) req->data);
break; break;
case UV_PROCESS_CLOSE: case UV_PROCESS_CLOSE:
uv_process_proc_close((uv_process_t*) req->data); uv_process_proc_close(loop, (uv_process_t*) req->data);
break; break;
case UV_FS: case UV_FS:
uv_process_fs_req((uv_fs_t*) req); uv_process_fs_req(loop, (uv_fs_t*) req);
break; break;
case UV_WORK: case UV_WORK:
uv_process_work_req((uv_work_t*) req); uv_process_work_req(loop, (uv_work_t*) req);
break; break;
default: default:

10
deps/uv/src/win/stdio.c

@ -27,7 +27,7 @@
#include "internal.h" #include "internal.h"
static uv_pipe_t* uv_make_pipe_for_std_handle(HANDLE handle) { static uv_pipe_t* uv_make_pipe_for_std_handle(uv_loop_t* loop, HANDLE handle) {
uv_pipe_t* pipe = NULL; uv_pipe_t* pipe = NULL;
pipe = (uv_pipe_t*)malloc(sizeof(uv_pipe_t)); pipe = (uv_pipe_t*)malloc(sizeof(uv_pipe_t));
@ -35,7 +35,7 @@ static uv_pipe_t* uv_make_pipe_for_std_handle(HANDLE handle) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
} }
if (uv_pipe_init_with_handle(pipe, handle)) { if (uv_pipe_init_with_handle(loop, pipe, handle)) {
free(pipe); free(pipe);
return NULL; return NULL;
} }
@ -45,7 +45,7 @@ static uv_pipe_t* uv_make_pipe_for_std_handle(HANDLE handle) {
} }
uv_stream_t* uv_std_handle(uv_std_type type) { uv_stream_t* uv_std_handle(uv_loop_t* loop, uv_std_type type) {
HANDLE handle; HANDLE handle;
switch (type) { switch (type) {
@ -56,7 +56,7 @@ uv_stream_t* uv_std_handle(uv_std_type type) {
} }
/* Assume only named pipes for now. */ /* Assume only named pipes for now. */
return (uv_stream_t*)uv_make_pipe_for_std_handle(handle); return (uv_stream_t*)uv_make_pipe_for_std_handle(loop, handle);
break; break;
case UV_STDOUT: case UV_STDOUT:
@ -69,7 +69,7 @@ uv_stream_t* uv_std_handle(uv_std_type type) {
default: default:
assert(0); assert(0);
uv_set_error(UV_EINVAL, 0); uv_set_error(loop, UV_EINVAL, 0);
return NULL; return NULL;
} }
} }

32
deps/uv/src/win/stream.c

@ -26,14 +26,15 @@
#include "internal.h" #include "internal.h"
void uv_stream_init(uv_stream_t* handle) { void uv_stream_init(uv_loop_t* loop, uv_stream_t* handle) {
handle->write_queue_size = 0; handle->write_queue_size = 0;
handle->loop = loop;
handle->flags = 0; handle->flags = 0;
uv_counters()->handle_init++; loop->counters.handle_init++;
uv_counters()->stream_init++; loop->counters.stream_init++;
uv_ref(); uv_ref(loop);
} }
@ -41,7 +42,7 @@ void uv_connection_init(uv_stream_t* handle) {
handle->flags |= UV_HANDLE_CONNECTION; handle->flags |= UV_HANDLE_CONNECTION;
handle->write_reqs_pending = 0; handle->write_reqs_pending = 0;
uv_req_init((uv_req_t*) &(handle->read_req)); uv_req_init(handle->loop, (uv_req_t*) &(handle->read_req));
handle->read_req.type = UV_READ; handle->read_req.type = UV_READ;
handle->read_req.data = handle; handle->read_req.data = handle;
} }
@ -75,7 +76,8 @@ int uv_accept(uv_stream_t* server, uv_stream_t* client) {
} }
int uv_read_start(uv_stream_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb) { int uv_read_start(uv_stream_t* handle, uv_alloc_cb alloc_cb,
uv_read_cb read_cb) {
switch (handle->type) { switch (handle->type) {
case UV_TCP: case UV_TCP:
return uv_tcp_read_start((uv_tcp_t*)handle, alloc_cb, read_cb); return uv_tcp_read_start((uv_tcp_t*)handle, alloc_cb, read_cb);
@ -97,31 +99,35 @@ int uv_read_stop(uv_stream_t* handle) {
int uv_write(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[], int bufcnt, int uv_write(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[], int bufcnt,
uv_write_cb cb) { uv_write_cb cb) {
uv_loop_t* loop = handle->loop;
switch (handle->type) { switch (handle->type) {
case UV_TCP: case UV_TCP:
return uv_tcp_write(req, (uv_tcp_t*) handle, bufs, bufcnt, cb); return uv_tcp_write(loop, req, (uv_tcp_t*) handle, bufs, bufcnt, cb);
case UV_NAMED_PIPE: case UV_NAMED_PIPE:
return uv_pipe_write(req, (uv_pipe_t*) handle, bufs, bufcnt, cb); return uv_pipe_write(loop, req, (uv_pipe_t*) handle, bufs, bufcnt, cb);
default: default:
assert(0); assert(0);
uv_set_sys_error(WSAEINVAL); uv_set_sys_error(loop, WSAEINVAL);
return -1; return -1;
} }
} }
int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) { int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
uv_loop_t* loop = handle->loop;
if (!(handle->flags & UV_HANDLE_CONNECTION)) { if (!(handle->flags & UV_HANDLE_CONNECTION)) {
uv_set_sys_error(WSAEINVAL); uv_set_sys_error(loop, WSAEINVAL);
return -1; return -1;
} }
if (handle->flags & UV_HANDLE_SHUTTING) { if (handle->flags & UV_HANDLE_SHUTTING) {
uv_set_sys_error(WSAESHUTDOWN); uv_set_sys_error(loop, WSAESHUTDOWN);
return -1; return -1;
} }
uv_req_init((uv_req_t*) req); uv_req_init(loop, (uv_req_t*) req);
req->type = UV_SHUTDOWN; req->type = UV_SHUTDOWN;
req->handle = handle; req->handle = handle;
req->cb = cb; req->cb = cb;
@ -130,7 +136,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
handle->shutdown_req = req; handle->shutdown_req = req;
handle->reqs_pending++; handle->reqs_pending++;
uv_want_endgame((uv_handle_t*)handle); uv_want_endgame(loop, (uv_handle_t*)handle);
return 0; return 0;
} }

194
deps/uv/src/win/tcp.c

@ -46,37 +46,39 @@ static char uv_zero_[] = "";
static unsigned int active_tcp_streams = 0; static unsigned int active_tcp_streams = 0;
static int uv_tcp_set_socket(uv_tcp_t* handle, SOCKET socket) { static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,
SOCKET socket) {
DWORD yes = 1; DWORD yes = 1;
assert(handle->socket == INVALID_SOCKET); assert(handle->socket == INVALID_SOCKET);
/* Set the socket to nonblocking mode */ /* Set the socket to nonblocking mode */
if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) { if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) {
uv_set_sys_error(WSAGetLastError()); uv_set_sys_error(loop, WSAGetLastError());
return -1; return -1;
} }
/* Make the socket non-inheritable */ /* Make the socket non-inheritable */
if (!SetHandleInformation((HANDLE)socket, HANDLE_FLAG_INHERIT, 0)) { if (!SetHandleInformation((HANDLE)socket, HANDLE_FLAG_INHERIT, 0)) {
uv_set_sys_error(GetLastError()); uv_set_sys_error(loop, GetLastError());
return -1; return -1;
} }
/* Associate it with the I/O completion port. */ /* Associate it with the I/O completion port. */
/* Use uv_handle_t pointer as completion key. */ /* Use uv_handle_t pointer as completion key. */
if (CreateIoCompletionPort((HANDLE)socket, if (CreateIoCompletionPort((HANDLE)socket,
LOOP->iocp, loop->iocp,
(ULONG_PTR)socket, (ULONG_PTR)socket,
0) == NULL) { 0) == NULL) {
uv_set_sys_error(GetLastError()); uv_set_sys_error(loop, GetLastError());
return -1; return -1;
} }
if (pSetFileCompletionNotificationModes) { if (pSetFileCompletionNotificationModes) {
if (!pSetFileCompletionNotificationModes((HANDLE)socket, FILE_SKIP_SET_EVENT_ON_HANDLE | if (!pSetFileCompletionNotificationModes((HANDLE) socket,
FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) { FILE_SKIP_SET_EVENT_ON_HANDLE |
uv_set_sys_error(GetLastError()); FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) {
uv_set_sys_error(loop, GetLastError());
return -1; return -1;
} }
@ -89,8 +91,8 @@ static int uv_tcp_set_socket(uv_tcp_t* handle, SOCKET socket) {
} }
int uv_tcp_init(uv_tcp_t* handle) { int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) {
uv_stream_init((uv_stream_t*)handle); uv_stream_init(loop, (uv_stream_t*)handle);
handle->accept_reqs = NULL; handle->accept_reqs = NULL;
handle->pending_accepts = NULL; handle->pending_accepts = NULL;
@ -98,13 +100,13 @@ int uv_tcp_init(uv_tcp_t* handle) {
handle->type = UV_TCP; handle->type = UV_TCP;
handle->reqs_pending = 0; handle->reqs_pending = 0;
uv_counters()->tcp_init++; loop->counters.tcp_init++;
return 0; return 0;
} }
void uv_tcp_endgame(uv_tcp_t* handle) { void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
uv_err_t err; uv_err_t err;
int status; int status;
@ -122,7 +124,7 @@ void uv_tcp_endgame(uv_tcp_t* handle) {
} }
if (handle->shutdown_req->cb) { if (handle->shutdown_req->cb) {
if (status == -1) { if (status == -1) {
LOOP->last_error = err; loop->last_error = err;
} }
handle->shutdown_req->cb(handle->shutdown_req, status); handle->shutdown_req->cb(handle->shutdown_req, status);
} }
@ -145,12 +147,13 @@ void uv_tcp_endgame(uv_tcp_t* handle) {
active_tcp_streams--; active_tcp_streams--;
uv_unref(); uv_unref(loop);
} }
} }
static int uv__bind(uv_tcp_t* handle, int domain, struct sockaddr* addr, int addrsize) { static int uv__bind(uv_loop_t* loop, uv_tcp_t* handle, int domain,
struct sockaddr* addr, int addrsize) {
DWORD err; DWORD err;
int r; int r;
SOCKET sock; SOCKET sock;
@ -158,11 +161,11 @@ static int uv__bind(uv_tcp_t* handle, int domain, struct sockaddr* addr, int add
if (handle->socket == INVALID_SOCKET) { if (handle->socket == INVALID_SOCKET) {
sock = socket(domain, SOCK_STREAM, 0); sock = socket(domain, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET) { if (sock == INVALID_SOCKET) {
uv_set_sys_error(WSAGetLastError()); uv_set_sys_error(loop, WSAGetLastError());
return -1; return -1;
} }
if (uv_tcp_set_socket(handle, sock) == -1) { if (uv_tcp_set_socket(loop, handle, sock) == -1) {
closesocket(sock); closesocket(sock);
return -1; return -1;
} }
@ -177,7 +180,7 @@ static int uv__bind(uv_tcp_t* handle, int domain, struct sockaddr* addr, int add
handle->bind_error = uv_new_sys_error(err); handle->bind_error = uv_new_sys_error(err);
handle->flags |= UV_HANDLE_BIND_ERROR; handle->flags |= UV_HANDLE_BIND_ERROR;
} else { } else {
uv_set_sys_error(err); uv_set_sys_error(loop, err);
return -1; return -1;
} }
} }
@ -189,31 +192,46 @@ static int uv__bind(uv_tcp_t* handle, int domain, struct sockaddr* addr, int add
int uv_tcp_bind(uv_tcp_t* handle, struct sockaddr_in addr) { int uv_tcp_bind(uv_tcp_t* handle, struct sockaddr_in addr) {
uv_loop_t* loop = handle->loop;
if (addr.sin_family != AF_INET) { if (addr.sin_family != AF_INET) {
uv_set_sys_error(WSAEFAULT); uv_set_sys_error(loop, WSAEFAULT);
return -1; return -1;
} }
return uv__bind(handle, AF_INET, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)); return uv__bind(loop,
handle,
AF_INET,
(struct sockaddr*)&addr,
sizeof(struct sockaddr_in));
} }
int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6 addr) { int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6 addr) {
uv_loop_t* loop = handle->loop;
if (addr.sin6_family != AF_INET6) { if (addr.sin6_family != AF_INET6) {
uv_set_sys_error(WSAEFAULT); uv_set_sys_error(loop, WSAEFAULT);
return -1; return -1;
} }
if (uv_allow_ipv6) { if (uv_allow_ipv6) {
handle->flags |= UV_HANDLE_IPV6; handle->flags |= UV_HANDLE_IPV6;
return uv__bind(handle, AF_INET6, (struct sockaddr*)&addr, sizeof(struct sockaddr_in6)); return uv__bind(loop,
handle,
AF_INET6,
(struct sockaddr*)&addr,
sizeof(struct sockaddr_in6));
} else { } else {
uv_new_sys_error(WSAEAFNOSUPPORT); uv_set_sys_error(loop, WSAEAFNOSUPPORT);
return -1; return -1;
} }
} }
static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) { static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
uv_loop_t* loop = handle->loop;
BOOL success; BOOL success;
DWORD bytes; DWORD bytes;
SOCKET accept_socket; SOCKET accept_socket;
@ -236,7 +254,7 @@ static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
accept_socket = socket(family, SOCK_STREAM, 0); accept_socket = socket(family, SOCK_STREAM, 0);
if (accept_socket == INVALID_SOCKET) { if (accept_socket == INVALID_SOCKET) {
SET_REQ_ERROR(req, WSAGetLastError()); SET_REQ_ERROR(req, WSAGetLastError());
uv_insert_pending_req((uv_req_t*)req); uv_insert_pending_req(loop, (uv_req_t*)req);
handle->reqs_pending++; handle->reqs_pending++;
return; return;
} }
@ -257,7 +275,7 @@ static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
/* Process the req without IOCP. */ /* Process the req without IOCP. */
req->accept_socket = accept_socket; req->accept_socket = accept_socket;
handle->reqs_pending++; handle->reqs_pending++;
uv_insert_pending_req((uv_req_t*)req); uv_insert_pending_req(loop, (uv_req_t*)req);
} else if (UV_SUCCEEDED_WITH_IOCP(success)) { } else if (UV_SUCCEEDED_WITH_IOCP(success)) {
/* The req will be processed with IOCP. */ /* The req will be processed with IOCP. */
req->accept_socket = accept_socket; req->accept_socket = accept_socket;
@ -265,7 +283,7 @@ static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
} else { } else {
/* Make this req pending reporting an error. */ /* Make this req pending reporting an error. */
SET_REQ_ERROR(req, WSAGetLastError()); SET_REQ_ERROR(req, WSAGetLastError());
uv_insert_pending_req((uv_req_t*)req); uv_insert_pending_req(loop, (uv_req_t*)req);
handle->reqs_pending++; handle->reqs_pending++;
/* Destroy the preallocated client socket. */ /* Destroy the preallocated client socket. */
closesocket(accept_socket); closesocket(accept_socket);
@ -273,7 +291,7 @@ static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
} }
static void uv_tcp_queue_read(uv_tcp_t* handle) { static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) {
uv_req_t* req; uv_req_t* req;
uv_buf_t buf; uv_buf_t buf;
int result; int result;
@ -314,7 +332,7 @@ static void uv_tcp_queue_read(uv_tcp_t* handle) {
handle->flags |= UV_HANDLE_READ_PENDING; handle->flags |= UV_HANDLE_READ_PENDING;
req->overlapped.InternalHigh = bytes; req->overlapped.InternalHigh = bytes;
handle->reqs_pending++; handle->reqs_pending++;
uv_insert_pending_req(req); uv_insert_pending_req(loop, req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
/* The req will be processed with IOCP. */ /* The req will be processed with IOCP. */
handle->flags |= UV_HANDLE_READ_PENDING; handle->flags |= UV_HANDLE_READ_PENDING;
@ -322,27 +340,28 @@ static void uv_tcp_queue_read(uv_tcp_t* handle) {
} else { } else {
/* Make this req pending reporting an error. */ /* Make this req pending reporting an error. */
SET_REQ_ERROR(req, WSAGetLastError()); SET_REQ_ERROR(req, WSAGetLastError());
uv_insert_pending_req(req); uv_insert_pending_req(loop, req);
handle->reqs_pending++; handle->reqs_pending++;
} }
} }
int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) { int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
uv_loop_t* loop = handle->loop;
unsigned int i; unsigned int i;
uv_tcp_accept_t* req; uv_tcp_accept_t* req;
assert(backlog > 0); assert(backlog > 0);
if (handle->flags & UV_HANDLE_BIND_ERROR) { if (handle->flags & UV_HANDLE_BIND_ERROR) {
LOOP->last_error = handle->bind_error; loop->last_error = handle->bind_error;
return -1; return -1;
} }
if (handle->flags & UV_HANDLE_LISTENING || if (handle->flags & UV_HANDLE_LISTENING ||
handle->flags & UV_HANDLE_READING) { handle->flags & UV_HANDLE_READING) {
/* Already listening. */ /* Already listening. */
uv_set_sys_error(WSAEALREADY); uv_set_sys_error(loop, WSAEALREADY);
return -1; return -1;
} }
@ -351,7 +370,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
return -1; return -1;
if (listen(handle->socket, backlog) == SOCKET_ERROR) { if (listen(handle->socket, backlog) == SOCKET_ERROR) {
uv_set_sys_error(WSAGetLastError()); uv_set_sys_error(loop, WSAGetLastError());
return -1; return -1;
} }
@ -367,7 +386,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
for (i = 0; i < uv_simultaneous_server_accepts; i++) { for (i = 0; i < uv_simultaneous_server_accepts; i++) {
req = &handle->accept_reqs[i]; req = &handle->accept_reqs[i];
uv_req_init((uv_req_t*)req); uv_req_init(loop, (uv_req_t*)req);
req->type = UV_ACCEPT; req->type = UV_ACCEPT;
req->accept_socket = INVALID_SOCKET; req->accept_socket = INVALID_SOCKET;
req->data = handle; req->data = handle;
@ -379,26 +398,27 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) { int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
uv_loop_t* loop = server->loop;
int rv = 0; int rv = 0;
uv_tcp_accept_t* req = server->pending_accepts; uv_tcp_accept_t* req = server->pending_accepts;
if (!req) { if (!req) {
/* No valid connections found, so we error out. */ /* No valid connections found, so we error out. */
uv_set_sys_error(WSAEWOULDBLOCK); uv_set_sys_error(loop, WSAEWOULDBLOCK);
return -1; return -1;
} }
if (req->accept_socket == INVALID_SOCKET) { if (req->accept_socket == INVALID_SOCKET) {
uv_set_sys_error(WSAENOTCONN); uv_set_sys_error(loop, WSAENOTCONN);
return -1; return -1;
} }
if (uv_tcp_set_socket(client, req->accept_socket) == -1) { if (uv_tcp_set_socket(client->loop, client, req->accept_socket) == -1) {
closesocket(req->accept_socket); closesocket(req->accept_socket);
rv = -1; rv = -1;
} else { } else {
uv_connection_init((uv_stream_t*)client); uv_connection_init((uv_stream_t*) client);
} }
/* Prepare the req to pick up a new connection */ /* Prepare the req to pick up a new connection */
@ -416,19 +436,22 @@ int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
} }
int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb) { int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb,
uv_read_cb read_cb) {
uv_loop_t* loop = handle->loop;
if (!(handle->flags & UV_HANDLE_CONNECTION)) { if (!(handle->flags & UV_HANDLE_CONNECTION)) {
uv_set_sys_error(WSAEINVAL); uv_set_sys_error(loop, WSAEINVAL);
return -1; return -1;
} }
if (handle->flags & UV_HANDLE_READING) { if (handle->flags & UV_HANDLE_READING) {
uv_set_sys_error(WSAEALREADY); uv_set_sys_error(loop, WSAEALREADY);
return -1; return -1;
} }
if (handle->flags & UV_HANDLE_EOF) { if (handle->flags & UV_HANDLE_EOF) {
uv_set_sys_error(WSAESHUTDOWN); uv_set_sys_error(loop, WSAESHUTDOWN);
return -1; return -1;
} }
@ -439,7 +462,7 @@ int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb
/* If reading was stopped and then started again, there could stell be a */ /* If reading was stopped and then started again, there could stell be a */
/* read request pending. */ /* read request pending. */
if (!(handle->flags & UV_HANDLE_READ_PENDING)) if (!(handle->flags & UV_HANDLE_READ_PENDING))
uv_tcp_queue_read(handle); uv_tcp_queue_read(loop, handle);
return 0; return 0;
} }
@ -447,17 +470,18 @@ int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb
int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle, int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle,
struct sockaddr_in address, uv_connect_cb cb) { struct sockaddr_in address, uv_connect_cb cb) {
uv_loop_t* loop = handle->loop;
int addrsize = sizeof(struct sockaddr_in); int addrsize = sizeof(struct sockaddr_in);
BOOL success; BOOL success;
DWORD bytes; DWORD bytes;
if (handle->flags & UV_HANDLE_BIND_ERROR) { if (handle->flags & UV_HANDLE_BIND_ERROR) {
LOOP->last_error = handle->bind_error; loop->last_error = handle->bind_error;
return -1; return -1;
} }
if (address.sin_family != AF_INET) { if (address.sin_family != AF_INET) {
uv_set_sys_error(WSAEFAULT); uv_set_sys_error(loop, WSAEFAULT);
return -1; return -1;
} }
@ -465,7 +489,7 @@ int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle,
uv_tcp_bind(handle, uv_addr_ip4_any_) < 0) uv_tcp_bind(handle, uv_addr_ip4_any_) < 0)
return -1; return -1;
uv_req_init((uv_req_t*) req); uv_req_init(loop, (uv_req_t*) req);
req->type = UV_CONNECT; req->type = UV_CONNECT;
req->handle = (uv_stream_t*) handle; req->handle = (uv_stream_t*) handle;
req->cb = cb; req->cb = cb;
@ -482,12 +506,12 @@ int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle,
if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
/* Process the req without IOCP. */ /* Process the req without IOCP. */
handle->reqs_pending++; handle->reqs_pending++;
uv_insert_pending_req((uv_req_t*)req); uv_insert_pending_req(loop, (uv_req_t*)req);
} else if (UV_SUCCEEDED_WITH_IOCP(success)) { } else if (UV_SUCCEEDED_WITH_IOCP(success)) {
/* The req will be processed with IOCP. */ /* The req will be processed with IOCP. */
handle->reqs_pending++; handle->reqs_pending++;
} else { } else {
uv_set_sys_error(WSAGetLastError()); uv_set_sys_error(loop, WSAGetLastError());
return -1; return -1;
} }
@ -497,6 +521,7 @@ int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle,
int uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle, int uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle,
struct sockaddr_in6 address, uv_connect_cb cb) { struct sockaddr_in6 address, uv_connect_cb cb) {
uv_loop_t* loop = handle->loop;
int addrsize = sizeof(struct sockaddr_in6); int addrsize = sizeof(struct sockaddr_in6);
BOOL success; BOOL success;
DWORD bytes; DWORD bytes;
@ -507,12 +532,12 @@ int uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle,
} }
if (handle->flags & UV_HANDLE_BIND_ERROR) { if (handle->flags & UV_HANDLE_BIND_ERROR) {
LOOP->last_error = handle->bind_error; loop->last_error = handle->bind_error;
return -1; return -1;
} }
if (address.sin6_family != AF_INET6) { if (address.sin6_family != AF_INET6) {
uv_set_sys_error(WSAEFAULT); uv_set_sys_error(loop, WSAEFAULT);
return -1; return -1;
} }
@ -520,7 +545,7 @@ int uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle,
uv_tcp_bind6(handle, uv_addr_ip6_any_) < 0) uv_tcp_bind6(handle, uv_addr_ip6_any_) < 0)
return -1; return -1;
uv_req_init((uv_req_t*) req); uv_req_init(loop, (uv_req_t*) req);
req->type = UV_CONNECT; req->type = UV_CONNECT;
req->handle = (uv_stream_t*) handle; req->handle = (uv_stream_t*) handle;
req->cb = cb; req->cb = cb;
@ -536,11 +561,11 @@ int uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle,
if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
handle->reqs_pending++; handle->reqs_pending++;
uv_insert_pending_req((uv_req_t*)req); uv_insert_pending_req(loop, (uv_req_t*)req);
} else if (UV_SUCCEEDED_WITH_IOCP(success)) { } else if (UV_SUCCEEDED_WITH_IOCP(success)) {
handle->reqs_pending++; handle->reqs_pending++;
} else { } else {
uv_set_sys_error(WSAGetLastError()); uv_set_sys_error(loop, WSAGetLastError());
return -1; return -1;
} }
@ -548,17 +573,18 @@ int uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle,
} }
int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name, int* namelen) { int uv_tcp_getsockname(uv_loop_t* loop, uv_tcp_t* handle,
struct sockaddr* name, int* namelen) {
int result; int result;
if (handle->flags & UV_HANDLE_SHUTTING) { if (handle->flags & UV_HANDLE_SHUTTING) {
uv_set_sys_error(WSAESHUTDOWN); uv_set_sys_error(loop, WSAESHUTDOWN);
return -1; return -1;
} }
result = getsockname(handle->socket, name, namelen); result = getsockname(handle->socket, name, namelen);
if (result != 0) { if (result != 0) {
uv_set_sys_error(WSAGetLastError()); uv_set_sys_error(loop, WSAGetLastError());
return -1; return -1;
} }
@ -566,22 +592,22 @@ int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name, int* namelen) {
} }
int uv_tcp_write(uv_write_t* req, uv_tcp_t* handle, uv_buf_t bufs[], int bufcnt, int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle,
uv_write_cb cb) { uv_buf_t bufs[], int bufcnt, uv_write_cb cb) {
int result; int result;
DWORD bytes; DWORD bytes;
if (!(handle->flags & UV_HANDLE_CONNECTION)) { if (!(handle->flags & UV_HANDLE_CONNECTION)) {
uv_set_sys_error(WSAEINVAL); uv_set_sys_error(loop, WSAEINVAL);
return -1; return -1;
} }
if (handle->flags & UV_HANDLE_SHUTTING) { if (handle->flags & UV_HANDLE_SHUTTING) {
uv_set_sys_error(WSAESHUTDOWN); uv_set_sys_error(loop, WSAESHUTDOWN);
return -1; return -1;
} }
uv_req_init((uv_req_t*) req); uv_req_init(loop, (uv_req_t*) req);
req->type = UV_WRITE; req->type = UV_WRITE;
req->handle = (uv_stream_t*) handle; req->handle = (uv_stream_t*) handle;
req->cb = cb; req->cb = cb;
@ -600,7 +626,7 @@ int uv_tcp_write(uv_write_t* req, uv_tcp_t* handle, uv_buf_t bufs[], int bufcnt,
req->queued_bytes = 0; req->queued_bytes = 0;
handle->reqs_pending++; handle->reqs_pending++;
handle->write_reqs_pending++; handle->write_reqs_pending++;
uv_insert_pending_req((uv_req_t*)req); uv_insert_pending_req(loop, (uv_req_t*) req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
/* Request queued by the kernel. */ /* Request queued by the kernel. */
req->queued_bytes = uv_count_bufs(bufs, bufcnt); req->queued_bytes = uv_count_bufs(bufs, bufcnt);
@ -609,7 +635,7 @@ int uv_tcp_write(uv_write_t* req, uv_tcp_t* handle, uv_buf_t bufs[], int bufcnt,
handle->write_queue_size += req->queued_bytes; handle->write_queue_size += req->queued_bytes;
} else { } else {
/* Send failed due to an error. */ /* Send failed due to an error. */
uv_set_sys_error(WSAGetLastError()); uv_set_sys_error(loop, WSAGetLastError());
return -1; return -1;
} }
@ -617,7 +643,8 @@ int uv_tcp_write(uv_write_t* req, uv_tcp_t* handle, uv_buf_t bufs[], int bufcnt,
} }
void uv_process_tcp_read_req(uv_tcp_t* handle, uv_req_t* req) { void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
uv_req_t* req) {
DWORD bytes, flags, err; DWORD bytes, flags, err;
uv_buf_t buf; uv_buf_t buf;
@ -629,7 +656,7 @@ void uv_process_tcp_read_req(uv_tcp_t* handle, uv_req_t* req) {
/* An error occurred doing the read. */ /* An error occurred doing the read. */
if ((handle->flags & UV_HANDLE_READING)) { if ((handle->flags & UV_HANDLE_READING)) {
handle->flags &= ~UV_HANDLE_READING; handle->flags &= ~UV_HANDLE_READING;
LOOP->last_error = GET_REQ_UV_SOCK_ERROR(req); loop->last_error = GET_REQ_UV_SOCK_ERROR(req);
buf = (handle->flags & UV_HANDLE_ZERO_READ) ? buf = (handle->flags & UV_HANDLE_ZERO_READ) ?
uv_buf_init(NULL, 0) : handle->read_buffer; uv_buf_init(NULL, 0) : handle->read_buffer;
handle->read_cb((uv_stream_t*)handle, -1, buf); handle->read_cb((uv_stream_t*)handle, -1, buf);
@ -639,7 +666,9 @@ void uv_process_tcp_read_req(uv_tcp_t* handle, uv_req_t* req) {
/* The read was done with a non-zero buffer length. */ /* The read was done with a non-zero buffer length. */
if (req->overlapped.InternalHigh > 0) { if (req->overlapped.InternalHigh > 0) {
/* Successful read */ /* Successful read */
handle->read_cb((uv_stream_t*)handle, req->overlapped.InternalHigh, handle->read_buffer); handle->read_cb((uv_stream_t*)handle,
req->overlapped.InternalHigh,
handle->read_buffer);
/* Read again only if bytes == buf.len */ /* Read again only if bytes == buf.len */
if (req->overlapped.InternalHigh < handle->read_buffer.len) { if (req->overlapped.InternalHigh < handle->read_buffer.len) {
goto done; goto done;
@ -648,8 +677,8 @@ void uv_process_tcp_read_req(uv_tcp_t* handle, uv_req_t* req) {
/* Connection closed */ /* Connection closed */
handle->flags &= ~UV_HANDLE_READING; handle->flags &= ~UV_HANDLE_READING;
handle->flags |= UV_HANDLE_EOF; handle->flags |= UV_HANDLE_EOF;
LOOP->last_error.code = UV_EOF; loop->last_error.code = UV_EOF;
LOOP->last_error.sys_errno_ = ERROR_SUCCESS; loop->last_error.sys_errno_ = ERROR_SUCCESS;
buf.base = 0; buf.base = 0;
buf.len = 0; buf.len = 0;
handle->read_cb((uv_stream_t*)handle, -1, handle->read_buffer); handle->read_cb((uv_stream_t*)handle, -1, handle->read_buffer);
@ -680,8 +709,8 @@ void uv_process_tcp_read_req(uv_tcp_t* handle, uv_req_t* req) {
/* Connection closed */ /* Connection closed */
handle->flags &= ~UV_HANDLE_READING; handle->flags &= ~UV_HANDLE_READING;
handle->flags |= UV_HANDLE_EOF; handle->flags |= UV_HANDLE_EOF;
LOOP->last_error.code = UV_EOF; loop->last_error.code = UV_EOF;
LOOP->last_error.sys_errno_ = ERROR_SUCCESS; loop->last_error.sys_errno_ = ERROR_SUCCESS;
handle->read_cb((uv_stream_t*)handle, -1, buf); handle->read_cb((uv_stream_t*)handle, -1, buf);
break; break;
} }
@ -689,11 +718,11 @@ void uv_process_tcp_read_req(uv_tcp_t* handle, uv_req_t* req) {
err = WSAGetLastError(); err = WSAGetLastError();
if (err == WSAEWOULDBLOCK) { if (err == WSAEWOULDBLOCK) {
/* Read buffer was completely empty, report a 0-byte read. */ /* Read buffer was completely empty, report a 0-byte read. */
uv_set_sys_error(WSAEWOULDBLOCK); uv_set_sys_error(loop, WSAEWOULDBLOCK);
handle->read_cb((uv_stream_t*)handle, 0, buf); handle->read_cb((uv_stream_t*)handle, 0, buf);
} else { } else {
/* Ouch! serious error. */ /* Ouch! serious error. */
uv_set_sys_error(err); uv_set_sys_error(loop, err);
handle->flags &= ~UV_HANDLE_READING; handle->flags &= ~UV_HANDLE_READING;
handle->read_cb((uv_stream_t*)handle, -1, buf); handle->read_cb((uv_stream_t*)handle, -1, buf);
} }
@ -705,7 +734,7 @@ done:
/* Post another read if still reading and not closing. */ /* Post another read if still reading and not closing. */
if ((handle->flags & UV_HANDLE_READING) && if ((handle->flags & UV_HANDLE_READING) &&
!(handle->flags & UV_HANDLE_READ_PENDING)) { !(handle->flags & UV_HANDLE_READ_PENDING)) {
uv_tcp_queue_read(handle); uv_tcp_queue_read(loop, handle);
} }
} }
@ -713,27 +742,29 @@ done:
} }
void uv_process_tcp_write_req(uv_tcp_t* handle, uv_write_t* req) { void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
uv_write_t* req) {
assert(handle->type == UV_TCP); assert(handle->type == UV_TCP);
handle->write_queue_size -= req->queued_bytes; handle->write_queue_size -= req->queued_bytes;
if (req->cb) { if (req->cb) {
LOOP->last_error = GET_REQ_UV_SOCK_ERROR(req); loop->last_error = GET_REQ_UV_SOCK_ERROR(req);
((uv_write_cb)req->cb)(req, LOOP->last_error.code == UV_OK ? 0 : -1); ((uv_write_cb)req->cb)(req, loop->last_error.code == UV_OK ? 0 : -1);
} }
handle->write_reqs_pending--; handle->write_reqs_pending--;
if (handle->flags & UV_HANDLE_SHUTTING && if (handle->flags & UV_HANDLE_SHUTTING &&
handle->write_reqs_pending == 0) { handle->write_reqs_pending == 0) {
uv_want_endgame((uv_handle_t*)handle); uv_want_endgame(loop, (uv_handle_t*)handle);
} }
DECREASE_PENDING_REQ_COUNT(handle); DECREASE_PENDING_REQ_COUNT(handle);
} }
void uv_process_tcp_accept_req(uv_tcp_t* handle, uv_req_t* raw_req) { void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle,
uv_req_t* raw_req) {
uv_tcp_accept_t* req = (uv_tcp_accept_t*) raw_req; uv_tcp_accept_t* req = (uv_tcp_accept_t*) raw_req;
assert(handle->type == UV_TCP); assert(handle->type == UV_TCP);
@ -746,7 +777,7 @@ void uv_process_tcp_accept_req(uv_tcp_t* handle, uv_req_t* raw_req) {
if (handle->flags & UV_HANDLE_LISTENING) { if (handle->flags & UV_HANDLE_LISTENING) {
handle->flags &= ~UV_HANDLE_LISTENING; handle->flags &= ~UV_HANDLE_LISTENING;
if (handle->connection_cb) { if (handle->connection_cb) {
LOOP->last_error = GET_REQ_UV_SOCK_ERROR(req); loop->last_error = GET_REQ_UV_SOCK_ERROR(req);
handle->connection_cb((uv_stream_t*)handle, -1); handle->connection_cb((uv_stream_t*)handle, -1);
} }
} }
@ -778,7 +809,8 @@ void uv_process_tcp_accept_req(uv_tcp_t* handle, uv_req_t* raw_req) {
} }
void uv_process_tcp_connect_req(uv_tcp_t* handle, uv_connect_t* req) { void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
uv_connect_t* req) {
assert(handle->type == UV_TCP); assert(handle->type == UV_TCP);
if (req->cb) { if (req->cb) {
@ -792,11 +824,11 @@ void uv_process_tcp_connect_req(uv_tcp_t* handle, uv_connect_t* req) {
active_tcp_streams++; active_tcp_streams++;
((uv_connect_cb)req->cb)(req, 0); ((uv_connect_cb)req->cb)(req, 0);
} else { } else {
uv_set_sys_error(WSAGetLastError()); uv_set_sys_error(loop, WSAGetLastError());
((uv_connect_cb)req->cb)(req, -1); ((uv_connect_cb)req->cb)(req, -1);
} }
} else { } else {
LOOP->last_error = GET_REQ_UV_SOCK_ERROR(req); loop->last_error = GET_REQ_UV_SOCK_ERROR(req);
((uv_connect_cb)req->cb)(req, -1); ((uv_connect_cb)req->cb)(req, -1);
} }
} }

22
deps/uv/src/win/threadpool.c

@ -25,9 +25,11 @@
#include "internal.h" #include "internal.h"
static void uv_work_req_init(uv_work_t* req, uv_work_cb work_cb, uv_after_work_cb after_work_cb) { static void uv_work_req_init(uv_loop_t* loop, uv_work_t* req,
uv_req_init((uv_req_t*) req); uv_work_cb work_cb, uv_after_work_cb after_work_cb) {
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_WORK; req->type = UV_WORK;
req->loop = loop;
req->work_cb = work_cb; req->work_cb = work_cb;
req->after_work_cb = after_work_cb; req->after_work_cb = after_work_cb;
memset(&req->overlapped, 0, sizeof(req->overlapped)); memset(&req->overlapped, 0, sizeof(req->overlapped));
@ -36,6 +38,7 @@ static void uv_work_req_init(uv_work_t* req, uv_work_cb work_cb, uv_after_work_c
static DWORD WINAPI uv_work_thread_proc(void* parameter) { static DWORD WINAPI uv_work_thread_proc(void* parameter) {
uv_work_t* req = (uv_work_t*)parameter; uv_work_t* req = (uv_work_t*)parameter;
uv_loop_t* loop = req->loop;
assert(req != NULL); assert(req != NULL);
assert(req->type == UV_WORK); assert(req->type == UV_WORK);
@ -43,27 +46,28 @@ static DWORD WINAPI uv_work_thread_proc(void* parameter) {
req->work_cb(req); req->work_cb(req);
POST_COMPLETION_FOR_REQ(req); POST_COMPLETION_FOR_REQ(loop, req);
return 0; return 0;
} }
int uv_queue_work(uv_work_t* req, uv_work_cb work_cb, uv_after_work_cb after_work_cb) { int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb,
uv_work_req_init(req, work_cb, after_work_cb); uv_after_work_cb after_work_cb) {
uv_work_req_init(loop, req, work_cb, after_work_cb);
if (!QueueUserWorkItem(&uv_work_thread_proc, req, WT_EXECUTELONGFUNCTION)) { if (!QueueUserWorkItem(&uv_work_thread_proc, req, WT_EXECUTELONGFUNCTION)) {
uv_set_sys_error(GetLastError()); uv_set_sys_error(loop, GetLastError());
return -1; return -1;
} }
uv_ref(); uv_ref(loop);
return 0; return 0;
} }
void uv_process_work_req(uv_work_t* req) { void uv_process_work_req(uv_loop_t* loop, uv_work_t* req) {
assert(req->after_work_cb); assert(req->after_work_cb);
req->after_work_cb(req); req->after_work_cb(req);
uv_unref(); uv_unref(loop);
} }

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

@ -36,12 +36,12 @@ static uint64_t uv_hrtime_frequency_ = 0;
static char uv_hrtime_initialized_ = 0; static char uv_hrtime_initialized_ = 0;
void uv_update_time() { void uv_update_time(uv_loop_t* loop) {
DWORD ticks = GetTickCount(); DWORD ticks = GetTickCount();
/* The assumption is made that LARGE_INTEGER.QuadPart has the same type */ /* The assumption is made that LARGE_INTEGER.QuadPart has the same type */
/* LOOP->time, which happens to be. Is there any way to assert this? */ /* loop->time, which happens to be. Is there any way to assert this? */
LARGE_INTEGER* time = (LARGE_INTEGER*) &LOOP->time; LARGE_INTEGER* time = (LARGE_INTEGER*) &loop->time;
/* If the timer has wrapped, add 1 to it's high-order dword. */ /* If the timer has wrapped, add 1 to it's high-order dword. */
/* uv_poll must make sure that the timer can never overflow more than */ /* uv_poll must make sure that the timer can never overflow more than */
@ -53,11 +53,11 @@ void uv_update_time() {
} }
int64_t uv_now() { int64_t uv_now(uv_loop_t* loop) {
return LOOP->time; return loop->time;
} }
/* TODO: thread safety */
uint64_t uv_hrtime(void) { uint64_t uv_hrtime(void) {
LARGE_INTEGER counter; LARGE_INTEGER counter;
@ -68,7 +68,7 @@ uint64_t uv_hrtime(void) {
if (!QueryPerformanceFrequency(&counter)) { if (!QueryPerformanceFrequency(&counter)) {
uv_hrtime_frequency_ = 0; uv_hrtime_frequency_ = 0;
uv_set_sys_error(GetLastError()); /* uv_set_sys_error(loop, GetLastError()); */
return 0; return 0;
} }
@ -77,12 +77,12 @@ uint64_t uv_hrtime(void) {
/* If the performance frequency is zero, there's no support. */ /* If the performance frequency is zero, there's no support. */
if (!uv_hrtime_frequency_) { if (!uv_hrtime_frequency_) {
uv_set_sys_error(ERROR_NOT_SUPPORTED); /* uv_set_sys_error(loop, ERROR_NOT_SUPPORTED); */
return 0; return 0;
} }
if (!QueryPerformanceCounter(&counter)) { if (!QueryPerformanceCounter(&counter)) {
uv_set_sys_error(GetLastError()); /* uv_set_sys_error(loop, GetLastError()); */
return 0; return 0;
} }
@ -111,22 +111,23 @@ static int uv_timer_compare(uv_timer_t* a, uv_timer_t* b) {
RB_GENERATE_STATIC(uv_timer_tree_s, uv_timer_s, tree_entry, uv_timer_compare); RB_GENERATE_STATIC(uv_timer_tree_s, uv_timer_s, tree_entry, uv_timer_compare);
int uv_timer_init(uv_timer_t* handle) { int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
uv_counters()->handle_init++; loop->counters.handle_init++;
uv_counters()->timer_init++; loop->counters.timer_init++;
handle->type = UV_TIMER; handle->type = UV_TIMER;
handle->loop = loop;
handle->flags = 0; handle->flags = 0;
handle->timer_cb = NULL; handle->timer_cb = NULL;
handle->repeat = 0; handle->repeat = 0;
uv_ref(); uv_ref(loop);
return 0; return 0;
} }
void uv_timer_endgame(uv_timer_t* handle) { void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle) {
if (handle->flags & UV_HANDLE_CLOSING) { if (handle->flags & UV_HANDLE_CLOSING) {
assert(!(handle->flags & UV_HANDLE_CLOSED)); assert(!(handle->flags & UV_HANDLE_CLOSED));
handle->flags |= UV_HANDLE_CLOSED; handle->flags |= UV_HANDLE_CLOSED;
@ -135,22 +136,25 @@ void uv_timer_endgame(uv_timer_t* handle) {
handle->close_cb((uv_handle_t*)handle); handle->close_cb((uv_handle_t*)handle);
} }
uv_unref(); uv_unref(loop);
} }
} }
int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, int64_t timeout, int64_t repeat) { int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, int64_t timeout,
int64_t repeat) {
uv_loop_t* loop = handle->loop;
if (handle->flags & UV_HANDLE_ACTIVE) { if (handle->flags & UV_HANDLE_ACTIVE) {
RB_REMOVE(uv_timer_tree_s, &LOOP->timers, handle); RB_REMOVE(uv_timer_tree_s, &loop->timers, handle);
} }
handle->timer_cb = timer_cb; handle->timer_cb = timer_cb;
handle->due = LOOP->time + timeout; handle->due = loop->time + timeout;
handle->repeat = repeat; handle->repeat = repeat;
handle->flags |= UV_HANDLE_ACTIVE; handle->flags |= UV_HANDLE_ACTIVE;
if (RB_INSERT(uv_timer_tree_s, &LOOP->timers, handle) != NULL) { if (RB_INSERT(uv_timer_tree_s, &loop->timers, handle) != NULL) {
uv_fatal_error(ERROR_INVALID_DATA, "RB_INSERT"); uv_fatal_error(ERROR_INVALID_DATA, "RB_INSERT");
} }
@ -159,10 +163,12 @@ int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, int64_t timeout, in
int uv_timer_stop(uv_timer_t* handle) { int uv_timer_stop(uv_timer_t* handle) {
uv_loop_t* loop = handle->loop;
if (!(handle->flags & UV_HANDLE_ACTIVE)) if (!(handle->flags & UV_HANDLE_ACTIVE))
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; handle->flags &= ~UV_HANDLE_ACTIVE;
@ -171,21 +177,23 @@ 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) {
uv_set_sys_error(ERROR_INVALID_DATA); uv_set_sys_error(loop, ERROR_INVALID_DATA);
return -1; return -1;
} }
if (handle->flags & UV_HANDLE_ACTIVE) { if (handle->flags & UV_HANDLE_ACTIVE) {
RB_REMOVE(uv_timer_tree_s, &LOOP->timers, handle); RB_REMOVE(uv_timer_tree_s, &loop->timers, handle);
handle->flags &= ~UV_HANDLE_ACTIVE; handle->flags &= ~UV_HANDLE_ACTIVE;
} }
if (handle->repeat) { if (handle->repeat) {
handle->due = LOOP->time + handle->repeat; handle->due = loop->time + handle->repeat;
if (RB_INSERT(uv_timer_tree_s, &LOOP->timers, handle) != NULL) { if (RB_INSERT(uv_timer_tree_s, &loop->timers, handle) != NULL) {
uv_fatal_error(ERROR_INVALID_DATA, "RB_INSERT"); uv_fatal_error(ERROR_INVALID_DATA, "RB_INSERT");
} }
@ -208,16 +216,16 @@ int64_t uv_timer_get_repeat(uv_timer_t* handle) {
} }
DWORD uv_get_poll_timeout() { DWORD uv_get_poll_timeout(uv_loop_t* loop) {
uv_timer_t* timer; uv_timer_t* timer;
int64_t delta; int64_t delta;
/* Check if there are any running timers */ /* Check if there are any running timers */
timer = RB_MIN(uv_timer_tree_s, &LOOP->timers); timer = RB_MIN(uv_timer_tree_s, &loop->timers);
if (timer) { if (timer) {
uv_update_time(); uv_update_time(loop);
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. But */
/* more importantly, there's always the risk that GetTickCount wraps. */ /* more importantly, there's always the risk that GetTickCount wraps. */
@ -240,22 +248,22 @@ DWORD uv_get_poll_timeout() {
} }
void uv_process_timers() { void uv_process_timers(uv_loop_t* loop) {
uv_timer_t* timer; uv_timer_t* timer;
/* Call timer callbacks */ /* Call timer callbacks */
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); RB_REMOVE(uv_timer_tree_s, &loop->timers, timer);
if (timer->repeat != 0) { if (timer->repeat != 0) {
/* If it is a repeating timer, reschedule with repeat timeout. */ /* If it is a repeating timer, reschedule with repeat timeout. */
timer->due += timer->repeat; timer->due += timer->repeat;
if (timer->due < LOOP->time) { if (timer->due < loop->time) {
timer->due = LOOP->time; timer->due = loop->time;
} }
if (RB_INSERT(uv_timer_tree_s, &LOOP->timers, timer) != NULL) { if (RB_INSERT(uv_timer_tree_s, &loop->timers, timer) != NULL) {
uv_fatal_error(ERROR_INVALID_DATA, "RB_INSERT"); uv_fatal_error(ERROR_INVALID_DATA, "RB_INSERT");
} }
} else { } else {

117
deps/uv/src/win/udp.c

@ -40,12 +40,13 @@ static char uv_zero_[] = "";
static unsigned int active_udp_streams = 0; static unsigned int active_udp_streams = 0;
int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, int* namelen) { int uv_udp_getsockname(uv_loop_t* loop, uv_udp_t* handle,
struct sockaddr* name, int* namelen) {
int result; int result;
result = getsockname(handle->socket, name, namelen); result = getsockname(handle->socket, name, namelen);
if (result != 0) { if (result != 0) {
uv_set_sys_error(WSAGetLastError()); uv_set_sys_error(loop, WSAGetLastError());
return -1; return -1;
} }
@ -53,37 +54,38 @@ int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, int* namelen) {
} }
static int uv_udp_set_socket(uv_udp_t* handle, SOCKET socket) { static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle,
SOCKET socket) {
DWORD yes = 1; DWORD yes = 1;
assert(handle->socket == INVALID_SOCKET); assert(handle->socket == INVALID_SOCKET);
/* Set the socket to nonblocking mode */ /* Set the socket to nonblocking mode */
if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) { if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) {
uv_set_sys_error(WSAGetLastError()); uv_set_sys_error(loop, WSAGetLastError());
return -1; return -1;
} }
/* Make the socket non-inheritable */ /* Make the socket non-inheritable */
if (!SetHandleInformation((HANDLE)socket, HANDLE_FLAG_INHERIT, 0)) { if (!SetHandleInformation((HANDLE)socket, HANDLE_FLAG_INHERIT, 0)) {
uv_set_sys_error(GetLastError()); uv_set_sys_error(loop, GetLastError());
return -1; return -1;
} }
/* Associate it with the I/O completion port. */ /* Associate it with the I/O completion port. */
/* Use uv_handle_t pointer as completion key. */ /* Use uv_handle_t pointer as completion key. */
if (CreateIoCompletionPort((HANDLE)socket, if (CreateIoCompletionPort((HANDLE)socket,
LOOP->iocp, loop->iocp,
(ULONG_PTR)socket, (ULONG_PTR)socket,
0) == NULL) { 0) == NULL) {
uv_set_sys_error(GetLastError()); uv_set_sys_error(loop, GetLastError());
return -1; return -1;
} }
if (pSetFileCompletionNotificationModes) { if (pSetFileCompletionNotificationModes) {
if (!pSetFileCompletionNotificationModes((HANDLE)socket, FILE_SKIP_SET_EVENT_ON_HANDLE | if (!pSetFileCompletionNotificationModes((HANDLE)socket,
FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) { FILE_SKIP_SET_EVENT_ON_HANDLE | FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) {
uv_set_sys_error(GetLastError()); uv_set_sys_error(loop, GetLastError());
return -1; return -1;
} }
@ -96,26 +98,27 @@ static int uv_udp_set_socket(uv_udp_t* handle, SOCKET socket) {
} }
int uv_udp_init(uv_udp_t* handle) { int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
handle->type = UV_UDP; handle->type = UV_UDP;
handle->socket = INVALID_SOCKET; handle->socket = INVALID_SOCKET;
handle->reqs_pending = 0; handle->reqs_pending = 0;
handle->loop = loop;
handle->flags = 0; handle->flags = 0;
uv_req_init((uv_req_t*) &(handle->recv_req)); uv_req_init(loop, (uv_req_t*) &(handle->recv_req));
handle->recv_req.type = UV_UDP_RECV; handle->recv_req.type = UV_UDP_RECV;
handle->recv_req.data = handle; handle->recv_req.data = handle;
uv_ref(); uv_ref(loop);
uv_counters()->handle_init++; loop->counters.handle_init++;
uv_counters()->udp_init++; loop->counters.udp_init++;
return 0; return 0;
} }
void uv_udp_endgame(uv_udp_t* handle) { void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle) {
if (handle->flags & UV_HANDLE_CLOSING && if (handle->flags & UV_HANDLE_CLOSING &&
handle->reqs_pending == 0) { handle->reqs_pending == 0) {
assert(!(handle->flags & UV_HANDLE_CLOSED)); assert(!(handle->flags & UV_HANDLE_CLOSED));
@ -125,30 +128,31 @@ void uv_udp_endgame(uv_udp_t* handle) {
handle->close_cb((uv_handle_t*)handle); handle->close_cb((uv_handle_t*)handle);
} }
uv_unref(); uv_unref(loop);
} }
} }
static int uv__bind(uv_udp_t* handle, int domain, struct sockaddr* addr, static int uv__bind(uv_udp_t* handle, int domain, struct sockaddr* addr,
int addrsize, unsigned int flags) { int addrsize, unsigned int flags) {
uv_loop_t* loop = handle->loop;
DWORD err; DWORD err;
int r; int r;
SOCKET sock; SOCKET sock;
if ((flags & UV_UDP_IPV6ONLY) && domain != AF_INET6) { if ((flags & UV_UDP_IPV6ONLY) && domain != AF_INET6) {
/* UV_UDP_IPV6ONLY is supported only for IPV6 sockets */ /* UV_UDP_IPV6ONLY is supported only for IPV6 sockets */
uv_set_sys_error(UV_EINVAL); uv_set_sys_error(loop, UV_EINVAL);
} }
if (handle->socket == INVALID_SOCKET) { if (handle->socket == INVALID_SOCKET) {
sock = socket(domain, SOCK_DGRAM, 0); sock = socket(domain, SOCK_DGRAM, 0);
if (sock == INVALID_SOCKET) { if (sock == INVALID_SOCKET) {
uv_set_sys_error(WSAGetLastError()); uv_set_sys_error(loop, WSAGetLastError());
return -1; return -1;
} }
if (uv_udp_set_socket(handle, sock) == -1) { if (uv_udp_set_socket(loop, handle, sock) == -1) {
closesocket(sock); closesocket(sock);
return -1; return -1;
} }
@ -162,14 +166,18 @@ static int uv__bind(uv_udp_t* handle, int domain, struct sockaddr* addr,
/* TODO: how to handle errors? This may fail if there is no ipv4 stack */ /* TODO: how to handle errors? This may fail if there is no ipv4 stack */
/* available, or when run on XP/2003 which have no support for dualstack */ /* available, or when run on XP/2003 which have no support for dualstack */
/* sockets. For now we're silently ignoring the error. */ /* sockets. For now we're silently ignoring the error. */
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*) &off, sizeof off); setsockopt(sock,
IPPROTO_IPV6,
IPV6_V6ONLY,
(const char*) &off,
sizeof off);
} }
r = bind(handle->socket, addr, addrsize); r = bind(handle->socket, addr, addrsize);
if (r == SOCKET_ERROR) { if (r == SOCKET_ERROR) {
err = WSAGetLastError(); err = WSAGetLastError();
uv_set_sys_error(WSAGetLastError()); uv_set_sys_error(loop, WSAGetLastError());
return -1; return -1;
} }
@ -179,9 +187,12 @@ static int uv__bind(uv_udp_t* handle, int domain, struct sockaddr* addr,
} }
int uv_udp_bind(uv_udp_t* handle, struct sockaddr_in addr, unsigned int flags) { int uv_udp_bind(uv_udp_t* handle, struct sockaddr_in addr,
unsigned int flags) {
uv_loop_t* loop = handle->loop;
if (addr.sin_family != AF_INET) { if (addr.sin_family != AF_INET) {
uv_set_sys_error(WSAEFAULT); uv_set_sys_error(loop, WSAEFAULT);
return -1; return -1;
} }
@ -193,9 +204,12 @@ int uv_udp_bind(uv_udp_t* handle, struct sockaddr_in addr, unsigned int flags) {
} }
int uv_udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr, unsigned int flags) { int uv_udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr,
unsigned int flags) {
uv_loop_t* loop = handle->loop;
if (addr.sin6_family != AF_INET6) { if (addr.sin6_family != AF_INET6) {
uv_set_sys_error(WSAEFAULT); uv_set_sys_error(loop, WSAEFAULT);
return -1; return -1;
} }
@ -213,7 +227,7 @@ int uv_udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr, unsigned int flags)
} }
static void uv_udp_queue_recv(uv_udp_t* handle) { static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) {
uv_req_t* req; uv_req_t* req;
uv_buf_t buf; uv_buf_t buf;
DWORD bytes, flags; DWORD bytes, flags;
@ -256,7 +270,7 @@ static void uv_udp_queue_recv(uv_udp_t* handle) {
handle->flags |= UV_HANDLE_READ_PENDING; handle->flags |= UV_HANDLE_READ_PENDING;
req->overlapped.InternalHigh = bytes; req->overlapped.InternalHigh = bytes;
handle->reqs_pending++; handle->reqs_pending++;
uv_insert_pending_req(req); uv_insert_pending_req(loop, req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
/* The req will be processed with IOCP. */ /* The req will be processed with IOCP. */
handle->flags |= UV_HANDLE_READ_PENDING; handle->flags |= UV_HANDLE_READ_PENDING;
@ -264,7 +278,7 @@ static void uv_udp_queue_recv(uv_udp_t* handle) {
} else { } else {
/* Make this req pending reporting an error. */ /* Make this req pending reporting an error. */
SET_REQ_ERROR(req, WSAGetLastError()); SET_REQ_ERROR(req, WSAGetLastError());
uv_insert_pending_req(req); uv_insert_pending_req(loop, req);
handle->reqs_pending++; handle->reqs_pending++;
} }
#if 0 #if 0
@ -288,7 +302,7 @@ static void uv_udp_queue_recv(uv_udp_t* handle) {
handle->flags |= UV_HANDLE_READ_PENDING; handle->flags |= UV_HANDLE_READ_PENDING;
req->overlapped.InternalHigh = bytes; req->overlapped.InternalHigh = bytes;
handle->reqs_pending++; handle->reqs_pending++;
uv_insert_pending_req(req); uv_insert_pending_req(loop, req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
/* The req will be processed with IOCP. */ /* The req will be processed with IOCP. */
handle->flags |= UV_HANDLE_READ_PENDING; handle->flags |= UV_HANDLE_READ_PENDING;
@ -296,7 +310,7 @@ static void uv_udp_queue_recv(uv_udp_t* handle) {
} else { } else {
/* Make this req pending reporting an error. */ /* Make this req pending reporting an error. */
SET_REQ_ERROR(req, WSAGetLastError()); SET_REQ_ERROR(req, WSAGetLastError());
uv_insert_pending_req(req); uv_insert_pending_req(loop, req);
handle->reqs_pending++; handle->reqs_pending++;
} }
} }
@ -304,9 +318,12 @@ static void uv_udp_queue_recv(uv_udp_t* handle) {
} }
int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb, uv_udp_recv_cb recv_cb) { int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
uv_udp_recv_cb recv_cb) {
uv_loop_t* loop = handle->loop;
if (handle->flags & UV_HANDLE_READING) { if (handle->flags & UV_HANDLE_READING) {
uv_set_sys_error(WSAEALREADY); uv_set_sys_error(loop, WSAEALREADY);
return -1; return -1;
} }
@ -324,7 +341,7 @@ int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb, uv_udp_recv_cb rec
/* If reading was stopped and then started again, there could stell be a */ /* If reading was stopped and then started again, there could stell be a */
/* recv request pending. */ /* recv request pending. */
if (!(handle->flags & UV_HANDLE_READ_PENDING)) if (!(handle->flags & UV_HANDLE_READ_PENDING))
uv_udp_queue_recv(handle); uv_udp_queue_recv(loop, handle);
return 0; return 0;
} }
@ -342,6 +359,7 @@ int uv_udp_recv_stop(uv_udp_t* handle) {
int uv_udp_connect6(uv_connect_t* req, uv_udp_t* handle, int uv_udp_connect6(uv_connect_t* req, uv_udp_t* handle,
struct sockaddr_in6 address, uv_connect_cb cb) { struct sockaddr_in6 address, uv_connect_cb cb) {
uv_loop_t* loop = handle->loop;
int addrsize = sizeof(struct sockaddr_in6); int addrsize = sizeof(struct sockaddr_in6);
BOOL success; BOOL success;
DWORD bytes; DWORD bytes;
@ -352,7 +370,7 @@ int uv_udp_connect6(uv_connect_t* req, uv_udp_t* handle,
} }
if (address.sin6_family != AF_INET6) { if (address.sin6_family != AF_INET6) {
uv_set_sys_error(WSAEFAULT); uv_set_sys_error(loop, WSAEFAULT);
return -1; return -1;
} }
@ -360,7 +378,7 @@ int uv_udp_connect6(uv_connect_t* req, uv_udp_t* handle,
uv_udp_bind6(handle, uv_addr_ip6_any_, 0) < 0) uv_udp_bind6(handle, uv_addr_ip6_any_, 0) < 0)
return -1; return -1;
uv_req_init((uv_req_t*) req); uv_req_init(loop, (uv_req_t*) req);
req->type = UV_CONNECT; req->type = UV_CONNECT;
req->handle = (uv_stream_t*) handle; req->handle = (uv_stream_t*) handle;
req->cb = cb; req->cb = cb;
@ -376,11 +394,11 @@ int uv_udp_connect6(uv_connect_t* req, uv_udp_t* handle,
if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
handle->reqs_pending++; handle->reqs_pending++;
uv_insert_pending_req((uv_req_t*)req); uv_insert_pending_req(loop, (uv_req_t*)req);
} else if (UV_SUCCEEDED_WITH_IOCP(success)) { } else if (UV_SUCCEEDED_WITH_IOCP(success)) {
handle->reqs_pending++; handle->reqs_pending++;
} else { } else {
uv_set_sys_error(WSAGetLastError()); uv_set_sys_error(loop, WSAGetLastError());
return -1; return -1;
} }
@ -390,9 +408,10 @@ int uv_udp_connect6(uv_connect_t* req, uv_udp_t* handle,
static int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[], static int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
int bufcnt, struct sockaddr* addr, int addr_len, uv_udp_send_cb cb) { int bufcnt, struct sockaddr* addr, int addr_len, uv_udp_send_cb cb) {
uv_loop_t* loop = handle->loop;
DWORD result, bytes; DWORD result, bytes;
uv_req_init((uv_req_t*) req); uv_req_init(loop, (uv_req_t*) req);
req->type = UV_UDP_SEND; req->type = UV_UDP_SEND;
req->handle = handle; req->handle = handle;
req->cb = cb; req->cb = cb;
@ -412,14 +431,14 @@ static int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
/* Request completed immediately. */ /* Request completed immediately. */
req->queued_bytes = 0; req->queued_bytes = 0;
handle->reqs_pending++; handle->reqs_pending++;
uv_insert_pending_req((uv_req_t*)req); uv_insert_pending_req(loop, (uv_req_t*)req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
/* Request queued by the kernel. */ /* Request queued by the kernel. */
req->queued_bytes = uv_count_bufs(bufs, bufcnt); req->queued_bytes = uv_count_bufs(bufs, bufcnt);
handle->reqs_pending++; handle->reqs_pending++;
} else { } else {
/* Send failed due to an error. */ /* Send failed due to an error. */
uv_set_sys_error(WSAGetLastError()); uv_set_sys_error(loop, WSAGetLastError());
return -1; return -1;
} }
@ -463,7 +482,8 @@ int uv_udp_send6(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
} }
void uv_process_udp_recv_req(uv_udp_t* handle, uv_req_t* req) { void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle,
uv_req_t* req) {
uv_buf_t buf; uv_buf_t buf;
int partial; int partial;
@ -475,7 +495,7 @@ void uv_process_udp_recv_req(uv_udp_t* handle, uv_req_t* req) {
GET_REQ_STATUS(req) != STATUS_RECEIVE_EXPEDITED) { GET_REQ_STATUS(req) != STATUS_RECEIVE_EXPEDITED) {
/* An error occurred doing the read. */ /* An error occurred doing the read. */
if ((handle->flags & UV_HANDLE_READING)) { if ((handle->flags & UV_HANDLE_READING)) {
LOOP->last_error = GET_REQ_UV_SOCK_ERROR(req); loop->last_error = GET_REQ_UV_SOCK_ERROR(req);
uv_udp_recv_stop(handle); uv_udp_recv_stop(handle);
#if 0 #if 0
buf = (handle->flags & UV_HANDLE_ZERO_READ) ? buf = (handle->flags & UV_HANDLE_ZERO_READ) ?
@ -532,11 +552,11 @@ void uv_process_udp_recv_req(uv_udp_t* handle, uv_req_t* req) {
} else { } else {
err = WSAGetLastError(); err = WSAGetLastError();
if (err == WSAEWOULDBLOCK) { if (err == WSAEWOULDBLOCK) {
uv_set_sys_error(WSAEWOULDBLOCK); uv_set_sys_error(loop, WSAEWOULDBLOCK);
handle->recv_cb(handle, 0, buf, NULL, 0); handle->recv_cb(handle, 0, buf, NULL, 0);
} else { } else {
/* Ouch! serious error. */ /* Ouch! serious error. */
uv_set_sys_error(err); uv_set_sys_error(loop, err);
handle->recv_cb(handle, -1, buf, NULL, 0); handle->recv_cb(handle, -1, buf, NULL, 0);
} }
} }
@ -547,21 +567,22 @@ done:
/* Post another read if still reading and not closing. */ /* Post another read if still reading and not closing. */
if ((handle->flags & UV_HANDLE_READING) && if ((handle->flags & UV_HANDLE_READING) &&
!(handle->flags & UV_HANDLE_READ_PENDING)) { !(handle->flags & UV_HANDLE_READ_PENDING)) {
uv_udp_queue_recv(handle); uv_udp_queue_recv(loop, handle);
} }
DECREASE_PENDING_REQ_COUNT(handle); DECREASE_PENDING_REQ_COUNT(handle);
} }
void uv_process_udp_send_req(uv_udp_t* handle, uv_udp_send_t* req) { void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle,
uv_udp_send_t* req) {
assert(handle->type == UV_UDP); assert(handle->type == UV_UDP);
if (req->cb) { if (req->cb) {
if (REQ_SUCCESS(req)) { if (REQ_SUCCESS(req)) {
req->cb(req, 0); req->cb(req, 0);
} else { } else {
LOOP->last_error = GET_REQ_UV_SOCK_ERROR(req); loop->last_error = GET_REQ_UV_SOCK_ERROR(req);
req->cb(req, -1); req->cb(req, -1);
} }
} }

26
deps/uv/src/win/util.c

@ -27,13 +27,27 @@
#include "internal.h" #include "internal.h"
int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size, char* utf8Buffer, size_t utf8Size) { int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size,
return WideCharToMultiByte(CP_UTF8, 0, utf16Buffer, utf16Size, utf8Buffer, utf8Size, NULL, NULL); char* utf8Buffer, size_t utf8Size) {
return WideCharToMultiByte(CP_UTF8,
0,
utf16Buffer,
utf16Size,
utf8Buffer,
utf8Size,
NULL,
NULL);
} }
int uv_utf8_to_utf16(const char* utf8Buffer, wchar_t* utf16Buffer, size_t utf16Size) { int uv_utf8_to_utf16(const char* utf8Buffer, wchar_t* utf16Buffer,
return MultiByteToWideChar(CP_UTF8, 0, utf8Buffer, -1, utf16Buffer, utf16Size); size_t utf16Size) {
return MultiByteToWideChar(CP_UTF8,
0,
utf8Buffer,
-1,
utf16Buffer,
utf16Size);
} }
@ -55,7 +69,7 @@ int uv_exepath(char* buffer, size_t* size) {
/* Get the path as UTF-16 */ /* Get the path as UTF-16 */
utf16Size = GetModuleFileNameW(NULL, utf16Buffer, *size - 1); utf16Size = GetModuleFileNameW(NULL, utf16Buffer, *size - 1);
if (utf16Size <= 0) { if (utf16Size <= 0) {
uv_set_sys_error(GetLastError()); /* uv_set_sys_error(loop, GetLastError()); */
retVal = -1; retVal = -1;
goto done; goto done;
} }
@ -65,7 +79,7 @@ int uv_exepath(char* buffer, size_t* size) {
/* Convert to UTF-8 */ /* Convert to UTF-8 */
*size = uv_utf16_to_utf8(utf16Buffer, utf16Size, buffer, *size); *size = uv_utf16_to_utf8(utf16Buffer, utf16Size, buffer, *size);
if (!*size) { if (!*size) {
uv_set_sys_error(GetLastError()); /* uv_set_sys_error(loop, GetLastError()); */
retVal = -1; retVal = -1;
goto done; goto done;
} }

16
deps/uv/test/benchmark-ares.c

@ -26,6 +26,8 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> /* strlen */ #include <string.h> /* strlen */
static uv_loop_t* loop;
ares_channel channel; ares_channel channel;
struct ares_options options; struct ares_options options;
int optmask; int optmask;
@ -67,7 +69,7 @@ static void prep_tcploopback()
options.tcp_port = htons(TEST_PORT_2); options.tcp_port = htons(TEST_PORT_2);
options.flags = ARES_FLAG_USEVC; options.flags = ARES_FLAG_USEVC;
rc = uv_ares_init_options(&channel, &options, optmask); rc = uv_ares_init_options(loop, &channel, &options, optmask);
ASSERT(rc == ARES_SUCCESS); ASSERT(rc == ARES_SUCCESS);
} }
@ -85,11 +87,13 @@ BENCHMARK_IMPL(gethostbyname) {
} }
uv_init(); uv_init();
loop = uv_default_loop();
ares_callbacks = 0; ares_callbacks = 0;
ares_errors = 0; ares_errors = 0;
uv_update_time(); uv_update_time(loop);
start_time = uv_now(); start_time = uv_now(loop);
prep_tcploopback(); prep_tcploopback();
@ -101,11 +105,11 @@ BENCHMARK_IMPL(gethostbyname) {
&argument); &argument);
} }
uv_run(); uv_run(loop);
uv_ares_destroy(channel); uv_ares_destroy(loop, channel);
end_time = uv_now(); end_time = uv_now(loop);
if (ares_errors > 0) { if (ares_errors > 0) {
printf("There were %d failures\n", ares_errors); printf("There were %d failures\n", ares_errors);

17
deps/uv/test/benchmark-getaddrinfo.c

@ -32,6 +32,8 @@
const char* name = "localhost"; const char* name = "localhost";
static uv_loop_t* loop;
static uv_getaddrinfo_t handles[CONCURRENT_CALLS]; static uv_getaddrinfo_t handles[CONCURRENT_CALLS];
static int calls_initiated = 0; static int calls_initiated = 0;
@ -58,7 +60,7 @@ static void getaddrinfo_initiate(uv_getaddrinfo_t* handle) {
calls_initiated++; calls_initiated++;
r = uv_getaddrinfo(handle, &getaddrinfo_cb, name, NULL, NULL); r = uv_getaddrinfo(loop, handle, &getaddrinfo_cb, name, NULL, NULL);
ASSERT(r == 0); ASSERT(r == 0);
} }
@ -66,19 +68,20 @@ static void getaddrinfo_initiate(uv_getaddrinfo_t* handle) {
BENCHMARK_IMPL(getaddrinfo) { BENCHMARK_IMPL(getaddrinfo) {
int i; int i;
uv_init(); uv_init(loop);
loop = uv_default_loop();
uv_update_time(); uv_update_time(loop);
start_time = uv_now(); start_time = uv_now(loop);
for (i = 0; i < CONCURRENT_CALLS; i++) { for (i = 0; i < CONCURRENT_CALLS; i++) {
getaddrinfo_initiate(&handles[i]); getaddrinfo_initiate(&handles[i]);
} }
uv_run(); uv_run(loop);
uv_update_time(); uv_update_time(loop);
end_time = uv_now(); end_time = uv_now(loop);
ASSERT(calls_initiated == TOTAL_CALLS); ASSERT(calls_initiated == TOTAL_CALLS);
ASSERT(calls_completed == TOTAL_CALLS); ASSERT(calls_completed == TOTAL_CALLS);

14
deps/uv/test/benchmark-ping-pongs.c

@ -46,6 +46,8 @@ typedef struct buf_s {
static char PING[] = "PING\n"; static char PING[] = "PING\n";
static uv_loop_t* loop;
static buf_t* buf_freelist = NULL; static buf_t* buf_freelist = NULL;
static int pinger_shutdown_cb_called; static int pinger_shutdown_cb_called;
static int completed_pingers = 0; static int completed_pingers = 0;
@ -130,7 +132,7 @@ static void pinger_read_cb(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
pinger = (pinger_t*)tcp->data; pinger = (pinger_t*)tcp->data;
if (nread < 0) { if (nread < 0) {
ASSERT(uv_last_error().code == UV_EOF); ASSERT(uv_last_error(loop).code == UV_EOF);
if (buf.base) { if (buf.base) {
buf_free(buf); buf_free(buf);
@ -148,7 +150,7 @@ static void pinger_read_cb(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
pinger->state = (pinger->state + 1) % (sizeof(PING) - 1); pinger->state = (pinger->state + 1) % (sizeof(PING) - 1);
if (pinger->state == 0) { if (pinger->state == 0) {
pinger->pongs++; pinger->pongs++;
if (uv_now() - start_time > TIME) { if (uv_now(loop) - start_time > TIME) {
uv_shutdown(&pinger->shutdown_req, (uv_stream_t*) tcp, pinger_shutdown_cb); uv_shutdown(&pinger->shutdown_req, (uv_stream_t*) tcp, pinger_shutdown_cb);
break; break;
} else { } else {
@ -185,7 +187,7 @@ static void pinger_new() {
pinger->pongs = 0; pinger->pongs = 0;
/* Try to connec to the server and do NUM_PINGS ping-pongs. */ /* Try to connec to the server and do NUM_PINGS ping-pongs. */
r = uv_tcp_init(&pinger->tcp); r = uv_tcp_init(loop, &pinger->tcp);
ASSERT(!r); ASSERT(!r);
pinger->tcp.data = pinger; pinger->tcp.data = pinger;
@ -199,10 +201,12 @@ static void pinger_new() {
BENCHMARK_IMPL(ping_pongs) { BENCHMARK_IMPL(ping_pongs) {
uv_init(); uv_init();
start_time = uv_now(); loop = uv_default_loop();
start_time = uv_now(loop);
pinger_new(); pinger_new();
uv_run(); uv_run(loop);
ASSERT(completed_pingers == 1); ASSERT(completed_pingers == 1);

25
deps/uv/test/benchmark-pound.c

@ -65,6 +65,8 @@ typedef struct {
static char buffer[] = "QS"; static char buffer[] = "QS";
static uv_loop_t* loop;
static tcp_conn_rec tcp_conns[MAX_CONNS]; static tcp_conn_rec tcp_conns[MAX_CONNS];
static pipe_conn_rec pipe_conns[MAX_CONNS]; static pipe_conn_rec pipe_conns[MAX_CONNS];
@ -89,7 +91,7 @@ static uv_buf_t alloc_cb(uv_handle_t* handle, size_t suggested_size) {
static void after_write(uv_write_t* req, int status) { static void after_write(uv_write_t* req, int status) {
if (status != 0) { if (status != 0) {
fprintf(stderr, "write error %s\n", uv_err_name(uv_last_error())); fprintf(stderr, "write error %s\n", uv_err_name(uv_last_error(loop)));
uv_close((uv_handle_t*)req->handle, close_cb); uv_close((uv_handle_t*)req->handle, close_cb);
conns_failed++; conns_failed++;
return; return;
@ -134,7 +136,7 @@ static void connect_cb(uv_connect_t* req, int status) {
static void read_cb(uv_stream_t* stream, ssize_t nread, uv_buf_t buf) { static void read_cb(uv_stream_t* stream, ssize_t nread, uv_buf_t buf) {
conn_rec* p = (conn_rec*)stream->data; conn_rec* p = (conn_rec*)stream->data;
uv_err_t err = uv_last_error(); uv_err_t err = uv_last_error(loop);
ASSERT(stream != NULL); ASSERT(stream != NULL);
@ -150,7 +152,7 @@ static void read_cb(uv_stream_t* stream, ssize_t nread, uv_buf_t buf) {
} else if (err.code == UV_ECONNRESET) { } else if (err.code == UV_ECONNRESET) {
conns_failed++; conns_failed++;
} else { } else {
fprintf(stderr, "read error %s\n", uv_err_name(uv_last_error())); fprintf(stderr, "read error %s\n", uv_err_name(uv_last_error(loop)));
ASSERT(0); ASSERT(0);
} }
} }
@ -167,7 +169,7 @@ static void close_cb(uv_handle_t* handle) {
printf("close_cb %d\n", p->i); printf("close_cb %d\n", p->i);
#endif #endif
if (uv_now() - start < 10000) { if (uv_now(loop) - start < 10000) {
p->make_connect(p); p->make_connect(p);
} }
} }
@ -195,7 +197,7 @@ static void tcp_make_connect(conn_rec* p) {
struct sockaddr_in addr; struct sockaddr_in addr;
int r; int r;
r = uv_tcp_init((uv_tcp_t*)&p->stream); r = uv_tcp_init(loop, (uv_tcp_t*)&p->stream);
ASSERT(r == 0); ASSERT(r == 0);
addr = uv_ip4_addr("127.0.0.1", TEST_PORT); addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
@ -203,7 +205,7 @@ static void tcp_make_connect(conn_rec* p) {
r = uv_tcp_connect(&((tcp_conn_rec*)p)->conn_req, (uv_tcp_t*)&p->stream, addr, connect_cb); r = uv_tcp_connect(&((tcp_conn_rec*)p)->conn_req, (uv_tcp_t*)&p->stream, addr, connect_cb);
if (r) { if (r) {
fprintf(stderr, "uv_tcp_connect error %s\n", fprintf(stderr, "uv_tcp_connect error %s\n",
uv_err_name(uv_last_error())); uv_err_name(uv_last_error(loop)));
ASSERT(0); ASSERT(0);
} }
@ -220,13 +222,13 @@ static void tcp_make_connect(conn_rec* p) {
static void pipe_make_connect(conn_rec* p) { static void pipe_make_connect(conn_rec* p) {
int r; int r;
r = uv_pipe_init((uv_pipe_t*)&p->stream); r = uv_pipe_init(loop, (uv_pipe_t*)&p->stream);
ASSERT(r == 0); ASSERT(r == 0);
r = uv_pipe_connect(&((pipe_conn_rec*)p)->conn_req, (uv_pipe_t*)&p->stream, TEST_PIPENAME, connect_cb); r = uv_pipe_connect(&((pipe_conn_rec*)p)->conn_req, (uv_pipe_t*)&p->stream, TEST_PIPENAME, connect_cb);
if (r) { if (r) {
fprintf(stderr, "uv_tcp_connect error %s\n", fprintf(stderr, "uv_tcp_connect error %s\n",
uv_err_name(uv_last_error())); uv_err_name(uv_last_error(loop)));
ASSERT(0); ASSERT(0);
} }
@ -276,9 +278,10 @@ static int pound_it(int concurrency,
uint64_t end_time; uint64_t end_time;
uv_init(); uv_init();
loop = uv_default_loop();
uv_update_time(); uv_update_time(loop);
start = uv_now(); start = uv_now(loop);
/* Run benchmark for at least five seconds. */ /* Run benchmark for at least five seconds. */
start_time = uv_hrtime(); start_time = uv_hrtime();
@ -288,7 +291,7 @@ static int pound_it(int concurrency,
r = do_connect(concurrency, make_connect, arg); r = do_connect(concurrency, make_connect, arg);
ASSERT(!r); ASSERT(!r);
uv_run(); uv_run(loop);
end_time = uv_hrtime(); end_time = uv_hrtime();

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

Loading…
Cancel
Save