uv: upgrade to ec825ff
authorBen Noordhuis <info@bnoordhuis.nl>
Sat, 22 Oct 2011 00:08:12 +0000 (17:08 -0700)
committerRyan Dahl <ry@tinyclouds.org>
Sat, 22 Oct 2011 01:09:17 +0000 (18:09 -0700)
deps/uv/include/uv.h
deps/uv/src/unix/core.c
deps/uv/src/unix/internal.h
deps/uv/src/unix/stream.c
deps/uv/src/unix/tcp.c
deps/uv/src/win/tcp.c
deps/uv/test/test-list.h
deps/uv/test/test-tcp-flags.c [new file with mode: 0644]
deps/uv/uv.gyp

index 179398d..7bee299 100644 (file)
@@ -448,6 +448,15 @@ struct uv_tcp_s {
 
 int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle);
 
+/* Enable/disable Nagle's algorithm. */
+int uv_tcp_nodelay(uv_tcp_t* handle, int enable);
+
+/* Enable/disable TCP keep-alive.
+ *
+ * `ms` is the initial delay in seconds, ignored when `enable` is zero.
+ */
+int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay);
+
 int uv_tcp_bind(uv_tcp_t* handle, struct sockaddr_in);
 int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6);
 int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name, int* namelen);
index c834aaa..27e949e 100644 (file)
@@ -667,7 +667,8 @@ int uv_getaddrinfo(uv_loop_t* loop,
 
 
 void uv_freeaddrinfo(struct addrinfo* ai) {
-  freeaddrinfo(ai);
+  if (ai)
+    freeaddrinfo(ai);
 }
 
 
index e6ae9b7..0ab8ba9 100644 (file)
 
 /* flags */
 enum {
-  UV_CLOSING  = 0x00000001, /* uv_close() called but not finished. */
-  UV_CLOSED   = 0x00000002, /* close(2) finished. */
-  UV_READING  = 0x00000004, /* uv_read_start() called. */
-  UV_SHUTTING = 0x00000008, /* uv_shutdown() called but not complete. */
-  UV_SHUT     = 0x00000010, /* Write side closed. */
-  UV_READABLE = 0x00000020, /* The stream is readable */
-  UV_WRITABLE = 0x00000040  /* The stream is writable */
+  UV_CLOSING       = 0x01,   /* uv_close() called but not finished. */
+  UV_CLOSED        = 0x02,   /* close(2) finished. */
+  UV_READING       = 0x04,   /* uv_read_start() called. */
+  UV_SHUTTING      = 0x08,   /* uv_shutdown() called but not complete. */
+  UV_SHUT          = 0x10,   /* Write side closed. */
+  UV_READABLE      = 0x20,   /* The stream is readable */
+  UV_WRITABLE      = 0x40,   /* The stream is writable */
+  UV_TCP_NODELAY   = 0x080,  /* Disable Nagle. */
+  UV_TCP_KEEPALIVE = 0x100   /* Turn on keep-alive. */
 };
 
 size_t uv__strlcpy(char* dst, const char* src, size_t size);
@@ -111,6 +113,8 @@ int uv__connect(uv_connect_t* req, uv_stream_t* stream, struct sockaddr* addr,
 
 /* tcp */
 int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb);
+int uv__tcp_nodelay(uv_tcp_t* handle, int enable);
+int uv__tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay);
 
 /* pipe */
 int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
index 3dbdf89..2e5bde0 100644 (file)
@@ -86,12 +86,24 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
 
   stream->flags |= flags;
 
-  /* Reuse the port address if applicable. */
-  yes = 1;
-  if (stream->type == UV_TCP
-      && setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
-    uv__set_sys_error(stream->loop, errno);
-    return -1;
+  if (stream->type == UV_TCP) {
+    /* Reuse the port address if applicable. */
+    yes = 1;
+    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes) == -1) {
+      uv__set_sys_error(stream->loop, errno);
+      return -1;
+    }
+
+    if ((stream->flags & UV_TCP_NODELAY) &&
+        uv__tcp_nodelay((uv_tcp_t*)stream, 1)) {
+      return -1;
+    }
+
+    /* TODO Use delay the user passed in. */
+    if ((stream->flags & UV_TCP_KEEPALIVE) &&
+        uv__tcp_keepalive((uv_tcp_t*)stream, 1, 60)) {
+      return -1;
+    }
   }
 
   /* Associate the fd with each ev_io watcher. */
index 8695a98..67ed217 100644 (file)
@@ -240,3 +240,82 @@ int uv__tcp_connect6(uv_connect_t* req,
   errno = saved_errno;
   return status;
 }
+
+
+int uv__tcp_nodelay(uv_tcp_t* handle, int enable) {
+  if (setsockopt(handle->fd,
+                 IPPROTO_TCP,
+                 TCP_NODELAY,
+                 &enable,
+                 sizeof enable) == -1) {
+    uv__set_sys_error(handle->loop, errno);
+    return -1;
+  }
+  return 0;
+}
+
+
+int uv__tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
+  if (setsockopt(handle->fd,
+                 SOL_SOCKET,
+                 SO_KEEPALIVE,
+                 &enable,
+                 sizeof enable) == -1) {
+    uv__set_sys_error(handle->loop, errno);
+    return -1;
+  }
+
+#ifdef TCP_KEEPIDLE
+  if (enable && setsockopt(handle->fd,
+                           IPPROTO_TCP,
+                           TCP_KEEPIDLE,
+                           &delay,
+                           sizeof delay) == -1) {
+    uv__set_sys_error(handle->loop, errno);
+    return -1;
+  }
+#endif
+
+#ifdef TCP_KEEPALIVE
+  if (enable && setsockopt(handle->fd,
+                           IPPROTO_TCP,
+                           TCP_KEEPALIVE,
+                           &delay,
+                           sizeof delay) == -1) {
+    uv__set_sys_error(handle->loop, errno);
+    return -1;
+  }
+#endif
+
+  return 0;
+}
+
+
+int uv_tcp_nodelay(uv_tcp_t* handle, int enable) {
+  if (handle->fd != -1 && uv__tcp_nodelay(handle, enable))
+    return -1;
+
+  if (enable)
+    handle->flags |= UV_TCP_NODELAY;
+  else
+    handle->flags &= ~UV_TCP_NODELAY;
+
+  return 0;
+}
+
+
+int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
+  if (handle->fd != -1 && uv__tcp_keepalive(handle, enable, delay))
+    return -1;
+
+  if (enable)
+    handle->flags |= UV_TCP_KEEPALIVE;
+  else
+    handle->flags &= ~UV_TCP_KEEPALIVE;
+
+  /* TODO Store delay if handle->fd == -1 but don't want to enlarge
+   *       uv_tcp_t with an int that's almost never used...
+   */
+
+  return 0;
+}
index b6ab497..1133cc3 100644 (file)
@@ -956,3 +956,15 @@ int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info) {
 
   return uv_tcp_set_socket(tcp->loop, tcp, socket, 1);
 }
+
+
+int uv_tcp_nodelay(uv_tcp_t* handle, int enable) {
+  uv__set_artificial_error(handle->loop, UV_ENOSYS);
+  return -1;
+}
+
+
+int uv_tcp_keepalive(uv_tcp_t* handle, int enable, int delay) {
+  uv__set_artificial_error(handle->loop, UV_ENOSYS);
+  return -1;
+}
index 17b98c2..19c9991 100644 (file)
@@ -37,6 +37,7 @@ TEST_DECLARE   (tcp_bind_error_inval)
 TEST_DECLARE   (tcp_bind_localhost_ok)
 TEST_DECLARE   (tcp_listen_without_bind)
 TEST_DECLARE   (tcp_close)
+TEST_DECLARE   (tcp_flags)
 TEST_DECLARE   (tcp_write_error)
 TEST_DECLARE   (tcp_bind6_error_addrinuse)
 TEST_DECLARE   (tcp_bind6_error_addrnotavail)
@@ -149,6 +150,7 @@ TASK_LIST_START
   TEST_ENTRY  (tcp_bind_localhost_ok)
   TEST_ENTRY  (tcp_listen_without_bind)
   TEST_ENTRY  (tcp_close)
+  TEST_ENTRY  (tcp_flags)
   TEST_ENTRY  (tcp_write_error)
 
   TEST_ENTRY  (tcp_bind6_error_addrinuse)
diff --git a/deps/uv/test/test-tcp-flags.c b/deps/uv/test/test-tcp-flags.c
new file mode 100644 (file)
index 0000000..c441b56
--- /dev/null
@@ -0,0 +1,51 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+TEST_IMPL(tcp_flags) {
+  uv_loop_t* loop;
+  uv_tcp_t handle;
+  int r;
+
+  loop = uv_default_loop();
+
+  r = uv_tcp_init(loop, &handle);
+  ASSERT(r == 0);
+
+  r = uv_tcp_nodelay(&handle, 1);
+  ASSERT(r == 0);
+
+  r = uv_tcp_keepalive(&handle, 1, 60);
+  ASSERT(r == 0);
+
+  uv_close((uv_handle_t*)&handle, NULL);
+
+  r = uv_run(loop);
+  ASSERT(r == 0);
+
+  return 0;
+}
index 9fe0867..b4ef014 100644 (file)
         'test/test-tcp-bind-error.c',
         'test/test-tcp-bind6-error.c',
         'test/test-tcp-close.c',
+        'test/test-tcp-flags.c',
         'test/test-tcp-connect-error.c',
         'test/test-tcp-connect6-error.c',
         'test/test-tcp-write-error.c',