diff --git a/deps/uv/LICENSE b/deps/uv/LICENSE index 65296f4b25..8ea2e36cc8 100644 --- a/deps/uv/LICENSE +++ b/deps/uv/LICENSE @@ -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. diff --git a/deps/uv/include/uv-private/ngx-queue.h b/deps/uv/include/uv-private/ngx-queue.h index 4bd66fc12f..3c3ed1b034 100644 --- a/deps/uv/include/uv-private/ngx-queue.h +++ b/deps/uv/include/uv-private/ngx-queue.h @@ -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 index 0000000000..d02608a597 --- /dev/null +++ b/deps/uv/include/uv-private/stdint-msvc2008.h @@ -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 + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap 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 +#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 +#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_ ] diff --git a/deps/uv/include/uv-private/uv-darwin.h b/deps/uv/include/uv-private/uv-darwin.h index 4d68d01321..1ae499c8e6 100644 --- a/deps/uv/include/uv-private/uv-darwin.h +++ b/deps/uv/include/uv-private/uv-darwin.h @@ -26,6 +26,7 @@ # include # include # include +# include # define UV_PLATFORM_SEM_T semaphore_t #endif diff --git a/deps/uv/include/uv-private/uv-win.h b/deps/uv/include/uv-private/uv-win.h index 10bd17ea4c..8c048bef51 100644 --- a/deps/uv/include/uv-private/uv-win.h +++ b/deps/uv/include/uv-private/uv-win.h @@ -36,9 +36,14 @@ typedef intptr_t ssize_t; #include #include -#include #include +#if defined(_MSC_VER) && _MSC_VER < 1600 +# include "uv-private/stdint-msvc2008.h" +#else +# include +#endif + #include "tree.h" #include "ngx-queue.h" diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index 99b69884ea..a7cd572934 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -50,7 +50,12 @@ extern "C" { #define UV_VERSION_MINOR 9 -#include /* int64_t */ +#if defined(_MSC_VER) && _MSC_VER < 1600 +# include "uv-private/stdint-msvc2008.h" +#else +# include +#endif + #include /* size_t */ #if defined(__SVR4) && !defined(__unix__) diff --git a/deps/uv/src/inet.c b/deps/uv/src/inet.c index 293fbf6d21..939a9fa576 100644 --- a/deps/uv/src/inet.c +++ b/deps/uv/src/inet.c @@ -16,9 +16,14 @@ */ #include -#include #include +#if defined(_MSC_VER) && _MSC_VER < 1600 +# include "uv-private/stdint-msvc2008.h" +#else +# include +#endif + #include "uv.h" #include "uv-common.h" diff --git a/deps/uv/src/unix/darwin.c b/deps/uv/src/unix/darwin.c index 675a4f6d9c..2b9da40bd6 100644 --- a/deps/uv/src/unix/darwin.c +++ b/deps/uv/src/unix/darwin.c @@ -28,11 +28,7 @@ #include #include -#include - -#if !TARGET_OS_IPHONE -#include -#endif +#include #include #include diff --git a/deps/uv/src/unix/fsevents.c b/deps/uv/src/unix/fsevents.c index ac58d4f18e..02565f3a1d 100644 --- a/deps/uv/src/unix/fsevents.c +++ b/deps/uv/src/unix/fsevents.c @@ -21,6 +21,21 @@ #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 #include #include @@ -278,3 +293,5 @@ int uv__fsevents_close(uv_fs_event_t* handle) { return 0; } + +#endif /* TARGET_OS_IPHONE */ diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h index 93e99b8da2..c418038f6e 100644 --- a/deps/uv/src/unix/internal.h +++ b/deps/uv/src/unix/internal.h @@ -62,7 +62,7 @@ # define HAVE_KQUEUE 1 #endif -#if defined(__APPLE__) && !defined(TARGET_OS_IPHONE) +#if defined(__APPLE__) && !TARGET_OS_IPHONE # include #endif diff --git a/deps/uv/src/unix/linux/linux-core.c b/deps/uv/src/unix/linux/linux-core.c index a773b0794d..e92869e3b0 100644 --- a/deps/uv/src/unix/linux/linux-core.c +++ b/deps/uv/src/unix/linux/linux-core.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -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); } diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c index 7c552a7361..79a8b6d777 100644 --- a/deps/uv/src/unix/process.c +++ b/deps/uv/src/unix/process.c @@ -33,10 +33,6 @@ #include #include -#ifdef __APPLE__ -# include -#endif - #if defined(__APPLE__) && !TARGET_OS_IPHONE # include # 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)) { diff --git a/deps/uv/src/unix/tty.c b/deps/uv/src/unix/tty.c index 3ef9064a10..aa42c20532 100644 --- a/deps/uv/src/unix/tty.c +++ b/deps/uv/src/unix/tty.c @@ -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; } diff --git a/deps/uv/src/uv-common.h b/deps/uv/src/uv-common.h index e9caed9af0..d4d1c8b277 100644 --- a/deps/uv/src/uv-common.h +++ b/deps/uv/src/uv-common.h @@ -29,7 +29,12 @@ #include #include -#include + +#if defined(_MSC_VER) && _MSC_VER < 1600 +# include "uv-private/stdint-msvc2008.h" +#else +# include +#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)) diff --git a/deps/uv/src/win/core.c b/deps/uv/src/win/core.c index dde1348ab7..509ea563f1 100644 --- a/deps/uv/src/win/core.c +++ b/deps/uv/src/win/core.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #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. */ diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c index 4a2d93624d..9b920c817a 100644 --- a/deps/uv/src/win/fs.c +++ b/deps/uv/src/win/fs.c @@ -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; } diff --git a/deps/uv/src/win/handle-inl.h b/deps/uv/src/win/handle-inl.h index 159d2208bb..52dfbbc1ab 100644 --- a/deps/uv/src/win/handle-inl.h +++ b/deps/uv/src/win/handle-inl.h @@ -62,25 +62,25 @@ #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) diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c index 6c9ca20550..adb66a62e5 100644 --- a/deps/uv/src/win/tty.c +++ b/deps/uv/src/win/tty.c @@ -22,7 +22,12 @@ #include #include #include -#include + +#if defined(_MSC_VER) && _MSC_VER < 1600 +# include "uv-private/stdint-msvc2008.h" +#else +# include +#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 */ diff --git a/deps/uv/test/benchmark-async-pummel.c b/deps/uv/test/benchmark-async-pummel.c index c83821322e..49cf442b08 100644 --- a/deps/uv/test/benchmark-async-pummel.c +++ b/deps/uv/test/benchmark-async-pummel.c @@ -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)); diff --git a/deps/uv/test/benchmark-udp-pummel.c b/deps/uv/test/benchmark-udp-pummel.c index 01f9a948dc..a41dce642f 100644 --- a/deps/uv/test/benchmark-udp-pummel.c +++ b/deps/uv/test/benchmark-udp-pummel.c @@ -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); diff --git a/deps/uv/test/task.h b/deps/uv/test/task.h index e06ae6470c..b351c423be 100644 --- a/deps/uv/test/task.h +++ b/deps/uv/test/task.h @@ -24,9 +24,14 @@ #include #include -#include #include +#if defined(_MSC_VER) && _MSC_VER < 1600 +# include "uv-private/stdint-msvc2008.h" +#else +# include +#endif + #define TEST_PORT 9123 #define TEST_PORT_2 9124 diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index fa05ca931e..99609617fa 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -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) diff --git a/deps/uv/test/test-ref.c b/deps/uv/test/test-ref.c index 484608acd8..bc0030d34a 100644 --- a/deps/uv/test/test-ref.c +++ b/deps/uv/test/test-ref.c @@ -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; diff --git a/deps/uv/vcbuild.bat b/deps/uv/vcbuild.bat index 12e5480aea..678a910714 100644 --- a/deps/uv/vcbuild.bat +++ b/deps/uv/vcbuild.bat @@ -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