$(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)
# 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
# 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
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
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)\"
$(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:
#else /* Not Windows */
+# include <sys/time.h>
# include <sys/types.h>
# include <sys/socket.h>
#endif
enum
{
EIO_MCL_CURRENT = 1,
- EIO_MCL_FUTURE = 2,
+ EIO_MCL_FUTURE = 2
};
/* request priorities */
enum {
EIO_PRI_MIN = -4,
EIO_PRI_MAX = 4,
- EIO_PRI_DEFAULT = 0,
+ EIO_PRI_DEFAULT = 0
};
/* eio request structure */
/* 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 */
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 */
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 */ \
#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
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 */ \
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 \
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;
UV_EAIFAMNOSUPPORT,
UV_EAINONAME,
UV_EAISERVICE,
- UV_EAISOCKTYPE
+ UV_EAISOCKTYPE,
+ UV_ESHUTDOWN
} uv_err_code;
typedef enum {
UV_CHECK,
UV_IDLE,
UV_ASYNC,
- UV_ARES,
UV_ARES_TASK,
+ UV_ARES_EVENT,
UV_GETADDRINFO
} uv_handle_type;
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;
uv_req_type type;
/* public */
uv_handle_t* handle;
- void* cb;
+ void *(*cb)(void *);
void* data;
/* private */
UV_REQ_PRIVATE_FIELDS
/*
* 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);
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 {
/* 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 {
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
/* 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;
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;
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
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
- <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;CARES_BUILDING_LIBRARY;CARES_STATICLIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\c-ares;..\c-ares\config_win32</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
- <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;CARES_BUILDING_LIBRARY;CARES_STATICLIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\c-ares;..\c-ares\config_win32</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- <AdditionalIncludeDirectories>..\c-ares;..\c-ares\config_win32</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>WIN32;_LIB;CARES_BUILDING_LIBRARY;CARES_STATICLIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- <AdditionalIncludeDirectories>..\c-ares;..\c-ares\config_win32</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>WIN32;_LIB;CARES_BUILDING_LIBRARY;CARES_STATICLIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
- <ClCompile Include="..\c-ares\ares__close_sockets.c" />
- <ClCompile Include="..\c-ares\ares__get_hostent.c" />
- <ClCompile Include="..\c-ares\ares__read_line.c" />
- <ClCompile Include="..\c-ares\ares__timeval.c" />
- <ClCompile Include="..\c-ares\ares_cancel.c" />
- <ClCompile Include="..\c-ares\ares_data.c" />
- <ClCompile Include="..\c-ares\ares_destroy.c" />
- <ClCompile Include="..\c-ares\ares_expand_name.c" />
- <ClCompile Include="..\c-ares\ares_expand_string.c" />
- <ClCompile Include="..\c-ares\ares_fds.c" />
- <ClCompile Include="..\c-ares\ares_free_hostent.c" />
- <ClCompile Include="..\c-ares\ares_free_string.c" />
- <ClCompile Include="..\c-ares\ares_gethostbyaddr.c" />
- <ClCompile Include="..\c-ares\ares_gethostbyname.c" />
- <ClCompile Include="..\c-ares\ares_getnameinfo.c" />
- <ClCompile Include="..\c-ares\ares_getsock.c" />
- <ClCompile Include="..\c-ares\ares_init.c" />
- <ClCompile Include="..\c-ares\ares_library_init.c" />
- <ClCompile Include="..\c-ares\ares_llist.c" />
- <ClCompile Include="..\c-ares\ares_mkquery.c" />
- <ClCompile Include="..\c-ares\ares_nowarn.c" />
- <ClCompile Include="..\c-ares\ares_options.c" />
- <ClCompile Include="..\c-ares\ares_parse_a_reply.c" />
- <ClCompile Include="..\c-ares\ares_parse_aaaa_reply.c" />
- <ClCompile Include="..\c-ares\ares_parse_mx_reply.c" />
- <ClCompile Include="..\c-ares\ares_parse_ns_reply.c" />
- <ClCompile Include="..\c-ares\ares_parse_ptr_reply.c" />
- <ClCompile Include="..\c-ares\ares_parse_srv_reply.c" />
- <ClCompile Include="..\c-ares\ares_parse_txt_reply.c" />
- <ClCompile Include="..\c-ares\ares_process.c" />
- <ClCompile Include="..\c-ares\ares_query.c" />
- <ClCompile Include="..\c-ares\ares_search.c" />
- <ClCompile Include="..\c-ares\ares_send.c" />
- <ClCompile Include="..\c-ares\ares_strcasecmp.c" />
- <ClCompile Include="..\c-ares\ares_strdup.c" />
- <ClCompile Include="..\c-ares\ares_strerror.c" />
- <ClCompile Include="..\c-ares\ares_timeout.c" />
- <ClCompile Include="..\c-ares\ares_version.c" />
- <ClCompile Include="..\c-ares\ares_writev.c" />
- <ClCompile Include="..\c-ares\bitncmp.c" />
- <ClCompile Include="..\c-ares\inet_net_pton.c" />
- <ClCompile Include="..\c-ares\inet_ntop.c" />
- <ClCompile Include="..\c-ares\windows_port.c" />
+ <ClCompile Include="..\src\ares\ares__close_sockets.c" />
+ <ClCompile Include="..\src\ares\ares__get_hostent.c" />
+ <ClCompile Include="..\src\ares\ares__read_line.c" />
+ <ClCompile Include="..\src\ares\ares__timeval.c" />
+ <ClCompile Include="..\src\ares\ares_cancel.c" />
+ <ClCompile Include="..\src\ares\ares_data.c" />
+ <ClCompile Include="..\src\ares\ares_destroy.c" />
+ <ClCompile Include="..\src\ares\ares_expand_name.c" />
+ <ClCompile Include="..\src\ares\ares_expand_string.c" />
+ <ClCompile Include="..\src\ares\ares_fds.c" />
+ <ClCompile Include="..\src\ares\ares_free_hostent.c" />
+ <ClCompile Include="..\src\ares\ares_free_string.c" />
+ <ClCompile Include="..\src\ares\ares_gethostbyaddr.c" />
+ <ClCompile Include="..\src\ares\ares_gethostbyname.c" />
+ <ClCompile Include="..\src\ares\ares_getnameinfo.c" />
+ <ClCompile Include="..\src\ares\ares_getsock.c" />
+ <ClCompile Include="..\src\ares\ares_init.c" />
+ <ClCompile Include="..\src\ares\ares_library_init.c" />
+ <ClCompile Include="..\src\ares\ares_llist.c" />
+ <ClCompile Include="..\src\ares\ares_mkquery.c" />
+ <ClCompile Include="..\src\ares\ares_nowarn.c" />
+ <ClCompile Include="..\src\ares\ares_options.c" />
+ <ClCompile Include="..\src\ares\ares_parse_a_reply.c" />
+ <ClCompile Include="..\src\ares\ares_parse_aaaa_reply.c" />
+ <ClCompile Include="..\src\ares\ares_parse_mx_reply.c" />
+ <ClCompile Include="..\src\ares\ares_parse_ns_reply.c" />
+ <ClCompile Include="..\src\ares\ares_parse_ptr_reply.c" />
+ <ClCompile Include="..\src\ares\ares_parse_srv_reply.c" />
+ <ClCompile Include="..\src\ares\ares_parse_txt_reply.c" />
+ <ClCompile Include="..\src\ares\ares_process.c" />
+ <ClCompile Include="..\src\ares\ares_query.c" />
+ <ClCompile Include="..\src\ares\ares_search.c" />
+ <ClCompile Include="..\src\ares\ares_send.c" />
+ <ClCompile Include="..\src\ares\ares_strcasecmp.c" />
+ <ClCompile Include="..\src\ares\ares_strdup.c" />
+ <ClCompile Include="..\src\ares\ares_strerror.c" />
+ <ClCompile Include="..\src\ares\ares_timeout.c" />
+ <ClCompile Include="..\src\ares\ares_version.c" />
+ <ClCompile Include="..\src\ares\ares_writev.c" />
+ <ClCompile Include="..\src\ares\bitncmp.c" />
+ <ClCompile Include="..\src\ares\inet_net_pton.c" />
+ <ClCompile Include="..\src\ares\inet_ntop.c" />
+ <ClCompile Include="..\src\ares\windows_port.c" />
</ItemGroup>
<ItemGroup>
- <ClInclude Include="..\c-ares\ares.h" />
- <ClInclude Include="..\c-ares\ares_data.h" />
- <ClInclude Include="..\c-ares\ares_dns.h" />
- <ClInclude Include="..\c-ares\ares_iphlpapi.h" />
- <ClInclude Include="..\c-ares\ares_ipv6.h" />
- <ClInclude Include="..\c-ares\ares_library_init.h" />
- <ClInclude Include="..\c-ares\ares_llist.h" />
- <ClInclude Include="..\c-ares\ares_nowarn.h" />
- <ClInclude Include="..\c-ares\ares_private.h" />
- <ClInclude Include="..\c-ares\ares_rules.h" />
- <ClInclude Include="..\c-ares\ares_setup.h" />
- <ClInclude Include="..\c-ares\ares_strcasecmp.h" />
- <ClInclude Include="..\c-ares\ares_strdup.h" />
- <ClInclude Include="..\c-ares\ares_version.h" />
- <ClInclude Include="..\c-ares\ares_writev.h" />
- <ClInclude Include="..\c-ares\bitncmp.h" />
- <ClInclude Include="..\c-ares\config-win32.h" />
- <ClInclude Include="..\c-ares\config_win32\ares_config.h" />
- <ClInclude Include="..\c-ares\inet_net_pton.h" />
- <ClInclude Include="..\c-ares\inet_ntop.h" />
- <ClInclude Include="..\c-ares\nameser.h" />
- <ClInclude Include="..\c-ares\setup_once.h" />
+ <ClInclude Include="..\include\ares.h" />
+ <ClInclude Include="..\include\ares_version.h" />
+ <ClInclude Include="..\src\ares\ares_data.h" />
+ <ClInclude Include="..\src\ares\ares_dns.h" />
+ <ClInclude Include="..\src\ares\ares_iphlpapi.h" />
+ <ClInclude Include="..\src\ares\ares_ipv6.h" />
+ <ClInclude Include="..\src\ares\ares_library_init.h" />
+ <ClInclude Include="..\src\ares\ares_llist.h" />
+ <ClInclude Include="..\src\ares\ares_nowarn.h" />
+ <ClInclude Include="..\src\ares\ares_private.h" />
+ <ClInclude Include="..\src\ares\ares_rules.h" />
+ <ClInclude Include="..\src\ares\ares_setup.h" />
+ <ClInclude Include="..\src\ares\ares_strcasecmp.h" />
+ <ClInclude Include="..\src\ares\ares_strdup.h" />
+ <ClInclude Include="..\src\ares\ares_version.h" />
+ <ClInclude Include="..\src\ares\ares_writev.h" />
+ <ClInclude Include="..\src\ares\bitncmp.h" />
+ <ClInclude Include="..\src\ares\config_win32\ares_config.h" />
+ <ClInclude Include="..\src\ares\inet_net_pton.h" />
+ <ClInclude Include="..\src\ares\inet_ntop.h" />
+ <ClInclude Include="..\src\ares\nameser.h" />
+ <ClInclude Include="..\src\ares\setup_once.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\c-ares\config_win32</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\c-ares\config_win32</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- <AdditionalIncludeDirectories>..\c-ares\config_win32</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- <AdditionalIncludeDirectories>..\c-ares\config_win32</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ClCompile Include="..\test\dns-server.c" />
<ClCompile Include="..\test\echo-server.c" />
<ClCompile Include="..\test\run-benchmarks.c" />
- <ClCompile Include="..\test\runner-unix.c">
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
- </ClCompile>
<ClCompile Include="..\test\runner-win.c" />
<ClCompile Include="..\test\runner.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\test\benchmark-list.h" />
- <ClInclude Include="..\test\runner-unix.h">
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
- </ClInclude>
<ClInclude Include="..\test\runner-win.h" />
<ClInclude Include="..\test\runner.h" />
<ClInclude Include="..\test\task.h" />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\c-ares\config_win32</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\c-ares\config_win32</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- <AdditionalIncludeDirectories>..\c-ares\config_win32</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- <AdditionalIncludeDirectories>..\c-ares\config_win32</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\test\echo-server.c" />
- <ClCompile Include="..\test\runner-unix.c">
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
- </ClCompile>
<ClCompile Include="..\test\test-async.c" />
<ClCompile Include="..\test\test-bind6-error.c" />
<ClCompile Include="..\test\test-delayed-accept.c" />
<ClCompile Include="..\test\test-fail-always.c" />
<ClCompile Include="..\test\test-gethostbyname.c" />
<ClCompile Include="..\test\test-getaddrinfo.c" />
+ <ClCompile Include="..\test\test-getsockname.c" />
<ClCompile Include="..\test\test-hrtime.c" />
<ClCompile Include="..\test\test-loop-handles.c" />
<ClCompile Include="..\test\test-pass-always.c" />
<ClCompile Include="..\test\run-tests.c" />
</ItemGroup>
<ItemGroup>
- <ClInclude Include="..\test\runner-unix.h">
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
- </ClInclude>
<ClInclude Include="..\test\test-list.h" />
<ClInclude Include="..\test\runner-win.h" />
<ClInclude Include="..\test\runner.h" />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\c-ares\config_win32</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\c-ares\config_win32</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- <AdditionalIncludeDirectories>..\c-ares\config_win32</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- <AdditionalIncludeDirectories>..\c-ares\config_win32</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>..\include;..\src\ares\config_win32</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
- <ClInclude Include="..\ngx-queue.h" />
- <ClInclude Include="..\uv-unix.h">
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
- </ClInclude>
- <ClInclude Include="..\uv-win.h" />
- <ClInclude Include="..\uv.h" />
- <ClInclude Include="..\tree.h" />
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="..\uv-unix.c">
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
- </ClCompile>
- <ClCompile Include="..\uv-win.c" />
- <ClCompile Include="..\uv-common.c" />
- </ItemGroup>
- <ItemGroup>
- <None Include="..\AUTHORS" />
- <None Include="..\config-mingw.mk" />
- <None Include="..\config-unix.mk" />
- <None Include="..\iocp-links.html" />
- <None Include="..\LICENSE" />
- <None Include="..\Makefile" />
- <None Include="..\README" />
- </ItemGroup>
- <ItemGroup>
<ProjectReference Include="c-ares.vcxproj">
<Project>{2b6a4644-eba9-dfb5-af35-6c56edf05c7f}</Project>
<Private>true</Private>
<UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
</ProjectReference>
</ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\src\uv-common.c" />
+ <ClCompile Include="..\src\uv-win.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\include\ares.h" />
+ <ClInclude Include="..\include\ares_version.h" />
+ <ClInclude Include="..\include\tree.h" />
+ <ClInclude Include="..\include\uv-win.h" />
+ <ClInclude Include="..\include\uv.h" />
+ <ClInclude Include="..\src\uv-common.h" />
+ </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
#ifdef HAVE_CONFIG_H
#include "ares_config.h"
-#else
-
-#ifdef WIN32
-#include "config-win32.h"
-#endif
-
#endif /* HAVE_CONFIG_H */
/* ================================================================ */
+++ /dev/null
-#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 <getopt.h> header file. */
-#if defined(__MINGW32__) || defined(__POCC__)
-#define HAVE_GETOPT_H 1
-#endif
-
-/* Define if you have the <limits.h> header file. */
-#define HAVE_LIMITS_H 1
-
-/* Define if you have the <process.h> header file. */
-#ifndef __SALFORDC__
-#define HAVE_PROCESS_H 1
-#endif
-
-/* Define if you have the <signal.h> header file. */
-#define HAVE_SIGNAL_H 1
-
-/* Define if you have the <sys/time.h> header file */
-/* #define HAVE_SYS_TIME_H 1 */
-
-/* Define if you have the <time.h> header file. */
-#define HAVE_TIME_H 1
-
-/* Define if you have the <unistd.h> header file. */
-#if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__LCC__) || \
- defined(__POCC__)
-#define HAVE_UNISTD_H 1
-#endif
-
-/* Define if you have the <winsock.h> header file. */
-#define HAVE_WINSOCK_H 1
-
-/* Define if you have the <winsock2.h> header file. */
-#ifndef __SALFORDC__
-#define HAVE_WINSOCK2_H 1
-#endif
-
-/* Define if you have the <ws2tcpip.h> 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 <sys/time.h> and <time.h>. */
-/* #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 */
-/* 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 <getopt.h> 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 <limits.h> 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 <process.h> 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 <signal.h> 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 <sys/time.h> 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 <time.h> header file. */
+#define HAVE_TIME_H 1
-/* Specifies the number of arguments to getservbyport_r */
-/* #undef GETSERVBYPORT_R_ARGS */
+/* Define if you have the <unistd.h> 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 <winsock.h> header file. */
+#define HAVE_WINSOCK_H 1
-/* Define to 1 if you have the <arpa/inet.h> header file. */
-/* #undef HAVE_ARPA_INET_H */
+/* Define if you have the <winsock2.h> header file. */
+#ifndef __SALFORDC__
+#define HAVE_WINSOCK2_H 1
+#endif
-/* Define to 1 if you have the <arpa/nameser_compat.h> header file. */
-/* #undef HAVE_ARPA_NAMESER_COMPAT_H */
+/* Define if you have the <ws2tcpip.h> header file. */
+#ifndef __SALFORDC__
+#define HAVE_WS2TCPIP_H 1
+#endif
-/* Define to 1 if you have the <arpa/nameser.h> header file. */
-/* #undef HAVE_ARPA_NAMESER_H */
+/* ---------------------------------------------------------------- */
+/* OTHER HEADER INFO */
+/* ---------------------------------------------------------------- */
-/* Define to 1 if you have the <assert.h> 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 <sys/time.h> and <time.h>. */
+/* #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 <dlfcn.h> header file. */
-/* #undef HAVE_DLFCN_H */
-
-/* Define to 1 if you have the <errno.h> 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 <fcntl.h> 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 <inttypes.h> 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 <limits.h> 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 <netdb.h> header file. */
-/* #undef HAVE_NETDB_H */
-
-/* Define to 1 if you have the <netinet/in.h> header file. */
-/* #undef HAVE_NETINET_IN_H */
-
-/* Define to 1 if you have the <netinet/tcp.h> header file. */
-/* #undef HAVE_NETINET_TCP_H */
-
-/* Define to 1 if you have the <net/if.h> 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 <signal.h> 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 <socket.h> header file. */
-/* #undef HAVE_SOCKET_H */
-
-/* Define to 1 if you have the <stdbool.h> header file. */
-#define HAVE_STDBOOL_H 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> 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 <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> 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 <stropts.h> 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 <sys/ioctl.h> header file. */
-/* #undef HAVE_SYS_IOCTL_H */
-
-/* Define to 1 if you have the <sys/param.h> header file. */
-#define HAVE_SYS_PARAM_H 1
-
-/* Define to 1 if you have the <sys/select.h> 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 <sys/socket.h> 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 <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#define HAVE_SYS_TIME_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <sys/uio.h> header file. */
-/* #undef HAVE_SYS_UIO_H */
-
-/* Define to 1 if you have the <time.h> header file. */
-#define HAVE_TIME_H 1
-
-/* Define to 1 if you have the <unistd.h> 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
/* 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
/* 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 *
/* 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 <sys/time.h> and <time.h>. */
-#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 <sys/types.h> does not define. */
-/* #undef size_t */
-/* the signed version of size_t */
-/* #undef ssize_t */
+#endif /* __ARES_CONFIG_WIN32_H */
#include <linux/version.h>
-#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 <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
#include <linux/version.h>
-#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 */
#include "uv.h"
+#define COUNTOF(a) (sizeof(a) / sizeof(a[0]))
+
/*
* Subclass of uv_handle_t. Used for integration of c-ares.
*/
#include "uv.h"
+#include <string.h>
+#include <time.h>
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+#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);
#include <stdint.h>
#include <stddef.h>
+#include <unistd.h>
#include <time.h>
#undef NANOSEC
int uv_exepath(char* buffer, size_t* size) {
- uint32_t usize;
- int result;
- char* path;
- char* fullpath;
-
if (!buffer || !size) {
return -1;
}
#include "uv.h"
-#include <limits.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
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);
fprintf(stderr, "\nlibuv fatal error. (%d) %s\n", errorno, errmsg);
}
- *((char*)NULL) = 0xff; /* Force debug break */
abort();
}
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:
/* 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;
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;
}
+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;
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);
}
-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;
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;
int uv_async_send(uv_async_t* async) {
ev_async_send(EV_DEFAULT_UC_ &async->async_watcher);
+ return 0;
}
h->read_watcher.data = h;
h->write_watcher.data = h;
+
+ return h;
}
handle->retcode = getaddrinfo(handle->hostname,
handle->service,
- &handle->hints,
+ handle->hints,
&handle->res);
return 0;
}
const char* hostname,
const char* service,
const struct addrinfo* hints) {
+ eio_req* req;
uv_eio_init();
if (handle == NULL || cb == NULL ||
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);
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");
+}
#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.
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;
/* 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)
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;
}
}
}
-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;
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;
}
-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_++;
}
+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;
}
+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));
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;
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;
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) {
}
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);
}
-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;
if (accept_socket == INVALID_SOCKET) {
req->error = uv_new_sys_error(WSAGetLastError());
uv_insert_pending_req(req);
+ handle->reqs_pending++;
return;
}
/* 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;
}
-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;
/* 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;
}
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;
/* 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;
}
+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;
}
-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;
}
+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;
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);
}
-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;
/* 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);
}
}
-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);
}
+#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:
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;
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_,
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) {
/* 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_,
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
}
/* 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,
}
/* 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);
* 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));
/* 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) {
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;
+}
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)
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;
/* 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;
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",
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);
}
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));
}
*/
if (uv_now() - start_time > 1000 && read_sockets == 0) {
read_show_stats();
- uv_close((uv_handle_t*)&server, NULL);
+ uv_close(server, NULL);
}
}
}
-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();
}
if (bytes < 0) {
- uv_close((uv_handle_t*)tcp, read_sockets_close_cb);
+ uv_close((uv_handle_t*)stream, read_sockets_close_cb);
return;
}
}
-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;
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);
/* 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]);
}
}
}
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++;
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;
}
-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();
}
-void pump(int n) {
+void tcp_pump(int n) {
ASSERT(n <= MAX_WRITE_HANDLES);
TARGET_CONNECTIONS = n;
+ type = TCP;
uv_init();
}
-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;
}
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));
rec_remaining = ntohs(reclen_n) - (DNSREC_LEN - 2);
}
}
-
+
if (rec_remaining <= readbuf_remaining) {
/* prepare reply */
addrsp(wr, hdrbuf);
#include <stdio.h>
#include <stdlib.h>
-
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);
}
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;
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)) {
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;
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");
}
/* 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");
}
-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();
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;
}
}
#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;
}
}
}
-/* 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");
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);
return -1;
}
- size_t nread, nwritten;
+ ssize_t nread, nwritten;
char buf[1024];
while ((nread = read(fileno(p->stdout_file), buf, 1024)) > 0) {
}
-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];
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);
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])) {
/* 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:
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;
}
} 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.
*/
/* 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);
/*
/* 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 */
#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__)
/* 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) {
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) {
/* 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");
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");
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");
}
/* 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);
#include <stdio.h>
#include <stdlib.h>
-static char BUFFER[1024];
-
static int connection_cb_called = 0;
static int do_accept_called = 0;
static int close_cb_called = 0;
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);
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);
}
--- /dev/null
+/* 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 <stdlib.h>
+#include <stdio.h>
+
+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 = b - a;
- printf("diff = %llu\n", diff);
+ printf("diff = %llu\n", (unsigned long long int)diff);
ASSERT(diff >= NANOSEC / MICROSEC);
ASSERT(diff > MICROSEC);
* 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)
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)
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)
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. */
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];
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");
}
-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);
}
-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));
/* 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));
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);
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++;
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);
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);
}
/* 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);
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);
}
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);
ReqWrap(uv_handle_t* handle, void* callback) {
HandleScope scope;
object_ = Persistent<Object>::New(Object::New());
- uv_req_init(&req_, handle, callback);
+ uv_req_init(&req_, handle, (void* (*)(void*))callback);
req_.data = this;
}