summaryrefslogtreecommitdiff
path: root/deps/uv
diff options
context:
space:
mode:
authorIgor Zinkovsky <igorzi@microsoft.com>2012-01-30 15:57:08 -0800
committerIgor Zinkovsky <igorzi@microsoft.com>2012-01-30 15:57:08 -0800
commitff40253566089cd5b89c1e6efca32d3b5772dbcb (patch)
tree01b4c194f0db0b3d245710f15ccfeb1f9ed81fbe /deps/uv
parente97b961815b8804e17d6793101960db53e4c32a2 (diff)
downloadnode-new-ff40253566089cd5b89c1e6efca32d3b5772dbcb.tar.gz
upgrade uv to 812e410772
Diffstat (limited to 'deps/uv')
-rw-r--r--deps/uv/include/uv-private/uv-unix.h3
-rw-r--r--deps/uv/include/uv-private/uv-win.h5
-rw-r--r--deps/uv/include/uv.h23
-rw-r--r--deps/uv/src/unix/core.c18
-rw-r--r--deps/uv/src/unix/error.c4
-rw-r--r--deps/uv/src/unix/internal.h24
-rw-r--r--deps/uv/src/unix/kqueue.c4
-rw-r--r--deps/uv/src/unix/linux.c3
-rw-r--r--deps/uv/src/unix/stream.c37
-rw-r--r--deps/uv/src/unix/sunos.c2
-rw-r--r--deps/uv/src/win/internal.h5
-rw-r--r--deps/uv/src/win/pipe.c2
-rw-r--r--deps/uv/src/win/stream.c24
-rw-r--r--deps/uv/src/win/tcp.c25
-rw-r--r--deps/uv/test/test-list.h4
-rw-r--r--deps/uv/uv.gyp1
16 files changed, 165 insertions, 19 deletions
diff --git a/deps/uv/include/uv-private/uv-unix.h b/deps/uv/include/uv-private/uv-unix.h
index 24ef37cb9d..792ca84a2c 100644
--- a/deps/uv/include/uv-private/uv-unix.h
+++ b/deps/uv/include/uv-private/uv-unix.h
@@ -192,6 +192,9 @@ typedef void* uv_lib_t;
struct termios orig_termios; \
int mode;
+#define UV_STREAM_INFO_PRIVATE_FIELDS \
+ int fd;
+
/* UV_FS_EVENT_PRIVATE_FIELDS */
#if defined(__linux__)
diff --git a/deps/uv/include/uv-private/uv-win.h b/deps/uv/include/uv-private/uv-win.h
index 5a6a949e53..626eb6db4c 100644
--- a/deps/uv/include/uv-private/uv-win.h
+++ b/deps/uv/include/uv-private/uv-win.h
@@ -450,6 +450,11 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
wchar_t* dirw; \
char* buffer;
+#define UV_STREAM_INFO_PRIVATE_FIELDS \
+ union { \
+ WSAPROTOCOL_INFOW socket_info; \
+ };
+
int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size,
char* utf8Buffer, size_t utf8Size);
int uv_utf8_to_utf16(const char* utf8Buffer, wchar_t* utf16Buffer,
diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h
index cedf529375..0fbd4d6876 100644
--- a/deps/uv/include/uv.h
+++ b/deps/uv/include/uv.h
@@ -180,6 +180,7 @@ typedef struct uv_process_s uv_process_t;
typedef struct uv_counters_s uv_counters_t;
typedef struct uv_cpu_info_s uv_cpu_info_t;
typedef struct uv_interface_address_s uv_interface_address_t;
+typedef struct uv_stream_info_s uv_stream_info_t;
/* Request types */
typedef struct uv_req_s uv_req_t;
typedef struct uv_shutdown_s uv_shutdown_t;
@@ -531,6 +532,28 @@ UV_EXTERN int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name,
int* namelen);
/*
+ * uv_stream_info_t is used to store exported stream (using uv_export),
+ * which can be imported into a different event-loop within the same process
+ * (using uv_import).
+ */
+struct uv_stream_info_s {
+ uv_handle_type type;
+ UV_STREAM_INFO_PRIVATE_FIELDS
+};
+
+/*
+ * Exports uv_stream_t as uv_stream_info_t value, which could
+ * be used to initialize shared streams within the same process.
+ */
+UV_EXTERN int uv_export(uv_stream_t* stream, uv_stream_info_t* info);
+
+/*
+ * Imports uv_stream_info_t value into uv_stream_t to initialize
+ * shared stream.
+ */
+UV_EXTERN int uv_import(uv_stream_t* stream, uv_stream_info_t* info);
+
+/*
* uv_tcp_connect, uv_tcp_connect6
* These functions establish IPv4 and IPv6 TCP connections. Provide an
* initialized TCP handle and an uninitialized uv_connect_t*. The callback
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
index 366e94b3c6..af39fc80dd 100644
--- a/deps/uv/src/unix/core.c
+++ b/deps/uv/src/unix/core.c
@@ -825,6 +825,24 @@ int uv__cloexec(int fd, int set) {
}
+/* This function is not execve-safe, there is a race window
+ * between the call to dup() and fcntl(FD_CLOEXEC).
+ */
+int uv__dup(int fd) {
+ fd = dup(fd);
+
+ if (fd == -1)
+ return -1;
+
+ if (uv__cloexec(fd, 1)) {
+ SAVE_ERRNO(uv__close(fd));
+ return -1;
+ }
+
+ return fd;
+}
+
+
/* TODO move to uv-common.c? */
size_t uv__strlcpy(char* dst, const char* src, size_t size) {
const char *org;
diff --git a/deps/uv/src/unix/error.c b/deps/uv/src/unix/error.c
index 80d3270db0..3d9c4072e6 100644
--- a/deps/uv/src/unix/error.c
+++ b/deps/uv/src/unix/error.c
@@ -86,7 +86,5 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
case ETIMEDOUT: return UV_ETIMEDOUT;
default: return UV_UNKNOWN;
}
-
- assert(0 && "unreachable");
- return -1;
+ UNREACHABLE();
}
diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h
index a962073c19..3591090d7a 100644
--- a/deps/uv/src/unix/internal.h
+++ b/deps/uv/src/unix/internal.h
@@ -25,6 +25,8 @@
#include "uv-common.h"
#include "uv-eio.h"
+#include <assert.h>
+#include <stdlib.h> /* abort */
#include <stddef.h> /* offsetof */
#if __STRICT_ANSI__
@@ -133,13 +135,20 @@ inline static int sys_accept4(int fd,
#define container_of(ptr, type, member) \
((type *) ((char *) (ptr) - offsetof(type, member)))
-#define SAVE_ERRNO(block) \
- do { \
- int _saved_errno = errno; \
- do { block; } while (0); \
- errno = _saved_errno; \
- } \
- while (0);
+#define UNREACHABLE() \
+ do { \
+ assert(0 && "unreachable code"); \
+ abort(); \
+ } \
+ while (0)
+
+#define SAVE_ERRNO(block) \
+ do { \
+ int _saved_errno = errno; \
+ do { block; } while (0); \
+ errno = _saved_errno; \
+ } \
+ while (0)
/* flags */
enum {
@@ -159,6 +168,7 @@ void uv__handle_init(uv_loop_t* loop, uv_handle_t* handle, uv_handle_type type);
int uv__nonblock(int fd, int set) __attribute__((unused));
int uv__cloexec(int fd, int set) __attribute__((unused));
int uv__socket(int domain, int type, int protocol);
+int uv__dup(int fd);
/* We used to handle EINTR in uv__close() but linux 2.6 will have closed the
* file descriptor anyway, even on EINTR. Retrying in that case isn't merely
diff --git a/deps/uv/src/unix/kqueue.c b/deps/uv/src/unix/kqueue.c
index cea583355b..68d064dad9 100644
--- a/deps/uv/src/unix/kqueue.c
+++ b/deps/uv/src/unix/kqueue.c
@@ -141,13 +141,13 @@ int uv_fs_event_init(uv_loop_t* loop,
void uv__fs_event_destroy(uv_fs_event_t* handle) {
- assert(0 && "unreachable");
+ UNREACHABLE();
}
/* Called by libev, don't touch. */
void uv__kqueue_hack(EV_P_ int fflags, ev_io *w) {
- assert(0 && "unreachable");
+ UNREACHABLE();
}
#endif /* HAVE_KQUEUE */
diff --git a/deps/uv/src/unix/linux.c b/deps/uv/src/unix/linux.c
index 12473596eb..2f04cb8df9 100644
--- a/deps/uv/src/unix/linux.c
+++ b/deps/uv/src/unix/linux.c
@@ -679,8 +679,7 @@ int uv_fs_event_init(uv_loop_t* loop,
void uv__fs_event_destroy(uv_fs_event_t* handle) {
- assert(0 && "unreachable");
- abort();
+ UNREACHABLE();
}
#endif /* HAVE_INOTIFY_INIT || HAVE_INOTIFY_INIT1 */
diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c
index e0689fbcdc..9e58fc5377 100644
--- a/deps/uv/src/unix/stream.c
+++ b/deps/uv/src/unix/stream.c
@@ -966,3 +966,40 @@ int uv_read_stop(uv_stream_t* stream) {
}
+int uv_export(uv_stream_t* stream, uv_stream_info_t* info) {
+ int fd;
+
+ if (stream->type != UV_TCP) {
+ uv__set_artificial_error(stream->loop, UV_EINVAL);
+ return -1;
+ }
+
+ fd = uv__dup(stream->fd);
+
+ if (fd == -1) {
+ uv__set_sys_error(stream->loop, errno);
+ return -1;
+ }
+
+ info->type = stream->type;
+ info->fd = fd;
+
+ return 0;
+}
+
+
+int uv_import(uv_stream_t* stream, uv_stream_info_t* info) {
+ if (info->type != UV_TCP) {
+ uv__set_artificial_error(stream->loop, UV_EINVAL);
+ return -1;
+ }
+
+ if (stream->fd != -1) {
+ uv__set_artificial_error(stream->loop, UV_EALREADY);
+ return -1;
+ }
+
+ stream->fd = info->fd;
+
+ return 0;
+}
diff --git a/deps/uv/src/unix/sunos.c b/deps/uv/src/unix/sunos.c
index 49d372b495..a87a2343a8 100644
--- a/deps/uv/src/unix/sunos.c
+++ b/deps/uv/src/unix/sunos.c
@@ -214,7 +214,7 @@ int uv_fs_event_init(uv_loop_t* loop,
void uv__fs_event_destroy(uv_fs_event_t* handle) {
- assert(0 && "unreachable"); /* should never be called */
+ UNREACHABLE();
}
#endif /* HAVE_PORTS_FS */
diff --git a/deps/uv/src/win/internal.h b/deps/uv/src/win/internal.h
index 0dc551dbaa..9435bb28bd 100644
--- a/deps/uv/src/win/internal.h
+++ b/deps/uv/src/win/internal.h
@@ -143,11 +143,14 @@ void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle);
-int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info);
+int uv__tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info);
int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid,
LPWSAPROTOCOL_INFOW protocol_info);
+int uv_tcp_export(uv_tcp_t* tcp, uv_stream_info_t* info);
+int uv_tcp_import(uv_tcp_t* tcp, uv_stream_info_t* info);
+
/*
* UDP
diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c
index 5c20fe4801..60f137e974 100644
--- a/deps/uv/src/win/pipe.c
+++ b/deps/uv/src/win/pipe.c
@@ -649,7 +649,7 @@ int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) {
return -1;
}
- return uv_tcp_import((uv_tcp_t*)client, server->pending_socket_info);
+ return uv__tcp_import((uv_tcp_t*)client, server->pending_socket_info);
} else {
pipe_client = (uv_pipe_t*)client;
diff --git a/deps/uv/src/win/stream.c b/deps/uv/src/win/stream.c
index c2354eecba..7faa0a2b61 100644
--- a/deps/uv/src/win/stream.c
+++ b/deps/uv/src/win/stream.c
@@ -186,3 +186,27 @@ size_t uv_count_bufs(uv_buf_t bufs[], int count) {
return bytes;
}
+
+
+int uv_export(uv_stream_t* stream, uv_stream_info_t* info) {
+ switch (stream->type) {
+ case UV_TCP:
+ return uv_tcp_export((uv_tcp_t*)stream, info);
+ default:
+ assert(0);
+ uv__set_sys_error(stream->loop, WSAEINVAL);
+ return -1;
+ }
+}
+
+
+int uv_import(uv_stream_t* stream, uv_stream_info_t* info) {
+ switch (stream->type) {
+ case UV_TCP:
+ return uv_tcp_import((uv_tcp_t*)stream, info);
+ default:
+ assert(0);
+ uv__set_sys_error(stream->loop, WSAEINVAL);
+ return -1;
+ }
+} \ No newline at end of file
diff --git a/deps/uv/src/win/tcp.c b/deps/uv/src/win/tcp.c
index f810913f30..590d0792fb 100644
--- a/deps/uv/src/win/tcp.c
+++ b/deps/uv/src/win/tcp.c
@@ -1019,7 +1019,7 @@ void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
}
-int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info) {
+int uv__tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info) {
SOCKET socket = WSASocketW(AF_INET,
SOCK_STREAM,
IPPROTO_IP,
@@ -1140,4 +1140,25 @@ int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
}
return 0;
-} \ No newline at end of file
+}
+
+
+int uv_tcp_export(uv_tcp_t* tcp, uv_stream_info_t* info) {
+ if (uv_tcp_duplicate_socket(tcp, GetCurrentProcessId(),
+ &info->socket_info) == -1) {
+ return -1;
+ }
+
+ info->type = UV_TCP;
+ return 0;
+}
+
+
+int uv_tcp_import(uv_tcp_t* tcp, uv_stream_info_t* info) {
+ if (info->type != UV_TCP) {
+ uv__set_sys_error(tcp->loop, WSAEINVAL);
+ return -1;
+ }
+
+ return uv__tcp_import(tcp, &info->socket_info);
+}
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
index 31dcb0a64c..bc13dd0fe9 100644
--- a/deps/uv/test/test-list.h
+++ b/deps/uv/test/test-list.h
@@ -24,6 +24,8 @@ TEST_DECLARE (tty)
TEST_DECLARE (stdio_over_pipes)
TEST_DECLARE (ipc_listen_before_write)
TEST_DECLARE (ipc_listen_after_write)
+TEST_DECLARE (ipc_threads_listen_after_write)
+TEST_DECLARE (ipc_threads_listen_before_write)
TEST_DECLARE (tcp_ping_pong)
TEST_DECLARE (tcp_ping_pong_v6)
TEST_DECLARE (pipe_ping_pong)
@@ -161,6 +163,8 @@ TASK_LIST_START
TEST_ENTRY (stdio_over_pipes)
TEST_ENTRY (ipc_listen_before_write)
TEST_ENTRY (ipc_listen_after_write)
+ TEST_ENTRY (ipc_threads_listen_after_write)
+ TEST_ENTRY (ipc_threads_listen_before_write)
TEST_ENTRY (tcp_ping_pong)
TEST_HELPER (tcp_ping_pong, tcp4_echo_server)
diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp
index 7a88cfa1ab..3ed08433e6 100644
--- a/deps/uv/uv.gyp
+++ b/deps/uv/uv.gyp
@@ -301,6 +301,7 @@
'test/test-hrtime.c',
'test/test-idle.c',
'test/test-ipc.c',
+ 'test/test-ipc-threads.c',
'test/test-list.h',
'test/test-loop-handles.c',
'test/test-multiple-listen.c',