deps: upgrade libuv to 97c527a
authorBen Noordhuis <info@bnoordhuis.nl>
Tue, 30 Oct 2012 22:06:03 +0000 (23:06 +0100)
committerBen Noordhuis <info@bnoordhuis.nl>
Thu, 1 Nov 2012 00:22:16 +0000 (01:22 +0100)
24 files changed:
deps/uv/LICENSE
deps/uv/include/uv-private/ngx-queue.h
deps/uv/include/uv-private/stdint-msvc2008.h [new file with mode: 0644]
deps/uv/include/uv-private/uv-darwin.h
deps/uv/include/uv-private/uv-win.h
deps/uv/include/uv.h
deps/uv/src/inet.c
deps/uv/src/unix/darwin.c
deps/uv/src/unix/fsevents.c
deps/uv/src/unix/internal.h
deps/uv/src/unix/linux/linux-core.c
deps/uv/src/unix/process.c
deps/uv/src/unix/tty.c
deps/uv/src/uv-common.h
deps/uv/src/win/core.c
deps/uv/src/win/fs.c
deps/uv/src/win/handle-inl.h
deps/uv/src/win/tty.c
deps/uv/test/benchmark-async-pummel.c
deps/uv/test/benchmark-udp-pummel.c
deps/uv/test/task.h
deps/uv/test/test-list.h
deps/uv/test/test-ref.c
deps/uv/vcbuild.bat

index 65296f4..8ea2e36 100644 (file)
@@ -39,3 +39,6 @@ The externally maintained libraries used by libuv are:
   - inet_pton and inet_ntop implementations, contained in src/inet.c, are
     copyright the Internet Systems Consortium, Inc., and licensed under the ISC
     license.
+
+  - stdint-msvc2008.h (from msinttypes), copyright Alexander Chemeris. Three
+    clause BSD license.
index 4bd66fc..3c3ed1b 100644 (file)
@@ -122,7 +122,7 @@ struct ngx_queue_s {
 
 #define ngx_queue_foreach(q, h)                                               \
     for ((q) = ngx_queue_head(h);                                             \
-         (q) != ngx_queue_sentinel(h);                                        \
+         (q) != ngx_queue_sentinel(h) && !ngx_queue_empty(h);                 \
          (q) = ngx_queue_next(q))
 
 
diff --git a/deps/uv/include/uv-private/stdint-msvc2008.h b/deps/uv/include/uv-private/stdint-msvc2008.h
new file mode 100644 (file)
index 0000000..d02608a
--- /dev/null
@@ -0,0 +1,247 @@
+// ISO C9x  compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 
+// 
+//  Copyright (c) 2006-2008 Alexander Chemeris
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+//   1. Redistributions of source code must retain the above copyright notice,
+//      this list of conditions and the following disclaimer.
+// 
+//   2. Redistributions in binary form must reproduce the above copyright
+//      notice, this list of conditions and the following disclaimer in the
+//      documentation and/or other materials provided with the distribution.
+// 
+//   3. The name of the author may be used to endorse or promote products
+//      derived from this software without specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// 
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include <limits.h>
+
+// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
+// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
+// or compiler give many errors like this:
+//   error C2733: second C linkage of overloaded function 'wmemchr' not allowed
+#ifdef __cplusplus
+extern "C" {
+#endif
+#  include <wchar.h>
+#ifdef __cplusplus
+}
+#endif
+
+// Define _W64 macros to mark types changing their size, like intptr_t.
+#ifndef _W64
+#  if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+#     define _W64 __w64
+#  else
+#     define _W64
+#  endif
+#endif
+
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+
+// Visual Studio 6 and Embedded Visual C++ 4 doesn't
+// realize that, e.g. char has the same size as __int8
+// so we give up on __intX for them.
+#if (_MSC_VER < 1300)
+   typedef signed char       int8_t;
+   typedef signed short      int16_t;
+   typedef signed int        int32_t;
+   typedef unsigned char     uint8_t;
+   typedef unsigned short    uint16_t;
+   typedef unsigned int      uint32_t;
+#else
+   typedef signed __int8     int8_t;
+   typedef signed __int16    int16_t;
+   typedef signed __int32    int32_t;
+   typedef unsigned __int8   uint8_t;
+   typedef unsigned __int16  uint16_t;
+   typedef unsigned __int32  uint32_t;
+#endif
+typedef signed __int64       int64_t;
+typedef unsigned __int64     uint64_t;
+
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t    int_least8_t;
+typedef int16_t   int_least16_t;
+typedef int32_t   int_least32_t;
+typedef int64_t   int_least64_t;
+typedef uint8_t   uint_least8_t;
+typedef uint16_t  uint_least16_t;
+typedef uint32_t  uint_least32_t;
+typedef uint64_t  uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t    int_fast8_t;
+typedef int16_t   int_fast16_t;
+typedef int32_t   int_fast32_t;
+typedef int64_t   int_fast64_t;
+typedef uint8_t   uint_fast8_t;
+typedef uint16_t  uint_fast16_t;
+typedef uint32_t  uint_fast32_t;
+typedef uint64_t  uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+#ifdef _WIN64 // [
+   typedef signed __int64    intptr_t;
+   typedef unsigned __int64  uintptr_t;
+#else // _WIN64 ][
+   typedef _W64 signed int   intptr_t;
+   typedef _W64 unsigned int uintptr_t;
+#endif // _WIN64 ]
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t   intmax_t;
+typedef uint64_t  uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [   See footnote 220 at page 257 and footnote 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN     ((int8_t)_I8_MIN)
+#define INT8_MAX     _I8_MAX
+#define INT16_MIN    ((int16_t)_I16_MIN)
+#define INT16_MAX    _I16_MAX
+#define INT32_MIN    ((int32_t)_I32_MIN)
+#define INT32_MAX    _I32_MAX
+#define INT64_MIN    ((int64_t)_I64_MIN)
+#define INT64_MAX    _I64_MAX
+#define UINT8_MAX    _UI8_MAX
+#define UINT16_MAX   _UI16_MAX
+#define UINT32_MAX   _UI32_MAX
+#define UINT64_MAX   _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN    INT8_MIN
+#define INT_LEAST8_MAX    INT8_MAX
+#define INT_LEAST16_MIN   INT16_MIN
+#define INT_LEAST16_MAX   INT16_MAX
+#define INT_LEAST32_MIN   INT32_MIN
+#define INT_LEAST32_MAX   INT32_MAX
+#define INT_LEAST64_MIN   INT64_MIN
+#define INT_LEAST64_MAX   INT64_MAX
+#define UINT_LEAST8_MAX   UINT8_MAX
+#define UINT_LEAST16_MAX  UINT16_MAX
+#define UINT_LEAST32_MAX  UINT32_MAX
+#define UINT_LEAST64_MAX  UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN    INT8_MIN
+#define INT_FAST8_MAX    INT8_MAX
+#define INT_FAST16_MIN   INT16_MIN
+#define INT_FAST16_MAX   INT16_MAX
+#define INT_FAST32_MIN   INT32_MIN
+#define INT_FAST32_MAX   INT32_MAX
+#define INT_FAST64_MIN   INT64_MIN
+#define INT_FAST64_MAX   INT64_MAX
+#define UINT_FAST8_MAX   UINT8_MAX
+#define UINT_FAST16_MAX  UINT16_MAX
+#define UINT_FAST32_MAX  UINT32_MAX
+#define UINT_FAST64_MAX  UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+#  define INTPTR_MIN   INT64_MIN
+#  define INTPTR_MAX   INT64_MAX
+#  define UINTPTR_MAX  UINT64_MAX
+#else // _WIN64 ][
+#  define INTPTR_MIN   INT32_MIN
+#  define INTPTR_MAX   INT32_MAX
+#  define UINTPTR_MAX  UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN   INT64_MIN
+#define INTMAX_MAX   INT64_MAX
+#define UINTMAX_MAX  UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+#  define PTRDIFF_MIN  _I64_MIN
+#  define PTRDIFF_MAX  _I64_MAX
+#else  // _WIN64 ][
+#  define PTRDIFF_MIN  _I32_MIN
+#  define PTRDIFF_MAX  _I32_MAX
+#endif  // _WIN64 ]
+
+#define SIG_ATOMIC_MIN  INT_MIN
+#define SIG_ATOMIC_MAX  INT_MAX
+
+#ifndef SIZE_MAX // [
+#  ifdef _WIN64 // [
+#     define SIZE_MAX  _UI64_MAX
+#  else // _WIN64 ][
+#     define SIZE_MAX  _UI32_MAX
+#  endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
+#ifndef WCHAR_MIN // [
+#  define WCHAR_MIN  0
+#endif  // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+#  define WCHAR_MAX  _UI16_MAX
+#endif  // WCHAR_MAX ]
+
+#define WINT_MIN  0
+#define WINT_MAX  _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [   See footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val)  val##i8
+#define INT16_C(val) val##i16
+#define INT32_C(val) val##i32
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val)  val##ui8
+#define UINT16_C(val) val##ui16
+#define UINT32_C(val) val##ui32
+#define UINT64_C(val) val##ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+#define INTMAX_C   INT64_C
+#define UINTMAX_C  UINT64_C
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+
+#endif // _MSC_STDINT_H_ ]
index 4d68d01..1ae499c 100644 (file)
@@ -26,6 +26,7 @@
 # include <mach/mach.h>
 # include <mach/task.h>
 # include <mach/semaphore.h>
+# include <TargetConditionals.h>
 # define UV_PLATFORM_SEM_T semaphore_t
 #endif
 
index 10bd17e..8c048be 100644 (file)
@@ -36,9 +36,14 @@ typedef intptr_t ssize_t;
 
 #include <process.h>
 #include <signal.h>
-#include <stdint.h>
 #include <sys/stat.h>
 
+#if defined(_MSC_VER) && _MSC_VER < 1600
+# include "uv-private/stdint-msvc2008.h"
+#else
+# include <stdint.h>
+#endif
+
 #include "tree.h"
 #include "ngx-queue.h"
 
index 99b6988..a7cd572 100644 (file)
@@ -50,7 +50,12 @@ extern "C" {
 #define UV_VERSION_MINOR 9
 
 
-#include <stdint.h> /* int64_t */
+#if defined(_MSC_VER) && _MSC_VER < 1600
+# include "uv-private/stdint-msvc2008.h"
+#else
+# include <stdint.h>
+#endif
+
 #include <sys/types.h> /* size_t */
 
 #if defined(__SVR4) && !defined(__unix__)
index 293fbf6..939a9fa 100644 (file)
  */
 
 #include <stdio.h>
-#include <stdint.h>
 #include <string.h>
 
+#if defined(_MSC_VER) && _MSC_VER < 1600
+# include "uv-private/stdint-msvc2008.h"
+#else
+# include <stdint.h>
+#endif
+
 #include "uv.h"
 #include "uv-common.h"
 
index 675a4f6..2b9da40 100644 (file)
 #include <ifaddrs.h>
 #include <net/if.h>
 
-#include <TargetConditionals.h>
-
-#if !TARGET_OS_IPHONE
-#include <CoreServices/CoreServices.h>
-#endif
+#include <CoreFoundation/CFRunLoop.h>
 
 #include <mach/mach.h>
 #include <mach/mach_time.h>
index ac58d4f..02565f3 100644 (file)
 #include "uv.h"
 #include "internal.h"
 
+#if TARGET_OS_IPHONE
+
+/* iOS (currently) doesn't provide the FSEvents-API (nor CoreServices) */
+
+int uv__fsevents_init(uv_fs_event_t* handle) {
+  return 0;
+}
+
+
+int uv__fsevents_close(uv_fs_event_t* handle) {
+  return 0;
+}
+
+#else /* TARGET_OS_IPHONE */
+
 #include <assert.h>
 #include <stdlib.h>
 #include <CoreServices/CoreServices.h>
@@ -278,3 +293,5 @@ int uv__fsevents_close(uv_fs_event_t* handle) {
 
   return 0;
 }
+
+#endif /* TARGET_OS_IPHONE */
index 93e99b8..c418038 100644 (file)
@@ -62,7 +62,7 @@
 # define HAVE_KQUEUE 1
 #endif
 
-#if defined(__APPLE__) && !defined(TARGET_OS_IPHONE)
+#if defined(__APPLE__) && !TARGET_OS_IPHONE
 # include <CoreServices/CoreServices.h>
 #endif
 
index a773b07..e92869e 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <net/if.h>
 #include <sys/param.h>
+#include <sys/prctl.h>
 #include <sys/sysinfo.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -186,6 +187,10 @@ uv_err_t uv_set_process_title(const char* title) {
   if (process_title.len)
     strncpy(process_title.str, title, process_title.len - 1);
 
+#if defined(PR_SET_NAME)
+  prctl(PR_SET_NAME, title);
+#endif
+
   return uv_ok_;
 }
 
@@ -339,10 +344,13 @@ uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
   if (ci == NULL)
     return uv__new_sys_error(ENOMEM);
 
-  read_speeds(numcpus, ci);
   read_models(numcpus, ci);
   read_times(numcpus, ci);
 
+  /* read_models() on x86 also reads the CPU speed from /proc/cpuinfo */
+  if (ci[0].speed == 0)
+    read_speeds(numcpus, ci);
+
   *cpu_infos = ci;
   *count = numcpus;
 
@@ -358,18 +366,26 @@ static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci) {
 }
 
 
+/* Also reads the CPU frequency on x86. The other architectures only have
+ * a BogoMIPS field, which may not be very accurate.
+ */
 static void read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
 #if defined(__i386__) || defined(__x86_64__)
-  static const char marker[] = "model name\t: ";
+  static const char model_marker[] = "model name\t: ";
+  static const char speed_marker[] = "cpu MHz\t\t: ";
 #elif defined(__arm__)
-  static const char marker[] = "Processor\t: ";
+  static const char model_marker[] = "Processor\t: ";
+  static const char speed_marker[] = "";
 #elif defined(__mips__)
-  static const char marker[] = "cpu model\t\t: ";
+  static const char model_marker[] = "cpu model\t\t: ";
+  static const char speed_marker[] = "";
 #else
 # warning uv_cpu_info() is not supported on this architecture.
-  static const char marker[] = "(dummy)";
+  static const char model_marker[] = "";
+  static const char speed_marker[] = "";
 #endif
-  unsigned int num;
+  unsigned int model_idx;
+  unsigned int speed_idx;
   char buf[1024];
   char* model;
   FILE* fp;
@@ -378,18 +394,27 @@ static void read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
   if (fp == NULL)
     return;
 
-  num = 0;
+  model_idx = 0;
+  speed_idx = 0;
 
   while (fgets(buf, sizeof(buf), fp)) {
-    if (num >= numcpus)
-      break;
-
-    if (strncmp(buf, marker, sizeof(marker) - 1))
+    if (model_marker[0] != '\0' &&
+        model_idx < numcpus &&
+        strncmp(buf, model_marker, sizeof(model_marker) - 1) == 0)
+    {
+      model = buf + sizeof(model_marker) - 1;
+      model = strndup(model, strlen(model) - 1); /* strip newline */
+      ci[model_idx++].model = model;
       continue;
+    }
 
-    model = buf + sizeof(marker) - 1;
-    model = strndup(model, strlen(model) - 1); /* strip newline */
-    ci[num++].model = model;
+    if (speed_marker[0] != '\0' &&
+        speed_idx < numcpus &&
+        strncmp(buf, speed_marker, sizeof(speed_marker) - 1) == 0)
+    {
+      ci[speed_idx++].speed = atoi(buf + sizeof(speed_marker) - 1);
+      continue;
+    }
   }
   fclose(fp);
 }
index 7c552a7..79a8b6d 100644 (file)
 #include <fcntl.h>
 #include <poll.h>
 
-#ifdef __APPLE__
-# include <TargetConditionals.h>
-#endif
-
 #if defined(__APPLE__) && !TARGET_OS_IPHONE
 # include <crt_externs.h>
 # define environ (*_NSGetEnviron())
@@ -289,24 +285,24 @@ static void uv__process_child_init(uv_process_options_t options,
                                    int error_fd) {
   int close_fd;
   int use_fd;
-  int i;
+  int fd;
 
   if (options.flags & UV_PROCESS_DETACHED)
     setsid();
 
-  for (i = 0; i < stdio_count; i++) {
-    close_fd = pipes[i][0];
-    use_fd = pipes[i][1];
+  for (fd = 0; fd < stdio_count; fd++) {
+    close_fd = pipes[fd][0];
+    use_fd = pipes[fd][1];
 
     if (use_fd >= 0)
       close(close_fd);
-    else if (i >= 3)
+    else if (fd >= 3)
       continue;
     else {
       /* redirect stdin, stdout and stderr to /dev/null even if UV_IGNORE is
        * set
        */
-      use_fd = open("/dev/null", i == 0 ? O_RDONLY : O_RDWR);
+      use_fd = open("/dev/null", fd == 0 ? O_RDONLY : O_RDWR);
 
       if (use_fd == -1) {
         uv__write_int(error_fd, errno);
@@ -315,12 +311,15 @@ static void uv__process_child_init(uv_process_options_t options,
       }
     }
 
-    if (i == use_fd)
+    if (fd == use_fd)
       uv__cloexec(use_fd, 0);
     else {
-      dup2(use_fd, i);
+      dup2(use_fd, fd);
       close(use_fd);
     }
+
+    if (fd <= 2)
+      uv__nonblock(fd, 0);
   }
 
   if (options.cwd && chdir(options.cwd)) {
index 3ef9064..aa42c20 100644 (file)
@@ -34,18 +34,53 @@ static struct termios orig_termios;
 
 
 int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
+  int flags;
+  int newfd;
+  int r;
+
   uv__stream_init(loop, (uv_stream_t*)tty, UV_TTY);
 
-  if (readable) {
-    uv__nonblock(fd, 1);
-    uv__stream_open((uv_stream_t*)tty, fd, UV_STREAM_READABLE);
-  } else {
-    /* Note: writable tty we set to blocking mode. */
-    uv__stream_open((uv_stream_t*)tty, fd, UV_STREAM_WRITABLE);
-    tty->flags |= UV_STREAM_BLOCKING;
+  /* Reopen the file descriptor when it refers to a tty. This lets us put the
+   * tty in non-blocking mode without affecting other processes that share it
+   * with us.
+   *
+   * Example: `node | cat` - if we put our fd 0 in non-blocking mode, it also
+   * affects fd 1 of `cat` because both file descriptors refer to the same
+   * struct file in the kernel. When we reopen our fd 0, it points to a
+   * different struct file, hence changing its properties doesn't affect
+   * other processes.
+   */
+  if (isatty(fd)) {
+    newfd = open("/dev/tty", O_RDWR);
+
+    if (newfd == -1)
+      return uv__set_sys_error(loop, errno);
+
+    do
+      r = dup2(newfd, fd);
+    while (r == -1 && (errno == EINTR || errno == EBUSY));
+
+    /* EINVAL means newfd == fd which could conceivably happen if another
+     * thread called close(fd) between our calls to isatty() and open().
+     * That's a rather unlikely event but let's handle it anyway.
+     */
+    if (r == -1 && errno != EINVAL) {
+      close(newfd);
+      return uv__set_sys_error(loop, errno);
+    }
+
+    fd = newfd;
   }
 
+  if (readable)
+    flags = UV_STREAM_READABLE;
+  else
+    flags = UV_STREAM_WRITABLE;
+
+  uv__nonblock(fd, 1);
+  uv__stream_open((uv_stream_t*)tty, fd, flags);
   tty->mode = 0;
+
   return 0;
 }
 
index e9caed9..d4d1c8b 100644 (file)
 
 #include <assert.h>
 #include <stddef.h>
-#include <stdint.h>
+
+#if defined(_MSC_VER) && _MSC_VER < 1600
+# include "uv-private/stdint-msvc2008.h"
+#else
+# include <stdint.h>
+#endif
 
 #include "uv.h"
 #include "tree.h"
@@ -130,34 +135,44 @@ UNUSED static int uv__is_active(const uv_handle_t* h) {
 #define uv__is_active(h) uv__is_active((const uv_handle_t*)(h))
 
 UNUSED static void uv__handle_start(uv_handle_t* h) {
-  if (h->flags & UV__HANDLE_ACTIVE) return;
+  assert(!(h->flags & UV__HANDLE_CLOSING));
+  if (h->flags & UV__HANDLE_ACTIVE)
+    return;
   h->flags |= UV__HANDLE_ACTIVE;
-  if (h->flags & UV__HANDLE_CLOSING) return;
-  if (h->flags & UV__HANDLE_REF) uv__active_handle_add(h);
+  if (h->flags & UV__HANDLE_REF)
+    uv__active_handle_add(h);
 }
 #define uv__handle_start(h) uv__handle_start((uv_handle_t*)(h))
 
 UNUSED static void uv__handle_stop(uv_handle_t* h) {
-  if (!(h->flags & UV__HANDLE_ACTIVE)) return;
+  assert(!(h->flags & UV__HANDLE_CLOSING));
+  if (!(h->flags & UV__HANDLE_ACTIVE))
+    return;
   h->flags &= ~UV__HANDLE_ACTIVE;
-  if (h->flags & UV__HANDLE_CLOSING) return;
-  if (h->flags & UV__HANDLE_REF) uv__active_handle_rm(h);
+  if (h->flags & UV__HANDLE_REF)
+    uv__active_handle_rm(h);
 }
 #define uv__handle_stop(h) uv__handle_stop((uv_handle_t*)(h))
 
 UNUSED static void uv__handle_ref(uv_handle_t* h) {
-  if (h->flags & UV__HANDLE_REF) return;
-  if (h->flags & (UV__HANDLE_ACTIVE | UV__HANDLE_CLOSING))
-    uv__active_handle_add(h);
+  if (h->flags & UV__HANDLE_REF)
+    return;
   h->flags |= UV__HANDLE_REF;
+  if (h->flags & UV__HANDLE_CLOSING)
+    return;
+  if (h->flags & UV__HANDLE_ACTIVE)
+    uv__active_handle_add(h);
 }
 #define uv__handle_ref(h) uv__handle_ref((uv_handle_t*)(h))
 
 UNUSED static void uv__handle_unref(uv_handle_t* h) {
-  if (!(h->flags & UV__HANDLE_REF)) return;
-  if (h->flags & (UV__HANDLE_ACTIVE | UV__HANDLE_CLOSING))
-    uv__active_handle_rm(h);
+  if (!(h->flags & UV__HANDLE_REF))
+    return;
   h->flags &= ~UV__HANDLE_REF;
+  if (h->flags & UV__HANDLE_CLOSING)
+    return;
+  if (h->flags & UV__HANDLE_ACTIVE)
+    uv__active_handle_rm(h);
 }
 #define uv__handle_unref(h) uv__handle_unref((uv_handle_t*)(h))
 
index dde1348..509ea56 100644 (file)
@@ -24,6 +24,7 @@
 #include <limits.h>
 #include <malloc.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
 #include "uv.h"
@@ -40,10 +41,23 @@ static uv_once_t uv_init_guard_ = UV_ONCE_INIT;
 static uv_once_t uv_default_loop_init_guard_ = UV_ONCE_INIT;
 
 
+static void uv__crt_invalid_parameter_handler(const wchar_t* expression,
+    const wchar_t* function, const wchar_t * file, unsigned int line,
+    uintptr_t reserved) {
+  /* No-op. */
+}
+
+
 static void uv_init(void) {
   /* Tell Windows that we will handle critical errors. */
   SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
-    SEM_NOOPENFILEERRORBOX);
+               SEM_NOOPENFILEERRORBOX);
+
+  /* Tell the CRT to not exit the application when an invalid parameter is */
+  /* passed. The main issue is that invalid FDs will trigger this behavior. */
+#ifdef _WRITE_ABORT_MSG
+  _set_invalid_parameter_handler(uv__crt_invalid_parameter_handler);
+#endif
 
   /* Fetch winapi function pointers. This must be done first because other */
   /* intialization code might need these function pointers to be loaded. */
index 4a2d936..9b920c8 100644 (file)
@@ -1137,9 +1137,12 @@ static void fs__utime(uv_fs_t* req) {
 
   if (fs__utime_handle(handle, req->atime, req->mtime) != 0) {
     SET_REQ_WIN32_ERROR(req, GetLastError());
+    CloseHandle(handle);
     return;
   }
 
+  CloseHandle(handle);
+
   req->result = 0;
 }
 
index 159d220..52dfbbc 100644 (file)
 #define uv__handle_closing(handle)                                      \
   do {                                                                  \
     assert(!((handle)->flags & UV__HANDLE_CLOSING));                    \
-    (handle)->flags |= UV__HANDLE_CLOSING;                              \
-    if ((handle)->flags & UV__HANDLE_ACTIVE) {                          \
-      (handle)->flags &= ~UV__HANDLE_ACTIVE;                            \
-    } else if ((handle)->flags & UV__HANDLE_REF) {                      \
+                                                                        \
+    if (!(((handle)->flags & UV__HANDLE_ACTIVE) &&                      \
+          ((handle)->flags & UV__HANDLE_REF)))                          \
       uv__active_handle_add((uv_handle_t*) (handle));                   \
-    }                                                                   \
+                                                                        \
+    (handle)->flags |= UV__HANDLE_CLOSING;                              \
+    (handle)->flags &= ~UV__HANDLE_ACTIVE;                              \
   } while (0)
 
 
 #define uv__handle_close(handle)                                        \
   do {                                                                  \
     ngx_queue_remove(&(handle)->handle_queue);                          \
+    uv__active_handle_rm((uv_handle_t*) (handle));                      \
+                                                                        \
     (handle)->flags |= UV_HANDLE_CLOSED;                                \
-    if (handle->flags & UV__HANDLE_REF) {                               \
-      uv__active_handle_rm((uv_handle_t*) (handle));                    \
-    }                                                                   \
-    if ((handle)->close_cb) {                                           \
+                                                                        \
+    if ((handle)->close_cb)                                             \
       (handle)->close_cb((uv_handle_t*) (handle));                      \
-    }                                                                   \
   } while (0)
 
 
index 6c9ca20..adb66a6 100644 (file)
 #include <assert.h>
 #include <io.h>
 #include <string.h>
-#include <stdint.h>
+
+#if defined(_MSC_VER) && _MSC_VER < 1600
+# include "uv-private/stdint-msvc2008.h"
+#else
+# include <stdint.h>
+#endif
 
 #include "uv.h"
 #include "internal.h"
@@ -1181,6 +1186,7 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) {
     } else if (arg ==  49) {
       /* Default background color */
       bg_color = 0;
+      bg_bright = 0;
 
     } else if (arg >= 90 && arg <= 97) {
       /* Set bold foreground color */
index c838213..49cf442 100644 (file)
@@ -32,14 +32,27 @@ static volatile int done;
 
 
 static void async_cb(uv_async_t* handle, int status) {
-  if (++callbacks == NUM_PINGS)
+  if (++callbacks == NUM_PINGS) {
+    /* Tell the pummel thread to stop. */
+    handle->data = (void*) (intptr_t) 1;
+
+    /* Wait for for the pummel thread to acknowledge that it has stoppped. */
+    while (*(volatile intptr_t*) &handle->data < 2)
+      uv_sleep(0);
+
     uv_close((uv_handle_t*) handle, NULL);
+  }
 }
 
 
 static void pummel(void* arg) {
-  while (!done)
-    uv_async_send((uv_async_t*) arg);
+  uv_async_t* handle = (uv_async_t*) arg;
+
+  while (*(volatile intptr_t*) &handle->data == 0)
+    uv_async_send(handle);
+
+  /* Acknowledge that we've seen handle->data change. */
+  handle->data = (void*) (intptr_t) 2;
 }
 
 
@@ -53,6 +66,7 @@ static int test_async_pummel(int nthreads) {
   ASSERT(tids != NULL);
 
   ASSERT(0 == uv_async_init(uv_default_loop(), &handle, async_cb));
+  handle.data = NULL;
 
   for (i = 0; i < nthreads; i++)
     ASSERT(0 == uv_thread_create(tids + i, pummel, &handle));
index 01f9a94..a41dce6 100644 (file)
@@ -56,6 +56,7 @@ static unsigned int send_cb_called;
 static unsigned int recv_cb_called;
 static unsigned int close_cb_called;
 static int timed;
+static int exiting;
 
 
 static uv_buf_t alloc_cb(uv_handle_t* handle, size_t suggested_size) {
@@ -76,6 +77,9 @@ static void send_cb(uv_udp_send_t* req, int status) {
     return;
   }
 
+  if (exiting)
+    return;
+
   s = container_of(req, struct sender_state, send_req);
   ASSERT(req->handle == &s->udp_handle);
 
@@ -129,6 +133,8 @@ static void close_cb(uv_handle_t* handle) {
 static void timeout_cb(uv_timer_t* timer, int status) {
   int i;
 
+  exiting = 1;
+
   for (i = 0; i < n_senders_; i++)
     uv_close((uv_handle_t*)&senders[i].udp_handle, close_cb);
 
index e06ae64..b351c42 100644 (file)
 
 #include <stdio.h>
 #include <stddef.h>
-#include <stdint.h>
 #include <stdlib.h>
 
+#if defined(_MSC_VER) && _MSC_VER < 1600
+# include "uv-private/stdint-msvc2008.h"
+#else
+# include <stdint.h>
+#endif
+
 #define TEST_PORT 9123
 #define TEST_PORT_2 9124
 
index fa05ca9..9960961 100644 (file)
@@ -112,6 +112,7 @@ TEST_DECLARE   (fs_event_ref)
 TEST_DECLARE   (fs_poll_ref)
 TEST_DECLARE   (tcp_ref)
 TEST_DECLARE   (tcp_ref2)
+TEST_DECLARE   (tcp_ref2b)
 TEST_DECLARE   (tcp_ref3)
 TEST_DECLARE   (tcp_ref4)
 TEST_DECLARE   (udp_ref)
@@ -338,6 +339,7 @@ TASK_LIST_START
   TEST_ENTRY  (fs_event_ref)
   TEST_ENTRY  (tcp_ref)
   TEST_ENTRY  (tcp_ref2)
+  TEST_ENTRY  (tcp_ref2b)
   TEST_ENTRY  (tcp_ref3)
   TEST_HELPER (tcp_ref3, tcp4_echo_server)
   TEST_ENTRY  (tcp_ref4)
index 484608a..bc0030d 100644 (file)
@@ -235,6 +235,26 @@ TEST_IMPL(tcp_ref2) {
 }
 
 
+static void tcp_ref2b_close_cb(uv_handle_t* handle) {
+  (*(int*) handle->data)++;
+}
+
+
+TEST_IMPL(tcp_ref2b) {
+  int close_cb_called = 0;
+  uv_tcp_t h;
+  h.data = &close_cb_called;
+  uv_tcp_init(uv_default_loop(), &h);
+  uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb);
+  uv_unref((uv_handle_t*)&h);
+  uv_close((uv_handle_t*)&h, tcp_ref2b_close_cb);
+  uv_run(uv_default_loop());
+  ASSERT(close_cb_called == 1);
+  MAKE_VALGRIND_HAPPY();
+  return 0;
+}
+
+
 TEST_IMPL(tcp_ref3) {
   struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
   uv_tcp_t h;
index 12e5480..678a910 100644 (file)
@@ -53,7 +53,6 @@ goto select-target
 if not defined VS90COMNTOOLS goto vc-set-notfound
 if not exist "%VS90COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-notfound
 call "%VS90COMNTOOLS%\..\..\vc\vcvarsall.bat" %vs_toolset%
-echo Warning: building with Visual Studio 2008 is currently not supported.
 set GYP_MSVS_VERSION=2008
 goto select-target