ext/libuv/src/uv-common.c in libuv-0.11.3 vs ext/libuv/src/uv-common.c in libuv-0.11.4
- old
+ new
@@ -1,440 +1,449 @@
-/* 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.
- */
-
-/* Expose glibc-specific EAI_* error codes. Needs to be defined before we
- * include any headers.
- */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE
-#endif
-
-#include "uv.h"
-#include "uv-common.h"
-
-#include <stdio.h>
-#include <assert.h>
-#include <stddef.h> /* NULL */
-#include <stdlib.h> /* malloc */
-#include <string.h> /* memset */
-
-#if defined(UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS) && !defined(_WIN32)
-# include <net/if.h> /* if_nametoindex */
-#endif
-
-/* EAI_* constants. */
-#if !defined(_WIN32)
-# include <sys/types.h>
-# include <sys/socket.h>
-# include <netdb.h>
-#endif
-
-#define XX(uc, lc) case UV_##uc: return sizeof(uv_##lc##_t);
-
-size_t uv_handle_size(uv_handle_type type) {
- switch (type) {
- UV_HANDLE_TYPE_MAP(XX)
- default:
- return -1;
- }
-}
-
-size_t uv_req_size(uv_req_type type) {
- switch(type) {
- UV_REQ_TYPE_MAP(XX)
- default:
- return -1;
- }
-}
-
-#undef XX
-
-
-uv_buf_t uv_buf_init(char* base, unsigned int len) {
- uv_buf_t buf;
- buf.base = base;
- buf.len = len;
- return buf;
-}
-
-
-#define UV_ERR_NAME_GEN(name, _) case UV_ ## name: return #name;
-const char* uv_err_name(int err) {
- switch (err) {
- UV_ERRNO_MAP(UV_ERR_NAME_GEN)
- default:
- assert(0);
- return NULL;
- }
-}
-#undef UV_ERR_NAME_GEN
-
-
-#define UV_STRERROR_GEN(name, msg) case UV_ ## name: return msg;
-const char* uv_strerror(int err) {
- switch (err) {
- UV_ERRNO_MAP(UV_STRERROR_GEN)
- default:
- return "Unknown system error";
- }
-}
-#undef UV_STRERROR_GEN
-
-
-int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr) {
- memset(addr, 0, sizeof(*addr));
- addr->sin_family = AF_INET;
- addr->sin_port = htons(port);
- /* TODO(bnoordhuis) Don't use inet_addr(), no good way to detect errors. */
- addr->sin_addr.s_addr = inet_addr(ip);
- return 0;
-}
-
-
-int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr) {
-#if defined(UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS)
- char address_part[40];
- size_t address_part_size;
- const char* zone_index;
-#endif
-
- memset(addr, 0, sizeof(*addr));
- addr->sin6_family = AF_INET6;
- addr->sin6_port = htons(port);
-
-#if defined(UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS)
- zone_index = strchr(ip, '%');
- if (zone_index != NULL) {
- address_part_size = zone_index - ip;
- if (address_part_size >= sizeof(address_part))
- address_part_size = sizeof(address_part) - 1;
-
- memcpy(address_part, ip, address_part_size);
- address_part[address_part_size] = '\0';
- ip = address_part;
-
- zone_index++; /* skip '%' */
- /* NOTE: unknown interface (id=0) is silently ignored */
-#ifdef _WIN32
- addr->sin6_scope_id = atoi(zone_index);
-#else
- addr->sin6_scope_id = if_nametoindex(zone_index);
-#endif
- }
-#endif
-
- /* TODO(bnoordhuis) Return an error when the address is bad. */
- uv_inet_pton(AF_INET6, ip, &addr->sin6_addr);
-
- return 0;
-}
-
-
-int uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size) {
- return uv_inet_ntop(AF_INET, &src->sin_addr, dst, size);
-}
-
-
-int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size) {
- return uv_inet_ntop(AF_INET6, &src->sin6_addr, dst, size);
-}
-
-
-int uv_tcp_bind(uv_tcp_t* handle, const struct sockaddr* addr) {
- unsigned int addrlen;
-
- if (handle->type != UV_TCP)
- return UV_EINVAL;
-
- if (addr->sa_family == AF_INET)
- addrlen = sizeof(struct sockaddr_in);
- else if (addr->sa_family == AF_INET6)
- addrlen = sizeof(struct sockaddr_in6);
- else
- return UV_EINVAL;
-
- return uv__tcp_bind(handle, addr, addrlen);
-}
-
-
-int uv_udp_bind(uv_udp_t* handle,
- const struct sockaddr* addr,
- unsigned int flags) {
- unsigned int addrlen;
-
- if (handle->type != UV_UDP)
- return UV_EINVAL;
-
- if (addr->sa_family == AF_INET)
- addrlen = sizeof(struct sockaddr_in);
- else if (addr->sa_family == AF_INET6)
- addrlen = sizeof(struct sockaddr_in6);
- else
- return UV_EINVAL;
-
- return uv__udp_bind(handle, addr, addrlen, flags);
-}
-
-
-int uv_tcp_connect(uv_connect_t* req,
- uv_tcp_t* handle,
- const struct sockaddr* addr,
- uv_connect_cb cb) {
- unsigned int addrlen;
-
- if (handle->type != UV_TCP)
- return UV_EINVAL;
-
- if (addr->sa_family == AF_INET)
- addrlen = sizeof(struct sockaddr_in);
- else if (addr->sa_family == AF_INET6)
- addrlen = sizeof(struct sockaddr_in6);
- else
- return UV_EINVAL;
-
- return uv__tcp_connect(req, handle, addr, addrlen, cb);
-}
-
-
-int uv_udp_send(uv_udp_send_t* req,
- uv_udp_t* handle,
- const uv_buf_t bufs[],
- unsigned int nbufs,
- const struct sockaddr* addr,
- uv_udp_send_cb send_cb) {
- unsigned int addrlen;
-
- if (handle->type != UV_UDP)
- return UV_EINVAL;
-
- if (addr->sa_family == AF_INET)
- addrlen = sizeof(struct sockaddr_in);
- else if (addr->sa_family == AF_INET6)
- addrlen = sizeof(struct sockaddr_in6);
- else
- return UV_EINVAL;
-
- return uv__udp_send(req, handle, bufs, nbufs, addr, addrlen, send_cb);
-}
-
-
-int uv_udp_recv_start(uv_udp_t* handle,
- uv_alloc_cb alloc_cb,
- uv_udp_recv_cb recv_cb) {
- if (handle->type != UV_UDP || alloc_cb == NULL || recv_cb == NULL)
- return UV_EINVAL;
- else
- return uv__udp_recv_start(handle, alloc_cb, recv_cb);
-}
-
-
-int uv_udp_recv_stop(uv_udp_t* handle) {
- if (handle->type != UV_UDP)
- return UV_EINVAL;
- else
- return uv__udp_recv_stop(handle);
-}
-
-
-struct thread_ctx {
- void (*entry)(void* arg);
- void* arg;
-};
-
-
-#ifdef _WIN32
-static UINT __stdcall uv__thread_start(void* arg)
-#else
-static void* uv__thread_start(void *arg)
-#endif
-{
- struct thread_ctx *ctx_p;
- struct thread_ctx ctx;
-
- ctx_p = arg;
- ctx = *ctx_p;
- free(ctx_p);
- ctx.entry(ctx.arg);
-
- return 0;
-}
-
-
-int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
- struct thread_ctx* ctx;
- int err;
-
- ctx = malloc(sizeof(*ctx));
- if (ctx == NULL)
- return UV_ENOMEM;
-
- ctx->entry = entry;
- ctx->arg = arg;
-
-#ifdef _WIN32
- *tid = (HANDLE) _beginthreadex(NULL, 0, uv__thread_start, ctx, 0, NULL);
- err = *tid ? 0 : errno;
-#else
- err = pthread_create(tid, NULL, uv__thread_start, ctx);
-#endif
-
- if (err)
- free(ctx);
-
- return err ? -1 : 0;
-}
-
-
-unsigned long uv_thread_self(void) {
-#ifdef _WIN32
- return (unsigned long) GetCurrentThreadId();
-#else
- return (unsigned long) pthread_self();
-#endif
-}
-
-
-void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) {
- QUEUE* q;
- uv_handle_t* h;
-
- QUEUE_FOREACH(q, &loop->handle_queue) {
- h = QUEUE_DATA(q, uv_handle_t, handle_queue);
- if (h->flags & UV__HANDLE_INTERNAL) continue;
- walk_cb(h, arg);
- }
-}
-
-
-#ifndef NDEBUG
-static void uv__print_handles(uv_loop_t* loop, int only_active) {
- const char* type;
- QUEUE* q;
- uv_handle_t* h;
-
- if (loop == NULL)
- loop = uv_default_loop();
-
- QUEUE_FOREACH(q, &loop->handle_queue) {
- h = QUEUE_DATA(q, uv_handle_t, handle_queue);
-
- if (only_active && !uv__is_active(h))
- continue;
-
- switch (h->type) {
-#define X(uc, lc) case UV_##uc: type = #lc; break;
- UV_HANDLE_TYPE_MAP(X)
-#undef X
- default: type = "<unknown>";
- }
-
- fprintf(stderr,
- "[%c%c%c] %-8s %p\n",
- "R-"[!(h->flags & UV__HANDLE_REF)],
- "A-"[!(h->flags & UV__HANDLE_ACTIVE)],
- "I-"[!(h->flags & UV__HANDLE_INTERNAL)],
- type,
- (void*)h);
- }
-}
-
-
-void uv_print_all_handles(uv_loop_t* loop) {
- uv__print_handles(loop, 0);
-}
-
-
-void uv_print_active_handles(uv_loop_t* loop) {
- uv__print_handles(loop, 1);
-}
-#endif
-
-
-void uv_ref(uv_handle_t* handle) {
- uv__handle_ref(handle);
-}
-
-
-void uv_unref(uv_handle_t* handle) {
- uv__handle_unref(handle);
-}
-
-
-int uv_has_ref(const uv_handle_t* handle) {
- return uv__has_ref(handle);
-}
-
-
-void uv_stop(uv_loop_t* loop) {
- loop->stop_flag = 1;
-}
-
-
-uint64_t uv_now(uv_loop_t* loop) {
- return loop->time;
-}
-
-
-int uv__getaddrinfo_translate_error(int sys_err) {
- switch (sys_err) {
- case 0: return 0;
-#if defined(EAI_ADDRFAMILY)
- case EAI_ADDRFAMILY: return UV_EAI_ADDRFAMILY;
-#endif
-#if defined(EAI_AGAIN)
- case EAI_AGAIN: return UV_EAI_AGAIN;
-#endif
-#if defined(EAI_BADFLAGS)
- case EAI_BADFLAGS: return UV_EAI_BADFLAGS;
-#endif
-#if defined(EAI_CANCELED)
- case EAI_CANCELED: return UV_EAI_CANCELED;
-#endif
-#if defined(EAI_FAIL)
- case EAI_FAIL: return UV_EAI_FAIL;
-#endif
-#if defined(EAI_FAMILY)
- case EAI_FAMILY: return UV_EAI_FAMILY;
-#endif
-#if defined(EAI_MEMORY)
- case EAI_MEMORY: return UV_EAI_MEMORY;
-#endif
-#if defined(EAI_NODATA)
- case EAI_NODATA: return UV_EAI_NODATA;
-#endif
-#if defined(EAI_NONAME)
-# if !defined(EAI_NODATA) || EAI_NODATA != EAI_NONAME
- case EAI_NONAME: return UV_EAI_NONAME;
-# endif
-#endif
-#if defined(EAI_SERVICE)
- case EAI_SERVICE: return UV_EAI_SERVICE;
-#endif
-#if defined(EAI_SOCKTYPE)
- case EAI_SOCKTYPE: return UV_EAI_SOCKTYPE;
-#endif
-#if defined(EAI_SYSTEM)
- case EAI_SYSTEM: return UV_EAI_SYSTEM;
-#endif
- }
- assert(!"unknown EAI_* error code");
- abort();
- return 0; /* Pacify compiler. */
-}
+/* 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.
+ */
+
+/* Expose glibc-specific EAI_* error codes. Needs to be defined before we
+ * include any headers.
+ */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+
+#include "uv.h"
+#include "uv-common.h"
+
+#include <stdio.h>
+#include <assert.h>
+#include <stddef.h> /* NULL */
+#include <stdlib.h> /* malloc */
+#include <string.h> /* memset */
+
+#if defined(UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS) && !defined(_WIN32)
+# include <net/if.h> /* if_nametoindex */
+#endif
+
+/* EAI_* constants. */
+#if !defined(_WIN32)
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netdb.h>
+#endif
+
+#define XX(uc, lc) case UV_##uc: return sizeof(uv_##lc##_t);
+
+size_t uv_handle_size(uv_handle_type type) {
+ switch (type) {
+ UV_HANDLE_TYPE_MAP(XX)
+ default:
+ return -1;
+ }
+}
+
+size_t uv_req_size(uv_req_type type) {
+ switch(type) {
+ UV_REQ_TYPE_MAP(XX)
+ default:
+ return -1;
+ }
+}
+
+#undef XX
+
+
+uv_buf_t uv_buf_init(char* base, unsigned int len) {
+ uv_buf_t buf;
+ buf.base = base;
+ buf.len = len;
+ return buf;
+}
+
+
+#define UV_ERR_NAME_GEN(name, _) case UV_ ## name: return #name;
+const char* uv_err_name(int err) {
+ switch (err) {
+ UV_ERRNO_MAP(UV_ERR_NAME_GEN)
+ default:
+ assert(0);
+ return NULL;
+ }
+}
+#undef UV_ERR_NAME_GEN
+
+
+#define UV_STRERROR_GEN(name, msg) case UV_ ## name: return msg;
+const char* uv_strerror(int err) {
+ switch (err) {
+ UV_ERRNO_MAP(UV_STRERROR_GEN)
+ default:
+ return "Unknown system error";
+ }
+}
+#undef UV_STRERROR_GEN
+
+
+int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr) {
+ memset(addr, 0, sizeof(*addr));
+ addr->sin_family = AF_INET;
+ addr->sin_port = htons(port);
+ /* TODO(bnoordhuis) Don't use inet_addr(), no good way to detect errors. */
+ addr->sin_addr.s_addr = inet_addr(ip);
+ return 0;
+}
+
+
+int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr) {
+#if defined(UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS)
+ char address_part[40];
+ size_t address_part_size;
+ const char* zone_index;
+#endif
+
+ memset(addr, 0, sizeof(*addr));
+ addr->sin6_family = AF_INET6;
+ addr->sin6_port = htons(port);
+
+#if defined(UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS)
+ zone_index = strchr(ip, '%');
+ if (zone_index != NULL) {
+ address_part_size = zone_index - ip;
+ if (address_part_size >= sizeof(address_part))
+ address_part_size = sizeof(address_part) - 1;
+
+ memcpy(address_part, ip, address_part_size);
+ address_part[address_part_size] = '\0';
+ ip = address_part;
+
+ zone_index++; /* skip '%' */
+ /* NOTE: unknown interface (id=0) is silently ignored */
+#ifdef _WIN32
+ addr->sin6_scope_id = atoi(zone_index);
+#else
+ addr->sin6_scope_id = if_nametoindex(zone_index);
+#endif
+ }
+#endif
+
+ /* TODO(bnoordhuis) Return an error when the address is bad. */
+ uv_inet_pton(AF_INET6, ip, &addr->sin6_addr);
+
+ return 0;
+}
+
+
+int uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size) {
+ return uv_inet_ntop(AF_INET, &src->sin_addr, dst, size);
+}
+
+
+int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size) {
+ return uv_inet_ntop(AF_INET6, &src->sin6_addr, dst, size);
+}
+
+
+int uv_tcp_bind(uv_tcp_t* handle, const struct sockaddr* addr) {
+ unsigned int addrlen;
+
+ if (handle->type != UV_TCP)
+ return UV_EINVAL;
+
+ if (addr->sa_family == AF_INET)
+ addrlen = sizeof(struct sockaddr_in);
+ else if (addr->sa_family == AF_INET6)
+ addrlen = sizeof(struct sockaddr_in6);
+ else
+ return UV_EINVAL;
+
+ return uv__tcp_bind(handle, addr, addrlen);
+}
+
+
+int uv_udp_bind(uv_udp_t* handle,
+ const struct sockaddr* addr,
+ unsigned int flags) {
+ unsigned int addrlen;
+
+ if (handle->type != UV_UDP)
+ return UV_EINVAL;
+
+ if (addr->sa_family == AF_INET)
+ addrlen = sizeof(struct sockaddr_in);
+ else if (addr->sa_family == AF_INET6)
+ addrlen = sizeof(struct sockaddr_in6);
+ else
+ return UV_EINVAL;
+
+ return uv__udp_bind(handle, addr, addrlen, flags);
+}
+
+
+int uv_tcp_connect(uv_connect_t* req,
+ uv_tcp_t* handle,
+ const struct sockaddr* addr,
+ uv_connect_cb cb) {
+ unsigned int addrlen;
+
+ if (handle->type != UV_TCP)
+ return UV_EINVAL;
+
+ if (addr->sa_family == AF_INET)
+ addrlen = sizeof(struct sockaddr_in);
+ else if (addr->sa_family == AF_INET6)
+ addrlen = sizeof(struct sockaddr_in6);
+ else
+ return UV_EINVAL;
+
+ return uv__tcp_connect(req, handle, addr, addrlen, cb);
+}
+
+
+int uv_udp_send(uv_udp_send_t* req,
+ uv_udp_t* handle,
+ const uv_buf_t bufs[],
+ unsigned int nbufs,
+ const struct sockaddr* addr,
+ uv_udp_send_cb send_cb) {
+ unsigned int addrlen;
+
+ if (handle->type != UV_UDP)
+ return UV_EINVAL;
+
+ if (addr->sa_family == AF_INET)
+ addrlen = sizeof(struct sockaddr_in);
+ else if (addr->sa_family == AF_INET6)
+ addrlen = sizeof(struct sockaddr_in6);
+ else
+ return UV_EINVAL;
+
+ return uv__udp_send(req, handle, bufs, nbufs, addr, addrlen, send_cb);
+}
+
+
+int uv_udp_recv_start(uv_udp_t* handle,
+ uv_alloc_cb alloc_cb,
+ uv_udp_recv_cb recv_cb) {
+ if (handle->type != UV_UDP || alloc_cb == NULL || recv_cb == NULL)
+ return UV_EINVAL;
+ else
+ return uv__udp_recv_start(handle, alloc_cb, recv_cb);
+}
+
+
+int uv_udp_recv_stop(uv_udp_t* handle) {
+ if (handle->type != UV_UDP)
+ return UV_EINVAL;
+ else
+ return uv__udp_recv_stop(handle);
+}
+
+
+struct thread_ctx {
+ void (*entry)(void* arg);
+ void* arg;
+};
+
+
+#ifdef _WIN32
+static UINT __stdcall uv__thread_start(void* arg)
+#else
+static void* uv__thread_start(void *arg)
+#endif
+{
+ struct thread_ctx *ctx_p;
+ struct thread_ctx ctx;
+
+ ctx_p = arg;
+ ctx = *ctx_p;
+ free(ctx_p);
+ ctx.entry(ctx.arg);
+
+ return 0;
+}
+
+
+int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
+ struct thread_ctx* ctx;
+ int err;
+
+ ctx = malloc(sizeof(*ctx));
+ if (ctx == NULL)
+ return UV_ENOMEM;
+
+ ctx->entry = entry;
+ ctx->arg = arg;
+
+#ifdef _WIN32
+ *tid = (HANDLE) _beginthreadex(NULL, 0, uv__thread_start, ctx, 0, NULL);
+ err = *tid ? 0 : errno;
+#else
+ err = pthread_create(tid, NULL, uv__thread_start, ctx);
+#endif
+
+ if (err)
+ free(ctx);
+
+ return err ? -1 : 0;
+}
+
+
+unsigned long uv_thread_self(void) {
+#ifdef _WIN32
+ return (unsigned long) GetCurrentThreadId();
+#else
+ return (unsigned long) pthread_self();
+#endif
+}
+
+
+void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) {
+ QUEUE* q;
+ uv_handle_t* h;
+
+ QUEUE_FOREACH(q, &loop->handle_queue) {
+ h = QUEUE_DATA(q, uv_handle_t, handle_queue);
+ if (h->flags & UV__HANDLE_INTERNAL) continue;
+ walk_cb(h, arg);
+ }
+}
+
+
+#ifndef NDEBUG
+static void uv__print_handles(uv_loop_t* loop, int only_active) {
+ const char* type;
+ QUEUE* q;
+ uv_handle_t* h;
+
+ if (loop == NULL)
+ loop = uv_default_loop();
+
+ QUEUE_FOREACH(q, &loop->handle_queue) {
+ h = QUEUE_DATA(q, uv_handle_t, handle_queue);
+
+ if (only_active && !uv__is_active(h))
+ continue;
+
+ switch (h->type) {
+#define X(uc, lc) case UV_##uc: type = #lc; break;
+ UV_HANDLE_TYPE_MAP(X)
+#undef X
+ default: type = "<unknown>";
+ }
+
+ fprintf(stderr,
+ "[%c%c%c] %-8s %p\n",
+ "R-"[!(h->flags & UV__HANDLE_REF)],
+ "A-"[!(h->flags & UV__HANDLE_ACTIVE)],
+ "I-"[!(h->flags & UV__HANDLE_INTERNAL)],
+ type,
+ (void*)h);
+ }
+}
+
+
+void uv_print_all_handles(uv_loop_t* loop) {
+ uv__print_handles(loop, 0);
+}
+
+
+void uv_print_active_handles(uv_loop_t* loop) {
+ uv__print_handles(loop, 1);
+}
+#endif
+
+
+void uv_ref(uv_handle_t* handle) {
+ uv__handle_ref(handle);
+}
+
+
+void uv_unref(uv_handle_t* handle) {
+ uv__handle_unref(handle);
+}
+
+
+int uv_has_ref(const uv_handle_t* handle) {
+ return uv__has_ref(handle);
+}
+
+
+void uv_stop(uv_loop_t* loop) {
+ loop->stop_flag = 1;
+}
+
+
+uint64_t uv_now(uv_loop_t* loop) {
+ return loop->time;
+}
+
+
+int uv__getaddrinfo_translate_error(int sys_err) {
+ switch (sys_err) {
+ case 0: return 0;
+#if defined(EAI_ADDRFAMILY)
+ case EAI_ADDRFAMILY: return UV_EAI_ADDRFAMILY;
+#endif
+#if defined(EAI_AGAIN)
+ case EAI_AGAIN: return UV_EAI_AGAIN;
+#endif
+#if defined(EAI_BADFLAGS)
+ case EAI_BADFLAGS: return UV_EAI_BADFLAGS;
+#endif
+#if defined(EAI_BADHINTS)
+ case EAI_BADHINTS: return UV_EAI_BADHINTS;
+#endif
+#if defined(EAI_CANCELED)
+ case EAI_CANCELED: return UV_EAI_CANCELED;
+#endif
+#if defined(EAI_FAIL)
+ case EAI_FAIL: return UV_EAI_FAIL;
+#endif
+#if defined(EAI_FAMILY)
+ case EAI_FAMILY: return UV_EAI_FAMILY;
+#endif
+#if defined(EAI_MEMORY)
+ case EAI_MEMORY: return UV_EAI_MEMORY;
+#endif
+#if defined(EAI_NODATA)
+ case EAI_NODATA: return UV_EAI_NODATA;
+#endif
+#if defined(EAI_NONAME)
+# if !defined(EAI_NODATA) || EAI_NODATA != EAI_NONAME
+ case EAI_NONAME: return UV_EAI_NONAME;
+# endif
+#endif
+#if defined(EAI_OVERFLOW)
+ case EAI_OVERFLOW: return UV_EAI_OVERFLOW;
+#endif
+#if defined(EAI_PROTOCOL)
+ case EAI_PROTOCOL: return UV_EAI_PROTOCOL;
+#endif
+#if defined(EAI_SERVICE)
+ case EAI_SERVICE: return UV_EAI_SERVICE;
+#endif
+#if defined(EAI_SOCKTYPE)
+ case EAI_SOCKTYPE: return UV_EAI_SOCKTYPE;
+#endif
+#if defined(EAI_SYSTEM)
+ case EAI_SYSTEM: return UV_EAI_SYSTEM;
+#endif
+ }
+ assert(!"unknown EAI_* error code");
+ abort();
+ return 0; /* Pacify compiler. */
+}