From 7a782164b9b236e33cb5c7d586f8f3085f400ab5 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Thu, 14 Jul 2011 14:28:52 -0700 Subject: [PATCH] Upgrade libuv to f5ff8694 --- deps/uv/Makefile | 12 +- deps/uv/config-mingw.mk | 4 +- deps/uv/config-unix.mk | 16 +- deps/uv/include/ares.h | 1 + deps/uv/include/eio.h | 4 +- deps/uv/{src/ev => include}/ev.h | 4 +- deps/uv/include/uv-unix.h | 5 + deps/uv/include/uv-win.h | 60 +- deps/uv/include/uv.h | 55 +- deps/uv/msvs/c-ares.vcxproj | 148 ++-- deps/uv/msvs/libuv-benchmark.vcxproj | 20 +- deps/uv/msvs/libuv-test.vcxproj | 21 +- deps/uv/msvs/libuv.vcxproj | 51 +- deps/uv/src/ares/ares_setup.h | 6 - deps/uv/src/ares/config-win32.h | 357 --------- deps/uv/src/ares/config_win32/ares_config.h | 671 +++++++--------- deps/uv/src/eio/config_linux.h | 7 +- deps/uv/src/ev/config_linux.h | 7 +- deps/uv/src/uv-common.h | 2 + deps/uv/src/uv-freebsd.c | 24 +- deps/uv/src/uv-linux.c | 6 +- deps/uv/src/uv-sunos.c | 3 +- deps/uv/src/uv-unix.c | 63 +- deps/uv/src/uv-win.c | 1146 ++++++++++++++++++++++----- deps/uv/test/benchmark-list.h | 28 +- deps/uv/test/benchmark-pump.c | 158 +++- deps/uv/test/benchmark-sizes.c | 1 + deps/uv/test/dns-server.c | 2 +- deps/uv/test/echo-server.c | 123 ++- deps/uv/test/run-benchmarks.c | 26 +- deps/uv/test/run-tests.c | 53 +- deps/uv/test/runner-unix.c | 8 +- deps/uv/test/runner-win.c | 26 +- deps/uv/test/runner.c | 211 +++-- deps/uv/test/runner.h | 30 +- deps/uv/test/task.h | 11 + deps/uv/test/test-async.c | 2 - deps/uv/test/test-callback-stack.c | 10 +- deps/uv/test/test-connection-fail.c | 2 +- deps/uv/test/test-delayed-accept.c | 6 +- deps/uv/test/test-getsockname.c | 186 +++++ deps/uv/test/test-hrtime.c | 2 +- deps/uv/test/test-list.h | 31 +- deps/uv/test/test-ping-pong.c | 87 +- deps/uv/test/test-shutdown-eof.c | 4 +- deps/uv/test/test-tcp-writealot.c | 8 +- src/tcp_wrap.cc | 2 +- 47 files changed, 2269 insertions(+), 1441 deletions(-) rename deps/uv/{src/ev => include}/ev.h (99%) delete mode 100644 deps/uv/src/ares/config-win32.h create mode 100644 deps/uv/test/test-getsockname.c diff --git a/deps/uv/Makefile b/deps/uv/Makefile index d9de2aa..cbbf635 100644 --- a/deps/uv/Makefile +++ b/deps/uv/Makefile @@ -97,17 +97,23 @@ test/echo.o: test/echo.c test/echo.h $(CC) $(CPPFLAGS) $(CFLAGS) -c test/echo.c -o test/echo.o -.PHONY: clean clean-platform distclean distclean-platform test benchmark +.PHONY: clean clean-platform distclean distclean-platform test bench test: test/run-tests$(E) test/run-tests +#test-%: test/run-tests$(E) +# test/run-tests $(@:test-%=%) + bench: test/run-benchmarks$(E) test/run-benchmarks +#bench-%: test/run-benchmarks$(E) +# test/run-benchmarks $(@:bench-%=%) + clean: clean-platform - $(RM) -f *.o *.a test/run-tests$(E) test/run-benchmarks$(E) + $(RM) -f src/*.o *.a test/run-tests$(E) test/run-benchmarks$(E) distclean: distclean-platform - $(RM) -f *.o *.a test/run-tests$(E) test/run-benchmarks$(E) + $(RM) -f src/*.o *.a test/run-tests$(E) test/run-benchmarks$(E) diff --git a/deps/uv/config-mingw.mk b/deps/uv/config-mingw.mk index be8abca..a115277 100644 --- a/deps/uv/config-mingw.mk +++ b/deps/uv/config-mingw.mk @@ -20,8 +20,8 @@ # Use make -f Makefile.gcc PREFIX=i686-w64-mingw32- # for cross compilation -CC ?= $(PREFIX)gcc -AR ?= $(PREFIX)ar +CC = $(PREFIX)gcc +AR = $(PREFIX)ar E=.exe CFLAGS=$(CPPFLAGS) -g --std=gnu89 -D_WIN32_WINNT=0x0501 -Isrc/ares/config_win32 diff --git a/deps/uv/config-unix.mk b/deps/uv/config-unix.mk index 862af2d..2b44dd6 100644 --- a/deps/uv/config-unix.mk +++ b/deps/uv/config-unix.mk @@ -18,10 +18,11 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. -CC ?= $(PREFIX)gcc -AR ?= $(PREFIX)ar +CC = $(PREFIX)gcc +AR = $(PREFIX)ar E= -CFLAGS=--std=gnu89 -g +CSTDFLAG=--std=c89 -pedantic +CFLAGS=-g CPPFLAGS += -Isrc/ev LINKFLAGS=-lm @@ -47,6 +48,7 @@ endif ifeq (Linux,$(uname_S)) EV_CONFIG=config_linux.h EIO_CONFIG=config_linux.h +CSTDFLAG += -D_XOPEN_SOURCE=600 CPPFLAGS += -Isrc/ares/config_linux LINKFLAGS+=-lrt UV_OS_FILE=uv-linux.c @@ -80,13 +82,13 @@ uv.a: src/uv-unix.o src/uv-common.o src/uv-platform.o src/ev/ev.o src/uv-eio.o s src/eio/eio.o $(CARES_OBJS) src/uv-platform.o: src/$(UV_OS_FILE) include/uv.h include/uv-unix.h - $(CC) $(CPPFLAGS) $(CFLAGS) -c src/$(UV_OS_FILE) -o src/uv-platform.o + $(CC) $(CSTDFLAG) $(CPPFLAGS) $(CFLAGS) -c src/$(UV_OS_FILE) -o src/uv-platform.o src/uv-unix.o: src/uv-unix.c include/uv.h include/uv-unix.h - $(CC) $(CPPFLAGS) -Ieio $(CFLAGS) -c src/uv-unix.c -o src/uv-unix.o + $(CC) $(CSTDFLAG) $(CPPFLAGS) -Ieio $(CFLAGS) -c src/uv-unix.c -o src/uv-unix.o src/uv-common.o: src/uv-common.c include/uv.h include/uv-unix.h - $(CC) $(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 $(CC) $(CPPFLAGS) $(CFLAGS) -c src/ev/ev.c -o src/ev/ev.o -DEV_CONFIG_H=\"$(EV_CONFIG)\" @@ -101,7 +103,7 @@ src/eio/eio.o: src/eio/eio.c $(CC) $(EIO_CPPFLAGS) $(CFLAGS) -c src/eio/eio.c -o src/eio/eio.o src/uv-eio.o: src/uv-eio.c - $(CC) $(CPPFLAGS) -Isrc/eio/ $(CFLAGS) -c src/uv-eio.c -o src/uv-eio.o + $(CC) $(CPPFLAGS) -Isrc/eio/ $(CSTDFLAG) $(CFLAGS) -c src/uv-eio.c -o src/uv-eio.o clean-platform: diff --git a/deps/uv/include/ares.h b/deps/uv/include/ares.h index a8d3815..905a29e 100644 --- a/deps/uv/include/ares.h +++ b/deps/uv/include/ares.h @@ -52,6 +52,7 @@ #else /* Not Windows */ +# include # include # include #endif diff --git a/deps/uv/include/eio.h b/deps/uv/include/eio.h index 1d597e1..3dd3267 100644 --- a/deps/uv/include/eio.h +++ b/deps/uv/include/eio.h @@ -176,7 +176,7 @@ enum enum { EIO_MCL_CURRENT = 1, - EIO_MCL_FUTURE = 2, + EIO_MCL_FUTURE = 2 }; /* request priorities */ @@ -184,7 +184,7 @@ enum enum { EIO_PRI_MIN = -4, EIO_PRI_MAX = 4, - EIO_PRI_DEFAULT = 0, + EIO_PRI_DEFAULT = 0 }; /* eio request structure */ diff --git a/deps/uv/src/ev/ev.h b/deps/uv/include/ev.h similarity index 99% rename from deps/uv/src/ev/ev.h rename to deps/uv/include/ev.h index 6fb8083..526b9f1 100644 --- a/deps/uv/src/ev/ev.h +++ b/deps/uv/include/ev.h @@ -197,7 +197,7 @@ struct ev_loop; /* eventmask, revents, events... */ enum { - EV_UNDEF = 0xFFFFFFFF, /* guaranteed to be invalid */ + EV_UNDEF = -1, /* guaranteed to be invalid */ EV_NONE = 0x00, /* no events */ EV_READ = 0x01, /* ev_io detected read will not block */ EV_WRITE = 0x02, /* ev_io detected write will not block */ @@ -219,7 +219,7 @@ enum { EV_CLEANUP = 0x00040000, /* event loop resumed in child */ EV_ASYNC = 0x00080000, /* async intra-loop signal */ EV_CUSTOM = 0x01000000, /* for use by user code */ - EV_ERROR = 0x80000000 /* sent when an error occurs */ + EV_ERROR = (-2147483647 - 1) /* sent when an error occurs */ }; /* can be used to add custom fields to all watchers, while losing binary compatibility */ diff --git a/deps/uv/include/uv-unix.h b/deps/uv/include/uv-unix.h index f68a7fd..d17ebc3 100644 --- a/deps/uv/include/uv-unix.h +++ b/deps/uv/include/uv-unix.h @@ -73,6 +73,11 @@ typedef struct { ev_io write_watcher; \ ngx_queue_t write_queue; \ ngx_queue_t write_completed_queue; + + +/* UV_NAMED_PIPE */ +#define UV_PIPE_PRIVATE_TYPEDEF +#define UV_PIPE_PRIVATE_FIELDS /* UV_PREPARE */ \ diff --git a/deps/uv/include/uv-win.h b/deps/uv/include/uv-win.h index e6254fe..2d6093a 100644 --- a/deps/uv/include/uv-win.h +++ b/deps/uv/include/uv-win.h @@ -31,6 +31,8 @@ #include "tree.h" +#define MAX_PIPENAME_LEN 256 + /** * It should be possible to cast uv_buf_t[] to WSABUF[] * see http://msdn.microsoft.com/en-us/library/ms741542(v=vs.85).aspx @@ -40,6 +42,22 @@ typedef struct uv_buf_t { char* base; } uv_buf_t; +/* + * Private uv_pipe_instance state. + */ +typedef enum { + UV_PIPEINSTANCE_CONNECTED = 0, + UV_PIPEINSTANCE_DISCONNECTED, + UV_PIPEINSTANCE_ACTIVE +} uv_pipeinstance_state; + +/* Used to store active pipe instances inside a linked list. */ +typedef struct uv_pipe_instance_s { + HANDLE handle; + uv_pipeinstance_state state; + struct uv_pipe_instance_s* next; +} uv_pipe_instance_t; + #define UV_REQ_PRIVATE_FIELDS \ union { \ /* Used by I/O operations */ \ @@ -52,30 +70,46 @@ typedef struct uv_buf_t { uv_err_t error; \ struct uv_req_s* next_req; +#define uv_stream_connection_fields \ + unsigned int write_reqs_pending; \ + uv_req_t* shutdown_req; + +#define uv_stream_server_fields \ + uv_connection_cb connection_cb; + #define UV_STREAM_PRIVATE_FIELDS \ + unsigned int reqs_pending; \ uv_alloc_cb alloc_cb; \ uv_read_cb read_cb; \ struct uv_req_s read_req; \ - -#define uv_tcp_connection_fields \ - unsigned int write_reqs_pending; \ - uv_req_t* shutdown_req; - -#define uv_tcp_server_fields \ - uv_connection_cb connection_cb; \ - SOCKET accept_socket; \ - struct uv_req_s accept_req; \ - char accept_buffer[sizeof(struct sockaddr_storage) * 2 + 32]; + union { \ + struct { uv_stream_connection_fields }; \ + struct { uv_stream_server_fields }; \ + }; #define UV_TCP_PRIVATE_FIELDS \ - unsigned int reqs_pending; \ union { \ SOCKET socket; \ HANDLE handle; \ }; \ + SOCKET accept_socket; \ + char accept_buffer[sizeof(struct sockaddr_storage) * 2 + 32]; \ + struct uv_req_s accept_req; + +#define uv_pipe_server_fields \ + char* name; \ + uv_pipe_instance_t* connections; \ + struct uv_req_s accept_reqs[4]; + +#define uv_pipe_connection_fields \ + uv_pipe_t* server; \ + uv_pipe_instance_t* connection; \ + uv_pipe_instance_t clientConnection; + +#define UV_PIPE_PRIVATE_FIELDS \ union { \ - struct { uv_tcp_connection_fields }; \ - struct { uv_tcp_server_fields }; \ + struct { uv_pipe_server_fields }; \ + struct { uv_pipe_connection_fields }; \ }; #define UV_TIMER_PRIVATE_FIELDS \ diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index aa27179..d470a25 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -43,6 +43,7 @@ typedef struct uv_err_s uv_err_t; typedef struct uv_handle_s uv_handle_t; typedef struct uv_stream_s uv_stream_t; typedef struct uv_tcp_s uv_tcp_t; +typedef struct uv_pipe_s uv_pipe_t; typedef struct uv_timer_s uv_timer_t; typedef struct uv_prepare_s uv_prepare_t; typedef struct uv_check_s uv_check_t; @@ -124,7 +125,8 @@ typedef enum { UV_EAIFAMNOSUPPORT, UV_EAINONAME, UV_EAISERVICE, - UV_EAISOCKTYPE + UV_EAISOCKTYPE, + UV_ESHUTDOWN } uv_err_code; typedef enum { @@ -138,8 +140,8 @@ typedef enum { UV_CHECK, UV_IDLE, UV_ASYNC, - UV_ARES, UV_ARES_TASK, + UV_ARES_EVENT, UV_GETADDRINFO } uv_handle_type; @@ -150,7 +152,11 @@ typedef enum { UV_READ, UV_WRITE, UV_SHUTDOWN, - UV_WAKEUP + UV_WAKEUP, + /* TODO: remove the req suffix */ + UV_ARES_EVENT_REQ, + UV_ARES_CLEANUP_REQ, + UV_GETADDRINFO_REQ } uv_req_type; @@ -167,7 +173,7 @@ struct uv_req_s { uv_req_type type; /* public */ uv_handle_t* handle; - void* cb; + void *(*cb)(void *); void* data; /* private */ UV_REQ_PRIVATE_FIELDS @@ -176,7 +182,7 @@ struct uv_req_s { /* * Initialize a request for use with uv_write, uv_shutdown, or uv_connect. */ -void uv_req_init(uv_req_t* req, uv_handle_t* handle, void* cb); +void uv_req_init(uv_req_t* req, uv_handle_t* handle, void *(*cb)(void *)); int uv_shutdown(uv_req_t* req); @@ -188,7 +194,7 @@ int uv_shutdown(uv_req_t* req); uv_close_cb close_cb; \ void* data; \ /* private */ \ - UV_HANDLE_PRIVATE_FIELDS \ + UV_HANDLE_PRIVATE_FIELDS /* The abstract base class of all handles. */ struct uv_handle_s { @@ -212,7 +218,7 @@ int uv_close(uv_handle_t* handle, uv_close_cb close_cb); /* number of bytes queued for writing */ \ size_t write_queue_size; \ /* private */ \ - UV_STREAM_PRIVATE_FIELDS \ + UV_STREAM_PRIVATE_FIELDS /* The abstract base class for all streams. */ struct uv_stream_s { @@ -286,6 +292,26 @@ int uv_tcp_connect6(uv_req_t* req, struct sockaddr_in6); int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb); +int uv_getsockname(uv_tcp_t* handle, struct sockaddr* name, int* namelen); + + +/* + * A subclass of uv_stream_t representing a pipe stream or pipe server. + */ +struct uv_pipe_s { + UV_HANDLE_FIELDS + UV_STREAM_FIELDS + UV_PIPE_PRIVATE_FIELDS +}; + +int uv_pipe_init(uv_pipe_t* handle); + +int uv_pipe_bind(uv_pipe_t* handle, const char* name); + +int uv_pipe_listen(uv_pipe_t* handle, uv_connection_cb cb); + +int uv_pipe_connect(uv_req_t* req, const char* name); + /* * Subclass of uv_handle_t. libev wrapper. Every active prepare handle gets @@ -466,6 +492,7 @@ extern uint64_t uv_hrtime(void); /* the presence of this union forces similar struct layout */ union uv_any_handle { uv_tcp_t tcp; + uv_pipe_t pipe; uv_prepare_t prepare; uv_check_t check; uv_idle_t idle; @@ -478,7 +505,9 @@ union uv_any_handle { typedef struct { uint64_t req_init; uint64_t handle_init; + uint64_t stream_init; uint64_t tcp_init; + uint64_t pipe_init; uint64_t prepare_init; uint64_t check_init; uint64_t idle_init; @@ -488,6 +517,18 @@ typedef struct { uv_counters_t* uv_counters(); + +/* Don't export the private CPP symbols. */ +#undef UV_REQ_PRIVATE_FIELDS +#undef UV_STREAM_PRIVATE_FIELDS +#undef UV_TCP_PRIVATE_FIELDS +#undef UV_PREPARE_PRIVATE_FIELDS +#undef UV_CHECK_PRIVATE_FIELDS +#undef UV_IDLE_PRIVATE_FIELDS +#undef UV_ASYNC_PRIVATE_FIELDS +#undef UV_TIMER_PRIVATE_FIELDS +#undef UV_GETADDRINFO_PRIVATE_FIELDS + #ifdef __cplusplus } #endif diff --git a/deps/uv/msvs/c-ares.vcxproj b/deps/uv/msvs/c-ares.vcxproj index 59bd976..4ada6cc 100644 --- a/deps/uv/msvs/c-ares.vcxproj +++ b/deps/uv/msvs/c-ares.vcxproj @@ -72,108 +72,108 @@ - WIN32;_DEBUG;_LIB;CARES_BUILDING_LIBRARY;CARES_STATICLIB;%(PreprocessorDefinitions) + WIN32;HAVE_CONFIG_H;_DEBUG;_LIB;%(PreprocessorDefinitions) MultiThreadedDebug Level3 ProgramDatabase Disabled - ..\c-ares;..\c-ares\config_win32 + ..\include;..\src\ares\config_win32 - WIN32;_DEBUG;_LIB;CARES_BUILDING_LIBRARY;CARES_STATICLIB;%(PreprocessorDefinitions) + WIN32;HAVE_CONFIG_H;_DEBUG;_LIB;%(PreprocessorDefinitions) MultiThreadedDebug Level3 ProgramDatabase Disabled - ..\c-ares;..\c-ares\config_win32 + ..\include;..\src\ares\config_win32 MultiThreaded - ..\c-ares;..\c-ares\config_win32 - WIN32;_LIB;CARES_BUILDING_LIBRARY;CARES_STATICLIB;%(PreprocessorDefinitions) + ..\include;..\src\ares\config_win32 + WIN32;HAVE_CONFIG_H;_LIB;%(PreprocessorDefinitions) MultiThreaded - ..\c-ares;..\c-ares\config_win32 - WIN32;_LIB;CARES_BUILDING_LIBRARY;CARES_STATICLIB;%(PreprocessorDefinitions) + ..\include;..\src\ares\config_win32 + WIN32;HAVE_CONFIG_H;_LIB;%(PreprocessorDefinitions) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file + diff --git a/deps/uv/msvs/libuv-benchmark.vcxproj b/deps/uv/msvs/libuv-benchmark.vcxproj index 12bf99d..5727a1a 100644 --- a/deps/uv/msvs/libuv-benchmark.vcxproj +++ b/deps/uv/msvs/libuv-benchmark.vcxproj @@ -81,7 +81,7 @@ Level3 ProgramDatabase Disabled - ..\c-ares\config_win32 + ..\include;..\src\ares\config_win32 MachineX86 @@ -97,7 +97,7 @@ Level3 ProgramDatabase Disabled - ..\c-ares\config_win32 + ..\include;..\src\ares\config_win32 true @@ -111,7 +111,7 @@ MultiThreaded Level3 ProgramDatabase - ..\c-ares\config_win32 + ..\include;..\src\ares\config_win32 MachineX86 @@ -128,7 +128,7 @@ MultiThreaded Level3 ProgramDatabase - ..\c-ares\config_win32 + ..\include;..\src\ares\config_win32 true @@ -147,23 +147,11 @@ - - true - true - true - true - - - true - true - true - true - diff --git a/deps/uv/msvs/libuv-test.vcxproj b/deps/uv/msvs/libuv-test.vcxproj index f772f64..e59786d 100644 --- a/deps/uv/msvs/libuv-test.vcxproj +++ b/deps/uv/msvs/libuv-test.vcxproj @@ -82,7 +82,7 @@ Level3 ProgramDatabase Disabled - ..\c-ares\config_win32 + ..\include;..\src\ares\config_win32 MachineX86 @@ -98,7 +98,7 @@ Level3 ProgramDatabase Disabled - ..\c-ares\config_win32 + ..\include;..\src\ares\config_win32 true @@ -112,7 +112,7 @@ MultiThreaded Level3 ProgramDatabase - ..\c-ares\config_win32 + ..\include;..\src\ares\config_win32 MachineX86 @@ -129,7 +129,7 @@ MultiThreaded Level3 ProgramDatabase - ..\c-ares\config_win32 + ..\include;..\src\ares\config_win32 true @@ -141,12 +141,6 @@ - - true - true - true - true - @@ -156,6 +150,7 @@ + @@ -170,12 +165,6 @@ - - true - true - true - true - diff --git a/deps/uv/msvs/libuv.vcxproj b/deps/uv/msvs/libuv.vcxproj index 1909d8b..c896c69 100644 --- a/deps/uv/msvs/libuv.vcxproj +++ b/deps/uv/msvs/libuv.vcxproj @@ -78,7 +78,7 @@ Level3 ProgramDatabase Disabled - ..\c-ares\config_win32 + ..\include;..\src\ares\config_win32 @@ -88,53 +88,22 @@ Level3 ProgramDatabase Disabled - ..\c-ares\config_win32 + ..\include;..\src\ares\config_win32 MultiThreaded - ..\c-ares\config_win32 + ..\include;..\src\ares\config_win32 MultiThreaded - ..\c-ares\config_win32 + ..\include;..\src\ares\config_win32 - - - true - true - true - true - - - - - - - - true - true - true - true - - - - - - - - - - - - - - {2b6a4644-eba9-dfb5-af35-6c56edf05c7f} true @@ -144,6 +113,18 @@ false + + + + + + + + + + + + diff --git a/deps/uv/src/ares/ares_setup.h b/deps/uv/src/ares/ares_setup.h index b405aae..9cec52a 100644 --- a/deps/uv/src/ares/ares_setup.h +++ b/deps/uv/src/ares/ares_setup.h @@ -31,12 +31,6 @@ #ifdef HAVE_CONFIG_H #include "ares_config.h" -#else - -#ifdef WIN32 -#include "config-win32.h" -#endif - #endif /* HAVE_CONFIG_H */ /* ================================================================ */ diff --git a/deps/uv/src/ares/config-win32.h b/deps/uv/src/ares/config-win32.h deleted file mode 100644 index 13c5de5..0000000 --- a/deps/uv/src/ares/config-win32.h +++ /dev/null @@ -1,357 +0,0 @@ -#ifndef __ARES_CONFIG_WIN32_H -#define __ARES_CONFIG_WIN32_H - - -/* Copyright (C) 2004 - 2008 by Daniel Stenberg et al - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, provided - * that the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of M.I.T. not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. M.I.T. makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - */ - -/* ================================================================ */ -/* ares/config-win32.h - Hand crafted config file for Windows */ -/* ================================================================ */ - -/* ---------------------------------------------------------------- */ -/* HEADER FILES */ -/* ---------------------------------------------------------------- */ - -/* Define if you have the header file. */ -#if defined(__MINGW32__) || defined(__POCC__) -#define HAVE_GETOPT_H 1 -#endif - -/* Define if you have the header file. */ -#define HAVE_LIMITS_H 1 - -/* Define if you have the header file. */ -#ifndef __SALFORDC__ -#define HAVE_PROCESS_H 1 -#endif - -/* Define if you have the header file. */ -#define HAVE_SIGNAL_H 1 - -/* Define if you have the header file */ -/* #define HAVE_SYS_TIME_H 1 */ - -/* Define if you have the header file. */ -#define HAVE_TIME_H 1 - -/* Define if you have the header file. */ -#if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__LCC__) || \ - defined(__POCC__) -#define HAVE_UNISTD_H 1 -#endif - -/* Define if you have the header file. */ -#define HAVE_WINSOCK_H 1 - -/* Define if you have the header file. */ -#ifndef __SALFORDC__ -#define HAVE_WINSOCK2_H 1 -#endif - -/* Define if you have the header file. */ -#ifndef __SALFORDC__ -#define HAVE_WS2TCPIP_H 1 -#endif - -/* ---------------------------------------------------------------- */ -/* OTHER HEADER INFO */ -/* ---------------------------------------------------------------- */ - -/* Define if sig_atomic_t is an available typedef. */ -#define HAVE_SIG_ATOMIC_T 1 - -/* Define if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define if you can safely include both and . */ -/* #define TIME_WITH_SYS_TIME 1 */ - -/* ---------------------------------------------------------------- */ -/* FUNCTIONS */ -/* ---------------------------------------------------------------- */ - -/* Define if you have the closesocket function. */ -#define HAVE_CLOSESOCKET 1 - -/* Define if you have the gethostname function. */ -#define HAVE_GETHOSTNAME 1 - -/* Define if you have the ioctlsocket function. */ -#define HAVE_IOCTLSOCKET 1 - -/* Define if you have a working ioctlsocket FIONBIO function. */ -#define HAVE_IOCTLSOCKET_FIONBIO 1 - -/* Define if you have the strcasecmp function. */ -/* #define HAVE_STRCASECMP 1 */ - -/* Define if you have the strdup function. */ -#define HAVE_STRDUP 1 - -/* Define if you have the stricmp function. */ -#define HAVE_STRICMP 1 - -/* Define if you have the strncasecmp function. */ -/* #define HAVE_STRNCASECMP 1 */ - -/* Define if you have the strnicmp function. */ -#define HAVE_STRNICMP 1 - -/* Define if you have the recv function. */ -#define HAVE_RECV 1 - -/* Define to the type of arg 1 for recv. */ -#define RECV_TYPE_ARG1 SOCKET - -/* Define to the type of arg 2 for recv. */ -#define RECV_TYPE_ARG2 char * - -/* Define to the type of arg 3 for recv. */ -#define RECV_TYPE_ARG3 int - -/* Define to the type of arg 4 for recv. */ -#define RECV_TYPE_ARG4 int - -/* Define to the function return type for recv. */ -#define RECV_TYPE_RETV int - -/* Define if you have the recvfrom function. */ -#define HAVE_RECVFROM 1 - -/* Define to the type of arg 1 for recvfrom. */ -#define RECVFROM_TYPE_ARG1 SOCKET - -/* Define to the type pointed by arg 2 for recvfrom. */ -#define RECVFROM_TYPE_ARG2 char - -/* Define to the type of arg 3 for recvfrom. */ -#define RECVFROM_TYPE_ARG3 int - -/* Define to the type of arg 4 for recvfrom. */ -#define RECVFROM_TYPE_ARG4 int - -/* Define to the type pointed by arg 5 for recvfrom. */ -#define RECVFROM_TYPE_ARG5 struct sockaddr - -/* Define to the type pointed by arg 6 for recvfrom. */ -#define RECVFROM_TYPE_ARG6 int - -/* Define to the function return type for recvfrom. */ -#define RECVFROM_TYPE_RETV int - -/* Define if you have the send function. */ -#define HAVE_SEND 1 - -/* Define to the type of arg 1 for send. */ -#define SEND_TYPE_ARG1 SOCKET - -/* Define to the type qualifier of arg 2 for send. */ -#define SEND_QUAL_ARG2 const - -/* Define to the type of arg 2 for send. */ -#define SEND_TYPE_ARG2 char * - -/* Define to the type of arg 3 for send. */ -#define SEND_TYPE_ARG3 int - -/* Define to the type of arg 4 for send. */ -#define SEND_TYPE_ARG4 int - -/* Define to the function return type for send. */ -#define SEND_TYPE_RETV int - -/* Specifics for the Watt-32 tcp/ip stack */ -#ifdef WATT32 - #define SOCKET int - #define NS_INADDRSZ 4 - #define HAVE_ARPA_NAMESER_H 1 - #define HAVE_ARPA_INET_H 1 - #define HAVE_NETDB_H 1 - #define HAVE_NETINET_IN_H 1 - #define HAVE_SYS_SOCKET_H 1 - #define HAVE_NETINET_TCP_H 1 - #define HAVE_AF_INET6 1 - #define HAVE_PF_INET6 1 - #define HAVE_STRUCT_IN6_ADDR 1 - #define HAVE_STRUCT_SOCKADDR_IN6 1 - #undef HAVE_WINSOCK_H - #undef HAVE_WINSOCK2_H - #undef HAVE_WS2TCPIP_H -#endif - -/* ---------------------------------------------------------------- */ -/* TYPEDEF REPLACEMENTS */ -/* ---------------------------------------------------------------- */ - -/* Define this if in_addr_t is not an available 'typedefed' type */ -#define in_addr_t unsigned long - -/* Define as the return type of signal handlers (int or void). */ -#define RETSIGTYPE void - -/* Define ssize_t if it is not an available 'typedefed' type */ -#ifndef _SSIZE_T_DEFINED -# if (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || \ - defined(__POCC__) || \ - defined(__MINGW32__) -# elif defined(_WIN64) -# define _SSIZE_T_DEFINED -# define ssize_t __int64 -# else -# define _SSIZE_T_DEFINED -# define ssize_t int -# endif -#endif - -/* ---------------------------------------------------------------- */ -/* TYPE SIZES */ -/* ---------------------------------------------------------------- */ - -/* The size of `int', as computed by sizeof. */ -#define SIZEOF_INT 4 - -/* The size of `short', as computed by sizeof. */ -#define SIZEOF_SHORT 2 - -/* The size of `size_t', as computed by sizeof. */ -#if defined(_WIN64) -# define SIZEOF_SIZE_T 8 -#else -# define SIZEOF_SIZE_T 4 -#endif - -/* ---------------------------------------------------------------- */ -/* STRUCT RELATED */ -/* ---------------------------------------------------------------- */ - -/* Define this if you have struct addrinfo */ -#define HAVE_STRUCT_ADDRINFO 1 - -/* Define this if you have struct sockaddr_storage */ -#ifndef __SALFORDC__ -#define HAVE_STRUCT_SOCKADDR_STORAGE 1 -#endif - -/* Define this if you have struct timeval */ -#define HAVE_STRUCT_TIMEVAL 1 - -/* ---------------------------------------------------------------- */ -/* COMPILER SPECIFIC */ -/* ---------------------------------------------------------------- */ - -/* Define to avoid VS2005 complaining about portable C functions */ -#if defined(_MSC_VER) && (_MSC_VER >= 1400) -#define _CRT_SECURE_NO_DEPRECATE 1 -#define _CRT_NONSTDC_NO_DEPRECATE 1 -#endif - -/* Officially, Microsoft's Windows SDK versions 6.X do not support Windows - 2000 as a supported build target. VS2008 default installations provide an - embedded Windows SDK v6.0A along with the claim that Windows 2000 is a - valid build target for VS2008. Popular belief is that binaries built using - Windows SDK versions 6.X and Windows 2000 as a build target are functional */ -#if defined(_MSC_VER) && (_MSC_VER >= 1500) -# define VS2008_MINIMUM_TARGET 0x0500 -#endif - -/* When no build target is specified VS2008 default build target is Windows - Vista, which leaves out even Winsows XP. If no build target has been given - for VS2008 we will target the minimum Officially supported build target, - which happens to be Windows XP. */ -#if defined(_MSC_VER) && (_MSC_VER >= 1500) -# define VS2008_DEFAULT_TARGET 0x0501 -#endif - -/* VS2008 default target settings and minimum build target check */ -#if defined(_MSC_VER) && (_MSC_VER >= 1500) -# ifndef _WIN32_WINNT -# define _WIN32_WINNT VS2008_DEFAULT_TARGET -# endif -# ifndef WINVER -# define WINVER VS2008_DEFAULT_TARGET -# endif -# if (_WIN32_WINNT < VS2008_MINIMUM_TARGET) || (WINVER < VS2008_MINIMUM_TARGET) -# error VS2008 does not support Windows build targets prior to Windows 2000 -# endif -#endif - -/* When no build target is specified Pelles C 5.00 and later default build - target is Windows Vista. We override default target to be Windows 2000. */ -#if defined(__POCC__) && (__POCC__ >= 500) -# ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x0500 -# endif -# ifndef WINVER -# define WINVER 0x0500 -# endif -#endif - -/* Availability of freeaddrinfo, getaddrinfo and getnameinfo functions is - quite convoluted, compiler dependent and even build target dependent. */ -#if defined(HAVE_WS2TCPIP_H) -# if defined(__POCC__) -# define HAVE_FREEADDRINFO 1 -# define HAVE_GETADDRINFO 1 -# define HAVE_GETNAMEINFO 1 -# elif defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) -# define HAVE_FREEADDRINFO 1 -# define HAVE_GETADDRINFO 1 -# define HAVE_GETNAMEINFO 1 -# elif defined(_MSC_VER) && (_MSC_VER >= 1200) -# define HAVE_FREEADDRINFO 1 -# define HAVE_GETADDRINFO 1 -# define HAVE_GETNAMEINFO 1 -# endif -#endif - -#if defined(__POCC__) -# ifndef _MSC_VER -# error Microsoft extensions /Ze compiler option is required -# endif -# ifndef __POCC__OLDNAMES -# error Compatibility names /Go compiler option is required -# endif -#endif - -/* ---------------------------------------------------------------- */ -/* IPV6 COMPATIBILITY */ -/* ---------------------------------------------------------------- */ - -/* Define this if you have address family AF_INET6 */ -#ifdef HAVE_WINSOCK2_H -#define HAVE_AF_INET6 1 -#endif - -/* Define this if you have protocol family PF_INET6 */ -#ifdef HAVE_WINSOCK2_H -#define HAVE_PF_INET6 1 -#endif - -/* Define this if you have struct in6_addr */ -#ifdef HAVE_WS2TCPIP_H -#define HAVE_STRUCT_IN6_ADDR 1 -#endif - -/* Define this if you have struct sockaddr_in6 */ -#ifdef HAVE_WS2TCPIP_H -#define HAVE_STRUCT_SOCKADDR_IN6 1 -#endif - -/* Define this if you have sockaddr_in6 with scopeid */ -#ifdef HAVE_WS2TCPIP_H -#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 -#endif - - -#endif /* __ARES_CONFIG_WIN32_H */ diff --git a/deps/uv/src/ares/config_win32/ares_config.h b/deps/uv/src/ares/config_win32/ares_config.h index a1f3c32..a269da2 100644 --- a/deps/uv/src/ares/config_win32/ares_config.h +++ b/deps/uv/src/ares/config_win32/ares_config.h @@ -1,382 +1,145 @@ -/* ares_config.h. Generated from ares_config.h.in by configure. */ -/* ares_config.h.in. Generated from configure.ac by autoheader. */ - -/* Define if building universal (internal helper macro) */ -/* #undef AC_APPLE_UNIVERSAL_BUILD */ - -/* define this if ares is built for a big endian system */ -/* #undef ARES_BIG_ENDIAN */ - -/* when building as static part of libcurl */ -/* #undef BUILDING_LIBCURL */ +#ifndef __ARES_CONFIG_WIN32_H +#define __ARES_CONFIG_WIN32_H /* when building c-ares library */ -/* #undef CARES_BUILDING_LIBRARY */ +#define CARES_BUILDING_LIBRARY 1 /* when not building a shared library */ #define CARES_STATICLIB 1 -/* Define to 1 to enable hiding of library internal symbols. */ -/* #undef CARES_SYMBOL_HIDING */ - -/* Definition to make a library symbol externally visible. */ -/* #undef CARES_SYMBOL_SCOPE_EXTERN */ - -/* if a /etc/inet dir is being used */ -/* #undef ETC_INET */ +/* Copyright (C) 2004 - 2008 by Daniel Stenberg et al + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. M.I.T. makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#define ARES_ + +/* ================================================================ */ +/* ares/config-win32.h - Hand crafted config file for Windows */ +/* ================================================================ */ + +/* ---------------------------------------------------------------- */ +/* HEADER FILES */ +/* ---------------------------------------------------------------- */ + +/* Define if you have the header file. */ +#if defined(__MINGW32__) || defined(__POCC__) +#define HAVE_GETOPT_H 1 +#endif -/* Define to the type qualifier of arg 1 for getnameinfo. */ -/* #undef GETNAMEINFO_QUAL_ARG1 */ +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 -/* Define to the type of arg 1 for getnameinfo. */ -/* #undef GETNAMEINFO_TYPE_ARG1 */ +/* Define if you have the header file. */ +#ifndef __SALFORDC__ +#define HAVE_PROCESS_H 1 +#endif -/* Define to the type of arg 2 for getnameinfo. */ -/* #undef GETNAMEINFO_TYPE_ARG2 */ +/* Define if you have the header file. */ +#define HAVE_SIGNAL_H 1 -/* Define to the type of args 4 and 6 for getnameinfo. */ -/* #undef GETNAMEINFO_TYPE_ARG46 */ +/* Define if you have the header file */ +#if defined(__MINGW32__) +#define HAVE_SYS_TIME_H 1 +#endif -/* Define to the type of arg 7 for getnameinfo. */ -/* #undef GETNAMEINFO_TYPE_ARG7 */ +/* Define if you have the header file. */ +#define HAVE_TIME_H 1 -/* Specifies the number of arguments to getservbyport_r */ -/* #undef GETSERVBYPORT_R_ARGS */ +/* Define if you have the header file. */ +#if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__LCC__) || \ + defined(__POCC__) +#define HAVE_UNISTD_H 1 +#endif -/* Specifies the size of the buffer to pass to getservbyport_r */ -/* #undef GETSERVBYPORT_R_BUFSIZE */ +/* Define if you have the windows.h header file. */ +#define HAVE_WINDOWS_H 1 -/* Define to 1 if you have AF_INET6. */ -#define HAVE_AF_INET6 1 +/* Define if you have the header file. */ +#define HAVE_WINSOCK_H 1 -/* Define to 1 if you have the header file. */ -/* #undef HAVE_ARPA_INET_H */ +/* Define if you have the header file. */ +#ifndef __SALFORDC__ +#define HAVE_WINSOCK2_H 1 +#endif -/* Define to 1 if you have the header file. */ -/* #undef HAVE_ARPA_NAMESER_COMPAT_H */ +/* Define if you have the header file. */ +#ifndef __SALFORDC__ +#define HAVE_WS2TCPIP_H 1 +#endif -/* Define to 1 if you have the header file. */ -/* #undef HAVE_ARPA_NAMESER_H */ +/* ---------------------------------------------------------------- */ +/* OTHER HEADER INFO */ +/* ---------------------------------------------------------------- */ -/* Define to 1 if you have the header file. */ -#define HAVE_ASSERT_H 1 +/* Define if sig_atomic_t is an available typedef. */ +#define HAVE_SIG_ATOMIC_T 1 -/* Define to 1 if you have the `bitncmp' function. */ -/* #undef HAVE_BITNCMP */ +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 -/* Define to 1 if bool is an available type. */ -#define HAVE_BOOL_T 1 +/* Define if you can safely include both and . */ +/* #define TIME_WITH_SYS_TIME 1 */ -/* Define to 1 if you have the clock_gettime function and monotonic timer. */ -/* #undef HAVE_CLOCK_GETTIME_MONOTONIC */ +/* ---------------------------------------------------------------- */ +/* FUNCTIONS */ +/* ---------------------------------------------------------------- */ -/* Define to 1 if you have the closesocket function. */ +/* Define if you have the closesocket function. */ #define HAVE_CLOSESOCKET 1 -/* Define to 1 if you have the CloseSocket camel case function. */ -/* #undef HAVE_CLOSESOCKET_CAMEL */ - -/* Define to 1 if you have the connect function. */ -#define HAVE_CONNECT 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_DLFCN_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_ERRNO_H 1 - -/* Define to 1 if you have the fcntl function. */ -/* #undef HAVE_FCNTL */ - -/* Define to 1 if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have a working fcntl O_NONBLOCK function. */ -/* #undef HAVE_FCNTL_O_NONBLOCK */ - -/* Define to 1 if you have the freeaddrinfo function. */ -/* #undef HAVE_FREEADDRINFO */ - -/* Define to 1 if you have a working getaddrinfo function. */ -/* #undef HAVE_GETADDRINFO */ - -/* Define to 1 if the getaddrinfo function is threadsafe. */ -/* #undef HAVE_GETADDRINFO_THREADSAFE */ - -/* Define to 1 if you have the gethostbyaddr function. */ -#define HAVE_GETHOSTBYADDR 1 - -/* Define to 1 if you have the gethostbyname function. */ -#define HAVE_GETHOSTBYNAME 1 - -/* Define to 1 if you have the gethostname function. */ +/* Define if you have the gethostname function. */ #define HAVE_GETHOSTNAME 1 -/* Define to 1 if you have the getnameinfo function. */ -/* #undef HAVE_GETNAMEINFO */ - -/* Define to 1 if you have the getservbyport_r function. */ -/* #undef HAVE_GETSERVBYPORT_R */ - -/* Define to 1 if you have the `gettimeofday' function. */ -#define HAVE_GETTIMEOFDAY 1 - -/* Define to 1 if you have the `if_indextoname' function. */ -/* #undef HAVE_IF_INDEXTONAME */ - -/* Define to 1 if you have the `inet_net_pton' function. */ -/* #undef HAVE_INET_NET_PTON */ - -/* Define to 1 if inet_net_pton supports IPv6. */ -/* #undef HAVE_INET_NET_PTON_IPV6 */ - -/* Define to 1 if you have a IPv6 capable working inet_ntop function. */ -/* #undef HAVE_INET_NTOP */ - -/* Define to 1 if you have a IPv6 capable working inet_pton function. */ -/* #undef HAVE_INET_PTON */ - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the ioctl function. */ -/* #undef HAVE_IOCTL */ - -/* Define to 1 if you have the ioctlsocket function. */ +/* Define if you have the ioctlsocket function. */ #define HAVE_IOCTLSOCKET 1 -/* Define to 1 if you have the IoctlSocket camel case function. */ -/* #undef HAVE_IOCTLSOCKET_CAMEL */ - -/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. - */ -/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ - -/* Define to 1 if you have a working ioctlsocket FIONBIO function. */ +/* Define if you have a working ioctlsocket FIONBIO function. */ #define HAVE_IOCTLSOCKET_FIONBIO 1 -/* Define to 1 if you have a working ioctl FIONBIO function. */ -/* #undef HAVE_IOCTL_FIONBIO */ - -/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ -/* #undef HAVE_IOCTL_SIOCGIFADDR */ - -/* Define to 1 if you have the `resolve' library (-lresolve). */ -/* #undef HAVE_LIBRESOLVE */ - -/* Define to 1 if you have the header file. */ -#define HAVE_LIMITS_H 1 - -/* if your compiler supports LL */ -#define HAVE_LL 1 - -/* Define to 1 if the compiler supports the 'long long' data type. */ -#define HAVE_LONGLONG 1 - -/* Define to 1 if you have the malloc.h header file. */ -#define HAVE_MALLOC_H 1 - -/* Define to 1 if you have the memory.h header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the MSG_NOSIGNAL flag. */ -/* #undef HAVE_MSG_NOSIGNAL */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_NETDB_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_NETINET_IN_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_NETINET_TCP_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_NET_IF_H */ - -/* Define to 1 if you have PF_INET6. */ -#define HAVE_PF_INET6 1 - -/* Define to 1 if you have the recv function. */ -#define HAVE_RECV 1 - -/* Define to 1 if you have the recvfrom function. */ -#define HAVE_RECVFROM 1 - -/* Define to 1 if you have the send function. */ -#define HAVE_SEND 1 - -/* Define to 1 if you have the setsockopt function. */ -#define HAVE_SETSOCKOPT 1 - -/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ -/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SIGNAL_H 1 - -/* Define to 1 if sig_atomic_t is an available typedef. */ -#define HAVE_SIG_ATOMIC_T 1 - -/* Define to 1 if sig_atomic_t is already defined as volatile. */ -/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */ - -/* Define to 1 if your struct sockaddr_in6 has sin6_scope_id. */ -#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 +/* Define if you have the strcasecmp function. */ +/* #define HAVE_STRCASECMP 1 */ -/* Define to 1 if you have the socket function. */ -#define HAVE_SOCKET 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SOCKET_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_STDBOOL_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the strcasecmp function. */ -#define HAVE_STRCASECMP 1 - -/* Define to 1 if you have the strcmpi function. */ -#define HAVE_STRCMPI 1 - -/* Define to 1 if you have the strdup function. */ +/* Define if you have the strdup function. */ #define HAVE_STRDUP 1 -/* Define to 1 if you have the stricmp function. */ +/* Define if you have the stricmp function. */ #define HAVE_STRICMP 1 -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the strncasecmp function. */ -#define HAVE_STRNCASECMP 1 - -/* Define to 1 if you have the strncmpi function. */ -/* #undef HAVE_STRNCMPI */ - -/* Define to 1 if you have the strnicmp function. */ -/* #undef HAVE_STRNICMP */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_STROPTS_H */ - -/* Define to 1 if you have struct addrinfo. */ -#define HAVE_STRUCT_ADDRINFO 1 - -/* Define to 1 if you have struct in6_addr. */ -#define HAVE_STRUCT_IN6_ADDR 1 - -/* Define to 1 if you have struct sockaddr_in6. */ -#define HAVE_STRUCT_SOCKADDR_IN6 1 - -/* if struct sockaddr_storage is defined */ -#define HAVE_STRUCT_SOCKADDR_STORAGE 1 - -/* Define to 1 if you have the timeval struct. */ -#define HAVE_STRUCT_TIMEVAL 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_IOCTL_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_SELECT_H */ +/* Define if you have the strncasecmp function. */ +/* #define HAVE_STRNCASECMP 1 */ -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_SOCKET_H */ +/* Define if you have the strnicmp function. */ +#define HAVE_STRNICMP 1 -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_UIO_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_TIME_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the windows.h header file. */ -#define HAVE_WINDOWS_H 1 - -/* Define to 1 if you have the winsock2.h header file. */ -#define HAVE_WINSOCK2_H 1 - -/* Define to 1 if you have the winsock.h header file. */ -#define HAVE_WINSOCK_H 1 - -/* Define to 1 if you have the writev function. */ -/* #undef HAVE_WRITEV */ - -/* Define to 1 if you have the ws2tcpip.h header file. */ -#define HAVE_WS2TCPIP_H 1 - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#define LT_OBJDIR ".libs/" - -/* Define to 1 if you are building a native Windows target. */ -#define NATIVE_WINDOWS 1 - -/* Define to 1 if you need the malloc.h header file even with stdlib.h */ -/* #undef NEED_MALLOC_H */ - -/* Define to 1 if you need the memory.h header file even with stdlib.h */ -/* #undef NEED_MEMORY_H */ - -/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ -/* #undef NEED_REENTRANT */ - -/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */ -/* #undef NEED_THREAD_SAFE */ - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -/* #undef NO_MINUS_C_MINUS_O */ - -/* cpu-machine-OS */ -#define OS "i686-pc-mingw32" - -/* Name of package */ -#define PACKAGE "c-ares" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "c-ares mailing list => http://cool.haxx.se/mailman/listinfo/c-ares" +/* Define if you have the recv function. */ +#define HAVE_RECV 1 -/* Define to the full name of this package. */ -#define PACKAGE_NAME "c-ares" +/* Define to the type of arg 1 for recv. */ +#define RECV_TYPE_ARG1 SOCKET -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "c-ares 1.7.3" +/* Define to the type of arg 2 for recv. */ +#define RECV_TYPE_ARG2 char * -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "c-ares" +/* Define to the type of arg 3 for recv. */ +#define RECV_TYPE_ARG3 int -/* Define to the home page for this package. */ -#define PACKAGE_URL "" +/* Define to the type of arg 4 for recv. */ +#define RECV_TYPE_ARG4 int -/* Define to the version of this package. */ -#define PACKAGE_VERSION "1.7.3" +/* Define to the function return type for recv. */ +#define RECV_TYPE_RETV int -/* a suitable file/device to read random data from */ -#define RANDOM_FILE "/dev/urandom" +/* Define if you have the recvfrom function. */ +#define HAVE_RECVFROM 1 /* Define to the type of arg 1 for recvfrom. */ #define RECVFROM_TYPE_ARG1 SOCKET @@ -384,9 +147,6 @@ /* Define to the type pointed by arg 2 for recvfrom. */ #define RECVFROM_TYPE_ARG2 char -/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */ -/* #undef RECVFROM_TYPE_ARG2_IS_VOID */ - /* Define to the type of arg 3 for recvfrom. */ #define RECVFROM_TYPE_ARG3 int @@ -396,42 +156,21 @@ /* Define to the type pointed by arg 5 for recvfrom. */ #define RECVFROM_TYPE_ARG5 struct sockaddr -/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */ -/* #undef RECVFROM_TYPE_ARG5_IS_VOID */ - /* Define to the type pointed by arg 6 for recvfrom. */ #define RECVFROM_TYPE_ARG6 int -/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */ -/* #undef RECVFROM_TYPE_ARG6_IS_VOID */ - /* Define to the function return type for recvfrom. */ #define RECVFROM_TYPE_RETV int -/* Define to the type of arg 1 for recv. */ -#define RECV_TYPE_ARG1 SOCKET - -/* Define to the type of arg 2 for recv. */ -#define RECV_TYPE_ARG2 char * - -/* Define to the type of arg 3 for recv. */ -#define RECV_TYPE_ARG3 int - -/* Define to the type of arg 4 for recv. */ -#define RECV_TYPE_ARG4 int - -/* Define to the function return type for recv. */ -#define RECV_TYPE_RETV int +/* Define if you have the send function. */ +#define HAVE_SEND 1 -/* Define as the return type of signal handlers (`int' or `void'). */ -#define RETSIGTYPE void +/* Define to the type of arg 1 for send. */ +#define SEND_TYPE_ARG1 SOCKET /* Define to the type qualifier of arg 2 for send. */ #define SEND_QUAL_ARG2 const -/* Define to the type of arg 1 for send. */ -#define SEND_TYPE_ARG1 SOCKET - /* Define to the type of arg 2 for send. */ #define SEND_TYPE_ARG2 char * @@ -444,67 +183,187 @@ /* Define to the function return type for send. */ #define SEND_TYPE_RETV int +/* Specifics for the Watt-32 tcp/ip stack */ +#ifdef WATT32 + #define SOCKET int + #define NS_INADDRSZ 4 + #define HAVE_ARPA_NAMESER_H 1 + #define HAVE_ARPA_INET_H 1 + #define HAVE_NETDB_H 1 + #define HAVE_NETINET_IN_H 1 + #define HAVE_SYS_SOCKET_H 1 + #define HAVE_NETINET_TCP_H 1 + #define HAVE_AF_INET6 1 + #define HAVE_PF_INET6 1 + #define HAVE_STRUCT_IN6_ADDR 1 + #define HAVE_STRUCT_SOCKADDR_IN6 1 + #undef HAVE_WINSOCK_H + #undef HAVE_WINSOCK2_H + #undef HAVE_WS2TCPIP_H +#endif + +/* ---------------------------------------------------------------- */ +/* TYPEDEF REPLACEMENTS */ +/* ---------------------------------------------------------------- */ + +/* Define this if in_addr_t is not an available 'typedefed' type */ +#define in_addr_t unsigned long + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define ssize_t if it is not an available 'typedefed' type */ +#ifndef _SSIZE_T_DEFINED +# if (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || \ + defined(__POCC__) || \ + defined(__MINGW32__) +# elif defined(_WIN64) +# define _SSIZE_T_DEFINED +# define ssize_t __int64 +# else +# define _SSIZE_T_DEFINED +# define ssize_t int +# endif +#endif + +/* ---------------------------------------------------------------- */ +/* TYPE SIZES */ +/* ---------------------------------------------------------------- */ + /* The size of `int', as computed by sizeof. */ #define SIZEOF_INT 4 -/* The size of `long', as computed by sizeof. */ -#define SIZEOF_LONG 4 +/* The size of `short', as computed by sizeof. */ +#define SIZEOF_SHORT 2 /* The size of `size_t', as computed by sizeof. */ -#define SIZEOF_SIZE_T 4 +#if defined(_WIN64) +# define SIZEOF_SIZE_T 8 +#else +# define SIZEOF_SIZE_T 4 +#endif -/* The size of `struct in6_addr', as computed by sizeof. */ -#define SIZEOF_STRUCT_IN6_ADDR 16 +/* ---------------------------------------------------------------- */ +/* STRUCT RELATED */ +/* ---------------------------------------------------------------- */ -/* The size of `struct in_addr', as computed by sizeof. */ -#define SIZEOF_STRUCT_IN_ADDR 4 +/* Define this if you have struct addrinfo */ +#define HAVE_STRUCT_ADDRINFO 1 -/* The size of `time_t', as computed by sizeof. */ -#define SIZEOF_TIME_T 4 +/* Define this if you have struct sockaddr_storage */ +#ifndef __SALFORDC__ +#define HAVE_STRUCT_SOCKADDR_STORAGE 1 +#endif -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 +/* Define this if you have struct timeval */ +#define HAVE_STRUCT_TIMEVAL 1 -/* Define to 1 if you can safely include both and . */ -#define TIME_WITH_SYS_TIME 1 +/* ---------------------------------------------------------------- */ +/* COMPILER SPECIFIC */ +/* ---------------------------------------------------------------- */ -/* Define to disable non-blocking sockets. */ -/* #undef USE_BLOCKING_SOCKETS */ +/* Define to avoid VS2005 complaining about portable C functions */ +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#define _CRT_SECURE_NO_DEPRECATE 1 +#define _CRT_NONSTDC_NO_DEPRECATE 1 +#endif -/* Version number of package */ -#define VERSION "1.7.3" +/* Officially, Microsoft's Windows SDK versions 6.X do not support Windows + 2000 as a supported build target. VS2008 default installations provide an + embedded Windows SDK v6.0A along with the claim that Windows 2000 is a + valid build target for VS2008. Popular belief is that binaries built using + Windows SDK versions 6.X and Windows 2000 as a build target are functional */ +#if defined(_MSC_VER) && (_MSC_VER >= 1500) +# define VS2008_MINIMUM_TARGET 0x0500 +#endif -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel). */ -#if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif -#else -# ifndef WORDS_BIGENDIAN -/* # undef WORDS_BIGENDIAN */ -# endif +/* When no build target is specified VS2008 default build target is Windows + Vista, which leaves out even Winsows XP. If no build target has been given + for VS2008 we will target the minimum Officially supported build target, + which happens to be Windows XP. */ +#if defined(_MSC_VER) && (_MSC_VER >= 1500) +# define VS2008_DEFAULT_TARGET 0x0501 #endif -/* Define to 1 if OS is AIX. */ -#ifndef _ALL_SOURCE -/* # undef _ALL_SOURCE */ +/* VS2008 default target settings and minimum build target check */ +#if defined(_MSC_VER) && (_MSC_VER >= 1500) +# ifndef _WIN32_WINNT +# define _WIN32_WINNT VS2008_DEFAULT_TARGET +# endif +# ifndef WINVER +# define WINVER VS2008_DEFAULT_TARGET +# endif +# if (_WIN32_WINNT < VS2008_MINIMUM_TARGET) || (WINVER < VS2008_MINIMUM_TARGET) +# error VS2008 does not support Windows build targets prior to Windows 2000 +# endif #endif -/* Number of bits in a file offset, on hosts where this is settable. */ -/* #undef _FILE_OFFSET_BITS */ +/* When no build target is specified Pelles C 5.00 and later default build + target is Windows Vista. We override default target to be Windows 2000. */ +#if defined(__POCC__) && (__POCC__ >= 500) +# ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0500 +# endif +# ifndef WINVER +# define WINVER 0x0500 +# endif +#endif -/* Define for large files, on AIX-style hosts. */ -/* #undef _LARGE_FILES */ +/* Availability of freeaddrinfo, getaddrinfo and getnameinfo functions is + quite convoluted, compiler dependent and even build target dependent. */ +#if defined(HAVE_WS2TCPIP_H) +# if defined(__POCC__) +# define HAVE_FREEADDRINFO 1 +# define HAVE_GETADDRINFO 1 +# define HAVE_GETNAMEINFO 1 +# elif defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) +# define HAVE_FREEADDRINFO 1 +# define HAVE_GETADDRINFO 1 +# define HAVE_GETNAMEINFO 1 +# elif defined(_MSC_VER) && (_MSC_VER >= 1200) +# define HAVE_FREEADDRINFO 1 +# define HAVE_GETADDRINFO 1 +# define HAVE_GETNAMEINFO 1 +# endif +#endif -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ +#if defined(__POCC__) +# ifndef _MSC_VER +# error Microsoft extensions /Ze compiler option is required +# endif +# ifndef __POCC__OLDNAMES +# error Compatibility names /Go compiler option is required +# endif +#endif -/* Type to use in place of in_addr_t when system does not provide it. */ -#define in_addr_t unsigned long +/* ---------------------------------------------------------------- */ +/* IPV6 COMPATIBILITY */ +/* ---------------------------------------------------------------- */ + +/* Define this if you have address family AF_INET6 */ +#ifdef HAVE_WINSOCK2_H +#define HAVE_AF_INET6 1 +#endif + +/* Define this if you have protocol family PF_INET6 */ +#ifdef HAVE_WINSOCK2_H +#define HAVE_PF_INET6 1 +#endif + +/* Define this if you have struct in6_addr */ +#ifdef HAVE_WS2TCPIP_H +#define HAVE_STRUCT_IN6_ADDR 1 +#endif + +/* Define this if you have struct sockaddr_in6 */ +#ifdef HAVE_WS2TCPIP_H +#define HAVE_STRUCT_SOCKADDR_IN6 1 +#endif + +/* Define this if you have sockaddr_in6 with scopeid */ +#ifdef HAVE_WS2TCPIP_H +#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 +#endif -/* Define to `unsigned int' if does not define. */ -/* #undef size_t */ -/* the signed version of size_t */ -/* #undef ssize_t */ +#endif /* __ARES_CONFIG_WIN32_H */ diff --git a/deps/uv/src/eio/config_linux.h b/deps/uv/src/eio/config_linux.h index f1bd91a..9823f62 100644 --- a/deps/uv/src/eio/config_linux.h +++ b/deps/uv/src/eio/config_linux.h @@ -3,8 +3,11 @@ #include -#define LINUX_VERSION_CODE_FOR(major, minor, patch) (((major & 255) >> 16) | ((minor & 255) >> 8) | (patch & 255)) -#define LINUX_VERSION_AT_LEAST(major, minor, patch) (LINUX_VERSION_CODE_FOR(major, minor, patch) >= LINUX_VERSION_CODE) +#define LINUX_VERSION_CODE_FOR(major, minor, patch) \ + (((major & 255) << 16) | ((minor & 255) << 8) | (patch & 255)) + +#define LINUX_VERSION_AT_LEAST(major, minor, patch) \ + (LINUX_VERSION_CODE >= LINUX_VERSION_CODE_FOR(major, minor, patch)) /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 diff --git a/deps/uv/src/ev/config_linux.h b/deps/uv/src/ev/config_linux.h index 248d15f..b147b59 100644 --- a/deps/uv/src/ev/config_linux.h +++ b/deps/uv/src/ev/config_linux.h @@ -3,8 +3,11 @@ #include -#define LINUX_VERSION_CODE_FOR(major, minor, patch) (((major & 255) >> 16) | ((minor & 255) >> 8) | (patch & 255)) -#define LINUX_VERSION_AT_LEAST(major, minor, patch) (LINUX_VERSION_CODE_FOR(major, minor, patch) >= LINUX_VERSION_CODE) +#define LINUX_VERSION_CODE_FOR(major, minor, patch) \ + (((major & 255) << 16) | ((minor & 255) << 8) | (patch & 255)) + +#define LINUX_VERSION_AT_LEAST(major, minor, patch) \ + (LINUX_VERSION_CODE >= LINUX_VERSION_CODE_FOR(major, minor, patch)) /* Define to 1 if you have the `clock_gettime' function. */ /* #undef HAVE_CLOCK_GETTIME */ diff --git a/deps/uv/src/uv-common.h b/deps/uv/src/uv-common.h index 74b4c4e..fbe4797 100644 --- a/deps/uv/src/uv-common.h +++ b/deps/uv/src/uv-common.h @@ -29,6 +29,8 @@ #include "uv.h" +#define COUNTOF(a) (sizeof(a) / sizeof(a[0])) + /* * Subclass of uv_handle_t. Used for integration of c-ares. */ diff --git a/deps/uv/src/uv-freebsd.c b/deps/uv/src/uv-freebsd.c index 108455d..6766538 100644 --- a/deps/uv/src/uv-freebsd.c +++ b/deps/uv/src/uv-freebsd.c @@ -20,28 +20,44 @@ #include "uv.h" +#include +#include + +#include +#include + +#undef NANOSEC +#define NANOSEC 1000000000 + +uint64_t uv_hrtime(void) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (ts.tv_sec * NANOSEC + ts.tv_nsec); +} + int uv_exepath(char* buffer, size_t* size) { uint32_t usize; int result; char* path; char* fullpath; + int mib[4]; + size_t cb; if (!buffer || !size) { return -1; } - int mib[4]; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PATHNAME; mib[3] = -1; - size_t cb = *size; + cb = *size; if (sysctl(mib, 4, buffer, &cb, NULL, 0) < 0) { - *size = 0; - return -1; + *size = 0; + return -1; } *size = strlen(buffer); diff --git a/deps/uv/src/uv-linux.c b/deps/uv/src/uv-linux.c index dc718c6..03396e9 100644 --- a/deps/uv/src/uv-linux.c +++ b/deps/uv/src/uv-linux.c @@ -22,6 +22,7 @@ #include #include +#include #include #undef NANOSEC @@ -39,11 +40,6 @@ uint64_t uv_hrtime() { int uv_exepath(char* buffer, size_t* size) { - uint32_t usize; - int result; - char* path; - char* fullpath; - if (!buffer || !size) { return -1; } diff --git a/deps/uv/src/uv-sunos.c b/deps/uv/src/uv-sunos.c index 879956f..4a75461 100644 --- a/deps/uv/src/uv-sunos.c +++ b/deps/uv/src/uv-sunos.c @@ -20,7 +20,6 @@ #include "uv.h" -#include #include #include #include @@ -40,7 +39,7 @@ uint64_t uv_hrtime() { int uv_exepath(char* buffer, size_t* size) { size_t res; pid_t pid; - char buf[PATH_MAX]; + char buf[128]; if (buffer == NULL) return (-1); diff --git a/deps/uv/src/uv-unix.c b/deps/uv/src/uv-unix.c index de92f3d..ab8a5e6 100644 --- a/deps/uv/src/uv-unix.c +++ b/deps/uv/src/uv-unix.c @@ -99,7 +99,6 @@ static void uv_fatal_error(const int errorno, const char* syscall) { fprintf(stderr, "\nlibuv fatal error. (%d) %s\n", errorno, errmsg); } - *((char*)NULL) = 0xff; /* Force debug break */ abort(); } @@ -169,8 +168,8 @@ int uv_close(uv_handle_t* handle, uv_close_cb close_cb) { switch (handle->type) { case UV_TCP: tcp = (uv_tcp_t*) handle; + uv_read_stop((uv_stream_t*)tcp); ev_io_stop(EV_DEFAULT_ &tcp->write_watcher); - ev_io_stop(EV_DEFAULT_ &tcp->read_watcher); break; case UV_PREPARE: @@ -633,7 +632,7 @@ static uv_req_t* uv__write(uv_tcp_t* tcp) { /* Successful write */ /* Update the counters. */ - while (n > 0) { + while (n >= 0) { uv_buf_t* buf = &(req->bufs[req->write_index]); size_t len = buf->len; @@ -871,7 +870,7 @@ static void uv__tcp_connect(uv_tcp_t* tcp) { return; } else { /* Error */ - uv_err_t err = uv_err_new((uv_handle_t*)tcp, error); + uv_err_new((uv_handle_t*)tcp, error); tcp->connect_req = NULL; @@ -962,6 +961,27 @@ int uv_tcp_connect6(uv_req_t* req, struct sockaddr_in6 addr) { } +int uv_getsockname(uv_tcp_t* handle, struct sockaddr* name, int* namelen) { + socklen_t socklen; + int saved_errno; + + /* Don't clobber errno. */ + saved_errno = errno; + + /* sizeof(socklen_t) != sizeof(int) on some systems. */ + socklen = (socklen_t)*namelen; + + if (getsockname(handle->fd, name, &socklen) == -1) { + uv_err_new((uv_handle_t*)handle, errno); + } else { + *namelen = (int)socklen; + } + + errno = saved_errno; + return 0; +} + + static size_t uv__buf_count(uv_buf_t bufs[], int bufcnt) { size_t total = 0; int i; @@ -996,7 +1016,9 @@ int uv_write(uv_req_t* req, uv_buf_t bufs[], int bufcnt) { memcpy(req->bufs, bufs, bufcnt * sizeof(uv_buf_t)); req->bufcnt = bufcnt; - // fprintf(stderr, "cnt: %d bufs: %p bufsml: %p\n", bufcnt, req->bufs, req->bufsml); + /* + * fprintf(stderr, "cnt: %d bufs: %p bufsml: %p\n", bufcnt, req->bufs, req->bufsml); + */ req->write_index = 0; tcp->write_queue_size += uv__buf_count(bufs, bufcnt); @@ -1096,7 +1118,7 @@ int uv_read_stop(uv_stream_t* stream) { } -void uv_req_init(uv_req_t* req, uv_handle_t* handle, void* cb) { +void uv_req_init(uv_req_t* req, uv_handle_t* handle, void *(*cb)(void *)) { uv_counters()->req_init++; req->type = UV_UNKNOWN_REQ; req->cb = cb; @@ -1166,7 +1188,7 @@ static void uv__check(EV_P_ ev_check* w, int revents) { int uv_check_init(uv_check_t* check) { uv__handle_init((uv_handle_t*)check, UV_CHECK); - uv_counters()->check_init; + uv_counters()->check_init++; ev_check_init(&check->check_watcher, uv__check); check->check_watcher.data = check; @@ -1303,6 +1325,7 @@ int uv_async_init(uv_async_t* async, uv_async_cb async_cb) { int uv_async_send(uv_async_t* async) { ev_async_send(EV_DEFAULT_UC_ &async->async_watcher); + return 0; } @@ -1413,6 +1436,8 @@ static uv_ares_task_t* uv__ares_task_create(int fd) { h->read_watcher.data = h; h->write_watcher.data = h; + + return h; } @@ -1544,7 +1569,7 @@ static int getaddrinfo_thread_proc(eio_req *req) { handle->retcode = getaddrinfo(handle->hostname, handle->service, - &handle->hints, + handle->hints, &handle->res); return 0; } @@ -1556,6 +1581,7 @@ int uv_getaddrinfo(uv_getaddrinfo_t* handle, const char* hostname, const char* service, const struct addrinfo* hints) { + eio_req* req; uv_eio_init(); if (handle == NULL || cb == NULL || @@ -1584,7 +1610,7 @@ int uv_getaddrinfo(uv_getaddrinfo_t* handle, uv_ref(); - eio_req* req = eio_custom(getaddrinfo_thread_proc, EIO_PRI_DEFAULT, + req = eio_custom(getaddrinfo_thread_proc, EIO_PRI_DEFAULT, uv_getaddrinfo_done, handle); assert(req); assert(req->data == handle); @@ -1592,3 +1618,22 @@ int uv_getaddrinfo(uv_getaddrinfo_t* handle, return 0; } + +int uv_pipe_init(uv_pipe_t* handle) { + assert(0 && "implement me"); +} + + +int uv_pipe_bind(uv_pipe_t* handle, const char* name) { + assert(0 && "implement me"); +} + + +int uv_pipe_listen(uv_pipe_t* handle, uv_connection_cb cb) { + assert(0 && "implement me"); +} + + +int uv_pipe_connect(uv_req_t* req, const char* name) { + assert(0 && "implement me"); +} diff --git a/deps/uv/src/uv-win.c b/deps/uv/src/uv-win.c index 1f54e07..7166e37 100644 --- a/deps/uv/src/uv-win.c +++ b/deps/uv/src/uv-win.c @@ -164,6 +164,7 @@ static LPFN_TRANSMITFILE pTransmitFile6; #define UV_HANDLE_ENDGAME_QUEUED 0x0400 #define UV_HANDLE_BIND_ERROR 0x1000 #define UV_HANDLE_IPV6 0x2000 +#define UV_HANDLE_PIPESERVER 0x4000 /* * Private uv_req flags. @@ -238,10 +239,12 @@ struct uv_ares_action_s { int write; }; -void uv_ares_process(uv_ares_action_t* handle, uv_req_t* req); -void uv_ares_task_cleanup(uv_ares_task_t* handle, uv_req_t* req); +void uv_process_ares_event_req(uv_ares_action_t* handle, uv_req_t* req); +void uv_process_ares_cleanup_req(uv_ares_task_t* handle, uv_req_t* req); void uv_ares_poll(uv_timer_t* handle, int status); +static void close_pipe(uv_pipe_t* handle, int* status, uv_err_t* err); + /* memory used per ares_channel */ struct uv_ares_channel_s { ares_channel channel; @@ -260,7 +263,7 @@ static uv_ares_channel_t uv_ares_data = { NULL, 0 }; /* getaddrinfo integration */ -static void uv_getaddrinfo_done(uv_getaddrinfo_t* handle, uv_req_t* req); +static void uv_process_getaddrinfo_req(uv_getaddrinfo_t* handle, uv_req_t* req); /* adjust size value to be multiple of 4. Use to keep pointer aligned */ /* Do we need different versions of this for different architectures? */ #define ALIGNED_SIZE(X) ((((X) + 3) >> 2) << 2) @@ -373,6 +376,8 @@ static uv_err_code uv_translate_sys_error(int sys_errno) { case ERROR_INVALID_FLAGS: return UV_EBADF; case ERROR_INVALID_PARAMETER: return UV_EINVAL; case ERROR_NO_UNICODE_TRANSLATION: return UV_ECHARSET; + case ERROR_BROKEN_PIPE: return UV_EOF; + case ERROR_PIPE_BUSY: return UV_EBUSY; default: return UV_UNKNOWN; } } @@ -513,7 +518,7 @@ void uv_init() { } -void uv_req_init(uv_req_t* req, uv_handle_t* handle, void* cb) { +void uv_req_init(uv_req_t* req, uv_handle_t* handle, void *(*cb)(void *)) { uv_counters()->req_init++; req->type = UV_UNKNOWN_REQ; req->flags = 0; @@ -531,6 +536,7 @@ static void uv_insert_pending_req(uv_req_t* req) { req->next_req = NULL; if (uv_pending_reqs_tail_) { req->next_req = uv_pending_reqs_tail_->next_req; + uv_pending_reqs_tail_->next_req = req; uv_pending_reqs_tail_ = req; } else { req->next_req = req; @@ -593,24 +599,20 @@ static int uv_tcp_set_socket(uv_tcp_t* handle, SOCKET socket) { } -static void uv_tcp_init_connection(uv_tcp_t* handle) { +static void uv_init_connection(uv_stream_t* handle) { handle->flags |= UV_HANDLE_CONNECTION; handle->write_reqs_pending = 0; uv_req_init(&(handle->read_req), (uv_handle_t*)handle, NULL); } -int uv_tcp_init(uv_tcp_t* handle) { - handle->socket = INVALID_SOCKET; +int uv_stream_init(uv_stream_t* handle) { handle->write_queue_size = 0; - handle->type = UV_TCP; handle->flags = 0; - handle->reqs_pending = 0; handle->error = uv_ok_; - handle->accept_socket = INVALID_SOCKET; uv_counters()->handle_init++; - uv_counters()->tcp_init++; + uv_counters()->stream_init++; uv_refs_++; @@ -618,6 +620,20 @@ int uv_tcp_init(uv_tcp_t* handle) { } +int uv_tcp_init(uv_tcp_t* handle) { + uv_stream_init((uv_stream_t*)handle); + + handle->socket = INVALID_SOCKET; + handle->type = UV_TCP; + handle->reqs_pending = 0; + handle->accept_socket = INVALID_SOCKET; + + uv_counters()->tcp_init++; + + return 0; +} + + static void uv_tcp_endgame(uv_tcp_t* handle) { uv_err_t err; int status; @@ -657,6 +673,39 @@ static void uv_tcp_endgame(uv_tcp_t* handle) { } +static void uv_pipe_endgame(uv_pipe_t* handle) { + uv_err_t err; + int status; + + if (handle->flags & UV_HANDLE_SHUTTING && + !(handle->flags & UV_HANDLE_SHUT) && + handle->write_reqs_pending == 0) { + close_pipe(handle, &status, &err); + + if (handle->shutdown_req->cb) { + handle->shutdown_req->flags &= ~UV_REQ_PENDING; + if (status == -1) { + uv_last_error_ = err; + } + ((uv_shutdown_cb)handle->shutdown_req->cb)(handle->shutdown_req, status); + } + handle->reqs_pending--; + } + + if (handle->flags & UV_HANDLE_CLOSING && + handle->reqs_pending == 0) { + assert(!(handle->flags & UV_HANDLE_CLOSED)); + handle->flags |= UV_HANDLE_CLOSED; + + if (handle->close_cb) { + handle->close_cb((uv_handle_t*)handle); + } + + uv_refs_--; + } +} + + static void uv_timer_endgame(uv_timer_t* handle) { if (handle->flags & UV_HANDLE_CLOSING) { assert(!(handle->flags & UV_HANDLE_CLOSED)); @@ -714,6 +763,10 @@ static void uv_process_endgames() { uv_tcp_endgame((uv_tcp_t*)handle); break; + case UV_NAMED_PIPE: + uv_pipe_endgame((uv_pipe_t*)handle); + break; + case UV_TIMER: uv_timer_endgame((uv_timer_t*)handle); break; @@ -748,6 +801,7 @@ static void uv_want_endgame(uv_handle_t* handle) { static int uv_close_error(uv_handle_t* handle, uv_err_t e) { uv_tcp_t* tcp; + uv_pipe_t* pipe; if (handle->flags & UV_HANDLE_CLOSING) { return 0; @@ -760,6 +814,12 @@ static int uv_close_error(uv_handle_t* handle, uv_err_t e) { switch (handle->type) { case UV_TCP: tcp = (uv_tcp_t*)handle; + /* If we don't shutdown before calling closesocket, windows will */ + /* silently discard the kernel send buffer and reset the connection. */ + if (!(tcp->flags & UV_HANDLE_SHUT)) { + shutdown(tcp->socket, SD_SEND); + tcp->flags |= UV_HANDLE_SHUT; + } tcp->flags &= ~(UV_HANDLE_READING | UV_HANDLE_LISTENING); closesocket(tcp->socket); if (tcp->reqs_pending == 0) { @@ -767,6 +827,15 @@ static int uv_close_error(uv_handle_t* handle, uv_err_t e) { } return 0; + case UV_NAMED_PIPE: + pipe = (uv_pipe_t*)handle; + pipe->flags &= ~(UV_HANDLE_READING | UV_HANDLE_LISTENING); + close_pipe(pipe, NULL, NULL); + if (pipe->reqs_pending == 0) { + uv_want_endgame(handle); + } + return 0; + case UV_TIMER: uv_timer_stop((uv_timer_t*)handle); uv_want_endgame(handle); @@ -870,7 +939,7 @@ int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6 addr) { } -static void uv_queue_accept(uv_tcp_t* handle) { +static void uv_tcp_queue_accept(uv_tcp_t* handle) { uv_req_t* req; BOOL success; DWORD bytes; @@ -901,6 +970,7 @@ static void uv_queue_accept(uv_tcp_t* handle) { if (accept_socket == INVALID_SOCKET) { req->error = uv_new_sys_error(WSAGetLastError()); uv_insert_pending_req(req); + handle->reqs_pending++; return; } @@ -920,6 +990,7 @@ static void uv_queue_accept(uv_tcp_t* handle) { /* Make this req pending reporting an error. */ req->error = uv_new_sys_error(WSAGetLastError()); uv_insert_pending_req(req); + handle->reqs_pending++; /* Destroy the preallocated client socket. */ closesocket(accept_socket); return; @@ -932,7 +1003,57 @@ static void uv_queue_accept(uv_tcp_t* handle) { } -static void uv_queue_read(uv_tcp_t* handle) { +static void uv_pipe_queue_accept(uv_pipe_t* handle) { + uv_req_t* req; + HANDLE pipeHandle; + int i; + + assert(handle->flags & UV_HANDLE_LISTENING); + + for (i = 0; i < COUNTOF(handle->accept_reqs); i++) { + req = &handle->accept_reqs[i]; + if (!(req->flags & UV_REQ_PENDING)) { + pipeHandle = CreateNamedPipe(handle->name, + PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, + PIPE_UNLIMITED_INSTANCES, + 65536, + 65536, + 0, + NULL); + + if (pipeHandle == INVALID_HANDLE_VALUE) { + continue; + } + + if (CreateIoCompletionPort(pipeHandle, + uv_iocp_, + (ULONG_PTR)handle, + 0) == NULL) { + continue; + } + + /* Prepare the overlapped structure. */ + memset(&(req->overlapped), 0, sizeof(req->overlapped)); + + if (!ConnectNamedPipe(pipeHandle, &req->overlapped) && + GetLastError() != ERROR_IO_PENDING && GetLastError() != ERROR_PIPE_CONNECTED) { + /* Make this req pending reporting an error. */ + req->error = uv_new_sys_error(GetLastError()); + uv_insert_pending_req(req); + handle->reqs_pending++; + continue; + } + + req->data = pipeHandle; + req->flags |= UV_REQ_PENDING; + handle->reqs_pending++; + } + } +} + + +static void uv_tcp_queue_read(uv_tcp_t* handle) { uv_req_t* req; uv_buf_t buf; int result; @@ -960,6 +1081,40 @@ static void uv_queue_read(uv_tcp_t* handle) { /* Make this req pending reporting an error. */ req->error = uv_new_sys_error(WSAGetLastError()); uv_insert_pending_req(req); + handle->reqs_pending++; + return; + } + + req->flags |= UV_REQ_PENDING; + handle->reqs_pending++; +} + + +static void uv_pipe_queue_read(uv_pipe_t* handle) { + uv_req_t* req; + int result; + + assert(handle->flags & UV_HANDLE_READING); + assert(handle->connection); + assert(handle->connection->handle != INVALID_HANDLE_VALUE); + + req = &handle->read_req; + assert(!(req->flags & UV_REQ_PENDING)); + memset(&req->overlapped, 0, sizeof(req->overlapped)); + req->type = UV_READ; + + /* Do 0-read */ + result = ReadFile(handle->connection->handle, + &uv_zero_, + 0, + NULL, + &req->overlapped); + + if (!result && GetLastError() != ERROR_IO_PENDING) { + /* Make this req pending reporting an error. */ + req->error = uv_new_sys_error(WSAGetLastError()); + uv_insert_pending_req(req); + handle->reqs_pending++; return; } @@ -992,40 +1147,88 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) { handle->connection_cb = cb; uv_req_init(&(handle->accept_req), (uv_handle_t*)handle, NULL); - uv_queue_accept(handle); + uv_tcp_queue_accept(handle); return 0; } -int uv_accept(uv_handle_t* server, uv_stream_t* client) { +static int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) { int rv = 0; - uv_tcp_t* tcpServer = (uv_tcp_t*)server; - uv_tcp_t* tcpClient = (uv_tcp_t*)client; - - if (tcpServer->accept_socket == INVALID_SOCKET) { + + if (server->accept_socket == INVALID_SOCKET) { uv_set_sys_error(WSAENOTCONN); return -1; } - if (uv_tcp_set_socket(tcpClient, tcpServer->accept_socket) == -1) { - closesocket(tcpServer->accept_socket); + if (uv_tcp_set_socket(client, server->accept_socket) == -1) { + closesocket(server->accept_socket); rv = -1; } else { - uv_tcp_init_connection(tcpClient); + uv_init_connection((uv_stream_t*)client); } - tcpServer->accept_socket = INVALID_SOCKET; + server->accept_socket = INVALID_SOCKET; - if (!(tcpServer->flags & UV_HANDLE_CLOSING)) { - uv_queue_accept(tcpServer); + if (!(server->flags & UV_HANDLE_CLOSING)) { + uv_tcp_queue_accept(server); } return rv; } -int uv_read_start(uv_stream_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb) { +static int uv_pipe_accept(uv_pipe_t* server, uv_pipe_t* client) { + uv_pipe_instance_t* connection = server->connections; + + /* Find a connection instance that has been connected, but not yet accepted. */ + while (connection) { + if (connection->state == UV_PIPEINSTANCE_CONNECTED) { + break; + } + + connection = connection->next; + } + + if (!connection) { + /* No valid connections found, so we error out. */ + uv_set_sys_error(UV_ENOTCONN); + return -1; + } + + /* Make the connection instance active */ + connection->state = UV_PIPEINSTANCE_ACTIVE; + + /* Assign the connection to the client. */ + client->connection = connection; + client->server = server; + + uv_init_connection((uv_stream_t*)client); + client->flags |= UV_HANDLE_PIPESERVER; + uv_req_init(&(client->read_req), (uv_handle_t*)client, NULL); + + if (!(server->flags & UV_HANDLE_CLOSING)) { + uv_pipe_queue_accept(server); + } + + return 0; +} + + +int uv_accept(uv_handle_t* server, uv_stream_t* client) { + assert(client->type == server->type); + + if (server->type == UV_TCP) { + return uv_tcp_accept((uv_tcp_t*)server, (uv_tcp_t*)client); + } else if (server->type == UV_NAMED_PIPE) { + return uv_pipe_accept((uv_pipe_t*)server, (uv_pipe_t*)client); + } + + return -1; +} + + +static int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb) { if (!(handle->flags & UV_HANDLE_CONNECTION)) { uv_set_sys_error(WSAEINVAL); return -1; @@ -1048,12 +1251,52 @@ int uv_read_start(uv_stream_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 */ /* read request pending. */ if (!(handle->read_req.flags & UV_REQ_PENDING)) - uv_queue_read((uv_tcp_t*)handle); + uv_tcp_queue_read(handle); + + return 0; +} + + +static int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb) { + if (!(handle->flags & UV_HANDLE_CONNECTION)) { + uv_set_sys_error(UV_EINVAL); + return -1; + } + + if (handle->flags & UV_HANDLE_READING) { + uv_set_sys_error(UV_EALREADY); + return -1; + } + + if (handle->flags & UV_HANDLE_EOF) { + uv_set_sys_error(UV_EOF); + return -1; + } + + handle->flags |= UV_HANDLE_READING; + handle->read_cb = read_cb; + handle->alloc_cb = alloc_cb; + + /* If reading was stopped and then started again, there could stell be a */ + /* read request pending. */ + if (!(handle->read_req.flags & UV_REQ_PENDING)) + uv_pipe_queue_read(handle); return 0; } +int uv_read_start(uv_stream_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb) { + if (handle->type == UV_TCP) { + return uv_tcp_read_start((uv_tcp_t*)handle, alloc_cb, read_cb); + } else if (handle->type == UV_NAMED_PIPE) { + return uv_pipe_read_start((uv_pipe_t*)handle, alloc_cb, read_cb); + } + + return -1; +} + + int uv_read_stop(uv_stream_t* handle) { handle->flags &= ~UV_HANDLE_READING; @@ -1156,6 +1399,24 @@ int uv_tcp_connect6(uv_req_t* req, struct sockaddr_in6 addr) { } +int uv_getsockname(uv_tcp_t* handle, struct sockaddr* name, int* namelen) { + int result; + + if (handle->flags & UV_HANDLE_SHUTTING) { + uv_set_sys_error(WSAESHUTDOWN); + return -1; + } + + result = getsockname(handle->socket, name, namelen); + if (result != 0) { + uv_set_sys_error(WSAGetLastError()); + return -1; + } + + return 0; +} + + static size_t uv_count_bufs(uv_buf_t bufs[], int count) { size_t bytes = 0; int i; @@ -1168,7 +1429,7 @@ static size_t uv_count_bufs(uv_buf_t bufs[], int count) { } -int uv_write(uv_req_t* req, uv_buf_t bufs[], int bufcnt) { +int uv_tcp_write(uv_req_t* req, uv_buf_t bufs[], int bufcnt) { int result; DWORD bytes, err; uv_tcp_t* handle = (uv_tcp_t*) req->handle; @@ -1221,6 +1482,72 @@ int uv_write(uv_req_t* req, uv_buf_t bufs[], int bufcnt) { } +int uv_pipe_write(uv_req_t* req, uv_buf_t bufs[], int bufcnt) { + int result; + uv_pipe_t* handle = (uv_pipe_t*) req->handle; + + assert(!(req->flags & UV_REQ_PENDING)); + + if (bufcnt != 1) { + uv_set_sys_error(UV_ENOTSUP); + return -1; + } + + assert(handle->connection); + assert(handle->connection->handle != INVALID_HANDLE_VALUE); + + if (!(req->handle->flags & UV_HANDLE_CONNECTION)) { + uv_set_sys_error(UV_EINVAL); + return -1; + } + + if (req->handle->flags & UV_HANDLE_SHUTTING) { + uv_set_sys_error(UV_EOF); + return -1; + } + + memset(&req->overlapped, 0, sizeof(req->overlapped)); + req->type = UV_WRITE; + + result = WriteFile(handle->connection->handle, + bufs[0].base, + bufs[0].len, + NULL, + &req->overlapped); + + if (!result && GetLastError() != WSA_IO_PENDING) { + uv_set_sys_error(GetLastError()); + return -1; + } + + if (result) { + /* Request completed immediately. */ + req->queued_bytes = 0; + } else { + /* Request queued by the kernel. */ + req->queued_bytes = uv_count_bufs(bufs, bufcnt); + handle->write_queue_size += req->queued_bytes; + } + + req->flags |= UV_REQ_PENDING; + handle->reqs_pending++; + handle->write_reqs_pending++; + + return 0; +} + + +int uv_write(uv_req_t* req, uv_buf_t bufs[], int bufcnt) { + if (req->handle->type == UV_TCP) { + return uv_tcp_write(req, bufs, bufcnt); + } else if (req->handle->type == UV_NAMED_PIPE) { + return uv_pipe_write(req, bufs, bufcnt); + } + + return -1; +} + + int uv_shutdown(uv_req_t* req) { uv_tcp_t* handle = (uv_tcp_t*) req->handle; int status = 0; @@ -1239,7 +1566,7 @@ int uv_shutdown(uv_req_t* req) { req->flags |= UV_REQ_PENDING; handle->flags |= UV_HANDLE_SHUTTING; - handle->shutdown_req = req; + handle->shutdown_req = req; handle->reqs_pending++; uv_want_endgame((uv_handle_t*)handle); @@ -1248,7 +1575,18 @@ int uv_shutdown(uv_req_t* req) { } -static void uv_tcp_return_req(uv_tcp_t* handle, uv_req_t* req) { +#define DECREASE_PENDING_REQ_COUNT(handle) \ + do { \ + handle->reqs_pending--; \ + \ + if (handle->flags & UV_HANDLE_CLOSING && \ + handle->reqs_pending == 0) { \ + uv_want_endgame((uv_handle_t*)handle); \ + } \ + } while (0) + + +static void uv_process_tcp_read_req(uv_tcp_t* handle, uv_req_t* req) { DWORD bytes, flags, err; uv_buf_t buf; @@ -1257,156 +1595,342 @@ static void uv_tcp_return_req(uv_tcp_t* handle, uv_req_t* req) { /* Mark the request non-pending */ req->flags &= ~UV_REQ_PENDING; - switch (req->type) { - case UV_WRITE: - handle->write_queue_size -= req->queued_bytes; - if (req->cb) { - uv_last_error_ = req->error; - ((uv_write_cb)req->cb)(req, uv_last_error_.code == UV_OK ? 0 : -1); - } - handle->write_reqs_pending--; - if (handle->write_reqs_pending == 0 && - handle->flags & UV_HANDLE_SHUTTING) { - uv_want_endgame((uv_handle_t*)handle); - } - break; - - case UV_READ: - if (req->error.code != UV_OK) { - /* An error occurred doing the 0-read. */ - if (!(handle->flags & UV_HANDLE_READING)) { + if (req->error.code != UV_OK) { + /* An error occurred doing the 0-read. */ + if ((handle->flags & UV_HANDLE_READING)) { + handle->flags &= ~UV_HANDLE_READING; + uv_last_error_ = req->error; + buf.base = 0; + buf.len = 0; + handle->read_cb((uv_stream_t*)handle, -1, buf); + } + } else { + /* Do nonblocking reads until the buffer is empty */ + while (handle->flags & UV_HANDLE_READING) { + buf = handle->alloc_cb((uv_stream_t*)handle, 65536); + assert(buf.len > 0); + flags = 0; + if (WSARecv(handle->socket, + (WSABUF*)&buf, + 1, + &bytes, + &flags, + NULL, + NULL) != SOCKET_ERROR) { + if (bytes > 0) { + /* Successful read */ + handle->read_cb((uv_stream_t*)handle, bytes, buf); + /* Read again only if bytes == buf.len */ + if (bytes < buf.len) { + break; + } + } else { + /* Connection closed */ + handle->flags &= ~UV_HANDLE_READING; + handle->flags |= UV_HANDLE_EOF; + uv_last_error_.code = UV_EOF; + uv_last_error_.sys_errno_ = ERROR_SUCCESS; + handle->read_cb((uv_stream_t*)handle, -1, buf); break; } + } else { + err = WSAGetLastError(); + if (err == WSAEWOULDBLOCK) { + /* Read buffer was completely empty, report a 0-byte read. */ + uv_set_sys_error(WSAEWOULDBLOCK); + handle->read_cb((uv_stream_t*)handle, 0, buf); + } else { + /* Ouch! serious error. */ + uv_set_sys_error(err); + handle->read_cb((uv_stream_t*)handle, -1, buf); + } + break; + } + } - /* Stop reading and report error. */ - handle->flags &= ~UV_HANDLE_READING; + /* Post another 0-read if still reading and not closing. */ + if (handle->flags & UV_HANDLE_READING) { + uv_tcp_queue_read(handle); + } + } + + DECREASE_PENDING_REQ_COUNT(handle); +} + + +static void uv_process_tcp_write_req(uv_tcp_t* handle, uv_req_t* req) { + assert(handle->type == UV_TCP); + + /* Mark the request non-pending */ + req->flags &= ~UV_REQ_PENDING; + + handle->write_queue_size -= req->queued_bytes; + + if (req->cb) { + uv_last_error_ = req->error; + ((uv_write_cb)req->cb)(req, uv_last_error_.code == UV_OK ? 0 : -1); + } + + handle->write_reqs_pending--; + if (handle->flags & UV_HANDLE_SHUTTING && + handle->write_reqs_pending == 0) { + uv_want_endgame((uv_handle_t*)handle); + } + + DECREASE_PENDING_REQ_COUNT(handle); +} + + +static void uv_process_tcp_accept_req(uv_tcp_t* handle, uv_req_t* req) { + assert(handle->type == UV_TCP); + + /* Mark the request non-pending */ + req->flags &= ~UV_REQ_PENDING; + + /* If handle->accepted_socket is not a valid socket, then */ + /* uv_queue_accept must have failed. This is a serious error. We stop */ + /* accepting connections and report this error to the connection */ + /* callback. */ + if (handle->accept_socket == INVALID_SOCKET) { + if (handle->flags & UV_HANDLE_LISTENING) { + handle->flags &= ~UV_HANDLE_LISTENING; + if (handle->connection_cb) { uv_last_error_ = req->error; - buf.base = 0; - buf.len = 0; - handle->read_cb((uv_stream_t*)handle, -1, buf); - break; + handle->connection_cb((uv_handle_t*)handle, -1); } + } + } else if (req->error.code == UV_OK && + setsockopt(handle->accept_socket, + SOL_SOCKET, + SO_UPDATE_ACCEPT_CONTEXT, + (char*)&handle->socket, + sizeof(handle->socket)) == 0) { + /* Accept and SO_UPDATE_ACCEPT_CONTEXT were successful. */ + if (handle->connection_cb) { + handle->connection_cb((uv_handle_t*)handle, 0); + } + } else { + /* Error related to accepted socket is ignored because the server */ + /* socket may still be healthy. If the server socket is broken + /* uv_queue_accept will detect it. */ + closesocket(handle->accept_socket); + if (handle->flags & UV_HANDLE_LISTENING) { + uv_tcp_queue_accept(handle); + } + } - /* Do nonblocking reads until the buffer is empty */ - while (handle->flags & UV_HANDLE_READING) { - buf = handle->alloc_cb((uv_stream_t*)handle, 65536); - assert(buf.len > 0); - flags = 0; - if (WSARecv(handle->socket, - (WSABUF*)&buf, - 1, - &bytes, - &flags, - NULL, - NULL) != SOCKET_ERROR) { - if (bytes > 0) { - /* Successful read */ - handle->read_cb((uv_stream_t*)handle, bytes, buf); - /* Read again only if bytes == buf.len */ - if (bytes < buf.len) { - break; - } - } else { - /* Connection closed */ - handle->flags &= ~UV_HANDLE_READING; - handle->flags |= UV_HANDLE_EOF; - uv_last_error_.code = UV_EOF; - uv_last_error_.sys_errno_ = ERROR_SUCCESS; - handle->read_cb((uv_stream_t*)handle, -1, buf); + DECREASE_PENDING_REQ_COUNT(handle); +} + + +static void uv_process_tcp_connect_req(uv_tcp_t* handle, uv_req_t* req) { + assert(handle->type == UV_TCP); + + /* Mark the request non-pending */ + req->flags &= ~UV_REQ_PENDING; + + if (req->cb) { + if (req->error.code == UV_OK) { + if (setsockopt(handle->socket, + SOL_SOCKET, + SO_UPDATE_CONNECT_CONTEXT, + NULL, + 0) == 0) { + uv_init_connection((uv_stream_t*)handle); + ((uv_connect_cb)req->cb)(req, 0); + } else { + uv_set_sys_error(WSAGetLastError()); + ((uv_connect_cb)req->cb)(req, -1); + } + } else { + uv_last_error_ = req->error; + ((uv_connect_cb)req->cb)(req, -1); + } + } + + DECREASE_PENDING_REQ_COUNT(handle); +} + + +static void uv_process_pipe_read_req(uv_pipe_t* handle, uv_req_t* req) { + DWORD bytes, err, mode; + uv_buf_t buf; + + assert(handle->type == UV_NAMED_PIPE); + + /* Mark the request non-pending */ + req->flags &= ~UV_REQ_PENDING; + + if (req->error.code != UV_OK) { + /* An error occurred doing the 0-read. */ + if (handle->flags & UV_HANDLE_READING) { + /* Stop reading and report error. */ + handle->flags &= ~UV_HANDLE_READING; + uv_last_error_ = req->error; + buf.base = 0; + buf.len = 0; + handle->read_cb((uv_stream_t*)handle, -1, buf); + } + } else { + /* + * Temporarily switch to non-blocking mode. + * This is so that ReadFile doesn't block if the read buffer is empty. + */ + mode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT; + if (!SetNamedPipeHandleState(handle->connection->handle, &mode, NULL, NULL)) { + /* We can't continue processing this read. */ + handle->flags &= ~UV_HANDLE_READING; + uv_set_sys_error(GetLastError()); + buf.base = 0; + buf.len = 0; + handle->read_cb((uv_stream_t*)handle, -1, buf); + } + + /* Do non-blocking reads until the buffer is empty */ + while (handle->flags & UV_HANDLE_READING) { + buf = handle->alloc_cb((uv_stream_t*)handle, 65536); + assert(buf.len > 0); + + if (ReadFile(handle->connection->handle, + buf.base, + buf.len, + &bytes, + NULL)) { + if (bytes > 0) { + /* Successful read */ + handle->read_cb((uv_stream_t*)handle, bytes, buf); + /* Read again only if bytes == buf.len */ + if (bytes < buf.len) { break; } } else { - err = WSAGetLastError(); - if (err == WSAEWOULDBLOCK) { - /* Read buffer was completely empty, report a 0-byte read. */ - uv_set_sys_error(WSAEWOULDBLOCK); - handle->read_cb((uv_stream_t*)handle, 0, buf); - } else { - /* Ouch! serious error. */ - uv_set_sys_error(err); - handle->read_cb((uv_stream_t*)handle, -1, buf); - } + /* Connection closed */ + handle->flags &= ~UV_HANDLE_READING; + handle->flags |= UV_HANDLE_EOF; + uv_last_error_.code = UV_EOF; + uv_last_error_.sys_errno_ = ERROR_SUCCESS; + handle->read_cb((uv_stream_t*)handle, -1, buf); break; } - } - /* Post another 0-read if still reading and not closing. */ - if (handle->flags & UV_HANDLE_READING) { - uv_queue_read(handle); - } - break; - - case UV_ACCEPT: - /* If handle->accepted_socket is not a valid socket, then */ - /* uv_queue_accept must have failed. This is a serious error. We stop */ - /* accepting connections and report this error to the connection */ - /* callback. */ - if (handle->accept_socket == INVALID_SOCKET) { - if (!(handle->flags & UV_HANDLE_LISTENING)) { - break; - } - handle->flags &= ~UV_HANDLE_LISTENING; - if (handle->connection_cb) { - uv_last_error_ = req->error; - handle->connection_cb((uv_handle_t*)handle, -1); + } else { + err = GetLastError(); + if (err == ERROR_NO_DATA) { + /* Read buffer was completely empty, report a 0-byte read. */ + uv_set_sys_error(UV_EAGAIN); + handle->read_cb((uv_stream_t*)handle, 0, buf); + } else { + /* Ouch! serious error. */ + uv_set_sys_error(err); + handle->read_cb((uv_stream_t*)handle, -1, buf); } break; } + } - if (req->error.code == UV_OK && - setsockopt(handle->accept_socket, - SOL_SOCKET, - SO_UPDATE_ACCEPT_CONTEXT, - (char*)&handle->socket, - sizeof(handle->socket)) == 0) { - /* Accept and SO_UPDATE_ACCEPT_CONTEXT were successful. */ - if (handle->connection_cb) { - handle->connection_cb((uv_handle_t*)handle, 0); - } + /* TODO: if the read callback stops reading we can't start reading again + because the pipe will still be in nowait mode. */ + if (handle->flags & UV_HANDLE_READING) { + /* Switch back to blocking mode so that we can use IOCP for 0-reads */ + mode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT; + if (SetNamedPipeHandleState(handle->connection->handle, &mode, NULL, NULL)) { + /* Post another 0-read */ + uv_pipe_queue_read(handle); } else { - /* Error related to accepted socket is ignored because the server */ - /* socket may still be healthy. If the server socket is broken - /* uv_queue_accept will detect it. */ - closesocket(handle->accept_socket); - if (handle->flags & UV_HANDLE_LISTENING) { - uv_queue_accept(handle); - } + /* Report and continue. */ + /* We can't continue processing this read. */ + handle->flags &= ~UV_HANDLE_READING; + uv_set_sys_error(GetLastError()); + buf.base = 0; + buf.len = 0; + handle->read_cb((uv_stream_t*)handle, -1, buf); } - break; + } + } - case UV_CONNECT: - if (req->cb) { - if (req->error.code == UV_OK) { - if (setsockopt(handle->socket, - SOL_SOCKET, - SO_UPDATE_CONNECT_CONTEXT, - NULL, - 0) == 0) { - uv_tcp_init_connection(handle); - ((uv_connect_cb)req->cb)(req, 0); - } else { - uv_set_sys_error(WSAGetLastError()); - ((uv_connect_cb)req->cb)(req, -1); - } - } else { - uv_last_error_ = req->error; - ((uv_connect_cb)req->cb)(req, -1); - } - } - break; + DECREASE_PENDING_REQ_COUNT(handle); +} - default: - assert(0); - } - /* The number of pending requests is now down by one */ - handle->reqs_pending--; +static void uv_process_pipe_write_req(uv_pipe_t* handle, uv_req_t* req) { + assert(handle->type == UV_NAMED_PIPE); - /* Queue the handle's close callback if it is closing and there are no */ - /* more pending requests. */ - if (handle->flags & UV_HANDLE_CLOSING && - handle->reqs_pending == 0) { + /* Mark the request non-pending */ + req->flags &= ~UV_REQ_PENDING; + + handle->write_queue_size -= req->queued_bytes; + + if (req->cb) { + uv_last_error_ = req->error; + ((uv_write_cb)req->cb)(req, uv_last_error_.code == UV_OK ? 0 : -1); + } + + handle->write_reqs_pending--; + if (handle->write_reqs_pending == 0 && + handle->flags & UV_HANDLE_SHUTTING) { uv_want_endgame((uv_handle_t*)handle); } + + DECREASE_PENDING_REQ_COUNT(handle); +} + + +static void uv_process_pipe_accept_req(uv_pipe_t* handle, uv_req_t* req) { + uv_pipe_instance_t* pipeInstance; + + assert(handle->type == UV_NAMED_PIPE); + + /* Mark the request non-pending */ + req->flags &= ~UV_REQ_PENDING; + + if (req->error.code == UV_OK) { + assert(req->data); + + /* Create the connection instance and add it to the connections list. */ + pipeInstance = (uv_pipe_instance_t*)malloc(sizeof(uv_pipe_instance_t)); + if (!pipeInstance) { + uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + } + + pipeInstance->handle = req->data; + pipeInstance->state = UV_PIPEINSTANCE_CONNECTED; + pipeInstance->next = handle->connections; + handle->connections = pipeInstance; + + /* Clear the request. */ + req->data = NULL; + req->flags = 0; + + if (handle->connection_cb) { + handle->connection_cb((uv_handle_t*)handle, 0); + } + } else { + /* Ignore errors and continue listening */ + if (handle->flags & UV_HANDLE_LISTENING) { + uv_pipe_queue_accept(handle); + } + } + + DECREASE_PENDING_REQ_COUNT(handle); +} + + +static void uv_process_pipe_connect_req(uv_pipe_t* handle, uv_req_t* req) { + assert(handle->type == UV_NAMED_PIPE); + + /* Mark the request non-pending */ + req->flags &= ~UV_REQ_PENDING; + + if (req->cb) { + if (req->error.code == UV_OK) { + uv_init_connection((uv_stream_t*)handle); + ((uv_connect_cb)req->cb)(req, 0); + } else { + uv_last_error_ = req->error; + ((uv_connect_cb)req->cb)(req, -1); + } + } + + DECREASE_PENDING_REQ_COUNT(handle); } @@ -1682,7 +2206,7 @@ int uv_async_send(uv_async_t* handle) { } -static void uv_async_return_req(uv_async_t* handle, uv_req_t* req) { +static void uv_process_async_wakeup_req(uv_async_t* handle, uv_req_t* req) { assert(handle->type == UV_ASYNC); assert(req->type == UV_WAKEUP); @@ -1696,32 +2220,58 @@ static void uv_async_return_req(uv_async_t* handle, uv_req_t* req) { } +#define DELEGATE_STREAM_REQ(req, method) \ + do { \ + switch (req->handle->type) { \ + case UV_TCP: \ + uv_process_tcp_##method##_req((uv_tcp_t*) req->handle, req); \ + break; \ + \ + case UV_NAMED_PIPE: \ + uv_process_pipe_##method##_req((uv_pipe_t*) req->handle, req); \ + break; \ + \ + default: \ + assert(0); \ + } \ + } while (0) + + static void uv_process_reqs() { uv_req_t* req; - uv_handle_t* handle; while (req = uv_remove_pending_req()) { - handle = req->handle; + switch (req->type) { + case UV_READ: + DELEGATE_STREAM_REQ(req, read); + break; - switch (handle->type) { - case UV_TCP: - uv_tcp_return_req((uv_tcp_t*)handle, req); + case UV_WRITE: + DELEGATE_STREAM_REQ(req, write); break; - case UV_ASYNC: - uv_async_return_req((uv_async_t*)handle, req); + case UV_ACCEPT: + DELEGATE_STREAM_REQ(req, accept); + break; + + case UV_CONNECT: + DELEGATE_STREAM_REQ(req, connect); + break; + + case UV_WAKEUP: + uv_process_async_wakeup_req((uv_async_t*) req->handle, req); break; - case UV_ARES: - uv_ares_process((uv_ares_action_t*)handle, req); + case UV_ARES_EVENT_REQ: + uv_process_ares_event_req((uv_ares_action_t*) req->handle, req); break; - case UV_ARES_TASK: - uv_ares_task_cleanup((uv_ares_task_t*)handle, req); + case UV_ARES_CLEANUP_REQ: + uv_process_ares_cleanup_req((uv_ares_task_t*) req->handle, req); break; - case UV_GETADDRINFO: - uv_getaddrinfo_done((uv_getaddrinfo_t*)handle, req); + case UV_GETADDRINFO_REQ: + uv_process_getaddrinfo_req((uv_getaddrinfo_t*) req->handle, req); break; default: @@ -1947,7 +2497,7 @@ VOID CALLBACK uv_ares_socksignal_tp(void* parameter, BOOLEAN timerfired) { if (selhandle == NULL) { uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); } - selhandle->type = UV_ARES; + selhandle->type = UV_ARES_EVENT; selhandle->close_cb = NULL; selhandle->data = sockhandle->data; selhandle->sock = sockhandle->sock; @@ -1956,7 +2506,7 @@ VOID CALLBACK uv_ares_socksignal_tp(void* parameter, BOOLEAN timerfired) { uv_ares_req = &selhandle->ares_req; uv_req_init(uv_ares_req, (uv_handle_t*)selhandle, NULL); - uv_ares_req->type = UV_WAKEUP; + uv_ares_req->type = UV_ARES_EVENT_REQ; /* post ares needs to called */ if (!PostQueuedCompletionStatus(uv_iocp_, @@ -1974,8 +2524,6 @@ void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read, int write) { uv_ares_task_t* uv_handle_ares = uv_find_ares_handle(sock); uv_ares_channel_t* uv_ares_data_ptr = (uv_ares_channel_t*)data; - struct timeval tv; - struct timeval* tvptr; int timeoutms = 0; if (read == 0 && write == 0) { @@ -2004,7 +2552,7 @@ void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read, int write) { /* Post request to cleanup the Task */ uv_ares_req = &uv_handle_ares->ares_req; uv_req_init(uv_ares_req, (uv_handle_t*)uv_handle_ares, NULL); - uv_ares_req->type = UV_WAKEUP; + uv_ares_req->type = UV_ARES_CLEANUP_REQ; /* post ares done with socket - finish cleanup when all threads done. */ if (!PostQueuedCompletionStatus(uv_iocp_, @@ -2049,7 +2597,7 @@ void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read, int write) { uv_add_ares_handle(uv_handle_ares); uv_refs_++; - /* + /* * we have a single polling timer for all ares sockets. * This is preferred to using ares_timeout. See ares_timeout.c warning. * if timer is not running start it, and keep socket count @@ -2079,7 +2627,7 @@ void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read, int write) { } /* called via uv_poll when ares completion port signaled */ -void uv_ares_process(uv_ares_action_t* handle, uv_req_t* req) { +void uv_process_ares_event_req(uv_ares_action_t* handle, uv_req_t* req) { uv_ares_channel_t* uv_ares_data_ptr = (uv_ares_channel_t*)handle->data; ares_process_fd(uv_ares_data_ptr->channel, @@ -2091,7 +2639,7 @@ void uv_ares_process(uv_ares_action_t* handle, uv_req_t* req) { } /* called via uv_poll when ares is finished with socket */ -void uv_ares_task_cleanup(uv_ares_task_t* handle, uv_req_t* req) { +void uv_process_ares_cleanup_req(uv_ares_task_t* handle, uv_req_t* req) { /* check for event complete without waiting */ unsigned int signaled = WaitForSingleObject(handle->h_close_event, 0); @@ -2223,7 +2771,7 @@ static DWORD WINAPI getaddrinfo_thread_proc(void* parameter) { * and copy all structs and referenced strings into the one block. * Each size calculation is adjusted to avoid unaligned pointers. */ -static void uv_getaddrinfo_done(uv_getaddrinfo_t* handle, uv_req_t* req) { +static void uv_process_getaddrinfo_req(uv_getaddrinfo_t* handle, uv_req_t* req) { int addrinfo_len = 0; int name_len = 0; size_t addrinfo_struct_len = ALIGNED_SIZE(sizeof(struct addrinfo)); @@ -2434,7 +2982,7 @@ int uv_getaddrinfo(uv_getaddrinfo_t* handle, /* init request for Post handling */ uv_req_init(&handle->getadddrinfo_req, (uv_handle_t*)handle, NULL); - handle->getadddrinfo_req.type = UV_WAKEUP; + handle->getadddrinfo_req.type = UV_GETADDRINFO_REQ; /* Ask thread to run. Treat this as a long operation */ if (QueueUserWorkItem(&getaddrinfo_thread_proc, handle, WT_EXECUTELONGFUNCTION) == 0) { @@ -2453,3 +3001,239 @@ error: return -1; } + +int uv_pipe_init(uv_pipe_t* handle) { + uv_stream_init((uv_stream_t*)handle); + + handle->type = UV_NAMED_PIPE; + handle->reqs_pending = 0; + + uv_counters()->pipe_init++; + + return 0; +} + + +/* Creates a pipe server. */ +/* TODO: make this work with UTF8 name */ +int uv_pipe_bind(uv_pipe_t* handle, const char* name) { + int i; + + if (!name) { + return -1; + } + + handle->connections = NULL; + + /* Initialize accept requests. */ + for (i = 0; i < COUNTOF(handle->accept_reqs); i++) { + handle->accept_reqs[i].flags = 0; + handle->accept_reqs[i].type = UV_ACCEPT; + handle->accept_reqs[i].handle = (uv_handle_t*)handle; + handle->accept_reqs[i].cb = NULL; + handle->accept_reqs[i].data = NULL; + uv_counters()->req_init++; + } + + /* Make our own copy of the pipe name */ + handle->name = (char*)malloc(MAX_PIPENAME_LEN); + if (!handle->name) { + uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + } + strcpy(handle->name, name); + handle->name[255] = '\0'; + + handle->flags |= UV_HANDLE_PIPESERVER; + return 0; +} + + +/* Starts listening for connections for the given pipe. */ +int uv_pipe_listen(uv_pipe_t* handle, uv_connection_cb cb) { + int i, maxInstances, errno; + HANDLE pipeHandle; + uv_pipe_instance_t* pipeInstance; + + if (handle->flags & UV_HANDLE_LISTENING || + handle->flags & UV_HANDLE_READING) { + uv_set_sys_error(UV_EALREADY); + return -1; + } + + if (!(handle->flags & UV_HANDLE_PIPESERVER)) { + uv_set_sys_error(UV_ENOTSUP); + return -1; + } + + handle->flags |= UV_HANDLE_LISTENING; + handle->connection_cb = cb; + + uv_pipe_queue_accept(handle); + return 0; +} + +/* TODO: make this work with UTF8 name */ +int uv_pipe_connect(uv_req_t* req, const char* name) { + int errno; + DWORD mode; + uv_pipe_t* handle = (uv_pipe_t*)req->handle; + + assert(!(req->flags & UV_REQ_PENDING)); + + req->type = UV_CONNECT; + handle->connection = &handle->clientConnection; + handle->server = NULL; + memset(&req->overlapped, 0, sizeof(req->overlapped)); + + handle->clientConnection.handle = CreateFile(name, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + NULL); + + if (handle->clientConnection.handle == INVALID_HANDLE_VALUE && + GetLastError() != ERROR_IO_PENDING) { + errno = GetLastError(); + goto error; + } + + mode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT; + + if (!SetNamedPipeHandleState(handle->clientConnection.handle, &mode, NULL, NULL)) { + errno = GetLastError(); + goto error; + } + + if (CreateIoCompletionPort(handle->clientConnection.handle, + uv_iocp_, + (ULONG_PTR)handle, + 0) == NULL) { + errno = GetLastError(); + goto error; + } + + req->error = uv_ok_; + req->flags |= UV_REQ_PENDING; + handle->connection->state = UV_PIPEINSTANCE_ACTIVE; + uv_insert_pending_req(req); + handle->reqs_pending++; + return 0; + +error: + close_pipe(handle, NULL, NULL); + req->error = uv_new_sys_error(errno); + uv_insert_pending_req(req); + handle->reqs_pending++; + return 0; +} + + +/* Cleans up uv_pipe_t (server or connection) and all resources associated with it */ +static void close_pipe(uv_pipe_t* handle, int* status, uv_err_t* err) { + uv_pipe_instance_t* connection, *next, *cur, **prev; + HANDLE pipeHandle; + int i; + + if (handle->flags & UV_HANDLE_PIPESERVER) { + if (handle->flags & UV_HANDLE_CONNECTION) { + /* + * The handle is for a connection instance on the pipe server. + * To clean-up, we call DisconnectNamedPipe, and then uv_pipe_queue_accept will cleanup the allocated uv_pipe_instance_t. + */ + + connection = handle->connection; + if (connection && connection->handle != INVALID_HANDLE_VALUE) { + /* Disconnect the connection intance and return it to pending state. */ + if (DisconnectNamedPipe(connection->handle)) { + if (status) *status = 0; + } else { + if (status) *status = -1; + if (err) *err = uv_new_sys_error(GetLastError()); + } + + connection->state = UV_PIPEINSTANCE_DISCONNECTED; + connection->handle = NULL; + + cur = handle->connections; + handle->connection = NULL; + prev = &handle->server->connections; + + /* Remove the connection from the list. */ + while (connection) { + if (cur == connection) { + *prev = connection->next; + free(connection); + break; + } else { + prev = &connection->next; + connection = connection->next; + } + } + + /* Queue accept now that the instance is in pending state. */ + if (!(handle->server->flags & UV_HANDLE_CLOSING)) { + uv_pipe_queue_accept(handle->server); + } + } + } else { + /* + * The handle is for the pipe server. + * To clean-up we close every active and pending connection instance. + */ + + if (handle->name) { + free(handle->name); + handle->name = NULL; + } + + connection = handle->connections; + while (connection) { + pipeHandle = connection->handle; + + if (pipeHandle) { + DisconnectNamedPipe(pipeHandle); + CloseHandle(pipeHandle); + } + + next = connection->next; + free(connection); + connection = next; + } + + handle->connections = NULL; + + for (i = 0; i < COUNTOF(handle->accept_reqs); i++) { + if (handle->accept_reqs[i].flags & UV_REQ_PENDING) { + pipeHandle = handle->accept_reqs[i].data; + assert(pipeHandle); + DisconnectNamedPipe(pipeHandle); + CloseHandle(pipeHandle); + handle->accept_reqs[i].flags = 0; + handle->reqs_pending--; + } + } + + if (status) *status = 0; + } + } else { + /* + * The handle is for a connection instance on the pipe client. + * To clean-up we close the pipe handle. + */ + connection = handle->connection; + if (connection && connection->handle != INVALID_HANDLE_VALUE) { + if (CloseHandle(connection->handle)) { + connection->state = UV_PIPEINSTANCE_DISCONNECTED; + handle->connection = NULL; + if (status) *status = 0; + } else { + if (status) *status = -1; + if (err) *err = uv_new_sys_error(GetLastError()); + } + } + } + + handle->flags |= UV_HANDLE_SHUT; +} diff --git a/deps/uv/test/benchmark-list.h b/deps/uv/test/benchmark-list.h index 6040e90..5e79878 100644 --- a/deps/uv/test/benchmark-list.h +++ b/deps/uv/test/benchmark-list.h @@ -21,25 +21,35 @@ BENCHMARK_DECLARE (sizes) BENCHMARK_DECLARE (ping_pongs) -BENCHMARK_DECLARE (pump100_client) -BENCHMARK_DECLARE (pump1_client) +BENCHMARK_DECLARE (tcp_pump100_client) +BENCHMARK_DECLARE (tcp_pump1_client) +BENCHMARK_DECLARE (pipe_pump100_client) +BENCHMARK_DECLARE (pipe_pump1_client) BENCHMARK_DECLARE (gethostbyname) BENCHMARK_DECLARE (getaddrinfo) -HELPER_DECLARE (pump_server) -HELPER_DECLARE (echo_server) +HELPER_DECLARE (tcp_pump_server) +HELPER_DECLARE (pipe_pump_server) +HELPER_DECLARE (tcp4_echo_server) +HELPER_DECLARE (pipe_echo_server) HELPER_DECLARE (dns_server) TASK_LIST_START BENCHMARK_ENTRY (sizes) BENCHMARK_ENTRY (ping_pongs) - BENCHMARK_HELPER (ping_pongs, echo_server) + BENCHMARK_HELPER (ping_pongs, tcp4_echo_server) - BENCHMARK_ENTRY (pump100_client) - BENCHMARK_HELPER (pump100_client, pump_server) + BENCHMARK_ENTRY (tcp_pump100_client) + BENCHMARK_HELPER (tcp_pump100_client, tcp_pump_server) - BENCHMARK_ENTRY (pump1_client) - BENCHMARK_HELPER (pump1_client, pump_server) + BENCHMARK_ENTRY (tcp_pump1_client) + BENCHMARK_HELPER (tcp_pump1_client, tcp_pump_server) + + BENCHMARK_ENTRY (pipe_pump100_client) + BENCHMARK_HELPER (pipe_pump100_client, pipe_pump_server) + + BENCHMARK_ENTRY (pipe_pump1_client) + BENCHMARK_HELPER (pipe_pump1_client, pipe_pump_server) BENCHMARK_ENTRY (gethostbyname) BENCHMARK_HELPER (gethostbyname, dns_server) diff --git a/deps/uv/test/benchmark-pump.c b/deps/uv/test/benchmark-pump.c index cd9c7d9..ad3676d 100644 --- a/deps/uv/test/benchmark-pump.c +++ b/deps/uv/test/benchmark-pump.c @@ -45,7 +45,9 @@ static uv_buf_t buf_alloc(uv_stream_t*, size_t size); static void buf_free(uv_buf_t uv_buf_t); -static uv_tcp_t server; +static uv_tcp_t tcpServer; +static uv_pipe_t pipeServer; +static uv_handle_t* server; static struct sockaddr_in listen_addr; static struct sockaddr_in connect_addr; @@ -68,7 +70,10 @@ static char write_buffer[WRITE_BUFFER_SIZE]; /* Make this as large as you need. */ #define MAX_WRITE_HANDLES 1000 -static uv_tcp_t write_handles[MAX_WRITE_HANDLES]; +static stream_type type; + +static uv_tcp_t tcp_write_handles[MAX_WRITE_HANDLES]; +static uv_pipe_t pipe_write_handles[MAX_WRITE_HANDLES]; static uv_timer_t timer_handle; @@ -81,6 +86,7 @@ static double gbit(int64_t bytes, int64_t passed_ms) { static void show_stats(uv_timer_t* handle, int status) { int64_t diff; + int i; #if PRINT_STATS LOGF("connections: %d, write: %.1f gbit/s\n", @@ -94,9 +100,13 @@ static void show_stats(uv_timer_t* handle, int status) { uv_update_time(); diff = uv_now() - start_time; - LOGF("pump%d_client: %.1f gbit/s\n", write_sockets, + LOGF("%s_pump%d_client: %.1f gbit/s\n", type == TCP ? "tcp" : "pipe", write_sockets, gbit(nsent_total, diff)); + for (i = 0; i < write_sockets; i++) { + uv_close(type == TCP ? (uv_handle_t*)&tcp_write_handles[i] : (uv_handle_t*)&pipe_write_handles[i], NULL); + } + exit(0); } @@ -112,7 +122,7 @@ static void read_show_stats() { uv_update_time(); diff = uv_now() - start_time; - LOGF("pump%d_server: %.1f gbit/s\n", max_read_sockets, + LOGF("%s_pump%d_server: %.1f gbit/s\n", type == TCP ? "tcp" : "pipe", max_read_sockets, gbit(nrecv_total, diff)); } @@ -133,7 +143,7 @@ void read_sockets_close_cb(uv_handle_t* handle) { */ if (uv_now() - start_time > 1000 && read_sockets == 0) { read_show_stats(); - uv_close((uv_handle_t*)&server, NULL); + uv_close(server, NULL); } } @@ -154,7 +164,7 @@ static void start_stats_collection() { } -static void read_cb(uv_stream_t* tcp, ssize_t bytes, uv_buf_t buf) { +static void read_cb(uv_stream_t* stream, ssize_t bytes, uv_buf_t buf) { if (nrecv_total == 0) { ASSERT(start_time == 0); uv_update_time(); @@ -162,7 +172,7 @@ static void read_cb(uv_stream_t* tcp, ssize_t bytes, uv_buf_t buf) { } if (bytes < 0) { - uv_close((uv_handle_t*)tcp, read_sockets_close_cb); + uv_close((uv_handle_t*)stream, read_sockets_close_cb); return; } @@ -187,7 +197,7 @@ static void write_cb(uv_req_t *req, int status) { } -static void do_write(uv_stream_t* tcp) { +static void do_write(uv_stream_t* stream) { uv_req_t* req; uv_buf_t buf; int r; @@ -195,9 +205,9 @@ static void do_write(uv_stream_t* tcp) { buf.base = (char*) &write_buffer; buf.len = sizeof write_buffer; - while (tcp->write_queue_size == 0) { + while (stream->write_queue_size == 0) { req = req_alloc(); - uv_req_init(req, (uv_handle_t*)tcp, write_cb); + uv_req_init(req, (uv_handle_t*)stream, write_cb); r = uv_write(req, &buf, 1); ASSERT(r == 0); @@ -221,7 +231,7 @@ static void connect_cb(uv_req_t* req, int status) { /* Yay! start writing */ for (i = 0; i < write_sockets; i++) { - do_write((uv_stream_t*)&write_handles[i]); + do_write(type == TCP ? (uv_stream_t*)&tcp_write_handles[i] : (uv_stream_t*)&pipe_write_handles[i]); } } } @@ -230,38 +240,62 @@ static void connect_cb(uv_req_t* req, int status) { static void maybe_connect_some() { uv_req_t* req; uv_tcp_t* tcp; + uv_pipe_t* pipe; int r; while (max_connect_socket < TARGET_CONNECTIONS && max_connect_socket < write_sockets + MAX_SIMULTANEOUS_CONNECTS) { - tcp = &write_handles[max_connect_socket++]; - - r = uv_tcp_init(tcp); - ASSERT(r == 0); - - req = req_alloc(); - uv_req_init(req, (uv_handle_t*)tcp, connect_cb); - r = uv_tcp_connect(req, connect_addr); - ASSERT(r == 0); + if (type == TCP) { + tcp = &tcp_write_handles[max_connect_socket++]; + + r = uv_tcp_init(tcp); + ASSERT(r == 0); + + req = req_alloc(); + uv_req_init(req, (uv_handle_t*)tcp, connect_cb); + r = uv_tcp_connect(req, connect_addr); + ASSERT(r == 0); + } else { + pipe = &pipe_write_handles[max_connect_socket++]; + + r = uv_pipe_init(pipe); + ASSERT(r == 0); + + req = req_alloc(); + uv_req_init(req, (uv_handle_t*)pipe, connect_cb); + r = uv_pipe_connect(req, TEST_PIPENAME); + ASSERT(r == 0); + +#ifdef _WIN32 + /* HACK: This is temporary to give the pipes server enough time to create new handles. + * This will go away once uv_pipe_connect can deal with UV_EBUSY. + */ + Sleep(1); +#endif + } } } static void connection_cb(uv_handle_t* s, int status) { - uv_tcp_t* tcp; + uv_stream_t* stream; int r; - ASSERT(&server == (uv_tcp_t*)s); + ASSERT(server == s); ASSERT(status == 0); - tcp = malloc(sizeof(uv_tcp_t)); - - uv_tcp_init(tcp); + if (type == TCP) { + stream = (uv_stream_t*)malloc(sizeof(uv_tcp_t)); + uv_tcp_init((uv_tcp_t*)stream); + } else { + stream = (uv_stream_t*)malloc(sizeof(uv_pipe_t)); + uv_pipe_init((uv_pipe_t*)stream); + } - r = uv_accept(s, (uv_stream_t*)tcp); + r = uv_accept(s, stream); ASSERT(r == 0); - r = uv_read_start((uv_stream_t*)tcp, buf_alloc, read_cb); + r = uv_read_start(stream, buf_alloc, read_cb); ASSERT(r == 0); read_sockets++; @@ -317,7 +351,7 @@ typedef struct buf_list_s { static buf_list_t* buf_freelist = NULL; -static uv_buf_t buf_alloc(uv_stream_t* tcp, size_t size) { +static uv_buf_t buf_alloc(uv_stream_t* stream, size_t size) { buf_list_t* buf; buf = buf_freelist; @@ -342,18 +376,41 @@ static void buf_free(uv_buf_t uv_buf_t) { } -HELPER_IMPL(pump_server) { +HELPER_IMPL(tcp_pump_server) { int r; + type = TCP; uv_init(); listen_addr = uv_ip4_addr("0.0.0.0", TEST_PORT); /* Server */ - r = uv_tcp_init(&server); + server = (uv_handle_t*)&tcpServer; + r = uv_tcp_init(&tcpServer); + ASSERT(r == 0); + r = uv_tcp_bind(&tcpServer, listen_addr); + ASSERT(r == 0); + r = uv_tcp_listen(&tcpServer, MAX_WRITE_HANDLES, connection_cb); + ASSERT(r == 0); + + uv_run(); + + return 0; +} + + +HELPER_IMPL(pipe_pump_server) { + int r; + type = PIPE; + + uv_init(); + + /* Server */ + server = (uv_handle_t*)&pipeServer; + r = uv_pipe_init(&pipeServer); ASSERT(r == 0); - r = uv_tcp_bind(&server, listen_addr); + r = uv_pipe_bind(&pipeServer, TEST_PIPENAME); ASSERT(r == 0); - r = uv_tcp_listen(&server, MAX_WRITE_HANDLES, connection_cb); + r = uv_pipe_listen(&pipeServer, connection_cb); ASSERT(r == 0); uv_run(); @@ -362,9 +419,10 @@ HELPER_IMPL(pump_server) { } -void pump(int n) { +void tcp_pump(int n) { ASSERT(n <= MAX_WRITE_HANDLES); TARGET_CONNECTIONS = n; + type = TCP; uv_init(); @@ -377,13 +435,39 @@ void pump(int n) { } -BENCHMARK_IMPL(pump100_client) { - pump(100); +void pipe_pump(int n) { + ASSERT(n <= MAX_WRITE_HANDLES); + TARGET_CONNECTIONS = n; + type = PIPE; + + uv_init(); + + /* Start making connections */ + maybe_connect_some(); + + uv_run(); +} + + +BENCHMARK_IMPL(tcp_pump100_client) { + tcp_pump(100); + return 0; +} + + +BENCHMARK_IMPL(tcp_pump1_client) { + tcp_pump(1); + return 0; +} + + +BENCHMARK_IMPL(pipe_pump100_client) { + pipe_pump(100); return 0; } -BENCHMARK_IMPL(pump1_client) { - pump(1); +BENCHMARK_IMPL(pipe_pump1_client) { + pipe_pump(1); return 0; } diff --git a/deps/uv/test/benchmark-sizes.c b/deps/uv/test/benchmark-sizes.c index 830de3a..9038645 100644 --- a/deps/uv/test/benchmark-sizes.c +++ b/deps/uv/test/benchmark-sizes.c @@ -26,6 +26,7 @@ BENCHMARK_IMPL(sizes) { LOGF("uv_req_t: %u bytes\n", (unsigned int) sizeof(uv_req_t)); LOGF("uv_tcp_t: %u bytes\n", (unsigned int) sizeof(uv_tcp_t)); + LOGF("uv_pipe_t: %u bytes\n", (unsigned int) sizeof(uv_pipe_t)); LOGF("uv_prepare_t: %u bytes\n", (unsigned int) sizeof(uv_prepare_t)); LOGF("uv_check_t: %u bytes\n", (unsigned int) sizeof(uv_check_t)); LOGF("uv_idle_t: %u bytes\n", (unsigned int) sizeof(uv_idle_t)); diff --git a/deps/uv/test/dns-server.c b/deps/uv/test/dns-server.c index 361c9d0..53076e7 100644 --- a/deps/uv/test/dns-server.c +++ b/deps/uv/test/dns-server.c @@ -165,7 +165,7 @@ static void process_req(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) { rec_remaining = ntohs(reclen_n) - (DNSREC_LEN - 2); } } - + if (rec_remaining <= readbuf_remaining) { /* prepare reply */ addrsp(wr, hdrbuf); diff --git a/deps/uv/test/echo-server.c b/deps/uv/test/echo-server.c index ea01631..4dc0e20 100644 --- a/deps/uv/test/echo-server.c +++ b/deps/uv/test/echo-server.c @@ -24,19 +24,16 @@ #include #include - typedef struct { uv_req_t req; uv_buf_t buf; } write_req_t; - static int server_closed; -static uv_tcp_t server; - -static int server6_closed; -static uv_tcp_t server6; - +static stream_type serverType; +static uv_tcp_t tcpServer; +static uv_pipe_t pipeServer; +static uv_handle_t* server; static void after_write(uv_req_t* req, int status); static void after_read(uv_stream_t*, ssize_t nread, uv_buf_t buf); @@ -82,7 +79,7 @@ static void after_read(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) { } req = (uv_req_t*) malloc(sizeof *req); - uv_req_init(req, (uv_handle_t*)handle, after_shutdown); + uv_req_init(req, (uv_handle_t*)handle, (void *(*)(void *))after_shutdown); uv_shutdown(req); return; @@ -98,17 +95,15 @@ static void after_read(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) { if (!server_closed) { for (i = 0; i < nread; i++) { if (buf.base[i] == 'Q') { - uv_close((uv_handle_t*)&server, on_server_close); + uv_close(server, on_server_close); server_closed = 1; - uv_close((uv_handle_t*)&server6, on_server_close); - server6_closed = 1; } } } wr = (write_req_t*) malloc(sizeof *wr); - uv_req_init(&wr->req, (uv_handle_t*)handle, after_write); + uv_req_init(&wr->req, (uv_handle_t*)handle, (void *(*)(void *))after_write); wr->buf.base = buf.base; wr->buf.len = nread; if (uv_write(&wr->req, &wr->buf, 1)) { @@ -131,18 +126,25 @@ static uv_buf_t echo_alloc(uv_stream_t* handle, size_t suggested_size) { static void on_connection(uv_handle_t* server, int status) { - uv_tcp_t* handle; + uv_handle_t* handle; int r; if (status != 0) { - fprintf(stderr, "Connect error %d\n", uv_last_error()); + fprintf(stderr, "Connect error %d\n", uv_last_error().code); } ASSERT(status == 0); - handle = (uv_tcp_t*) malloc(sizeof *handle); - ASSERT(handle != NULL); + if (serverType == TCP) { + handle = (uv_handle_t*) malloc(sizeof(uv_tcp_t)); + ASSERT(handle != NULL); - uv_tcp_init(handle); + uv_tcp_init((uv_tcp_t*)handle); + } else { + handle = (uv_handle_t*) malloc(sizeof(uv_pipe_t)); + ASSERT(handle != NULL); + + uv_pipe_init((uv_pipe_t*)handle); + } /* associate server with stream */ handle->data = server; @@ -156,37 +158,50 @@ static void on_connection(uv_handle_t* server, int status) { static void on_server_close(uv_handle_t* handle) { - ASSERT(handle == (uv_handle_t*)&server || handle == (uv_handle_t*)&server6); + ASSERT(handle == server); } -static int echo_start(int port) { +static int tcp4_echo_start(int port) { struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", port); - struct sockaddr_in6 addr6 = uv_ip6_addr("::1", port); int r; - r = uv_tcp_init(&server); + server = (uv_handle_t*)&tcpServer; + serverType = TCP; + + r = uv_tcp_init(&tcpServer); if (r) { /* TODO: Error codes */ fprintf(stderr, "Socket creation error\n"); return 1; } - r = uv_tcp_bind(&server, addr); + r = uv_tcp_bind(&tcpServer, addr); if (r) { /* TODO: Error codes */ fprintf(stderr, "Bind error\n"); return 1; } - r = uv_tcp_listen(&server, 128, on_connection); + r = uv_tcp_listen(&tcpServer, 128, on_connection); if (r) { /* TODO: Error codes */ fprintf(stderr, "Listen error\n"); return 1; } - r = uv_tcp_init(&server6); + return 0; +} + + +static int tcp6_echo_start(int port) { + struct sockaddr_in6 addr6 = uv_ip6_addr("::1", port); + int r; + + server = (uv_handle_t*)&tcpServer; + serverType = TCP; + + r = uv_tcp_init(&tcpServer); if (r) { /* TODO: Error codes */ fprintf(stderr, "Socket creation error\n"); @@ -194,14 +209,45 @@ static int echo_start(int port) { } /* IPv6 is optional as not all platforms support it */ - r = uv_tcp_bind6(&server6, addr6); + r = uv_tcp_bind6(&tcpServer, addr6); if (r) { /* show message but return OK */ fprintf(stderr, "IPv6 not supported\n"); return 0; } - r = uv_tcp_listen(&server6, 128, on_connection); + r = uv_tcp_listen(&tcpServer, 128, on_connection); + if (r) { + /* TODO: Error codes */ + fprintf(stderr, "Listen error\n"); + return 1; + } + + return 0; +} + + +static int pipe_echo_start(char* pipeName) { + int r; + + server = (uv_handle_t*)&pipeServer; + serverType = PIPE; + + r = uv_pipe_init(&pipeServer); + if (r) { + /* TODO: Error codes */ + fprintf(stderr, "Pipe creation error\n"); + return 1; + } + + r = uv_pipe_bind(&pipeServer, pipeName); + if (r) { + /* TODO: Error codes */ + fprintf(stderr, "create error\n"); + return 1; + } + + r = uv_pipe_listen(&pipeServer, on_connection); if (r) { /* TODO: Error codes */ fprintf(stderr, "Listen error on IPv6\n"); @@ -212,9 +258,30 @@ static int echo_start(int port) { } -HELPER_IMPL(echo_server) { +HELPER_IMPL(tcp4_echo_server) { + uv_init(); + if (tcp4_echo_start(TEST_PORT)) + return 1; + + uv_run(); + return 0; +} + + +HELPER_IMPL(tcp6_echo_server) { + uv_init(); + if (tcp6_echo_start(TEST_PORT)) + return 1; + + uv_run(); + return 0; +} + + +HELPER_IMPL(pipe_echo_server) { uv_init(); - if (echo_start(TEST_PORT)) + + if (pipe_echo_start(TEST_PIPENAME)) return 1; uv_run(); diff --git a/deps/uv/test/run-benchmarks.c b/deps/uv/test/run-benchmarks.c index 43d25a6..bdef4a4 100644 --- a/deps/uv/test/run-benchmarks.c +++ b/deps/uv/test/run-benchmarks.c @@ -34,26 +34,14 @@ int main(int argc, char **argv) { - task_entry_t *task; - platform_init(argc, argv); - if (argc > 1) { - /* A specific process was requested. */ - return run_process(argv[1]); - - } else { - /* Run all benchmarks. */ - task = (task_entry_t*)&TASKS; - for (task = (task_entry_t*)&TASKS; task->main; task++) { - if (task->is_helper) { - continue; - } - - run_task(task, BENCHMARK_TIMEOUT, 1); - } - LOG("Done.\n"); - - return 0; + switch (argc) { + case 1: return run_tests(BENCHMARK_TIMEOUT, 1); + case 2: return run_test(argv[1], BENCHMARK_TIMEOUT, 1); + case 3: return run_test_part(argv[1], argv[2]); + default: + LOGF("Too many arguments.\n"); + return 1; } } diff --git a/deps/uv/test/run-tests.c b/deps/uv/test/run-tests.c index f83006b..7ae6c6c 100644 --- a/deps/uv/test/run-tests.c +++ b/deps/uv/test/run-tests.c @@ -33,54 +33,15 @@ #define TEST_TIMEOUT 5000 -static void log_progress(int total, int passed, int failed, char* name) { - LOGF("[%% %3d|+ %3d|- %3d]: %s", (passed + failed) / total * 100, - passed, failed, name); -} - - int main(int argc, char **argv) { - int total, passed, failed; - task_entry_t* task; - platform_init(argc, argv); - if (argc > 1) { - /* A specific process was requested. */ - return run_process(argv[1]); - - } else { - /* Count the number of tests. */ - total = 0; - task = (task_entry_t*)&TASKS; - for (task = (task_entry_t*)&TASKS; task->main; task++) { - if (!task->is_helper) { - total++; - } - } - - /* Run all tests. */ - passed = 0; - failed = 0; - task = (task_entry_t*)&TASKS; - for (task = (task_entry_t*)&TASKS; task->main; task++) { - if (task->is_helper) { - continue; - } - - rewind_cursor(); - log_progress(total, passed, failed, task->task_name); - - if (run_task(task, TEST_TIMEOUT, 0)) { - passed++; - } else { - failed++; - } - } - - rewind_cursor(); - log_progress(total, passed, failed, "Done.\n"); - - return 0; + switch (argc) { + case 1: return run_tests(TEST_TIMEOUT, 0); + case 2: return run_test(argv[1], TEST_TIMEOUT, 0); + case 3: return run_test_part(argv[1], argv[2]); + default: + LOGF("Too many arguments.\n"); + return 1; } } diff --git a/deps/uv/test/runner-unix.c b/deps/uv/test/runner-unix.c index 61d6a96..0bbfd62 100644 --- a/deps/uv/test/runner-unix.c +++ b/deps/uv/test/runner-unix.c @@ -68,9 +68,9 @@ void platform_init(int argc, char **argv) { } -/* Invoke "arv[0] test-name". Store process info in *p. */ +/* Invoke "argv[0] test-name [test-part]". Store process info in *p. */ /* Make sure that all stdio output of the processes is buffered up. */ -int process_start(char* name, process_info_t* p) { +int process_start(char* name, char* part, process_info_t* p) { FILE* stdout_file = tmpfile(); if (!stdout_file) { perror("tmpfile"); @@ -92,7 +92,7 @@ int process_start(char* name, process_info_t* p) { dup2(fileno(stdout_file), STDOUT_FILENO); dup2(fileno(stdout_file), STDERR_FILENO); - char* args[3] = { executable_path, name, NULL }; + char* args[] = { executable_path, name, part, NULL }; execvp(executable_path, args); perror("execvp()"); _exit(127); @@ -248,7 +248,7 @@ int process_copy_output(process_info_t *p, int fd) { return -1; } - size_t nread, nwritten; + ssize_t nread, nwritten; char buf[1024]; while ((nread = read(fileno(p->stdout_file), buf, 1024)) > 0) { diff --git a/deps/uv/test/runner-win.c b/deps/uv/test/runner-win.c index 09458a6..fc08839 100644 --- a/deps/uv/test/runner-win.c +++ b/deps/uv/test/runner-win.c @@ -52,7 +52,7 @@ void platform_init(int argc, char **argv) { } -int process_start(char *name, process_info_t *p) { +int process_start(char *name, char *part, process_info_t *p) { HANDLE file = INVALID_HANDLE_VALUE; HANDLE nul = INVALID_HANDLE_VALUE; WCHAR path[MAX_PATH], filename[MAX_PATH]; @@ -97,12 +97,24 @@ int process_start(char *name, process_info_t *p) { if (result == 0 || result == sizeof(image)) goto error; - if (_snwprintf((wchar_t*)&args, - sizeof(args) / sizeof(wchar_t), - L"\"%s\" %S", - image, - name) < 0) - goto error; + if (part) { + if (_snwprintf((wchar_t*)args, + sizeof(args) / sizeof(wchar_t), + L"\"%s\" %S %S", + image, + name, + part) < 0) { + goto error; + } + } else { + if (_snwprintf((wchar_t*)args, + sizeof(args) / sizeof(wchar_t), + L"\"%s\" %S", + image, + name) < 0) { + goto error; + } + } memset((void*)&si, 0, sizeof(si)); si.cb = sizeof(si); diff --git a/deps/uv/test/runner.c b/deps/uv/test/runner.c index 7b6590f..48f9776 100644 --- a/deps/uv/test/runner.c +++ b/deps/uv/test/runner.c @@ -26,102 +26,155 @@ char executable_path[PATHMAX] = { '\0' }; -/* Start a specific process declared by TEST_ENTRY or TEST_HELPER. */ -/* Returns the exit code of the specific process. */ -int run_process(char* name) { - task_entry_t *test; - - for (test = (task_entry_t*)&TASKS; test->main; test++) { - if (strcmp(name, test->process_name) == 0) { - return test->main(); + +static void log_progress(int total, int passed, int failed, const char* name) { + LOGF("[%% %3d|+ %3d|- %3d]: %s", (passed + failed) / total * 100, + passed, failed, name); +} + + +int run_tests(int timeout, int benchmark_output) { + int total, passed, failed; + task_entry_t* task; + + /* Count the number of tests. */ + total = 0; + for (task = TASKS; task->main; task++) { + if (!task->is_helper) { + total++; } } - LOGF("Test process %s not found!\n", name); - return 255; + /* Run all tests. */ + passed = 0; + failed = 0; + for (task = TASKS; task->main; task++) { + if (task->is_helper) { + continue; + } + + rewind_cursor(); + log_progress(total, passed, failed, task->task_name); + + if (run_test(task->task_name, timeout, benchmark_output) == 0) { + passed++; + } else { + failed++; + } + } + + rewind_cursor(); + log_progress(total, passed, failed, "Done.\n"); + + return 0; } -/* - * Runs all processes associated with a particular test or benchmark. - * It returns 1 if the test succeeded, 0 if it failed. - * If the test fails it prints diagnostic information. - * If benchmark_output is nonzero, the output from the main process is - * always shown. - */ -int run_task(task_entry_t *test, int timeout, int benchmark_output) { - int i, result, success; - char errmsg[256]; - task_entry_t *helper; +int run_test(const char* test, int timeout, int benchmark_output) { + char errmsg[1024] = "no error"; + process_info_t processes[1024]; + process_info_t *main_proc; + task_entry_t* task; int process_count; - process_info_t processes[MAX_PROCESSES]; - process_info_t *main_process; - - success = 0; + int result; + int status; + int i; + status = 255; process_count = 0; - /* Start all helpers for this test first. */ - for (helper = (task_entry_t*)&TASKS; helper->main; helper++) { - if (helper->is_helper && - strcmp(test->task_name, helper->task_name) == 0) { - if (process_start(helper->process_name, &processes[process_count]) == -1) { - snprintf((char*)&errmsg, - sizeof(errmsg), - "process `%s` failed to start.", - helper->process_name); - goto finalize; - } - process_count++; + /* Start the helpers first. */ + for (task = TASKS; task->main; task++) { + if (strcmp(test, task->task_name) != 0) { + continue; + } + + /* Skip the test itself. */ + if (!task->is_helper) { + continue; + } + + if (process_start(task->task_name, + task->process_name, + &processes[process_count]) == -1) { + snprintf(errmsg, + sizeof errmsg, + "Process `%s` failed to start.", + task->process_name); + goto out; } + + process_count++; } - /* Wait a little bit to allow servers to start. Racy. */ - uv_sleep(100); + /* Give the helpers time to settle. Race-y, fix this. */ + uv_sleep(250); + + /* Now start the test itself. */ + for (main_proc = NULL, task = TASKS; task->main; task++) { + if (strcmp(test, task->task_name) != 0) { + continue; + } + + if (task->is_helper) { + continue; + } + + if (process_start(task->task_name, + task->process_name, + &processes[process_count]) == -1) { + snprintf(errmsg, + sizeof errmsg, + "Process `%s` failed to start.", + task->process_name); + goto out; + } - /* Start the main test process. */ - if (process_start(test->process_name, &processes[process_count]) == -1) { - snprintf((char*)&errmsg, sizeof(errmsg), "process `%s` failed to start.", - test->process_name); - goto finalize; + main_proc = &processes[process_count]; + process_count++; + break; } - main_process = &processes[process_count]; - process_count++; - /* Wait for the main process to terminate. */ - result = process_wait(main_process, 1, timeout); + if (main_proc == NULL) { + snprintf(errmsg, + sizeof errmsg, + "No test with that name: %s", + test); + goto out; + } + + result = process_wait(main_proc, 1, timeout); if (result == -1) { FATAL("process_wait failed"); } else if (result == -2) { - snprintf((char*)&errmsg, sizeof(errmsg), "timeout."); - goto finalize; + /* Don't have to clean up the process, process_wait() has killed it. */ + snprintf(errmsg, + sizeof errmsg, + "timeout"); + goto out; } - /* Reap the main process. */ - result = process_reap(main_process); - if (result != 0) { - snprintf((char*)&errmsg, sizeof(errmsg), "exit code %d.", result); - goto finalize; + status = process_reap(main_proc); + if (status != 0) { + snprintf(errmsg, + sizeof errmsg, + "exit code %d", + status); } - /* Yes! did it. */ - success = 1; - -finalize: - /* Kill all (helper) processes that are still running. */ - for (i = 0; i < process_count; i++) { - /* If terminate fails the process is probably already closed. */ +out: + /* Reap running processes except the main process, it's already dead. */ + for (i = 0; i < process_count - 1; i++) { process_terminate(&processes[i]); } - /* Wait until all processes have really terminated. */ - if (process_wait((process_info_t*)&processes, process_count, -1) < 0) { + if (process_wait(processes, process_count - 1, -1) < 0) { FATAL("process_wait failed"); } /* Show error and output from processes if the test failed. */ - if (!success) { - LOGF("\n`%s` failed: %s\n", test->task_name, errmsg); + if (status != 0) { + LOGF("\n`%s` failed: %s\n", test, errmsg); for (i = 0; i < process_count; i++) { switch (process_output_size(&processes[i])) { @@ -145,13 +198,13 @@ finalize: /* In benchmark mode show concise output from the main process. */ } else if (benchmark_output) { - switch (process_output_size(main_process)) { + switch (process_output_size(main_proc)) { case -1: - LOGF("%s: (unavailabe)\n", test->task_name); + LOGF("%s: (unavailabe)\n", test); break; case 0: - LOGF("%s: (no output)\n", test->task_name); + LOGF("%s: (no output)\n", test); break; default: @@ -167,5 +220,23 @@ finalize: process_cleanup(&processes[i]); } - return success; + return status; +} + + +/* Returns the status code of the task part + * or 255 if no matching task was not found. + */ +int run_test_part(const char* test, const char* part) { + task_entry_t* task; + + for (task = TASKS; task->main; task++) { + if (strcmp(test, task->task_name) == 0 + && strcmp(part, task->process_name) == 0) { + return task->main(); + } + } + + LOGF("No test part with that name: %s:%s\n", test, part); + return 255; } diff --git a/deps/uv/test/runner.h b/deps/uv/test/runner.h index 11d4980..59eff1e 100644 --- a/deps/uv/test/runner.h +++ b/deps/uv/test/runner.h @@ -41,13 +41,6 @@ typedef struct { } task_entry_t, bench_entry_t; -/* Runs an individual task; returns 1 if the test succeeded, 0 if it failed. */ -/* If the test fails it prints diagnostic information. */ -/* If benchmark_output is nonzero, the output from the main process is -/* always shown. */ -int run_task(task_entry_t *test, int timeout, int benchmark_output); - - /* * Macros used by test-list.h and benchmark-list.h. */ @@ -95,13 +88,20 @@ extern char executable_path[PATHMAX]; /* The array that is filled by test-list.h or benchmark-list.h */ extern task_entry_t TASKS[]; -/* Start a specific process declared by TEST_ENTRY or TEST_HELPER. */ -/* Returns the exit code of the specific process. */ -int run_task(task_entry_t *test, int timeout, int benchmark_output); +/* + * Run all tests. + */ +int run_tests(int timeout, int benchmark_output); -/* Start a specific process declared by TEST_ENTRY or TEST_HELPER. */ -/* Returns the exit code of the specific process. */ -int run_process(char* name); +/* + * Run a single test. Starts up any helpers. + */ +int run_test(const char* test, int timeout, int benchmark_output); + +/* + * Run a test part, i.e. the test or one of its helpers. + */ +int run_test_part(const char* test, const char* part); /* @@ -113,9 +113,9 @@ int run_process(char* name); /* Do platform-specific initialization. */ void platform_init(); -/* Invoke "arv[0] test-name". Store process info in *p. */ +/* Invoke "argv[0] test-name [test-part]". Store process info in *p. */ /* Make sure that all stdio output of the processes is buffered up. */ -int process_start(char *name, process_info_t *p); +int process_start(char *name, char* part, process_info_t *p); /* Wait for all `n` processes in `vec` to terminate. */ /* Time out after `timeout` msec, or never if timeout == -1 */ diff --git a/deps/uv/test/task.h b/deps/uv/test/task.h index 8d9a1e8..d47c209 100644 --- a/deps/uv/test/task.h +++ b/deps/uv/test/task.h @@ -30,6 +30,17 @@ #define TEST_PORT 9123 #define TEST_PORT_2 9124 +#ifdef _WIN32 +# define TEST_PIPENAME "\\\\.\\pipe\\uv-test" +#else +# /* TODO: define unix pipe name */ +# define TEST_PIPENAME "" +#endif + +typedef enum { + TCP = 0, + PIPE +} stream_type; /* Log to stderr. */ #define LOG(...) fprintf(stderr, "%s", __VA_ARGS__) diff --git a/deps/uv/test/test-async.c b/deps/uv/test/test-async.c index a9933fd..f91d9b4 100644 --- a/deps/uv/test/test-async.c +++ b/deps/uv/test/test-async.c @@ -47,8 +47,6 @@ static uintptr_t thread3_id = 0; /* Thread 1 makes sure that async1_cb_called reaches 3 before exiting. */ void thread1_entry(void *arg) { - int state = 0; - uv_sleep(50); while (1) { diff --git a/deps/uv/test/test-callback-stack.c b/deps/uv/test/test-callback-stack.c index 286fef3..5b12c8b 100644 --- a/deps/uv/test/test-callback-stack.c +++ b/deps/uv/test/test-callback-stack.c @@ -70,7 +70,7 @@ static void shutdown_cb(uv_req_t* req, int status) { static void read_cb(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) { ASSERT(nested == 0 && "read_cb must be called from a fresh stack"); - printf("Read. nread == %d\n", nread); + printf("Read. nread == %d\n", (int)nread); free(buf.base); if (nread == 0) { @@ -97,7 +97,7 @@ static void read_cb(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) { /* from a fresh stack. */ if (bytes_received == sizeof MESSAGE) { nested++; - uv_req_init(&shutdown_req, (uv_handle_t*)tcp, shutdown_cb); + uv_req_init(&shutdown_req, (uv_handle_t*)tcp, (void *(*)(void *))shutdown_cb); puts("Shutdown"); @@ -167,7 +167,7 @@ static void connect_cb(uv_req_t* req, int status) { buf.base = (char*) &MESSAGE; buf.len = sizeof MESSAGE; - uv_req_init(&write_req, req->handle, write_cb); + uv_req_init(&write_req, req->handle, (void *(*)(void *))write_cb); if (uv_write(&write_req, &buf, 1)) { FATAL("uv_write failed"); @@ -191,7 +191,9 @@ TEST_IMPL(callback_stack) { puts("Connecting..."); nested++; - uv_req_init(&connect_req, (uv_handle_t*)&client, connect_cb); + uv_req_init(&connect_req, (uv_handle_t*)&client, + (void *(*)(void *))connect_cb); + if (uv_tcp_connect(&connect_req, addr)) { FATAL("uv_tcp_connect failed"); } diff --git a/deps/uv/test/test-connection-fail.c b/deps/uv/test/test-connection-fail.c index e9120b9..9fc3f0b 100644 --- a/deps/uv/test/test-connection-fail.c +++ b/deps/uv/test/test-connection-fail.c @@ -103,7 +103,7 @@ void connection_fail(uv_connect_cb connect_cb) { /* We are never doing multiple reads/connects at a time anyway. */ /* so these handles can be pre-initialized. */ - uv_req_init(&req, (uv_handle_t*)&tcp, connect_cb); + uv_req_init(&req, (uv_handle_t*)&tcp, (void *(*)(void *))connect_cb); uv_tcp_bind(&tcp, client_addr); r = uv_tcp_connect(&req, server_addr); diff --git a/deps/uv/test/test-delayed-accept.c b/deps/uv/test/test-delayed-accept.c index b254ccb..6f56518 100644 --- a/deps/uv/test/test-delayed-accept.c +++ b/deps/uv/test/test-delayed-accept.c @@ -24,8 +24,6 @@ #include #include -static char BUFFER[1024]; - static int connection_cb_called = 0; static int do_accept_called = 0; static int close_cb_called = 0; @@ -52,8 +50,8 @@ static void close_cb(uv_handle_t* handle) { static void do_accept(uv_timer_t* timer_handle, int status) { uv_tcp_t* server; uv_tcp_t* accepted_handle = (uv_tcp_t*)malloc(sizeof *accepted_handle); + uint64_t tcpcnt; int r; - int tcpcnt; ASSERT(timer_handle != NULL); ASSERT(status == 0); @@ -178,7 +176,7 @@ static void client_connect() { r = uv_tcp_init(client); ASSERT(r == 0); - uv_req_init(connect_req, (uv_handle_t*)client, connect_cb); + uv_req_init(connect_req, (uv_handle_t*)client, (void *(*)(void *))connect_cb); r = uv_tcp_connect(connect_req, addr); ASSERT(r == 0); } diff --git a/deps/uv/test/test-getsockname.c b/deps/uv/test/test-getsockname.c new file mode 100644 index 0000000..9d265d3 --- /dev/null +++ b/deps/uv/test/test-getsockname.c @@ -0,0 +1,186 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + +static int getsocknamecount = 0; + + +static uv_tcp_t tcp; +static uv_req_t connect_req; +static uv_tcp_t tcpServer; + + +static uv_buf_t alloc(uv_stream_t* handle, size_t suggested_size) { + uv_buf_t buf; + buf.base = (char*) malloc(suggested_size); + buf.len = suggested_size; + return buf; +} + + +static void on_close(uv_handle_t* peer) { + free(peer); + uv_close((uv_handle_t*)&tcpServer, NULL); +} + + +static void after_shutdown(uv_req_t* req, int status) { + uv_close(req->handle, on_close); + free(req); +} + + +static void after_read(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) { + uv_req_t* req; + + if (buf.base) { + free(buf.base); + } + + req = (uv_req_t*) malloc(sizeof *req); + uv_req_init(req, (uv_handle_t*)handle, (void *(*)(void *))after_shutdown); + uv_shutdown(req); +} + + +static void on_connection(uv_handle_t* server, int status) { + struct sockaddr sockname; + int namelen = sizeof(sockname); + uv_handle_t* handle; + int r; + + if (status != 0) { + fprintf(stderr, "Connect error %d\n", uv_last_error().code); + } + ASSERT(status == 0); + + handle = (uv_handle_t*) malloc(sizeof(uv_tcp_t)); + ASSERT(handle != NULL); + + uv_tcp_init((uv_tcp_t*)handle); + + /* associate server with stream */ + handle->data = server; + + r = uv_accept(server, (uv_stream_t*)handle); + ASSERT(r == 0); + + status = uv_getsockname((uv_tcp_t*)handle, &sockname, &namelen); + if (status != 0) { + fprintf(stderr, "uv_getsockname error (accepted) %d\n", uv_last_error().code); + } + ASSERT(status == 0); + + getsocknamecount++; + + r = uv_read_start((uv_stream_t*)handle, alloc, after_read); + ASSERT(r == 0); + +} + + +static void on_connect(void* req) { + struct sockaddr sockname; + int namelen = sizeof(sockname); + int status; + + status = uv_getsockname(&tcp, &sockname, &namelen); + if (status != 0) { + fprintf(stderr, "uv_getsockname error (connector) %d\n", uv_last_error().code); + } + ASSERT(status == 0); + + getsocknamecount++; + + uv_close((uv_handle_t*)&tcp, NULL); +} + + +static int tcp_listener(int port) { + struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", port); + struct sockaddr sockname; + int namelen = sizeof(sockname); + int r; + + r = uv_tcp_init(&tcpServer); + if (r) { + fprintf(stderr, "Socket creation error\n"); + return 1; + } + + r = uv_tcp_bind(&tcpServer, addr); + if (r) { + fprintf(stderr, "Bind error\n"); + return 1; + } + + r = uv_tcp_listen(&tcpServer, 128, on_connection); + if (r) { + fprintf(stderr, "Listen error\n"); + return 1; + } + + r = uv_getsockname(&tcpServer, &sockname, &namelen); + if (r != 0) { + fprintf(stderr, "uv_getsockname error (listening) %d\n", uv_last_error().code); + } + ASSERT(r == 0); + getsocknamecount++; + + return 0; +} + + +static void tcp_connector() { + int r; + struct sockaddr_in server_addr = uv_ip4_addr("127.0.0.1", TEST_PORT); + + r = uv_tcp_init(&tcp); + tcp.data = &connect_req; + ASSERT(!r); + + uv_req_init(&connect_req, (uv_handle_t*)(&tcp), (void *(*)(void *))on_connect); + + r = uv_tcp_connect(&connect_req, server_addr); + ASSERT(!r); +} + + +TEST_IMPL(getsockname) { + uv_init(); + + if (tcp_listener(TEST_PORT)) + return 1; + + tcp_connector(); + + uv_run(); + + ASSERT(getsocknamecount == 3); + + return 0; +} + diff --git a/deps/uv/test/test-hrtime.c b/deps/uv/test/test-hrtime.c index 4d96e33..e1959b0 100644 --- a/deps/uv/test/test-hrtime.c +++ b/deps/uv/test/test-hrtime.c @@ -46,7 +46,7 @@ TEST_IMPL(hrtime) { diff = b - a; - printf("diff = %llu\n", diff); + printf("diff = %llu\n", (unsigned long long int)diff); ASSERT(diff >= NANOSEC / MICROSEC); ASSERT(diff > MICROSEC); diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index 190574a..919d7b7 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -19,8 +19,9 @@ * IN THE SOFTWARE. */ -TEST_DECLARE (ping_pong) -TEST_DECLARE (ping_pong_v6) +TEST_DECLARE (tcp_ping_pong) +TEST_DECLARE (tcp_ping_pong_v6) +TEST_DECLARE (pipe_ping_pong) TEST_DECLARE (delayed_accept) TEST_DECLARE (tcp_writealot) TEST_DECLARE (bind_error_addrinuse) @@ -52,22 +53,28 @@ TEST_DECLARE (hrtime) TEST_DECLARE (getaddrinfo_basic) TEST_DECLARE (getaddrinfo_concurrent) TEST_DECLARE (gethostbyname) +TEST_DECLARE (getsockname) TEST_DECLARE (fail_always) TEST_DECLARE (pass_always) -HELPER_DECLARE (echo_server) +HELPER_DECLARE (tcp4_echo_server) +HELPER_DECLARE (tcp6_echo_server) +HELPER_DECLARE (pipe_echo_server) TASK_LIST_START - TEST_ENTRY (ping_pong) - TEST_HELPER (ping_pong, echo_server) + TEST_ENTRY (tcp_ping_pong) + TEST_HELPER (tcp_ping_pong, tcp4_echo_server) - TEST_ENTRY (ping_pong_v6) - TEST_HELPER (ping_pong_v6, echo_server) + TEST_ENTRY (tcp_ping_pong_v6) + TEST_HELPER (tcp_ping_pong_v6, tcp6_echo_server) + + TEST_ENTRY (pipe_ping_pong) + TEST_HELPER (pipe_ping_pong, pipe_echo_server) TEST_ENTRY (delayed_accept) TEST_ENTRY (tcp_writealot) - TEST_HELPER (tcp_writealot, echo_server) + TEST_HELPER (tcp_writealot, tcp4_echo_server) TEST_ENTRY (bind_error_addrinuse) TEST_ENTRY (bind_error_addrnotavail_1) @@ -86,10 +93,10 @@ TASK_LIST_START TEST_ENTRY (connection_fail_doesnt_auto_close) TEST_ENTRY (shutdown_eof) - TEST_HELPER (shutdown_eof, echo_server) + TEST_HELPER (shutdown_eof, tcp4_echo_server) TEST_ENTRY (callback_stack) - TEST_HELPER (callback_stack, echo_server) + TEST_HELPER (callback_stack, tcp4_echo_server) TEST_ENTRY (timer) @@ -113,7 +120,9 @@ TASK_LIST_START TEST_ENTRY (getaddrinfo_concurrent) TEST_ENTRY (gethostbyname) - TEST_HELPER (gethostbyname, echo_server) + TEST_HELPER (gethostbyname, tcp4_echo_server) + + TEST_ENTRY (getsockname) #if 0 /* These are for testing the test runner. */ diff --git a/deps/uv/test/test-ping-pong.c b/deps/uv/test/test-ping-pong.c index 7004fc6..81cd93e 100644 --- a/deps/uv/test/test-ping-pong.c +++ b/deps/uv/test/test-ping-pong.c @@ -39,7 +39,10 @@ static char PING[] = "PING\n"; typedef struct { int pongs; int state; - uv_tcp_t tcp; + union { + uv_tcp_t tcp; + uv_pipe_t pipe; + }; uv_req_t connect_req; uv_req_t read_req; char read_buffer[BUFSIZE]; @@ -82,7 +85,8 @@ static void pinger_write_ping(pinger_t* pinger) { buf.len = strlen(PING); req = (uv_req_t*)malloc(sizeof(*req)); - uv_req_init(req, (uv_handle_t*)(&pinger->tcp), pinger_after_write); + uv_req_init(req, (uv_handle_t*)(&pinger->tcp), + (void *(*)(void *))pinger_after_write); if (uv_write(req, &buf, 1)) { FATAL("uv_write failed"); @@ -92,11 +96,11 @@ static void pinger_write_ping(pinger_t* pinger) { } -static void pinger_read_cb(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) { +static void pinger_read_cb(uv_stream_t* stream, ssize_t nread, uv_buf_t buf) { unsigned int i; pinger_t* pinger; - pinger = (pinger_t*)tcp->data; + pinger = (pinger_t*)stream->data; if (nread < 0) { ASSERT(uv_last_error().code == UV_EOF); @@ -141,9 +145,10 @@ static void pinger_on_connect(uv_req_t *req, int status) { } -static void pinger_new() { +/* same ping-pong test, but using IPv6 connection */ +static void tcp_pinger_v6_new() { int r; - struct sockaddr_in server_addr = uv_ip4_addr("127.0.0.1", TEST_PORT); + struct sockaddr_in6 server_addr = uv_ip6_addr("::1", TEST_PORT); pinger_t *pinger; pinger = (pinger_t*)malloc(sizeof(*pinger)); @@ -158,29 +163,39 @@ static void pinger_new() { /* We are never doing multiple reads/connects at a time anyway. */ /* so these handles can be pre-initialized. */ uv_req_init(&pinger->connect_req, (uv_handle_t*)(&pinger->tcp), - pinger_on_connect); + (void *(*)(void *))pinger_on_connect); - r = uv_tcp_connect(&pinger->connect_req, server_addr); + r = uv_tcp_connect6(&pinger->connect_req, server_addr); ASSERT(!r); } -TEST_IMPL(ping_pong) { - uv_init(); +static void tcp_pinger_new() { + int r; + struct sockaddr_in server_addr = uv_ip4_addr("127.0.0.1", TEST_PORT); + pinger_t *pinger; - pinger_new(); - uv_run(); + pinger = (pinger_t*)malloc(sizeof(*pinger)); + pinger->state = 0; + pinger->pongs = 0; - ASSERT(completed_pingers == 1); + /* Try to connec to the server and do NUM_PINGS ping-pongs. */ + r = uv_tcp_init(&pinger->tcp); + pinger->tcp.data = pinger; + ASSERT(!r); - return 0; + /* We are never doing multiple reads/connects at a time anyway. */ + /* so these handles can be pre-initialized. */ + uv_req_init(&pinger->connect_req, (uv_handle_t*)(&pinger->tcp), + (void *(*)(void *))pinger_on_connect); + + r = uv_tcp_connect(&pinger->connect_req, server_addr); + ASSERT(!r); } -/* same ping-pong test, but using IPv6 connection */ -static void pinger_v6_new() { +static void pipe_pinger_new() { int r; - struct sockaddr_in6 server_addr = uv_ip6_addr("::1", TEST_PORT); pinger_t *pinger; pinger = (pinger_t*)malloc(sizeof(*pinger)); @@ -188,24 +203,48 @@ static void pinger_v6_new() { pinger->pongs = 0; /* Try to connec to the server and do NUM_PINGS ping-pongs. */ - r = uv_tcp_init(&pinger->tcp); - pinger->tcp.data = pinger; + r = uv_pipe_init(&pinger->pipe); + pinger->pipe.data = pinger; ASSERT(!r); /* We are never doing multiple reads/connects at a time anyway. */ /* so these handles can be pre-initialized. */ - uv_req_init(&pinger->connect_req, (uv_handle_t*)(&pinger->tcp), - pinger_on_connect); + uv_req_init(&pinger->connect_req, (uv_handle_t*)(&pinger->pipe), + (void *(*)(void *))pinger_on_connect); - r = uv_tcp_connect6(&pinger->connect_req, server_addr); + r = uv_pipe_connect(&pinger->connect_req, TEST_PIPENAME); ASSERT(!r); } -TEST_IMPL(ping_pong_v6) { +TEST_IMPL(tcp_ping_pong) { + uv_init(); + + tcp_pinger_new(); + uv_run(); + + ASSERT(completed_pingers == 1); + + return 0; +} + + +TEST_IMPL(tcp_ping_pong_v6) { + uv_init(); + + tcp_pinger_v6_new(); + uv_run(); + + ASSERT(completed_pingers == 1); + + return 0; +} + + +TEST_IMPL(pipe_ping_pong) { uv_init(); - pinger_v6_new(); + pipe_pinger_new(); uv_run(); ASSERT(completed_pingers == 1); diff --git a/deps/uv/test/test-shutdown-eof.c b/deps/uv/test/test-shutdown-eof.c index e986a19..8a960c9 100644 --- a/deps/uv/test/test-shutdown-eof.c +++ b/deps/uv/test/test-shutdown-eof.c @@ -102,7 +102,7 @@ static void connect_cb(uv_req_t *req, int status) { uv_write(&write_req, &qbuf, 1); /* Shutdown our end of the connection. */ - uv_req_init(&shutdown_req, (uv_handle_t*)&tcp, shutdown_cb); + uv_req_init(&shutdown_req, (uv_handle_t*)&tcp, (void *(*)(void *))shutdown_cb); uv_shutdown(&shutdown_req); called_connect_cb++; @@ -165,7 +165,7 @@ TEST_IMPL(shutdown_eof) { r = uv_tcp_init(&tcp); ASSERT(!r); - uv_req_init(&connect_req, (uv_handle_t*) &tcp, connect_cb); + uv_req_init(&connect_req, (uv_handle_t*) &tcp, (void *(*)(void *))connect_cb); r = uv_tcp_connect(&connect_req, server_addr); ASSERT(!r); diff --git a/deps/uv/test/test-tcp-writealot.c b/deps/uv/test/test-tcp-writealot.c index b033489..4e305a9 100644 --- a/deps/uv/test/test-tcp-writealot.c +++ b/deps/uv/test/test-tcp-writealot.c @@ -144,7 +144,7 @@ static void connect_cb(uv_req_t* req, int status) { req = (uv_req_t*)malloc(sizeof *req); ASSERT(req != NULL); - uv_req_init(req, (uv_handle_t*)tcp, write_cb); + uv_req_init(req, (uv_handle_t*)tcp, (void *(*)(void *))write_cb); r = uv_write(req, (uv_buf_t*)&send_bufs, CHUNKS_PER_WRITE); ASSERT(r == 0); } @@ -152,7 +152,7 @@ static void connect_cb(uv_req_t* req, int status) { /* Shutdown on drain. FIXME: dealloc req? */ req = (uv_req_t*) malloc(sizeof(uv_req_t)); ASSERT(req != NULL); - uv_req_init(req, (uv_handle_t*)tcp, shutdown_cb); + uv_req_init(req, (uv_handle_t*)tcp, (void *(*)(void *))shutdown_cb); r = uv_shutdown(req); ASSERT(r == 0); @@ -160,7 +160,7 @@ static void connect_cb(uv_req_t* req, int status) { req = (uv_req_t*)malloc(sizeof *req); ASSERT(req != NULL); - uv_req_init(req, (uv_handle_t*)tcp, read_cb); + uv_req_init(req, (uv_handle_t*)tcp, (void *(*)(void *))read_cb); r = uv_read_start((uv_stream_t*)tcp, alloc_cb, read_cb); ASSERT(r == 0); } @@ -184,7 +184,7 @@ TEST_IMPL(tcp_writealot) { r = uv_tcp_init(client); ASSERT(r == 0); - uv_req_init(connect_req, (uv_handle_t*)client, connect_cb); + uv_req_init(connect_req, (uv_handle_t*)client, (void *(*)(void *))connect_cb); r = uv_tcp_connect(connect_req, addr); ASSERT(r == 0); diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc index db2b8d1..1e530e8 100644 --- a/src/tcp_wrap.cc +++ b/src/tcp_wrap.cc @@ -66,7 +66,7 @@ class ReqWrap { ReqWrap(uv_handle_t* handle, void* callback) { HandleScope scope; object_ = Persistent::New(Object::New()); - uv_req_init(&req_, handle, callback); + uv_req_init(&req_, handle, (void* (*)(void*))callback); req_.data = this; } -- 2.7.4