- 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.
#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))
--- /dev/null
+// 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_ ]
# include <mach/mach.h>
# include <mach/task.h>
# include <mach/semaphore.h>
+# include <TargetConditionals.h>
# define UV_PLATFORM_SEM_T semaphore_t
#endif
#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"
#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__)
*/
#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"
#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>
#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>
return 0;
}
+
+#endif /* TARGET_OS_IPHONE */
# define HAVE_KQUEUE 1
#endif
-#if defined(__APPLE__) && !defined(TARGET_OS_IPHONE)
+#if defined(__APPLE__) && !TARGET_OS_IPHONE
# include <CoreServices/CoreServices.h>
#endif
#include <net/if.h>
#include <sys/param.h>
+#include <sys/prctl.h>
#include <sys/sysinfo.h>
#include <unistd.h>
#include <fcntl.h>
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_;
}
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;
}
+/* 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;
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);
}
#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())
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);
}
}
- 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)) {
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;
}
#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"
#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))
#include <limits.h>
#include <malloc.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "uv.h"
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. */
if (fs__utime_handle(handle, req->atime, req->mtime) != 0) {
SET_REQ_WIN32_ERROR(req, GetLastError());
+ CloseHandle(handle);
return;
}
+ CloseHandle(handle);
+
req->result = 0;
}
#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)
#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"
} else if (arg == 49) {
/* Default background color */
bg_color = 0;
+ bg_bright = 0;
} else if (arg >= 90 && arg <= 97) {
/* Set bold foreground color */
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;
}
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));
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) {
return;
}
+ if (exiting)
+ return;
+
s = container_of(req, struct sender_state, send_req);
ASSERT(req->handle == &s->udp_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);
#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
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)
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)
}
+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;
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