about summary refs log tree commit diff
path: root/src/rt/libuv/include
diff options
context:
space:
mode:
authorErick Tryzelaar <erick.tryzelaar@gmail.com>2011-11-07 21:38:33 -0800
committerErick Tryzelaar <erick.tryzelaar@gmail.com>2011-11-07 21:38:33 -0800
commita727bbaf70792b0a4315a95ef00ea911d7852be6 (patch)
treece45614b33228690d30743fd343fe56c29b2236c /src/rt/libuv/include
parente8519b5b2f683ee9e81f8c50ddb23eee5def08fa (diff)
downloadrust-a727bbaf70792b0a4315a95ef00ea911d7852be6.tar.gz
rust-a727bbaf70792b0a4315a95ef00ea911d7852be6.zip
Revert "Removing the baked in libuv."
This reverts commit df30663fdd518c9148a839a40cb9682015a0b79c.
Diffstat (limited to 'src/rt/libuv/include')
-rw-r--r--src/rt/libuv/include/ares.h591
-rw-r--r--src/rt/libuv/include/ares_version.h24
-rw-r--r--src/rt/libuv/include/uv-private/eio.h376
-rw-r--r--src/rt/libuv/include/uv-private/ev.h836
-rw-r--r--src/rt/libuv/include/uv-private/ngx-queue.h102
-rw-r--r--src/rt/libuv/include/uv-private/tree.h762
-rw-r--r--src/rt/libuv/include/uv-private/uv-unix.h219
-rw-r--r--src/rt/libuv/include/uv-private/uv-win.h422
-rw-r--r--src/rt/libuv/include/uv.h1317
9 files changed, 4649 insertions, 0 deletions
diff --git a/src/rt/libuv/include/ares.h b/src/rt/libuv/include/ares.h
new file mode 100644
index 00000000000..53ac861b2ce
--- /dev/null
+++ b/src/rt/libuv/include/ares.h
@@ -0,0 +1,591 @@
+
+/* Copyright 1998, 2009 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2007-2011 by Daniel Stenberg
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#ifndef ARES__H
+#define ARES__H
+
+#include "ares_version.h"  /* c-ares version defines   */
+
+/*
+ * Define WIN32 when build target is Win32 API
+ */
+
+#if (defined(_WIN32) || defined(__WIN32__)) && \
+   !defined(WIN32) && !defined(__SYMBIAN32__)
+#  define WIN32
+#endif
+
+/*************************** libuv patch ***************/
+
+/*
+ * We want to avoid autoconf altogether since there are a finite number of
+ * operating systems and simply build c-ares. Therefore we do not want the
+ * configurations provided by ares_build.h since we are always statically
+ * linking c-ares into libuv. Having a system dependent ares_build.h forces
+ * all users of ares.h to include the correct ares_build.h.  We do not care
+ * about the linking checks provided by ares_rules.h. This would complicate
+ * the libuv build process.
+ */
+
+
+#if defined(WIN32)
+/* Configure process defines this to 1 when it finds out that system  */
+/* header file ws2tcpip.h must be included by the external interface. */
+/* #undef CARES_PULL_WS2TCPIP_H */
+# include <winsock2.h>
+# include <ws2tcpip.h>
+# include <windows.h>
+
+#else /* Not Windows */
+
+# include <sys/time.h>
+# include <sys/types.h>
+# include <sys/socket.h>
+#endif
+
+#if 0
+/* The size of `long', as computed by sizeof. */
+#define CARES_SIZEOF_LONG 4
+#endif
+
+/* Integral data type used for ares_socklen_t. */
+#define CARES_TYPEOF_ARES_SOCKLEN_T socklen_t
+
+#if 0
+/* The size of `ares_socklen_t', as computed by sizeof. */
+#define CARES_SIZEOF_ARES_SOCKLEN_T 4
+#endif
+
+/* Data type definition of ares_socklen_t. */
+typedef int ares_socklen_t;
+
+#if 0 /* libuv disabled */
+#include "ares_rules.h"    /* c-ares rules enforcement */
+#endif
+
+/*********************** end libuv patch ***************/
+
+#include <sys/types.h>
+
+/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
+   libc5-based Linux systems. Only include it on system that are known to
+   require it! */
+#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
+    defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY)
+#include <sys/select.h>
+#endif
+#if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
+#include <sys/bsdskt.h>
+#endif
+
+#if defined(WATT32)
+#  include <netinet/in.h>
+#  include <sys/socket.h>
+#  include <tcp.h>
+#elif defined(_WIN32_WCE)
+#  ifndef WIN32_LEAN_AND_MEAN
+#    define WIN32_LEAN_AND_MEAN
+#  endif
+#  include <windows.h>
+#  include <winsock.h>
+#elif defined(WIN32)
+#  ifndef WIN32_LEAN_AND_MEAN
+#    define WIN32_LEAN_AND_MEAN
+#  endif
+#  include <windows.h>
+#  include <winsock2.h>
+#  include <ws2tcpip.h>
+#else
+#  include <sys/socket.h>
+#  include <netinet/in.h>
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+** c-ares external API function linkage decorations.
+*/
+
+#if !defined(CARES_STATICLIB) && \
+   (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__))
+   /* __declspec function decoration for Win32 and Symbian DLL's */
+#  if defined(CARES_BUILDING_LIBRARY)
+#    define CARES_EXTERN  __declspec(dllexport)
+#  else
+#    define CARES_EXTERN  __declspec(dllimport)
+#  endif
+#else
+   /* visibility function decoration for other cases */
+#  if !defined(CARES_SYMBOL_HIDING) || \
+     defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)
+#    define CARES_EXTERN
+#  else
+#    define CARES_EXTERN CARES_SYMBOL_SCOPE_EXTERN
+#  endif
+#endif
+
+
+#define ARES_SUCCESS            0
+
+/* Server error codes (ARES_ENODATA indicates no relevant answer) */
+#define ARES_ENODATA            1
+#define ARES_EFORMERR           2
+#define ARES_ESERVFAIL          3
+#define ARES_ENOTFOUND          4
+#define ARES_ENOTIMP            5
+#define ARES_EREFUSED           6
+
+/* Locally generated error codes */
+#define ARES_EBADQUERY          7
+#define ARES_EBADNAME           8
+#define ARES_EBADFAMILY         9
+#define ARES_EBADRESP           10
+#define ARES_ECONNREFUSED       11
+#define ARES_ETIMEOUT           12
+#define ARES_EOF                13
+#define ARES_EFILE              14
+#define ARES_ENOMEM             15
+#define ARES_EDESTRUCTION       16
+#define ARES_EBADSTR            17
+
+/* ares_getnameinfo error codes */
+#define ARES_EBADFLAGS          18
+
+/* ares_getaddrinfo error codes */
+#define ARES_ENONAME            19
+#define ARES_EBADHINTS          20
+
+/* Uninitialized library error code */
+#define ARES_ENOTINITIALIZED    21          /* introduced in 1.7.0 */
+
+/* ares_library_init error codes */
+#define ARES_ELOADIPHLPAPI           22     /* introduced in 1.7.0 */
+#define ARES_EADDRGETNETWORKPARAMS   23     /* introduced in 1.7.0 */
+
+/* More error codes */
+#define ARES_ECANCELLED         24          /* introduced in 1.7.0 */
+
+/* Flag values */
+#define ARES_FLAG_USEVC         (1 << 0)
+#define ARES_FLAG_PRIMARY       (1 << 1)
+#define ARES_FLAG_IGNTC         (1 << 2)
+#define ARES_FLAG_NORECURSE     (1 << 3)
+#define ARES_FLAG_STAYOPEN      (1 << 4)
+#define ARES_FLAG_NOSEARCH      (1 << 5)
+#define ARES_FLAG_NOALIASES     (1 << 6)
+#define ARES_FLAG_NOCHECKRESP   (1 << 7)
+
+/* Option mask values */
+#define ARES_OPT_FLAGS          (1 << 0)
+#define ARES_OPT_TIMEOUT        (1 << 1)
+#define ARES_OPT_TRIES          (1 << 2)
+#define ARES_OPT_NDOTS          (1 << 3)
+#define ARES_OPT_UDP_PORT       (1 << 4)
+#define ARES_OPT_TCP_PORT       (1 << 5)
+#define ARES_OPT_SERVERS        (1 << 6)
+#define ARES_OPT_DOMAINS        (1 << 7)
+#define ARES_OPT_LOOKUPS        (1 << 8)
+#define ARES_OPT_SOCK_STATE_CB  (1 << 9)
+#define ARES_OPT_SORTLIST       (1 << 10)
+#define ARES_OPT_SOCK_SNDBUF    (1 << 11)
+#define ARES_OPT_SOCK_RCVBUF    (1 << 12)
+#define ARES_OPT_TIMEOUTMS      (1 << 13)
+#define ARES_OPT_ROTATE         (1 << 14)
+
+/* Nameinfo flag values */
+#define ARES_NI_NOFQDN                  (1 << 0)
+#define ARES_NI_NUMERICHOST             (1 << 1)
+#define ARES_NI_NAMEREQD                (1 << 2)
+#define ARES_NI_NUMERICSERV             (1 << 3)
+#define ARES_NI_DGRAM                   (1 << 4)
+#define ARES_NI_TCP                     0
+#define ARES_NI_UDP                     ARES_NI_DGRAM
+#define ARES_NI_SCTP                    (1 << 5)
+#define ARES_NI_DCCP                    (1 << 6)
+#define ARES_NI_NUMERICSCOPE            (1 << 7)
+#define ARES_NI_LOOKUPHOST              (1 << 8)
+#define ARES_NI_LOOKUPSERVICE           (1 << 9)
+/* Reserved for future use */
+#define ARES_NI_IDN                     (1 << 10)
+#define ARES_NI_IDN_ALLOW_UNASSIGNED    (1 << 11)
+#define ARES_NI_IDN_USE_STD3_ASCII_RULES (1 << 12)
+
+/* Addrinfo flag values */
+#define ARES_AI_CANONNAME               (1 << 0)
+#define ARES_AI_NUMERICHOST             (1 << 1)
+#define ARES_AI_PASSIVE                 (1 << 2)
+#define ARES_AI_NUMERICSERV             (1 << 3)
+#define ARES_AI_V4MAPPED                (1 << 4)
+#define ARES_AI_ALL                     (1 << 5)
+#define ARES_AI_ADDRCONFIG              (1 << 6)
+/* Reserved for future use */
+#define ARES_AI_IDN                     (1 << 10)
+#define ARES_AI_IDN_ALLOW_UNASSIGNED    (1 << 11)
+#define ARES_AI_IDN_USE_STD3_ASCII_RULES (1 << 12)
+#define ARES_AI_CANONIDN                (1 << 13)
+
+#define ARES_AI_MASK (ARES_AI_CANONNAME|ARES_AI_NUMERICHOST|ARES_AI_PASSIVE| \
+                      ARES_AI_NUMERICSERV|ARES_AI_V4MAPPED|ARES_AI_ALL| \
+                      ARES_AI_ADDRCONFIG)
+#define ARES_GETSOCK_MAXNUM 16 /* ares_getsock() can return info about this
+                                  many sockets */
+#define ARES_GETSOCK_READABLE(bits,num) (bits & (1<< (num)))
+#define ARES_GETSOCK_WRITABLE(bits,num) (bits & (1 << ((num) + \
+                                         ARES_GETSOCK_MAXNUM)))
+
+/* c-ares library initialization flag values */
+#define ARES_LIB_INIT_NONE   (0)
+#define ARES_LIB_INIT_WIN32  (1 << 0)
+#define ARES_LIB_INIT_ALL    (ARES_LIB_INIT_WIN32)
+
+
+/*
+ * Typedef our socket type
+ */
+
+#ifndef ares_socket_typedef
+#ifdef WIN32
+typedef SOCKET ares_socket_t;
+#define ARES_SOCKET_BAD INVALID_SOCKET
+#else
+typedef int ares_socket_t;
+#define ARES_SOCKET_BAD -1
+#endif
+#define ares_socket_typedef
+#endif /* ares_socket_typedef */
+
+typedef void (*ares_sock_state_cb)(void *data,
+                                   ares_socket_t socket_fd,
+                                   int readable,
+                                   int writable);
+
+struct apattern;
+
+/* NOTE about the ares_options struct to users and developers.
+
+   This struct will remain looking like this. It will not be extended nor
+   shrunk in future releases, but all new options will be set by ares_set_*()
+   options instead of with the ares_init_options() function.
+
+   Eventually (in a galaxy far far away), all options will be settable by
+   ares_set_*() options and the ares_init_options() function will become
+   deprecated.
+
+   When new options are added to c-ares, they are not added to this
+   struct. And they are not "saved" with the ares_save_options() function but
+   instead we encourage the use of the ares_dup() function. Needless to say,
+   if you add config options to c-ares you need to make sure ares_dup()
+   duplicates this new option.
+
+ */
+struct ares_options {
+  int flags;
+  int timeout; /* in seconds or milliseconds, depending on options */
+  int tries;
+  int ndots;
+  unsigned short udp_port;
+  unsigned short tcp_port;
+  int socket_send_buffer_size;
+  int socket_receive_buffer_size;
+  struct in_addr *servers;
+  int nservers;
+  char **domains;
+  int ndomains;
+  char *lookups;
+  ares_sock_state_cb sock_state_cb;
+  void *sock_state_cb_data;
+  struct apattern *sortlist;
+  int nsort;
+};
+
+struct hostent;
+struct timeval;
+struct sockaddr;
+struct ares_channeldata;
+
+typedef struct ares_channeldata *ares_channel;
+
+typedef void (*ares_callback)(void *arg,
+                              int status,
+                              int timeouts,
+                              unsigned char *abuf,
+                              int alen);
+
+typedef void (*ares_host_callback)(void *arg,
+                                   int status,
+                                   int timeouts,
+                                   struct hostent *hostent);
+
+typedef void (*ares_nameinfo_callback)(void *arg,
+                                       int status,
+                                       int timeouts,
+                                       char *node,
+                                       char *service);
+
+typedef int  (*ares_sock_create_callback)(ares_socket_t socket_fd,
+                                          int type,
+                                          void *data);
+
+CARES_EXTERN int ares_library_init(int flags);
+
+CARES_EXTERN void ares_library_cleanup(void);
+
+CARES_EXTERN const char *ares_version(int *version);
+
+CARES_EXTERN int ares_init(ares_channel *channelptr);
+
+CARES_EXTERN int ares_init_options(ares_channel *channelptr,
+                                   struct ares_options *options,
+                                   int optmask);
+
+CARES_EXTERN int ares_save_options(ares_channel channel,
+                                   struct ares_options *options,
+                                   int *optmask);
+
+CARES_EXTERN void ares_destroy_options(struct ares_options *options);
+
+CARES_EXTERN int ares_dup(ares_channel *dest,
+                          ares_channel src);
+
+CARES_EXTERN void ares_destroy(ares_channel channel);
+
+CARES_EXTERN void ares_cancel(ares_channel channel);
+
+/* These next 3 configure local binding for the out-going socket
+ * connection.  Use these to specify source IP and/or network device
+ * on multi-homed systems.
+ */
+CARES_EXTERN void ares_set_local_ip4(ares_channel channel, unsigned int local_ip);
+
+/* local_ip6 should be 16 bytes in length */
+CARES_EXTERN void ares_set_local_ip6(ares_channel channel,
+                                     const unsigned char* local_ip6);
+
+/* local_dev_name should be null terminated. */
+CARES_EXTERN void ares_set_local_dev(ares_channel channel,
+                                     const char* local_dev_name);
+
+CARES_EXTERN void ares_set_socket_callback(ares_channel channel,
+                                           ares_sock_create_callback callback,
+                                           void *user_data);
+
+CARES_EXTERN void ares_send(ares_channel channel,
+                            const unsigned char *qbuf,
+                            int qlen,
+                            ares_callback callback,
+                            void *arg);
+
+CARES_EXTERN void ares_query(ares_channel channel,
+                             const char *name,
+                             int dnsclass,
+                             int type,
+                             ares_callback callback,
+                             void *arg);
+
+CARES_EXTERN void ares_search(ares_channel channel,
+                              const char *name,
+                              int dnsclass,
+                              int type,
+                              ares_callback callback,
+                              void *arg);
+
+CARES_EXTERN void ares_gethostbyname(ares_channel channel,
+                                     const char *name,
+                                     int family,
+                                     ares_host_callback callback,
+                                     void *arg);
+
+CARES_EXTERN int ares_gethostbyname_file(ares_channel channel,
+                                         const char *name,
+                                         int family,
+                                         struct hostent **host);
+
+CARES_EXTERN void ares_gethostbyaddr(ares_channel channel,
+                                     const void *addr,
+                                     int addrlen,
+                                     int family,
+                                     ares_host_callback callback,
+                                     void *arg);
+
+CARES_EXTERN void ares_getnameinfo(ares_channel channel,
+                                   const struct sockaddr *sa,
+                                   ares_socklen_t salen,
+                                   int flags,
+                                   ares_nameinfo_callback callback,
+                                   void *arg);
+
+CARES_EXTERN int ares_fds(ares_channel channel,
+                          fd_set *read_fds,
+                          fd_set *write_fds);
+
+CARES_EXTERN int ares_getsock(ares_channel channel,
+                              ares_socket_t *socks,
+                              int numsocks);
+
+CARES_EXTERN struct timeval *ares_timeout(ares_channel channel,
+                                          struct timeval *maxtv,
+                                          struct timeval *tv);
+
+CARES_EXTERN void ares_process(ares_channel channel,
+                               fd_set *read_fds,
+                               fd_set *write_fds);
+
+CARES_EXTERN void ares_process_fd(ares_channel channel,
+                                  ares_socket_t read_fd,
+                                  ares_socket_t write_fd);
+
+CARES_EXTERN int ares_mkquery(const char *name,
+                              int dnsclass,
+                              int type,
+                              unsigned short id,
+                              int rd,
+                              unsigned char **buf,
+                              int *buflen);
+
+CARES_EXTERN int ares_expand_name(const unsigned char *encoded,
+                                  const unsigned char *abuf,
+                                  int alen,
+                                  char **s,
+                                  long *enclen);
+
+CARES_EXTERN int ares_expand_string(const unsigned char *encoded,
+                                    const unsigned char *abuf,
+                                    int alen,
+                                    unsigned char **s,
+                                    long *enclen);
+
+/*
+ * NOTE: before c-ares 1.7.0 we would most often use the system in6_addr
+ * struct below when ares itself was built, but many apps would use this
+ * private version since the header checked a HAVE_* define for it. Starting
+ * with 1.7.0 we always declare and use our own to stop relying on the
+ * system's one.
+ */
+struct ares_in6_addr {
+  union {
+    unsigned char _S6_u8[16];
+  } _S6_un;
+};
+
+struct ares_addrttl {
+  struct in_addr ipaddr;
+  int            ttl;
+};
+
+struct ares_addr6ttl {
+  struct ares_in6_addr ip6addr;
+  int             ttl;
+};
+
+struct ares_srv_reply {
+  struct ares_srv_reply  *next;
+  char                   *host;
+  unsigned short          priority;
+  unsigned short          weight;
+  unsigned short          port;
+};
+
+struct ares_mx_reply {
+  struct ares_mx_reply   *next;
+  char                   *host;
+  unsigned short          priority;
+};
+
+struct ares_txt_reply {
+  struct ares_txt_reply  *next;
+  unsigned char          *txt;
+  size_t                  length;  /* length excludes null termination */
+};
+
+/*
+** Parse the buffer, starting at *abuf and of length alen bytes, previously
+** obtained from an ares_search call.  Put the results in *host, if nonnull.
+** Also, if addrttls is nonnull, put up to *naddrttls IPv4 addresses along with
+** their TTLs in that array, and set *naddrttls to the number of addresses
+** so written.
+*/
+
+CARES_EXTERN int ares_parse_a_reply(const unsigned char *abuf,
+                                    int alen,
+                                    struct hostent **host,
+                                    struct ares_addrttl *addrttls,
+                                    int *naddrttls);
+
+CARES_EXTERN int ares_parse_aaaa_reply(const unsigned char *abuf,
+                                       int alen,
+                                       struct hostent **host,
+                                       struct ares_addr6ttl *addrttls,
+                                       int *naddrttls);
+
+CARES_EXTERN int ares_parse_ptr_reply(const unsigned char *abuf,
+                                      int alen,
+                                      const void *addr,
+                                      int addrlen,
+                                      int family,
+                                      struct hostent **host);
+
+CARES_EXTERN int ares_parse_ns_reply(const unsigned char *abuf,
+                                     int alen,
+                                     struct hostent **host);
+
+CARES_EXTERN int ares_parse_srv_reply(const unsigned char* abuf,
+                                      int alen,
+                                      struct ares_srv_reply** srv_out);
+
+CARES_EXTERN int ares_parse_mx_reply(const unsigned char* abuf,
+                                      int alen,
+                                      struct ares_mx_reply** mx_out);
+
+CARES_EXTERN int ares_parse_txt_reply(const unsigned char* abuf,
+                                      int alen,
+                                      struct ares_txt_reply** txt_out);
+
+CARES_EXTERN void ares_free_string(void *str);
+
+CARES_EXTERN void ares_free_hostent(struct hostent *host);
+
+CARES_EXTERN void ares_free_data(void *dataptr);
+
+CARES_EXTERN const char *ares_strerror(int code);
+
+/* TODO:  Hold port here as well. */
+struct ares_addr_node {
+  struct ares_addr_node *next;
+  int family;
+  union {
+    struct in_addr       addr4;
+    struct ares_in6_addr addr6;
+  } addr;
+};
+
+CARES_EXTERN int ares_set_servers(ares_channel channel,
+                                  struct ares_addr_node *servers);
+
+/* Incomming string format: host[:port][,host[:port]]... */
+CARES_EXTERN int ares_set_servers_csv(ares_channel channel,
+                                      const char* servers);
+
+CARES_EXTERN int ares_get_servers(ares_channel channel,
+                                  struct ares_addr_node **servers);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* ARES__H */
diff --git a/src/rt/libuv/include/ares_version.h b/src/rt/libuv/include/ares_version.h
new file mode 100644
index 00000000000..efd0156dd10
--- /dev/null
+++ b/src/rt/libuv/include/ares_version.h
@@ -0,0 +1,24 @@
+
+#ifndef ARES__VERSION_H
+#define ARES__VERSION_H
+
+/* This is the global package copyright */
+#define ARES_COPYRIGHT "2004 - 2010 Daniel Stenberg, <daniel@haxx.se>."
+
+#define ARES_VERSION_MAJOR 1
+#define ARES_VERSION_MINOR 7
+#define ARES_VERSION_PATCH 5
+#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
+                       (ARES_VERSION_MINOR<<8)|\
+                       (ARES_VERSION_PATCH))
+#define ARES_VERSION_STR "1.7.5-DEV"
+
+#if (ARES_VERSION >= 0x010700)
+#  define CARES_HAVE_ARES_LIBRARY_INIT 1
+#  define CARES_HAVE_ARES_LIBRARY_CLEANUP 1
+#else
+#  undef CARES_HAVE_ARES_LIBRARY_INIT
+#  undef CARES_HAVE_ARES_LIBRARY_CLEANUP
+#endif
+
+#endif
diff --git a/src/rt/libuv/include/uv-private/eio.h b/src/rt/libuv/include/uv-private/eio.h
new file mode 100644
index 00000000000..450df6ba299
--- /dev/null
+++ b/src/rt/libuv/include/uv-private/eio.h
@@ -0,0 +1,376 @@
+/*
+ * libeio API header
+ *
+ * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libeio@schmorp.de>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, 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.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
+ * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
+ * CIAL, 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 OTH-
+ * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License ("GPL") version 2 or any later version,
+ * in which case the provisions of the GPL are applicable instead of
+ * the above. If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the BSD license, indicate your decision
+ * by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL. If you do not delete the
+ * provisions above, a recipient may use your version of this file under
+ * either the BSD or the GPL.
+ */
+
+#ifndef EIO_H_
+#define EIO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <signal.h>
+#include <sys/types.h>
+
+typedef struct eio_req    eio_req;
+typedef struct eio_dirent eio_dirent;
+
+typedef int (*eio_cb)(eio_req *req);
+
+#ifndef EIO_REQ_MEMBERS
+# define EIO_REQ_MEMBERS
+#endif
+
+#ifndef EIO_STRUCT_STAT
+# ifdef _WIN32
+#  define EIO_STRUCT_STAT struct _stati64
+#  define EIO_STRUCT_STATI64
+# else
+#  define EIO_STRUCT_STAT struct stat
+# endif
+#endif
+
+#ifdef _WIN32
+  typedef int      eio_uid_t;
+  typedef int      eio_gid_t;
+  typedef int      eio_mode_t;
+  #ifdef __MINGW32__ /* no intptr_t */
+    typedef ssize_t  eio_ssize_t;
+  #else
+    typedef intptr_t eio_ssize_t; /* or SSIZE_T */
+  #endif
+  #if __GNUC__
+    typedef long long eio_ino_t;
+  #else
+    typedef __int64   eio_ino_t; /* unsigned not supported by msvc */
+  #endif
+#else
+  typedef uid_t    eio_uid_t;
+  typedef gid_t    eio_gid_t;
+  typedef ssize_t  eio_ssize_t;
+  typedef ino_t    eio_ino_t;
+  typedef mode_t   eio_mode_t;
+#endif
+
+#ifndef EIO_STRUCT_STATVFS
+# define EIO_STRUCT_STATVFS struct statvfs
+#endif
+
+/* for readdir */
+
+/* eio_readdir flags */
+enum
+{
+  EIO_READDIR_DENTS         = 0x01, /* ptr2 contains eio_dirents, not just the (unsorted) names */
+  EIO_READDIR_DIRS_FIRST    = 0x02, /* dirents gets sorted into a good stat() ing order to find directories first */
+  EIO_READDIR_STAT_ORDER    = 0x04, /* dirents gets sorted into a good stat() ing order to quickly stat all files */
+  EIO_READDIR_FOUND_UNKNOWN = 0x80, /* set by eio_readdir when *_ARRAY was set and any TYPE=UNKNOWN's were found */
+
+  EIO_READDIR_CUSTOM1       = 0x100, /* for use by apps */
+  EIO_READDIR_CUSTOM2       = 0x200  /* for use by apps */
+};
+
+/* using "typical" values in the hope that the compiler will do something sensible */
+enum eio_dtype
+{
+  EIO_DT_UNKNOWN =  0,
+  EIO_DT_FIFO    =  1,
+  EIO_DT_CHR     =  2,
+  EIO_DT_MPC     =  3, /* multiplexed char device (v7+coherent) */
+  EIO_DT_DIR     =  4,
+  EIO_DT_NAM     =  5, /* xenix special named file */
+  EIO_DT_BLK     =  6,
+  EIO_DT_MPB     =  7, /* multiplexed block device (v7+coherent) */
+  EIO_DT_REG     =  8,
+  EIO_DT_NWK     =  9, /* HP-UX network special */
+  EIO_DT_CMP     =  9, /* VxFS compressed */
+  EIO_DT_LNK     = 10,
+  /*  DT_SHAD    = 11,*/
+  EIO_DT_SOCK    = 12,
+  EIO_DT_DOOR    = 13, /* solaris door */
+  EIO_DT_WHT     = 14,
+  EIO_DT_MAX     = 15  /* highest DT_VALUE ever, hopefully */
+};
+
+struct eio_dirent
+{
+  int nameofs; /* offset of null-terminated name string in (char *)req->ptr2 */
+  unsigned short namelen; /* size of filename without trailing 0 */
+  unsigned char type; /* one of EIO_DT_* */
+  signed char score; /* internal use */
+  eio_ino_t inode; /* the inode number, if available, otherwise unspecified */
+};
+
+/* eio_msync flags */
+enum
+{
+  EIO_MS_ASYNC      = 1,
+  EIO_MS_INVALIDATE = 2,
+  EIO_MS_SYNC       = 4
+};
+
+/* eio_mtouch flags */
+enum
+{
+  EIO_MT_MODIFY     = 1
+};
+
+/* eio_sync_file_range flags */
+enum
+{
+  EIO_SYNC_FILE_RANGE_WAIT_BEFORE = 1,
+  EIO_SYNC_FILE_RANGE_WRITE       = 2,
+  EIO_SYNC_FILE_RANGE_WAIT_AFTER  = 4
+};
+
+/* eio_fallocate flags */
+enum
+{
+  EIO_FALLOC_FL_KEEP_SIZE = 1 /* MUST match the value in linux/falloc.h */
+};
+
+/* timestamps and differences - feel free to use double in your code directly */
+typedef double eio_tstamp;
+
+/* the eio request structure */
+enum
+{
+  EIO_CUSTOM,
+  EIO_OPEN, EIO_CLOSE, EIO_DUP2,
+  EIO_READ, EIO_WRITE,
+  EIO_READAHEAD, EIO_SENDFILE,
+  EIO_STAT, EIO_LSTAT, EIO_FSTAT,
+  EIO_STATVFS, EIO_FSTATVFS,
+  EIO_TRUNCATE, EIO_FTRUNCATE,
+  EIO_UTIME, EIO_FUTIME,
+  EIO_CHMOD, EIO_FCHMOD,
+  EIO_CHOWN, EIO_FCHOWN,
+  EIO_SYNC, EIO_FSYNC, EIO_FDATASYNC, EIO_SYNCFS,
+  EIO_MSYNC, EIO_MTOUCH, EIO_SYNC_FILE_RANGE, EIO_FALLOCATE,
+  EIO_MLOCK, EIO_MLOCKALL,
+  EIO_UNLINK, EIO_RMDIR, EIO_MKDIR, EIO_RENAME,
+  EIO_MKNOD, EIO_READDIR,
+  EIO_LINK, EIO_SYMLINK, EIO_READLINK, EIO_REALPATH,
+  EIO_GROUP, EIO_NOP,
+  EIO_BUSY
+};
+
+/* mlockall constants */
+enum
+{
+  EIO_MCL_CURRENT = 1,
+  EIO_MCL_FUTURE  = 2
+};
+
+/* request priorities */
+
+enum {
+  EIO_PRI_MIN     = -4,
+  EIO_PRI_MAX     =  4,
+  EIO_PRI_DEFAULT =  0
+};
+
+/* eio request structure */
+/* this structure is mostly read-only */
+/* when initialising it, all members must be zero-initialised */
+struct eio_req
+{
+  eio_req volatile *next; /* private ETP */
+
+  eio_ssize_t result;  /* result of syscall, e.g. result = read (... */
+  off_t offs;      /* read, write, truncate, readahead, sync_file_range, fallocate: file offset, mknod: dev_t */
+  size_t size;     /* read, write, readahead, sendfile, msync, mlock, sync_file_range, fallocate: length */
+  void *ptr1;      /* all applicable requests: pathname, old name; readdir: optional eio_dirents */
+  void *ptr2;      /* all applicable requests: new name or memory buffer; readdir: name strings */
+  eio_tstamp nv1;  /* utime, futime: atime; busy: sleep time */
+  eio_tstamp nv2;  /* utime, futime: mtime */
+
+  int type;        /* EIO_xxx constant ETP */
+  int int1;        /* all applicable requests: file descriptor; sendfile: output fd; open, msync, mlockall, readdir: flags */
+  long int2;       /* chown, fchown: uid; sendfile: input fd; open, chmod, mkdir, mknod: file mode, sync_file_range, fallocate: flags */
+  long int3;       /* chown, fchown: gid */
+  int errorno;     /* errno value on syscall return */
+
+#if __i386 || __amd64
+  unsigned char cancelled;
+#else
+  sig_atomic_t cancelled;
+#endif
+
+  unsigned char flags; /* private */
+  signed char pri;     /* the priority */
+
+  void *data;
+  eio_cb finish;
+  void (*destroy)(eio_req *req); /* called when request no longer needed */
+  void (*feed)(eio_req *req);    /* only used for group requests */
+
+  EIO_REQ_MEMBERS
+
+  eio_req *grp, *grp_prev, *grp_next, *grp_first; /* private */
+};
+
+/* _private_ request flags */
+enum {
+  EIO_FLAG_PTR1_FREE = 0x01, /* need to free(ptr1) */
+  EIO_FLAG_PTR2_FREE = 0x02, /* need to free(ptr2) */
+  EIO_FLAG_GROUPADD  = 0x04  /* some request was added to the group */
+};
+
+/* undocumented/unsupported/private helper */
+/*void eio_page_align (void **addr, size_t *length);*/
+
+/* returns < 0 on error, errno set
+ * need_poll, if non-zero, will be called when results are available
+ * and eio_poll_cb needs to be invoked (it MUST NOT call eio_poll_cb itself).
+ * done_poll is called when the need to poll is gone.
+ */
+int eio_init (void (*want_poll)(void), void (*done_poll)(void));
+
+/* must be called regularly to handle pending requests */
+/* returns 0 if all requests were handled, -1 if not, or the value of EIO_FINISH if != 0 */
+int eio_poll (void);
+
+/* stop polling if poll took longer than duration seconds */
+void eio_set_max_poll_time (eio_tstamp nseconds);
+/* do not handle more then count requests in one call to eio_poll_cb */
+void eio_set_max_poll_reqs (unsigned int nreqs);
+
+/* set minimum required number
+ * maximum wanted number
+ * or maximum idle number of threads */
+void eio_set_min_parallel (unsigned int nthreads);
+void eio_set_max_parallel (unsigned int nthreads);
+void eio_set_max_idle     (unsigned int nthreads);
+void eio_set_idle_timeout (unsigned int seconds);
+
+unsigned int eio_nreqs    (void); /* number of requests in-flight */
+unsigned int eio_nready   (void); /* number of not-yet handled requests */
+unsigned int eio_npending (void); /* number of finished but unhandled requests */
+unsigned int eio_nthreads (void); /* number of worker threads in use currently */
+
+/*****************************************************************************/
+/* convenience wrappers */
+
+#ifndef EIO_NO_WRAPPERS
+eio_req *eio_nop       (int pri, eio_cb cb, void *data); /* does nothing except go through the whole process */
+eio_req *eio_busy      (eio_tstamp delay, int pri, eio_cb cb, void *data); /* ties a thread for this long, simulating busyness */
+eio_req *eio_sync      (int pri, eio_cb cb, void *data);
+eio_req *eio_fsync     (int fd, int pri, eio_cb cb, void *data);
+eio_req *eio_fdatasync (int fd, int pri, eio_cb cb, void *data);
+eio_req *eio_syncfs    (int fd, int pri, eio_cb cb, void *data);
+eio_req *eio_msync     (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data);
+eio_req *eio_mtouch    (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data);
+eio_req *eio_mlock     (void *addr, size_t length, int pri, eio_cb cb, void *data);
+eio_req *eio_mlockall  (int flags, int pri, eio_cb cb, void *data);
+eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data);
+eio_req *eio_fallocate (int fd, int mode, off_t offset, size_t len, int pri, eio_cb cb, void *data);
+eio_req *eio_close     (int fd, int pri, eio_cb cb, void *data);
+eio_req *eio_readahead (int fd, off_t offset, size_t length, int pri, eio_cb cb, void *data);
+eio_req *eio_read      (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data);
+eio_req *eio_write     (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data);
+eio_req *eio_fstat     (int fd, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
+eio_req *eio_fstatvfs  (int fd, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
+eio_req *eio_futime    (int fd, eio_tstamp atime, eio_tstamp mtime, int pri, eio_cb cb, void *data);
+eio_req *eio_ftruncate (int fd, off_t offset, int pri, eio_cb cb, void *data);
+eio_req *eio_fchmod    (int fd, eio_mode_t mode, int pri, eio_cb cb, void *data);
+eio_req *eio_fchown    (int fd, eio_uid_t uid, eio_gid_t gid, int pri, eio_cb cb, void *data);
+eio_req *eio_dup2      (int fd, int fd2, int pri, eio_cb cb, void *data);
+eio_req *eio_sendfile  (int out_fd, int in_fd, off_t in_offset, size_t length, int pri, eio_cb cb, void *data);
+eio_req *eio_open      (const char *path, int flags, eio_mode_t mode, int pri, eio_cb cb, void *data);
+eio_req *eio_utime     (const char *path, eio_tstamp atime, eio_tstamp mtime, int pri, eio_cb cb, void *data);
+eio_req *eio_truncate  (const char *path, off_t offset, int pri, eio_cb cb, void *data);
+eio_req *eio_chown     (const char *path, eio_uid_t uid, eio_gid_t gid, int pri, eio_cb cb, void *data);
+eio_req *eio_chmod     (const char *path, eio_mode_t mode, int pri, eio_cb cb, void *data);
+eio_req *eio_mkdir     (const char *path, eio_mode_t mode, int pri, eio_cb cb, void *data);
+eio_req *eio_readdir   (const char *path, int flags, int pri, eio_cb cb, void *data); /* result=ptr2 allocated dynamically */
+eio_req *eio_rmdir     (const char *path, int pri, eio_cb cb, void *data);
+eio_req *eio_unlink    (const char *path, int pri, eio_cb cb, void *data);
+eio_req *eio_readlink  (const char *path, int pri, eio_cb cb, void *data); /* result=ptr2 allocated dynamically */
+eio_req *eio_realpath  (const char *path, int pri, eio_cb cb, void *data); /* result=ptr2 allocated dynamically */
+eio_req *eio_stat      (const char *path, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
+eio_req *eio_lstat     (const char *path, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
+eio_req *eio_statvfs   (const char *path, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
+eio_req *eio_mknod     (const char *path, eio_mode_t mode, dev_t dev, int pri, eio_cb cb, void *data);
+eio_req *eio_link      (const char *path, const char *new_path, int pri, eio_cb cb, void *data);
+eio_req *eio_symlink   (const char *path, const char *new_path, int pri, eio_cb cb, void *data);
+eio_req *eio_rename    (const char *path, const char *new_path, int pri, eio_cb cb, void *data);
+eio_req *eio_custom    (void (*execute)(eio_req *), int pri, eio_cb cb, void *data);
+#endif
+
+/*****************************************************************************/
+/* groups */
+
+eio_req *eio_grp       (eio_cb cb, void *data);
+void eio_grp_feed      (eio_req *grp, void (*feed)(eio_req *req), int limit);
+void eio_grp_limit     (eio_req *grp, int limit);
+void eio_grp_add       (eio_req *grp, eio_req *req);
+void eio_grp_cancel    (eio_req *grp); /* cancels all sub requests but not the group */
+
+/*****************************************************************************/
+/* request api */
+
+/* true if the request was cancelled, useful in the invoke callback */
+#define EIO_CANCELLED(req)   ((req)->cancelled)
+
+#define EIO_RESULT(req)      ((req)->result)
+/* returns a pointer to the result buffer allocated by eio */
+#define EIO_BUF(req)         ((req)->ptr2)
+#define EIO_STAT_BUF(req)    ((EIO_STRUCT_STAT    *)EIO_BUF(req))
+#define EIO_STATVFS_BUF(req) ((EIO_STRUCT_STATVFS *)EIO_BUF(req))
+#define EIO_PATH(req)        ((char *)(req)->ptr1)
+
+/* submit a request for execution */
+void eio_submit (eio_req *req);
+/* cancel a request as soon fast as possible, if possible */
+void eio_cancel (eio_req *req);
+
+/*****************************************************************************/
+/* convenience functions */
+
+eio_ssize_t eio_sendfile_sync (int ofd, int ifd, off_t offset, size_t count);
+eio_ssize_t eio__pread        (int fd, void *buf, size_t count, off_t offset);
+eio_ssize_t eio__pwrite       (int fd, void *buf, size_t count, off_t offset);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/rt/libuv/include/uv-private/ev.h b/src/rt/libuv/include/uv-private/ev.h
new file mode 100644
index 00000000000..5d2d7a1e37e
--- /dev/null
+++ b/src/rt/libuv/include/uv-private/ev.h
@@ -0,0 +1,836 @@
+/*
+ * libev native API header
+ *
+ * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
+ * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
+ * CIAL, 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 OTH-
+ * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License ("GPL") version 2 or any later version,
+ * in which case the provisions of the GPL are applicable instead of
+ * the above. If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the BSD license, indicate your decision
+ * by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL. If you do not delete the
+ * provisions above, a recipient may use your version of this file under
+ * either the BSD or the GPL.
+ */
+
+#ifndef EV_H_
+#define EV_H_
+
+#ifdef __cplusplus
+# define EV_CPP(x) x
+#else
+# define EV_CPP(x)
+#endif
+
+EV_CPP(extern "C" {)
+
+#ifdef __GNUC__
+# define EV_MAYBE_UNUSED __attribute__ ((unused))
+#else
+# define EV_MAYBE_UNUSED
+#endif
+
+/*****************************************************************************/
+
+/* pre-4.0 compatibility */
+#ifndef EV_COMPAT3
+# define EV_COMPAT3 1
+#endif
+
+#ifndef EV_FEATURES
+# define EV_FEATURES 0x7f
+#endif
+
+#define EV_FEATURE_CODE     ((EV_FEATURES) &  1)
+#define EV_FEATURE_DATA     ((EV_FEATURES) &  2)
+#define EV_FEATURE_CONFIG   ((EV_FEATURES) &  4)
+#define EV_FEATURE_API      ((EV_FEATURES) &  8)
+#define EV_FEATURE_WATCHERS ((EV_FEATURES) & 16)
+#define EV_FEATURE_BACKENDS ((EV_FEATURES) & 32)
+#define EV_FEATURE_OS       ((EV_FEATURES) & 64)
+
+/* these priorities are inclusive, higher priorities will be invoked earlier */
+#ifndef EV_MINPRI
+# define EV_MINPRI (EV_FEATURE_CONFIG ? -2 : 0)
+#endif
+#ifndef EV_MAXPRI
+# define EV_MAXPRI (EV_FEATURE_CONFIG ? +2 : 0)
+#endif
+
+#ifndef EV_MULTIPLICITY
+# define EV_MULTIPLICITY EV_FEATURE_CONFIG
+#endif
+
+#ifndef EV_PERIODIC_ENABLE
+# define EV_PERIODIC_ENABLE EV_FEATURE_WATCHERS
+#endif
+
+#ifndef EV_STAT_ENABLE
+# define EV_STAT_ENABLE EV_FEATURE_WATCHERS
+#endif
+
+#ifndef EV_PREPARE_ENABLE
+# define EV_PREPARE_ENABLE EV_FEATURE_WATCHERS
+#endif
+
+#ifndef EV_CHECK_ENABLE
+# define EV_CHECK_ENABLE EV_FEATURE_WATCHERS
+#endif
+
+#ifndef EV_IDLE_ENABLE
+# define EV_IDLE_ENABLE EV_FEATURE_WATCHERS
+#endif
+
+#ifndef EV_FORK_ENABLE
+# define EV_FORK_ENABLE EV_FEATURE_WATCHERS
+#endif
+
+#ifndef EV_CLEANUP_ENABLE
+# define EV_CLEANUP_ENABLE EV_FEATURE_WATCHERS
+#endif
+
+#ifndef EV_SIGNAL_ENABLE
+# define EV_SIGNAL_ENABLE EV_FEATURE_WATCHERS
+#endif
+
+#ifndef EV_CHILD_ENABLE
+# ifdef _WIN32
+#  define EV_CHILD_ENABLE 0
+# else
+#  define EV_CHILD_ENABLE EV_FEATURE_WATCHERS
+#endif
+#endif
+
+#ifndef EV_ASYNC_ENABLE
+# define EV_ASYNC_ENABLE EV_FEATURE_WATCHERS
+#endif
+
+#ifndef EV_EMBED_ENABLE
+# define EV_EMBED_ENABLE EV_FEATURE_WATCHERS
+#endif
+
+#ifndef EV_WALK_ENABLE
+# define EV_WALK_ENABLE 0 /* not yet */
+#endif
+
+/*****************************************************************************/
+
+#if EV_CHILD_ENABLE && !EV_SIGNAL_ENABLE
+# undef EV_SIGNAL_ENABLE
+# define EV_SIGNAL_ENABLE 1
+#endif
+
+/*****************************************************************************/
+
+typedef double ev_tstamp;
+
+#ifndef EV_ATOMIC_T
+# include <signal.h>
+# define EV_ATOMIC_T sig_atomic_t volatile
+#endif
+
+#if EV_STAT_ENABLE
+# ifdef _WIN32
+#  include <time.h>
+#  include <sys/types.h>
+# endif
+# include <sys/stat.h>
+#endif
+
+/* support multiple event loops? */
+#if EV_MULTIPLICITY
+struct ev_loop;
+# define EV_P  struct ev_loop *loop               /* a loop as sole parameter in a declaration */
+# define EV_P_ EV_P,                              /* a loop as first of multiple parameters */
+# define EV_A  loop                               /* a loop as sole argument to a function call */
+# define EV_A_ EV_A,                              /* a loop as first of multiple arguments */
+# define EV_DEFAULT_UC  ev_default_loop_uc_ ()    /* the default loop, if initialised, as sole arg */
+# define EV_DEFAULT_UC_ EV_DEFAULT_UC,            /* the default loop as first of multiple arguments */
+# define EV_DEFAULT  ev_default_loop (0)          /* the default loop as sole arg */
+# define EV_DEFAULT_ EV_DEFAULT,                  /* the default loop as first of multiple arguments */
+#else
+# define EV_P void
+# define EV_P_
+# define EV_A
+# define EV_A_
+# define EV_DEFAULT
+# define EV_DEFAULT_
+# define EV_DEFAULT_UC
+# define EV_DEFAULT_UC_
+# undef EV_EMBED_ENABLE
+#endif
+
+/* EV_INLINE is used for functions in header files */
+#if __STDC_VERSION__ >= 199901L && __GNUC__ >= 3
+# define EV_INLINE static inline
+#else
+# define EV_INLINE static
+#endif
+
+/* EV_PROTOTYPES can be used to switch of prototype declarations */
+#ifndef EV_PROTOTYPES
+# define EV_PROTOTYPES 1
+#endif
+
+/*****************************************************************************/
+
+#define EV_VERSION_MAJOR 4
+#define EV_VERSION_MINOR 4
+
+/* eventmask, revents, events... */
+enum {
+  EV_UNDEF    =         -1, /* guaranteed to be invalid */
+  EV_NONE     =       0x00, /* no events */
+  EV_READ     =       0x01, /* ev_io detected read will not block */
+  EV_WRITE    =       0x02, /* ev_io detected write will not block */
+  EV_LIBUV_KQUEUE_HACK = 0x40,
+  EV__IOFDSET =       0x80, /* internal use only */
+  EV_IO       =    EV_READ, /* alias for type-detection */
+  EV_TIMER    = 0x00000100, /* timer timed out */
+#if EV_COMPAT3
+  EV_TIMEOUT  =   EV_TIMER, /* pre 4.0 API compatibility */
+#endif
+  EV_PERIODIC = 0x00000200, /* periodic timer timed out */
+  EV_SIGNAL   = 0x00000400, /* signal was received */
+  EV_CHILD    = 0x00000800, /* child/pid had status change */
+  EV_STAT     = 0x00001000, /* stat data changed */
+  EV_IDLE     = 0x00002000, /* event loop is idling */
+  EV_PREPARE  = 0x00004000, /* event loop about to poll */
+  EV_CHECK    = 0x00008000, /* event loop finished poll */
+  EV_EMBED    = 0x00010000, /* embedded event loop needs sweep */
+  EV_FORK     = 0x00020000, /* event loop resumed in child */
+  EV_CLEANUP  = 0x00040000, /* event loop resumed in child */
+  EV_ASYNC    = 0x00080000, /* async intra-loop signal */
+  EV_CUSTOM   = 0x01000000, /* for use by user code */
+  EV_ERROR    = (-2147483647 - 1) /* sent when an error occurs */
+};
+
+/* can be used to add custom fields to all watchers, while losing binary compatibility */
+#ifndef EV_COMMON
+# define EV_COMMON void *data;
+#endif
+
+#ifndef EV_CB_DECLARE
+# define EV_CB_DECLARE(type) void (*cb)(EV_P_ struct type *w, int revents);
+#endif
+#ifndef EV_CB_INVOKE
+# define EV_CB_INVOKE(watcher,revents) (watcher)->cb (EV_A_ (watcher), (revents))
+#endif
+
+/* not official, do not use */
+#define EV_CB(type,name) void name (EV_P_ struct ev_ ## type *w, int revents)
+
+/*
+ * struct member types:
+ * private: you may look at them, but not change them,
+ *          and they might not mean anything to you.
+ * ro: can be read anytime, but only changed when the watcher isn't active.
+ * rw: can be read and modified anytime, even when the watcher is active.
+ *
+ * some internal details that might be helpful for debugging:
+ *
+ * active is either 0, which means the watcher is not active,
+ *           or the array index of the watcher (periodics, timers)
+ *           or the array index + 1 (most other watchers)
+ *           or simply 1 for watchers that aren't in some array.
+ * pending is either 0, in which case the watcher isn't,
+ *           or the array index + 1 in the pendings array.
+ */
+
+#if EV_MINPRI == EV_MAXPRI
+# define EV_DECL_PRIORITY
+#elif !defined (EV_DECL_PRIORITY)
+# define EV_DECL_PRIORITY int priority;
+#endif
+
+/* shared by all watchers */
+#define EV_WATCHER(type)			\
+  int active; /* private */			\
+  int pending; /* private */			\
+  EV_DECL_PRIORITY /* private */		\
+  EV_COMMON /* rw */				\
+  EV_CB_DECLARE (type) /* private */
+
+#define EV_WATCHER_LIST(type)			\
+  EV_WATCHER (type)				\
+  struct ev_watcher_list *next; /* private */
+
+#define EV_WATCHER_TIME(type)			\
+  EV_WATCHER (type)				\
+  ev_tstamp at;     /* private */
+
+/* base class, nothing to see here unless you subclass */
+typedef struct ev_watcher
+{
+  EV_WATCHER (ev_watcher)
+} ev_watcher;
+
+/* base class, nothing to see here unless you subclass */
+typedef struct ev_watcher_list
+{
+  EV_WATCHER_LIST (ev_watcher_list)
+} ev_watcher_list;
+
+/* base class, nothing to see here unless you subclass */
+typedef struct ev_watcher_time
+{
+  EV_WATCHER_TIME (ev_watcher_time)
+} ev_watcher_time;
+
+/* invoked when fd is either EV_READable or EV_WRITEable */
+/* revent EV_READ, EV_WRITE */
+typedef struct ev_io
+{
+  EV_WATCHER_LIST (ev_io)
+
+  int fd;     /* ro */
+  int events; /* ro */
+} ev_io;
+
+/* invoked after a specific time, repeatable (based on monotonic clock) */
+/* revent EV_TIMEOUT */
+typedef struct ev_timer
+{
+  EV_WATCHER_TIME (ev_timer)
+
+  ev_tstamp repeat; /* rw */
+} ev_timer;
+
+/* invoked at some specific time, possibly repeating at regular intervals (based on UTC) */
+/* revent EV_PERIODIC */
+typedef struct ev_periodic
+{
+  EV_WATCHER_TIME (ev_periodic)
+
+  ev_tstamp offset; /* rw */
+  ev_tstamp interval; /* rw */
+  ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now); /* rw */
+} ev_periodic;
+
+/* invoked when the given signal has been received */
+/* revent EV_SIGNAL */
+typedef struct ev_signal
+{
+  EV_WATCHER_LIST (ev_signal)
+
+  int signum; /* ro */
+} ev_signal;
+
+/* invoked when sigchld is received and waitpid indicates the given pid */
+/* revent EV_CHILD */
+/* does not support priorities */
+typedef struct ev_child
+{
+  EV_WATCHER_LIST (ev_child)
+
+  int flags;   /* private */
+  int pid;     /* ro */
+  int rpid;    /* rw, holds the received pid */
+  int rstatus; /* rw, holds the exit status, use the macros from sys/wait.h */
+} ev_child;
+
+#if EV_STAT_ENABLE
+/* st_nlink = 0 means missing file or other error */
+# ifdef _WIN32
+typedef struct _stati64 ev_statdata;
+# else
+typedef struct stat ev_statdata;
+# endif
+
+/* invoked each time the stat data changes for a given path */
+/* revent EV_STAT */
+typedef struct ev_stat
+{
+  EV_WATCHER_LIST (ev_stat)
+
+  ev_timer timer;     /* private */
+  ev_tstamp interval; /* ro */
+  const char *path;   /* ro */
+  ev_statdata prev;   /* ro */
+  ev_statdata attr;   /* ro */
+
+  int wd; /* wd for inotify, fd for kqueue */
+} ev_stat;
+#endif
+
+#if EV_IDLE_ENABLE
+/* invoked when the nothing else needs to be done, keeps the process from blocking */
+/* revent EV_IDLE */
+typedef struct ev_idle
+{
+  EV_WATCHER (ev_idle)
+} ev_idle;
+#endif
+
+/* invoked for each run of the mainloop, just before the blocking call */
+/* you can still change events in any way you like */
+/* revent EV_PREPARE */
+typedef struct ev_prepare
+{
+  EV_WATCHER (ev_prepare)
+} ev_prepare;
+
+/* invoked for each run of the mainloop, just after the blocking call */
+/* revent EV_CHECK */
+typedef struct ev_check
+{
+  EV_WATCHER (ev_check)
+} ev_check;
+
+#if EV_FORK_ENABLE
+/* the callback gets invoked before check in the child process when a fork was detected */
+/* revent EV_FORK */
+typedef struct ev_fork
+{
+  EV_WATCHER (ev_fork)
+} ev_fork;
+#endif
+
+#if EV_CLEANUP_ENABLE
+/* is invoked just before the loop gets destroyed */
+/* revent EV_CLEANUP */
+typedef struct ev_cleanup
+{
+  EV_WATCHER (ev_cleanup)
+} ev_cleanup;
+#endif
+
+#if EV_EMBED_ENABLE
+/* used to embed an event loop inside another */
+/* the callback gets invoked when the event loop has handled events, and can be 0 */
+typedef struct ev_embed
+{
+  EV_WATCHER (ev_embed)
+
+  struct ev_loop *other; /* ro */
+  ev_io io;              /* private */
+  ev_prepare prepare;    /* private */
+  ev_check check;        /* unused */
+  ev_timer timer;        /* unused */
+  ev_periodic periodic;  /* unused */
+  ev_idle idle;          /* unused */
+  ev_fork fork;          /* private */
+#if EV_CLEANUP_ENABLE
+  ev_cleanup cleanup;    /* unused */
+#endif
+} ev_embed;
+#endif
+
+#if EV_ASYNC_ENABLE
+/* invoked when somebody calls ev_async_send on the watcher */
+/* revent EV_ASYNC */
+typedef struct ev_async
+{
+  EV_WATCHER (ev_async)
+
+  EV_ATOMIC_T sent; /* private */
+} ev_async;
+
+# define ev_async_pending(w) (+(w)->sent)
+#endif
+
+/* the presence of this union forces similar struct layout */
+union ev_any_watcher
+{
+  struct ev_watcher w;
+  struct ev_watcher_list wl;
+
+  struct ev_io io;
+  struct ev_timer timer;
+  struct ev_periodic periodic;
+  struct ev_signal signal;
+  struct ev_child child;
+#if EV_STAT_ENABLE
+  struct ev_stat stat;
+#endif
+#if EV_IDLE_ENABLE
+  struct ev_idle idle;
+#endif
+  struct ev_prepare prepare;
+  struct ev_check check;
+#if EV_FORK_ENABLE
+  struct ev_fork fork;
+#endif
+#if EV_CLEANUP_ENABLE
+  struct ev_cleanup cleanup;
+#endif
+#if EV_EMBED_ENABLE
+  struct ev_embed embed;
+#endif
+#if EV_ASYNC_ENABLE
+  struct ev_async async;
+#endif
+};
+
+/* flag bits for ev_default_loop and ev_loop_new */
+enum {
+  /* the default */
+  EVFLAG_AUTO      = 0x00000000U, /* not quite a mask */
+  /* flag bits */
+  EVFLAG_NOENV     = 0x01000000U, /* do NOT consult environment */
+  EVFLAG_FORKCHECK = 0x02000000U, /* check for a fork in each iteration */
+  /* debugging/feature disable */
+  EVFLAG_NOINOTIFY = 0x00100000U, /* do not attempt to use inotify */
+#if EV_COMPAT3
+  EVFLAG_NOSIGFD   = 0, /* compatibility to pre-3.9 */
+#endif
+  EVFLAG_SIGNALFD  = 0x00200000U, /* attempt to use signalfd */
+  EVFLAG_NOSIGMASK = 0x00400000U  /* avoid modifying the signal mask */
+};
+
+/* method bits to be ored together */
+enum {
+  EVBACKEND_SELECT  = 0x00000001U, /* about anywhere */
+  EVBACKEND_POLL    = 0x00000002U, /* !win */
+  EVBACKEND_EPOLL   = 0x00000004U, /* linux */
+  EVBACKEND_KQUEUE  = 0x00000008U, /* bsd */
+  EVBACKEND_DEVPOLL = 0x00000010U, /* solaris 8 */ /* NYI */
+  EVBACKEND_PORT    = 0x00000020U, /* solaris 10 */
+  EVBACKEND_ALL     = 0x0000003FU, /* all known backends */
+  EVBACKEND_MASK    = 0x0000FFFFU  /* all future backends */
+};
+
+#if EV_PROTOTYPES
+int ev_version_major (void);
+int ev_version_minor (void);
+
+unsigned int ev_supported_backends (void);
+unsigned int ev_recommended_backends (void);
+unsigned int ev_embeddable_backends (void);
+
+ev_tstamp ev_time (void);
+void ev_sleep (ev_tstamp delay); /* sleep for a while */
+
+/* Sets the allocation function to use, works like realloc.
+ * It is used to allocate and free memory.
+ * If it returns zero when memory needs to be allocated, the library might abort
+ * or take some potentially destructive action.
+ * The default is your system realloc function.
+ */
+void ev_set_allocator (void *(*cb)(void *ptr, long size));
+
+/* set the callback function to call on a
+ * retryable syscall error
+ * (such as failed select, poll, epoll_wait)
+ */
+void ev_set_syserr_cb (void (*cb)(const char *msg));
+
+#if EV_MULTIPLICITY
+
+/* the default loop is the only one that handles signals and child watchers */
+/* you can call this as often as you like */
+struct ev_loop *ev_default_loop (unsigned int flags EV_CPP (= 0));
+
+EV_INLINE struct ev_loop *
+EV_MAYBE_UNUSED ev_default_loop_uc_ (void)
+{
+  extern struct ev_loop *ev_default_loop_ptr;
+
+  return ev_default_loop_ptr;
+}
+
+EV_INLINE int
+EV_MAYBE_UNUSED ev_is_default_loop (EV_P)
+{
+  return EV_A == EV_DEFAULT_UC;
+}
+
+/* create and destroy alternative loops that don't handle signals */
+struct ev_loop *ev_loop_new (unsigned int flags EV_CPP (= 0));
+
+ev_tstamp ev_now (EV_P); /* time w.r.t. timers and the eventloop, updated after each poll */
+
+#else
+
+int ev_default_loop (unsigned int flags EV_CPP (= 0)); /* returns true when successful */
+
+EV_INLINE ev_tstamp
+ev_now (void)
+{
+  extern ev_tstamp ev_rt_now;
+
+  return ev_rt_now;
+}
+
+/* looks weird, but ev_is_default_loop (EV_A) still works if this exists */
+EV_INLINE int
+ev_is_default_loop (void)
+{
+  return 1;
+}
+
+#endif /* multiplicity */
+
+/* destroy event loops, also works for the default loop */
+void ev_loop_destroy (EV_P);
+
+/* this needs to be called after fork, to duplicate the loop */
+/* when you want to re-use it in the child */
+/* you can call it in either the parent or the child */
+/* you can actually call it at any time, anywhere :) */
+void ev_loop_fork (EV_P);
+
+unsigned int ev_backend (EV_P); /* backend in use by loop */
+
+void ev_now_update (EV_P); /* update event loop time */
+
+#if EV_WALK_ENABLE
+/* walk (almost) all watchers in the loop of a given type, invoking the */
+/* callback on every such watcher. The callback might stop the watcher, */
+/* but do nothing else with the loop */
+void ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w));
+#endif
+
+#endif /* prototypes */
+
+/* ev_run flags values */
+enum {
+  EVRUN_NOWAIT = 1, /* do not block/wait */
+  EVRUN_ONCE   = 2  /* block *once* only */
+};
+
+/* ev_break how values */
+enum {
+  EVBREAK_CANCEL = 0, /* undo unloop */
+  EVBREAK_ONE    = 1, /* unloop once */
+  EVBREAK_ALL    = 2  /* unloop all loops */
+};
+
+#if EV_PROTOTYPES
+void ev_run (EV_P_ int flags EV_CPP (= 0));
+void ev_break (EV_P_ int how EV_CPP (= EVBREAK_ONE)); /* break out of the loop */
+
+/*
+ * ref/unref can be used to add or remove a refcount on the mainloop. every watcher
+ * keeps one reference. if you have a long-running watcher you never unregister that
+ * should not keep ev_loop from running, unref() after starting, and ref() before stopping.
+ */
+void ev_ref   (EV_P);
+void ev_unref (EV_P);
+
+/*
+ * convenience function, wait for a single event, without registering an event watcher
+ * if timeout is < 0, do wait indefinitely
+ */
+void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg);
+
+# if EV_FEATURE_API
+unsigned int ev_iteration (EV_P); /* number of loop iterations */
+unsigned int ev_depth     (EV_P); /* #ev_loop enters - #ev_loop leaves */
+void         ev_verify    (EV_P); /* abort if loop data corrupted */
+
+void ev_set_io_collect_interval (EV_P_ ev_tstamp interval); /* sleep at least this time, default 0 */
+void ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval); /* sleep at least this time, default 0 */
+
+/* advanced stuff for threading etc. support, see docs */
+void ev_set_userdata (EV_P_ void *data);
+void *ev_userdata (EV_P);
+void ev_set_invoke_pending_cb (EV_P_ void (*invoke_pending_cb)(EV_P));
+void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P), void (*acquire)(EV_P));
+
+unsigned int ev_pending_count (EV_P); /* number of pending events, if any */
+void ev_invoke_pending (EV_P); /* invoke all pending watchers */
+
+/*
+ * stop/start the timer handling.
+ */
+void ev_suspend (EV_P);
+void ev_resume  (EV_P);
+#endif
+
+#endif
+
+/* these may evaluate ev multiple times, and the other arguments at most once */
+/* either use ev_init + ev_TYPE_set, or the ev_TYPE_init macro, below, to first initialise a watcher */
+#define ev_init(ev,cb_) do {			\
+  ((ev_watcher *)(void *)(ev))->active  =	\
+  ((ev_watcher *)(void *)(ev))->pending = 0;	\
+  ev_set_priority ((ev), 0);			\
+  ev_set_cb ((ev), cb_);			\
+} while (0)
+
+#define ev_io_set(ev,fd_,events_)            do { (ev)->fd = (fd_); (ev)->events = (events_) | EV__IOFDSET; } while (0)
+#define ev_timer_set(ev,after_,repeat_)      do { ((ev_watcher_time *)(ev))->at = (after_); (ev)->repeat = (repeat_); } while (0)
+#define ev_periodic_set(ev,ofs_,ival_,rcb_)  do { (ev)->offset = (ofs_); (ev)->interval = (ival_); (ev)->reschedule_cb = (rcb_); } while (0)
+#define ev_signal_set(ev,signum_)            do { (ev)->signum = (signum_); } while (0)
+#define ev_child_set(ev,pid_,trace_)         do { (ev)->pid = (pid_); (ev)->flags = !!(trace_); } while (0)
+#define ev_stat_set(ev,path_,interval_)      do { (ev)->path = (path_); (ev)->interval = (interval_); (ev)->wd = -2; } while (0)
+#define ev_idle_set(ev)                      /* nop, yes, this is a serious in-joke */
+#define ev_prepare_set(ev)                   /* nop, yes, this is a serious in-joke */
+#define ev_check_set(ev)                     /* nop, yes, this is a serious in-joke */
+#define ev_embed_set(ev,other_)              do { (ev)->other = (other_); } while (0)
+#define ev_fork_set(ev)                      /* nop, yes, this is a serious in-joke */
+#define ev_cleanup_set(ev)                   /* nop, yes, this is a serious in-joke */
+#define ev_async_set(ev)                     /* nop, yes, this is a serious in-joke */
+
+#define ev_io_init(ev,cb,fd,events)          do { ev_init ((ev), (cb)); ev_io_set ((ev),(fd),(events)); } while (0)
+#define ev_timer_init(ev,cb,after,repeat)    do { ev_init ((ev), (cb)); ev_timer_set ((ev),(after),(repeat)); } while (0)
+#define ev_periodic_init(ev,cb,ofs,ival,rcb) do { ev_init ((ev), (cb)); ev_periodic_set ((ev),(ofs),(ival),(rcb)); } while (0)
+#define ev_signal_init(ev,cb,signum)         do { ev_init ((ev), (cb)); ev_signal_set ((ev), (signum)); } while (0)
+#define ev_child_init(ev,cb,pid,trace)       do { ev_init ((ev), (cb)); ev_child_set ((ev),(pid),(trace)); } while (0)
+#define ev_stat_init(ev,cb,path,interval)    do { ev_init ((ev), (cb)); ev_stat_set ((ev),(path),(interval)); } while (0)
+#define ev_idle_init(ev,cb)                  do { ev_init ((ev), (cb)); ev_idle_set ((ev)); } while (0)
+#define ev_prepare_init(ev,cb)               do { ev_init ((ev), (cb)); ev_prepare_set ((ev)); } while (0)
+#define ev_check_init(ev,cb)                 do { ev_init ((ev), (cb)); ev_check_set ((ev)); } while (0)
+#define ev_embed_init(ev,cb,other)           do { ev_init ((ev), (cb)); ev_embed_set ((ev),(other)); } while (0)
+#define ev_fork_init(ev,cb)                  do { ev_init ((ev), (cb)); ev_fork_set ((ev)); } while (0)
+#define ev_cleanup_init(ev,cb)               do { ev_init ((ev), (cb)); ev_cleanup_set ((ev)); } while (0)
+#define ev_async_init(ev,cb)                 do { ev_init ((ev), (cb)); ev_async_set ((ev)); } while (0)
+
+#define ev_is_pending(ev)                    (0 + ((ev_watcher *)(void *)(ev))->pending) /* ro, true when watcher is waiting for callback invocation */
+#define ev_is_active(ev)                     (0 + ((ev_watcher *)(void *)(ev))->active) /* ro, true when the watcher has been started */
+
+#define ev_cb(ev)                            (ev)->cb /* rw */
+
+#if EV_MINPRI == EV_MAXPRI
+# define ev_priority(ev)                     ((ev), EV_MINPRI)
+# define ev_set_priority(ev,pri)             ((ev), (pri))
+#else
+# define ev_priority(ev)                     (+(((ev_watcher *)(void *)(ev))->priority))
+# define ev_set_priority(ev,pri)             (   (ev_watcher *)(void *)(ev))->priority = (pri)
+#endif
+
+#define ev_periodic_at(ev)                   (+((ev_watcher_time *)(ev))->at)
+
+#ifndef ev_set_cb
+# define ev_set_cb(ev,cb_)                   ev_cb (ev) = (cb_)
+#endif
+
+/* stopping (enabling, adding) a watcher does nothing if it is already running */
+/* stopping (disabling, deleting) a watcher does nothing unless its already running */
+#if EV_PROTOTYPES
+
+/* feeds an event into a watcher as if the event actually occured */
+/* accepts any ev_watcher type */
+void ev_feed_event     (EV_P_ void *w, int revents);
+void ev_feed_fd_event  (EV_P_ int fd, int revents);
+#if EV_SIGNAL_ENABLE
+void ev_feed_signal    (int signum);
+void ev_feed_signal_event (EV_P_ int signum);
+#endif
+void ev_invoke         (EV_P_ void *w, int revents);
+int  ev_clear_pending  (EV_P_ void *w);
+
+void ev_io_start       (EV_P_ ev_io *w);
+void ev_io_stop        (EV_P_ ev_io *w);
+
+void ev_timer_start    (EV_P_ ev_timer *w);
+void ev_timer_stop     (EV_P_ ev_timer *w);
+/* stops if active and no repeat, restarts if active and repeating, starts if inactive and repeating */
+void ev_timer_again    (EV_P_ ev_timer *w);
+/* return remaining time */
+ev_tstamp ev_timer_remaining (EV_P_ ev_timer *w);
+
+#if EV_PERIODIC_ENABLE
+void ev_periodic_start (EV_P_ ev_periodic *w);
+void ev_periodic_stop  (EV_P_ ev_periodic *w);
+void ev_periodic_again (EV_P_ ev_periodic *w);
+#endif
+
+/* only supported in the default loop */
+#if EV_SIGNAL_ENABLE
+void ev_signal_start   (EV_P_ ev_signal *w);
+void ev_signal_stop    (EV_P_ ev_signal *w);
+#endif
+
+/* only supported in the default loop */
+# if EV_CHILD_ENABLE
+void ev_child_start    (EV_P_ ev_child *w);
+void ev_child_stop     (EV_P_ ev_child *w);
+# endif
+
+# if EV_STAT_ENABLE
+void ev_stat_start     (EV_P_ ev_stat *w);
+void ev_stat_stop      (EV_P_ ev_stat *w);
+void ev_stat_stat      (EV_P_ ev_stat *w);
+# endif
+
+# if EV_IDLE_ENABLE
+void ev_idle_start     (EV_P_ ev_idle *w);
+void ev_idle_stop      (EV_P_ ev_idle *w);
+# endif
+
+#if EV_PREPARE_ENABLE
+void ev_prepare_start  (EV_P_ ev_prepare *w);
+void ev_prepare_stop   (EV_P_ ev_prepare *w);
+#endif
+
+#if EV_CHECK_ENABLE
+void ev_check_start    (EV_P_ ev_check *w);
+void ev_check_stop     (EV_P_ ev_check *w);
+#endif
+
+# if EV_FORK_ENABLE
+void ev_fork_start     (EV_P_ ev_fork *w);
+void ev_fork_stop      (EV_P_ ev_fork *w);
+# endif
+
+# if EV_CLEANUP_ENABLE
+void ev_cleanup_start  (EV_P_ ev_cleanup *w);
+void ev_cleanup_stop   (EV_P_ ev_cleanup *w);
+# endif
+
+# if EV_EMBED_ENABLE
+/* only supported when loop to be embedded is in fact embeddable */
+void ev_embed_start    (EV_P_ ev_embed *w);
+void ev_embed_stop     (EV_P_ ev_embed *w);
+void ev_embed_sweep    (EV_P_ ev_embed *w);
+# endif
+
+# if EV_ASYNC_ENABLE
+void ev_async_start    (EV_P_ ev_async *w);
+void ev_async_stop     (EV_P_ ev_async *w);
+void ev_async_send     (EV_P_ ev_async *w);
+# endif
+
+#if EV_COMPAT3
+  #define EVLOOP_NONBLOCK EVRUN_NOWAIT
+  #define EVLOOP_ONESHOT  EVRUN_ONCE
+  #define EVUNLOOP_CANCEL EVBREAK_CANCEL
+  #define EVUNLOOP_ONE    EVBREAK_ONE
+  #define EVUNLOOP_ALL    EVBREAK_ALL
+  #if EV_PROTOTYPES
+    EV_INLINE void EV_MAYBE_UNUSED ev_loop   (EV_P_ int flags) { ev_run   (EV_A_ flags); }
+    EV_INLINE void EV_MAYBE_UNUSED ev_unloop (EV_P_ int how  ) { ev_break (EV_A_ how  ); }
+    EV_INLINE void EV_MAYBE_UNUSED ev_default_destroy (void) { ev_loop_destroy (EV_DEFAULT); }
+    EV_INLINE void EV_MAYBE_UNUSED ev_default_fork    (void) { ev_loop_fork    (EV_DEFAULT); }
+    #if EV_FEATURE_API
+      EV_INLINE unsigned int EV_MAYBE_UNUSED ev_loop_count  (EV_P) { return ev_iteration  (EV_A); }
+      EV_INLINE unsigned int EV_MAYBE_UNUSED ev_loop_depth  (EV_P) { return ev_depth      (EV_A); }
+      EV_INLINE void         EV_MAYBE_UNUSED ev_loop_verify (EV_P) {        ev_verify     (EV_A); }
+    #endif
+  #endif
+#else
+  typedef struct ev_loop ev_loop;
+#endif
+
+#endif
+
+EV_CPP(})
+
+#endif
+
diff --git a/src/rt/libuv/include/uv-private/ngx-queue.h b/src/rt/libuv/include/uv-private/ngx-queue.h
new file mode 100644
index 00000000000..f8576d67dc2
--- /dev/null
+++ b/src/rt/libuv/include/uv-private/ngx-queue.h
@@ -0,0 +1,102 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#ifndef _NGX_QUEUE_H_INCLUDED_
+#define _NGX_QUEUE_H_INCLUDED_
+
+
+typedef struct ngx_queue_s  ngx_queue_t;
+
+struct ngx_queue_s {
+    ngx_queue_t  *prev;
+    ngx_queue_t  *next;
+};
+
+
+#define ngx_queue_init(q)                                                     \
+    (q)->prev = q;                                                            \
+    (q)->next = q
+
+
+#define ngx_queue_empty(h)                                                    \
+    (h == (h)->prev)
+
+
+#define ngx_queue_insert_head(h, x)                                           \
+    (x)->next = (h)->next;                                                    \
+    (x)->next->prev = x;                                                      \
+    (x)->prev = h;                                                            \
+    (h)->next = x
+
+
+#define ngx_queue_insert_after   ngx_queue_insert_head
+
+
+#define ngx_queue_insert_tail(h, x)                                           \
+    (x)->prev = (h)->prev;                                                    \
+    (x)->prev->next = x;                                                      \
+    (x)->next = h;                                                            \
+    (h)->prev = x
+
+
+#define ngx_queue_head(h)                                                     \
+    (h)->next
+
+
+#define ngx_queue_last(h)                                                     \
+    (h)->prev
+
+
+#define ngx_queue_sentinel(h)                                                 \
+    (h)
+
+
+#define ngx_queue_next(q)                                                     \
+    (q)->next
+
+
+#define ngx_queue_prev(q)                                                     \
+    (q)->prev
+
+
+#if (NGX_DEBUG)
+
+#define ngx_queue_remove(x)                                                   \
+    (x)->next->prev = (x)->prev;                                              \
+    (x)->prev->next = (x)->next;                                              \
+    (x)->prev = NULL;                                                         \
+    (x)->next = NULL
+
+#else
+
+#define ngx_queue_remove(x)                                                   \
+    (x)->next->prev = (x)->prev;                                              \
+    (x)->prev->next = (x)->next
+
+#endif
+
+
+#define ngx_queue_split(h, q, n)                                              \
+    (n)->prev = (h)->prev;                                                    \
+    (n)->prev->next = n;                                                      \
+    (n)->next = q;                                                            \
+    (h)->prev = (q)->prev;                                                    \
+    (h)->prev->next = h;                                                      \
+    (q)->prev = n;
+
+
+#define ngx_queue_add(h, n)                                                   \
+    (h)->prev->next = (n)->next;                                              \
+    (n)->next->prev = (h)->prev;                                              \
+    (h)->prev = (n)->prev;                                                    \
+    (h)->prev->next = h;
+
+
+#define ngx_queue_data(q, type, link)                                         \
+    (type *) ((unsigned char *) q - offsetof(type, link))
+
+
+#endif /* _NGX_QUEUE_H_INCLUDED_ */
diff --git a/src/rt/libuv/include/uv-private/tree.h b/src/rt/libuv/include/uv-private/tree.h
new file mode 100644
index 00000000000..37966d353c3
--- /dev/null
+++ b/src/rt/libuv/include/uv-private/tree.h
@@ -0,0 +1,762 @@
+/*-
+ * Copyright 2002 Niels Provos <provos@citi.umich.edu>
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * 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  _UV_TREE_H_
+#define  _UV_TREE_H_
+
+#define __unused
+
+/*
+ * This file defines data structures for different types of trees:
+ * splay trees and red-black trees.
+ *
+ * A splay tree is a self-organizing data structure.  Every operation
+ * on the tree causes a splay to happen.  The splay moves the requested
+ * node to the root of the tree and partly rebalances it.
+ *
+ * This has the benefit that request locality causes faster lookups as
+ * the requested nodes move to the top of the tree.  On the other hand,
+ * every lookup causes memory writes.
+ *
+ * The Balance Theorem bounds the total access time for m operations
+ * and n inserts on an initially empty tree as O((m + n)lg n).  The
+ * amortized cost for a sequence of m accesses to a splay tree is O(lg n);
+ *
+ * A red-black tree is a binary search tree with the node color as an
+ * extra attribute.  It fulfills a set of conditions:
+ *  - every search path from the root to a leaf consists of the
+ *    same number of black nodes,
+ *  - each red node (except for the root) has a black parent,
+ *  - each leaf node is black.
+ *
+ * Every operation on a red-black tree is bounded as O(lg n).
+ * The maximum height of a red-black tree is 2lg (n+1).
+ */
+
+#define SPLAY_HEAD(name, type)                                                \
+struct name {                                                                 \
+  struct type *sph_root; /* root of the tree */                               \
+}
+
+#define SPLAY_INITIALIZER(root)                                               \
+  { NULL }
+
+#define SPLAY_INIT(root) do {                                                 \
+  (root)->sph_root = NULL;                                                    \
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_ENTRY(type)                                                     \
+struct {                                                                      \
+  struct type *spe_left;          /* left element */                          \
+  struct type *spe_right;         /* right element */                         \
+}
+
+#define SPLAY_LEFT(elm, field)    (elm)->field.spe_left
+#define SPLAY_RIGHT(elm, field)   (elm)->field.spe_right
+#define SPLAY_ROOT(head)          (head)->sph_root
+#define SPLAY_EMPTY(head)         (SPLAY_ROOT(head) == NULL)
+
+/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
+#define SPLAY_ROTATE_RIGHT(head, tmp, field) do {                             \
+  SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field);              \
+  SPLAY_RIGHT(tmp, field) = (head)->sph_root;                                 \
+  (head)->sph_root = tmp;                                                     \
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_ROTATE_LEFT(head, tmp, field) do {                              \
+  SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field);              \
+  SPLAY_LEFT(tmp, field) = (head)->sph_root;                                  \
+  (head)->sph_root = tmp;                                                     \
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_LINKLEFT(head, tmp, field) do {                                 \
+  SPLAY_LEFT(tmp, field) = (head)->sph_root;                                  \
+  tmp = (head)->sph_root;                                                     \
+  (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);                     \
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_LINKRIGHT(head, tmp, field) do {                                \
+  SPLAY_RIGHT(tmp, field) = (head)->sph_root;                                 \
+  tmp = (head)->sph_root;                                                     \
+  (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);                    \
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_ASSEMBLE(head, node, left, right, field) do {                   \
+  SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field);             \
+  SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);            \
+  SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field);             \
+  SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field);             \
+} while (/*CONSTCOND*/ 0)
+
+/* Generates prototypes and inline functions */
+
+#define SPLAY_PROTOTYPE(name, type, field, cmp)                               \
+void name##_SPLAY(struct name *, struct type *);                              \
+void name##_SPLAY_MINMAX(struct name *, int);                                 \
+struct type *name##_SPLAY_INSERT(struct name *, struct type *);               \
+struct type *name##_SPLAY_REMOVE(struct name *, struct type *);               \
+                                                                              \
+/* Finds the node with the same key as elm */                                 \
+static __inline struct type *                                                 \
+name##_SPLAY_FIND(struct name *head, struct type *elm)                        \
+{                                                                             \
+  if (SPLAY_EMPTY(head))                                                      \
+    return(NULL);                                                             \
+  name##_SPLAY(head, elm);                                                    \
+  if ((cmp)(elm, (head)->sph_root) == 0)                                      \
+    return (head->sph_root);                                                  \
+  return (NULL);                                                              \
+}                                                                             \
+                                                                              \
+static __inline struct type *                                                 \
+name##_SPLAY_NEXT(struct name *head, struct type *elm)                        \
+{                                                                             \
+  name##_SPLAY(head, elm);                                                    \
+  if (SPLAY_RIGHT(elm, field) != NULL) {                                      \
+    elm = SPLAY_RIGHT(elm, field);                                            \
+    while (SPLAY_LEFT(elm, field) != NULL) {                                  \
+      elm = SPLAY_LEFT(elm, field);                                           \
+    }                                                                         \
+  } else                                                                      \
+    elm = NULL;                                                               \
+  return (elm);                                                               \
+}                                                                             \
+                                                                              \
+static __inline struct type *                                                 \
+name##_SPLAY_MIN_MAX(struct name *head, int val)                              \
+{                                                                             \
+  name##_SPLAY_MINMAX(head, val);                                             \
+  return (SPLAY_ROOT(head));                                                  \
+}
+
+/* Main splay operation.
+ * Moves node close to the key of elm to top
+ */
+#define SPLAY_GENERATE(name, type, field, cmp)                                \
+struct type *                                                                 \
+name##_SPLAY_INSERT(struct name *head, struct type *elm)                      \
+{                                                                             \
+    if (SPLAY_EMPTY(head)) {                                                  \
+      SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL;                \
+    } else {                                                                  \
+      int __comp;                                                             \
+      name##_SPLAY(head, elm);                                                \
+      __comp = (cmp)(elm, (head)->sph_root);                                  \
+      if(__comp < 0) {                                                        \
+        SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);         \
+        SPLAY_RIGHT(elm, field) = (head)->sph_root;                           \
+        SPLAY_LEFT((head)->sph_root, field) = NULL;                           \
+      } else if (__comp > 0) {                                                \
+        SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);       \
+        SPLAY_LEFT(elm, field) = (head)->sph_root;                            \
+        SPLAY_RIGHT((head)->sph_root, field) = NULL;                          \
+      } else                                                                  \
+        return ((head)->sph_root);                                            \
+    }                                                                         \
+    (head)->sph_root = (elm);                                                 \
+    return (NULL);                                                            \
+}                                                                             \
+                                                                              \
+struct type *                                                                 \
+name##_SPLAY_REMOVE(struct name *head, struct type *elm)                      \
+{                                                                             \
+  struct type *__tmp;                                                         \
+  if (SPLAY_EMPTY(head))                                                      \
+    return (NULL);                                                            \
+  name##_SPLAY(head, elm);                                                    \
+  if ((cmp)(elm, (head)->sph_root) == 0) {                                    \
+    if (SPLAY_LEFT((head)->sph_root, field) == NULL) {                        \
+      (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);                \
+    } else {                                                                  \
+      __tmp = SPLAY_RIGHT((head)->sph_root, field);                           \
+      (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);                 \
+      name##_SPLAY(head, elm);                                                \
+      SPLAY_RIGHT((head)->sph_root, field) = __tmp;                           \
+    }                                                                         \
+    return (elm);                                                             \
+  }                                                                           \
+  return (NULL);                                                              \
+}                                                                             \
+                                                                              \
+void                                                                          \
+name##_SPLAY(struct name *head, struct type *elm)                             \
+{                                                                             \
+  struct type __node, *__left, *__right, *__tmp;                              \
+  int __comp;                                                                 \
+                                                                              \
+  SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;            \
+  __left = __right = &__node;                                                 \
+                                                                              \
+  while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) {                      \
+    if (__comp < 0) {                                                         \
+      __tmp = SPLAY_LEFT((head)->sph_root, field);                            \
+      if (__tmp == NULL)                                                      \
+        break;                                                                \
+      if ((cmp)(elm, __tmp) < 0){                                             \
+        SPLAY_ROTATE_RIGHT(head, __tmp, field);                               \
+        if (SPLAY_LEFT((head)->sph_root, field) == NULL)                      \
+          break;                                                              \
+      }                                                                       \
+      SPLAY_LINKLEFT(head, __right, field);                                   \
+    } else if (__comp > 0) {                                                  \
+      __tmp = SPLAY_RIGHT((head)->sph_root, field);                           \
+      if (__tmp == NULL)                                                      \
+        break;                                                                \
+      if ((cmp)(elm, __tmp) > 0){                                             \
+        SPLAY_ROTATE_LEFT(head, __tmp, field);                                \
+        if (SPLAY_RIGHT((head)->sph_root, field) == NULL)                     \
+          break;                                                              \
+      }                                                                       \
+      SPLAY_LINKRIGHT(head, __left, field);                                   \
+    }                                                                         \
+  }                                                                           \
+  SPLAY_ASSEMBLE(head, &__node, __left, __right, field);                      \
+}                                                                             \
+                                                                              \
+/* Splay with either the minimum or the maximum element                       \
+ * Used to find minimum or maximum element in tree.                           \
+ */                                                                           \
+void name##_SPLAY_MINMAX(struct name *head, int __comp)                       \
+{                                                                             \
+  struct type __node, *__left, *__right, *__tmp;                              \
+                                                                              \
+  SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;            \
+  __left = __right = &__node;                                                 \
+                                                                              \
+  while (1) {                                                                 \
+    if (__comp < 0) {                                                         \
+      __tmp = SPLAY_LEFT((head)->sph_root, field);                            \
+      if (__tmp == NULL)                                                      \
+        break;                                                                \
+      if (__comp < 0){                                                        \
+        SPLAY_ROTATE_RIGHT(head, __tmp, field);                               \
+        if (SPLAY_LEFT((head)->sph_root, field) == NULL)                      \
+          break;                                                              \
+      }                                                                       \
+      SPLAY_LINKLEFT(head, __right, field);                                   \
+    } else if (__comp > 0) {                                                  \
+      __tmp = SPLAY_RIGHT((head)->sph_root, field);                           \
+      if (__tmp == NULL)                                                      \
+        break;                                                                \
+      if (__comp > 0) {                                                       \
+        SPLAY_ROTATE_LEFT(head, __tmp, field);                                \
+        if (SPLAY_RIGHT((head)->sph_root, field) == NULL)                     \
+          break;                                                              \
+      }                                                                       \
+      SPLAY_LINKRIGHT(head, __left, field);                                   \
+    }                                                                         \
+  }                                                                           \
+  SPLAY_ASSEMBLE(head, &__node, __left, __right, field);                      \
+}
+
+#define SPLAY_NEGINF  -1
+#define SPLAY_INF     1
+
+#define SPLAY_INSERT(name, x, y)  name##_SPLAY_INSERT(x, y)
+#define SPLAY_REMOVE(name, x, y)  name##_SPLAY_REMOVE(x, y)
+#define SPLAY_FIND(name, x, y)    name##_SPLAY_FIND(x, y)
+#define SPLAY_NEXT(name, x, y)    name##_SPLAY_NEXT(x, y)
+#define SPLAY_MIN(name, x)        (SPLAY_EMPTY(x) ? NULL                      \
+                                  : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
+#define SPLAY_MAX(name, x)        (SPLAY_EMPTY(x) ? NULL                      \
+                                  : name##_SPLAY_MIN_MAX(x, SPLAY_INF))
+
+#define SPLAY_FOREACH(x, name, head)                                          \
+  for ((x) = SPLAY_MIN(name, head);                                           \
+       (x) != NULL;                                                           \
+       (x) = SPLAY_NEXT(name, head, x))
+
+/* Macros that define a red-black tree */
+#define RB_HEAD(name, type)                                                   \
+struct name {                                                                 \
+  struct type *rbh_root; /* root of the tree */                               \
+}
+
+#define RB_INITIALIZER(root)                                                  \
+  { NULL }
+
+#define RB_INIT(root) do {                                                    \
+  (root)->rbh_root = NULL;                                                    \
+} while (/*CONSTCOND*/ 0)
+
+#define RB_BLACK  0
+#define RB_RED    1
+#define RB_ENTRY(type)                                                        \
+struct {                                                                      \
+  struct type *rbe_left;        /* left element */                            \
+  struct type *rbe_right;       /* right element */                           \
+  struct type *rbe_parent;      /* parent element */                          \
+  int rbe_color;                /* node color */                              \
+}
+
+#define RB_LEFT(elm, field)     (elm)->field.rbe_left
+#define RB_RIGHT(elm, field)    (elm)->field.rbe_right
+#define RB_PARENT(elm, field)   (elm)->field.rbe_parent
+#define RB_COLOR(elm, field)    (elm)->field.rbe_color
+#define RB_ROOT(head)           (head)->rbh_root
+#define RB_EMPTY(head)          (RB_ROOT(head) == NULL)
+
+#define RB_SET(elm, parent, field) do {                                       \
+  RB_PARENT(elm, field) = parent;                                             \
+  RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL;                          \
+  RB_COLOR(elm, field) = RB_RED;                                              \
+} while (/*CONSTCOND*/ 0)
+
+#define RB_SET_BLACKRED(black, red, field) do {                               \
+  RB_COLOR(black, field) = RB_BLACK;                                          \
+  RB_COLOR(red, field) = RB_RED;                                              \
+} while (/*CONSTCOND*/ 0)
+
+#ifndef RB_AUGMENT
+#define RB_AUGMENT(x)  do {} while (0)
+#endif
+
+#define RB_ROTATE_LEFT(head, elm, tmp, field) do {                            \
+  (tmp) = RB_RIGHT(elm, field);                                               \
+  if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) {                 \
+    RB_PARENT(RB_LEFT(tmp, field), field) = (elm);                            \
+  }                                                                           \
+  RB_AUGMENT(elm);                                                            \
+  if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) {              \
+    if ((elm) == RB_LEFT(RB_PARENT(elm, field), field))                       \
+      RB_LEFT(RB_PARENT(elm, field), field) = (tmp);                          \
+    else                                                                      \
+      RB_RIGHT(RB_PARENT(elm, field), field) = (tmp);                         \
+  } else                                                                      \
+    (head)->rbh_root = (tmp);                                                 \
+  RB_LEFT(tmp, field) = (elm);                                                \
+  RB_PARENT(elm, field) = (tmp);                                              \
+  RB_AUGMENT(tmp);                                                            \
+  if ((RB_PARENT(tmp, field)))                                                \
+    RB_AUGMENT(RB_PARENT(tmp, field));                                        \
+} while (/*CONSTCOND*/ 0)
+
+#define RB_ROTATE_RIGHT(head, elm, tmp, field) do {                           \
+  (tmp) = RB_LEFT(elm, field);                                                \
+  if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) {                 \
+    RB_PARENT(RB_RIGHT(tmp, field), field) = (elm);                           \
+  }                                                                           \
+  RB_AUGMENT(elm);                                                            \
+  if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) {              \
+    if ((elm) == RB_LEFT(RB_PARENT(elm, field), field))                       \
+      RB_LEFT(RB_PARENT(elm, field), field) = (tmp);                          \
+    else                                                                      \
+      RB_RIGHT(RB_PARENT(elm, field), field) = (tmp);                         \
+  } else                                                                      \
+    (head)->rbh_root = (tmp);                                                 \
+  RB_RIGHT(tmp, field) = (elm);                                               \
+  RB_PARENT(elm, field) = (tmp);                                              \
+  RB_AUGMENT(tmp);                                                            \
+  if ((RB_PARENT(tmp, field)))                                                \
+    RB_AUGMENT(RB_PARENT(tmp, field));                                        \
+} while (/*CONSTCOND*/ 0)
+
+/* Generates prototypes and inline functions */
+#define  RB_PROTOTYPE(name, type, field, cmp)                                 \
+  RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
+#define  RB_PROTOTYPE_STATIC(name, type, field, cmp)                          \
+  RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static)
+#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr)                   \
+attr void name##_RB_INSERT_COLOR(struct name *, struct type *);               \
+attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
+attr struct type *name##_RB_REMOVE(struct name *, struct type *);             \
+attr struct type *name##_RB_INSERT(struct name *, struct type *);             \
+attr struct type *name##_RB_FIND(struct name *, struct type *);               \
+attr struct type *name##_RB_NFIND(struct name *, struct type *);              \
+attr struct type *name##_RB_NEXT(struct type *);                              \
+attr struct type *name##_RB_PREV(struct type *);                              \
+attr struct type *name##_RB_MINMAX(struct name *, int);                       \
+                                                                              \
+
+/* Main rb operation.
+ * Moves node close to the key of elm to top
+ */
+#define  RB_GENERATE(name, type, field, cmp)                                  \
+  RB_GENERATE_INTERNAL(name, type, field, cmp,)
+#define  RB_GENERATE_STATIC(name, type, field, cmp)                           \
+  RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static)
+#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr)                    \
+attr void                                                                     \
+name##_RB_INSERT_COLOR(struct name *head, struct type *elm)                   \
+{                                                                             \
+  struct type *parent, *gparent, *tmp;                                        \
+  while ((parent = RB_PARENT(elm, field)) != NULL &&                          \
+      RB_COLOR(parent, field) == RB_RED) {                                    \
+    gparent = RB_PARENT(parent, field);                                       \
+    if (parent == RB_LEFT(gparent, field)) {                                  \
+      tmp = RB_RIGHT(gparent, field);                                         \
+      if (tmp && RB_COLOR(tmp, field) == RB_RED) {                            \
+        RB_COLOR(tmp, field) = RB_BLACK;                                      \
+        RB_SET_BLACKRED(parent, gparent, field);                              \
+        elm = gparent;                                                        \
+        continue;                                                             \
+      }                                                                       \
+      if (RB_RIGHT(parent, field) == elm) {                                   \
+        RB_ROTATE_LEFT(head, parent, tmp, field);                             \
+        tmp = parent;                                                         \
+        parent = elm;                                                         \
+        elm = tmp;                                                            \
+      }                                                                       \
+      RB_SET_BLACKRED(parent, gparent, field);                                \
+      RB_ROTATE_RIGHT(head, gparent, tmp, field);                             \
+    } else {                                                                  \
+      tmp = RB_LEFT(gparent, field);                                          \
+      if (tmp && RB_COLOR(tmp, field) == RB_RED) {                            \
+        RB_COLOR(tmp, field) = RB_BLACK;                                      \
+        RB_SET_BLACKRED(parent, gparent, field);                              \
+        elm = gparent;                                                        \
+        continue;                                                             \
+      }                                                                       \
+      if (RB_LEFT(parent, field) == elm) {                                    \
+        RB_ROTATE_RIGHT(head, parent, tmp, field);                            \
+        tmp = parent;                                                         \
+        parent = elm;                                                         \
+        elm = tmp;                                                            \
+      }                                                                       \
+      RB_SET_BLACKRED(parent, gparent, field);                                \
+      RB_ROTATE_LEFT(head, gparent, tmp, field);                              \
+    }                                                                         \
+  }                                                                           \
+  RB_COLOR(head->rbh_root, field) = RB_BLACK;                                 \
+}                                                                             \
+                                                                              \
+attr void                                                                     \
+name##_RB_REMOVE_COLOR(struct name *head, struct type *parent,                \
+    struct type *elm)                                                         \
+{                                                                             \
+  struct type *tmp;                                                           \
+  while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) &&                 \
+      elm != RB_ROOT(head)) {                                                 \
+    if (RB_LEFT(parent, field) == elm) {                                      \
+      tmp = RB_RIGHT(parent, field);                                          \
+      if (RB_COLOR(tmp, field) == RB_RED) {                                   \
+        RB_SET_BLACKRED(tmp, parent, field);                                  \
+        RB_ROTATE_LEFT(head, parent, tmp, field);                             \
+        tmp = RB_RIGHT(parent, field);                                        \
+      }                                                                       \
+      if ((RB_LEFT(tmp, field) == NULL ||                                     \
+          RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&                \
+          (RB_RIGHT(tmp, field) == NULL ||                                    \
+          RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {               \
+        RB_COLOR(tmp, field) = RB_RED;                                        \
+        elm = parent;                                                         \
+        parent = RB_PARENT(elm, field);                                       \
+      } else {                                                                \
+        if (RB_RIGHT(tmp, field) == NULL ||                                   \
+            RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {              \
+          struct type *oleft;                                                 \
+          if ((oleft = RB_LEFT(tmp, field))                                   \
+              != NULL)                                                        \
+            RB_COLOR(oleft, field) = RB_BLACK;                                \
+          RB_COLOR(tmp, field) = RB_RED;                                      \
+          RB_ROTATE_RIGHT(head, tmp, oleft, field);                           \
+          tmp = RB_RIGHT(parent, field);                                      \
+        }                                                                     \
+        RB_COLOR(tmp, field) = RB_COLOR(parent, field);                       \
+        RB_COLOR(parent, field) = RB_BLACK;                                   \
+        if (RB_RIGHT(tmp, field))                                             \
+          RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;                   \
+        RB_ROTATE_LEFT(head, parent, tmp, field);                             \
+        elm = RB_ROOT(head);                                                  \
+        break;                                                                \
+      }                                                                       \
+    } else {                                                                  \
+      tmp = RB_LEFT(parent, field);                                           \
+      if (RB_COLOR(tmp, field) == RB_RED) {                                   \
+        RB_SET_BLACKRED(tmp, parent, field);                                  \
+        RB_ROTATE_RIGHT(head, parent, tmp, field);                            \
+        tmp = RB_LEFT(parent, field);                                         \
+      }                                                                       \
+      if ((RB_LEFT(tmp, field) == NULL ||                                     \
+          RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&                \
+          (RB_RIGHT(tmp, field) == NULL ||                                    \
+          RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {               \
+        RB_COLOR(tmp, field) = RB_RED;                                        \
+        elm = parent;                                                         \
+        parent = RB_PARENT(elm, field);                                       \
+      } else {                                                                \
+        if (RB_LEFT(tmp, field) == NULL ||                                    \
+            RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {               \
+          struct type *oright;                                                \
+          if ((oright = RB_RIGHT(tmp, field))                                 \
+              != NULL)                                                        \
+            RB_COLOR(oright, field) = RB_BLACK;                               \
+          RB_COLOR(tmp, field) = RB_RED;                                      \
+          RB_ROTATE_LEFT(head, tmp, oright, field);                           \
+          tmp = RB_LEFT(parent, field);                                       \
+        }                                                                     \
+        RB_COLOR(tmp, field) = RB_COLOR(parent, field);                       \
+        RB_COLOR(parent, field) = RB_BLACK;                                   \
+        if (RB_LEFT(tmp, field))                                              \
+          RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;                    \
+        RB_ROTATE_RIGHT(head, parent, tmp, field);                            \
+        elm = RB_ROOT(head);                                                  \
+        break;                                                                \
+      }                                                                       \
+    }                                                                         \
+  }                                                                           \
+  if (elm)                                                                    \
+    RB_COLOR(elm, field) = RB_BLACK;                                          \
+}                                                                             \
+                                                                              \
+attr struct type *                                                            \
+name##_RB_REMOVE(struct name *head, struct type *elm)                         \
+{                                                                             \
+  struct type *child, *parent, *old = elm;                                    \
+  int color;                                                                  \
+  if (RB_LEFT(elm, field) == NULL)                                            \
+    child = RB_RIGHT(elm, field);                                             \
+  else if (RB_RIGHT(elm, field) == NULL)                                      \
+    child = RB_LEFT(elm, field);                                              \
+  else {                                                                      \
+    struct type *left;                                                        \
+    elm = RB_RIGHT(elm, field);                                               \
+    while ((left = RB_LEFT(elm, field)) != NULL)                              \
+      elm = left;                                                             \
+    child = RB_RIGHT(elm, field);                                             \
+    parent = RB_PARENT(elm, field);                                           \
+    color = RB_COLOR(elm, field);                                             \
+    if (child)                                                                \
+      RB_PARENT(child, field) = parent;                                       \
+    if (parent) {                                                             \
+      if (RB_LEFT(parent, field) == elm)                                      \
+        RB_LEFT(parent, field) = child;                                       \
+      else                                                                    \
+        RB_RIGHT(parent, field) = child;                                      \
+      RB_AUGMENT(parent);                                                     \
+    } else                                                                    \
+      RB_ROOT(head) = child;                                                  \
+    if (RB_PARENT(elm, field) == old)                                         \
+      parent = elm;                                                           \
+    (elm)->field = (old)->field;                                              \
+    if (RB_PARENT(old, field)) {                                              \
+      if (RB_LEFT(RB_PARENT(old, field), field) == old)                       \
+        RB_LEFT(RB_PARENT(old, field), field) = elm;                          \
+      else                                                                    \
+        RB_RIGHT(RB_PARENT(old, field), field) = elm;                         \
+      RB_AUGMENT(RB_PARENT(old, field));                                      \
+    } else                                                                    \
+      RB_ROOT(head) = elm;                                                    \
+    RB_PARENT(RB_LEFT(old, field), field) = elm;                              \
+    if (RB_RIGHT(old, field))                                                 \
+      RB_PARENT(RB_RIGHT(old, field), field) = elm;                           \
+    if (parent) {                                                             \
+      left = parent;                                                          \
+      do {                                                                    \
+        RB_AUGMENT(left);                                                     \
+      } while ((left = RB_PARENT(left, field)) != NULL);                      \
+    }                                                                         \
+    goto color;                                                               \
+  }                                                                           \
+  parent = RB_PARENT(elm, field);                                             \
+  color = RB_COLOR(elm, field);                                               \
+  if (child)                                                                  \
+    RB_PARENT(child, field) = parent;                                         \
+  if (parent) {                                                               \
+    if (RB_LEFT(parent, field) == elm)                                        \
+      RB_LEFT(parent, field) = child;                                         \
+    else                                                                      \
+      RB_RIGHT(parent, field) = child;                                        \
+    RB_AUGMENT(parent);                                                       \
+  } else                                                                      \
+    RB_ROOT(head) = child;                                                    \
+color:                                                                        \
+  if (color == RB_BLACK)                                                      \
+    name##_RB_REMOVE_COLOR(head, parent, child);                              \
+  return (old);                                                               \
+}                                                                             \
+                                                                              \
+/* Inserts a node into the RB tree */                                         \
+attr struct type *                                                            \
+name##_RB_INSERT(struct name *head, struct type *elm)                         \
+{                                                                             \
+  struct type *tmp;                                                           \
+  struct type *parent = NULL;                                                 \
+  int comp = 0;                                                               \
+  tmp = RB_ROOT(head);                                                        \
+  while (tmp) {                                                               \
+    parent = tmp;                                                             \
+    comp = (cmp)(elm, parent);                                                \
+    if (comp < 0)                                                             \
+      tmp = RB_LEFT(tmp, field);                                              \
+    else if (comp > 0)                                                        \
+      tmp = RB_RIGHT(tmp, field);                                             \
+    else                                                                      \
+      return (tmp);                                                           \
+  }                                                                           \
+  RB_SET(elm, parent, field);                                                 \
+  if (parent != NULL) {                                                       \
+    if (comp < 0)                                                             \
+      RB_LEFT(parent, field) = elm;                                           \
+    else                                                                      \
+      RB_RIGHT(parent, field) = elm;                                          \
+    RB_AUGMENT(parent);                                                       \
+  } else                                                                      \
+    RB_ROOT(head) = elm;                                                      \
+  name##_RB_INSERT_COLOR(head, elm);                                          \
+  return (NULL);                                                              \
+}                                                                             \
+                                                                              \
+/* Finds the node with the same key as elm */                                 \
+attr struct type *                                                            \
+name##_RB_FIND(struct name *head, struct type *elm)                           \
+{                                                                             \
+  struct type *tmp = RB_ROOT(head);                                           \
+  int comp;                                                                   \
+  while (tmp) {                                                               \
+    comp = cmp(elm, tmp);                                                     \
+    if (comp < 0)                                                             \
+      tmp = RB_LEFT(tmp, field);                                              \
+    else if (comp > 0)                                                        \
+      tmp = RB_RIGHT(tmp, field);                                             \
+    else                                                                      \
+      return (tmp);                                                           \
+  }                                                                           \
+  return (NULL);                                                              \
+}                                                                             \
+                                                                              \
+/* Finds the first node greater than or equal to the search key */            \
+attr struct type *                                                            \
+name##_RB_NFIND(struct name *head, struct type *elm)                          \
+{                                                                             \
+  struct type *tmp = RB_ROOT(head);                                           \
+  struct type *res = NULL;                                                    \
+  int comp;                                                                   \
+  while (tmp) {                                                               \
+    comp = cmp(elm, tmp);                                                     \
+    if (comp < 0) {                                                           \
+      res = tmp;                                                              \
+      tmp = RB_LEFT(tmp, field);                                              \
+    }                                                                         \
+    else if (comp > 0)                                                        \
+      tmp = RB_RIGHT(tmp, field);                                             \
+    else                                                                      \
+      return (tmp);                                                           \
+  }                                                                           \
+  return (res);                                                               \
+}                                                                             \
+                                                                              \
+/* ARGSUSED */                                                                \
+attr struct type *                                                            \
+name##_RB_NEXT(struct type *elm)                                              \
+{                                                                             \
+  if (RB_RIGHT(elm, field)) {                                                 \
+    elm = RB_RIGHT(elm, field);                                               \
+    while (RB_LEFT(elm, field))                                               \
+      elm = RB_LEFT(elm, field);                                              \
+  } else {                                                                    \
+    if (RB_PARENT(elm, field) &&                                              \
+        (elm == RB_LEFT(RB_PARENT(elm, field), field)))                       \
+      elm = RB_PARENT(elm, field);                                            \
+    else {                                                                    \
+      while (RB_PARENT(elm, field) &&                                         \
+          (elm == RB_RIGHT(RB_PARENT(elm, field), field)))                    \
+        elm = RB_PARENT(elm, field);                                          \
+      elm = RB_PARENT(elm, field);                                            \
+    }                                                                         \
+  }                                                                           \
+  return (elm);                                                               \
+}                                                                             \
+                                                                              \
+/* ARGSUSED */                                                                \
+attr struct type *                                                            \
+name##_RB_PREV(struct type *elm)                                              \
+{                                                                             \
+  if (RB_LEFT(elm, field)) {                                                  \
+    elm = RB_LEFT(elm, field);                                                \
+    while (RB_RIGHT(elm, field))                                              \
+      elm = RB_RIGHT(elm, field);                                             \
+  } else {                                                                    \
+    if (RB_PARENT(elm, field) &&                                              \
+        (elm == RB_RIGHT(RB_PARENT(elm, field), field)))                      \
+      elm = RB_PARENT(elm, field);                                            \
+    else {                                                                    \
+      while (RB_PARENT(elm, field) &&                                         \
+          (elm == RB_LEFT(RB_PARENT(elm, field), field)))                     \
+        elm = RB_PARENT(elm, field);                                          \
+      elm = RB_PARENT(elm, field);                                            \
+    }                                                                         \
+  }                                                                           \
+  return (elm);                                                               \
+}                                                                             \
+                                                                              \
+attr struct type *                                                            \
+name##_RB_MINMAX(struct name *head, int val)                                  \
+{                                                                             \
+  struct type *tmp = RB_ROOT(head);                                           \
+  struct type *parent = NULL;                                                 \
+  while (tmp) {                                                               \
+    parent = tmp;                                                             \
+    if (val < 0)                                                              \
+      tmp = RB_LEFT(tmp, field);                                              \
+    else                                                                      \
+      tmp = RB_RIGHT(tmp, field);                                             \
+  }                                                                           \
+  return (parent);                                                            \
+}
+
+#define RB_NEGINF   -1
+#define RB_INF      1
+
+#define RB_INSERT(name, x, y)   name##_RB_INSERT(x, y)
+#define RB_REMOVE(name, x, y)   name##_RB_REMOVE(x, y)
+#define RB_FIND(name, x, y)     name##_RB_FIND(x, y)
+#define RB_NFIND(name, x, y)    name##_RB_NFIND(x, y)
+#define RB_NEXT(name, x, y)     name##_RB_NEXT(y)
+#define RB_PREV(name, x, y)     name##_RB_PREV(y)
+#define RB_MIN(name, x)         name##_RB_MINMAX(x, RB_NEGINF)
+#define RB_MAX(name, x)         name##_RB_MINMAX(x, RB_INF)
+
+#define RB_FOREACH(x, name, head)                                             \
+  for ((x) = RB_MIN(name, head);                                              \
+       (x) != NULL;                                                           \
+       (x) = name##_RB_NEXT(x))
+
+#define RB_FOREACH_FROM(x, name, y)                                           \
+  for ((x) = (y);                                                             \
+      ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL);                \
+       (x) = (y))
+
+#define RB_FOREACH_SAFE(x, name, head, y)                                     \
+  for ((x) = RB_MIN(name, head);                                              \
+      ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL);                \
+       (x) = (y))
+
+#define RB_FOREACH_REVERSE(x, name, head)                                     \
+  for ((x) = RB_MAX(name, head);                                              \
+       (x) != NULL;                                                           \
+       (x) = name##_RB_PREV(x))
+
+#define RB_FOREACH_REVERSE_FROM(x, name, y)                                   \
+  for ((x) = (y);                                                             \
+      ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL);                \
+       (x) = (y))
+
+#define RB_FOREACH_REVERSE_SAFE(x, name, head, y)                             \
+  for ((x) = RB_MAX(name, head);                                              \
+      ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL);                \
+       (x) = (y))
+
+#endif  /* _UV_TREE_H_ */
diff --git a/src/rt/libuv/include/uv-private/uv-unix.h b/src/rt/libuv/include/uv-private/uv-unix.h
new file mode 100644
index 00000000000..b07781f4068
--- /dev/null
+++ b/src/rt/libuv/include/uv-private/uv-unix.h
@@ -0,0 +1,219 @@
+/* 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.
+ */
+
+#ifndef UV_UNIX_H
+#define UV_UNIX_H
+
+#include "ngx-queue.h"
+
+#include "ev.h"
+#include "eio.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <termios.h>
+
+/* Note: May be cast to struct iovec. See writev(2). */
+typedef struct {
+  char* base;
+  size_t len;
+} uv_buf_t;
+
+typedef int uv_file;
+
+/* Platform-specific definitions for uv_dlopen support. */
+typedef void* uv_lib_t;
+#define UV_DYNAMIC /* empty */
+
+#define UV_LOOP_PRIVATE_FIELDS \
+  ares_channel channel; \
+  /* \
+   * While the channel is active this timer is called once per second to be \
+   * sure that we're always calling ares_process. See the warning above the \
+   * definition of ares_timeout(). \
+   */ \
+  ev_timer timer; \
+  struct ev_loop* ev;
+
+#define UV_REQ_BUFSML_SIZE (4)
+
+#define UV_REQ_PRIVATE_FIELDS  /* empty */
+
+#define UV_WRITE_PRIVATE_FIELDS \
+  ngx_queue_t queue; \
+  int write_index; \
+  uv_buf_t* bufs; \
+  int bufcnt; \
+  int error; \
+  uv_buf_t bufsml[UV_REQ_BUFSML_SIZE];
+
+#define UV_SHUTDOWN_PRIVATE_FIELDS /* empty */
+
+#define UV_CONNECT_PRIVATE_FIELDS \
+  ngx_queue_t queue;
+
+#define UV_UDP_SEND_PRIVATE_FIELDS  \
+  ngx_queue_t queue;                \
+  struct sockaddr_storage addr;     \
+  socklen_t addrlen;                \
+  uv_buf_t* bufs;                   \
+  int bufcnt;                       \
+  ssize_t status;                   \
+  uv_udp_send_cb send_cb;           \
+  uv_buf_t bufsml[UV_REQ_BUFSML_SIZE];  \
+
+#define UV_PRIVATE_REQ_TYPES /* empty */
+
+
+/* TODO: union or classes please! */
+#define UV_HANDLE_PRIVATE_FIELDS \
+  int fd; \
+  int flags; \
+  ev_idle next_watcher;
+
+
+#define UV_STREAM_PRIVATE_FIELDS \
+  uv_connect_t *connect_req; \
+  uv_shutdown_t *shutdown_req; \
+  ev_io read_watcher; \
+  ev_io write_watcher; \
+  ngx_queue_t write_queue; \
+  ngx_queue_t write_completed_queue; \
+  int delayed_error; \
+  uv_connection_cb connection_cb; \
+  int accepted_fd; \
+  int blocking;
+
+
+/* UV_TCP */
+#define UV_TCP_PRIVATE_FIELDS
+
+
+/* UV_UDP */
+#define UV_UDP_PRIVATE_FIELDS         \
+  uv_alloc_cb alloc_cb;               \
+  uv_udp_recv_cb recv_cb;             \
+  ev_io read_watcher;                 \
+  ev_io write_watcher;                \
+  ngx_queue_t write_queue;            \
+  ngx_queue_t write_completed_queue;  \
+
+
+/* UV_NAMED_PIPE */
+#define UV_PIPE_PRIVATE_FIELDS \
+  const char* pipe_fname; /* strdup'ed */
+
+
+/* UV_PREPARE */ \
+#define UV_PREPARE_PRIVATE_FIELDS \
+  ev_prepare prepare_watcher; \
+  uv_prepare_cb prepare_cb;
+
+
+/* UV_CHECK */
+#define UV_CHECK_PRIVATE_FIELDS \
+  ev_check check_watcher; \
+  uv_check_cb check_cb;
+
+
+/* UV_IDLE */
+#define UV_IDLE_PRIVATE_FIELDS \
+  ev_idle idle_watcher; \
+  uv_idle_cb idle_cb;
+
+
+/* UV_ASYNC */
+#define UV_ASYNC_PRIVATE_FIELDS \
+  ev_async async_watcher; \
+  uv_async_cb async_cb;
+
+
+/* UV_TIMER */
+#define UV_TIMER_PRIVATE_FIELDS \
+  ev_timer timer_watcher; \
+  uv_timer_cb timer_cb;
+
+#define UV_ARES_TASK_PRIVATE_FIELDS \
+  int sock; \
+  ev_io read_watcher; \
+  ev_io write_watcher;
+
+#define UV_GETADDRINFO_PRIVATE_FIELDS \
+  uv_getaddrinfo_cb cb; \
+  struct addrinfo* hints; \
+  char* hostname; \
+  char* service; \
+  struct addrinfo* res; \
+  int retcode;
+
+#define UV_PROCESS_PRIVATE_FIELDS \
+  ev_child child_watcher;
+
+#define UV_FS_PRIVATE_FIELDS \
+  struct stat statbuf; \
+  eio_req* eio;
+
+#define UV_WORK_PRIVATE_FIELDS \
+  eio_req* eio;
+
+#define UV_TTY_PRIVATE_FIELDS \
+  struct termios orig_termios; \
+  int mode;
+
+/* UV_FS_EVENT_PRIVATE_FIELDS */
+#if defined(__linux__)
+
+#define UV_FS_EVENT_PRIVATE_FIELDS \
+  ev_io read_watcher; \
+  uv_fs_event_cb cb; \
+
+#elif (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060) \
+  || defined(__FreeBSD__) \
+  || defined(__OpenBSD__) \
+  || defined(__NetBSD__)
+
+#define UV_FS_EVENT_PRIVATE_FIELDS \
+  ev_io event_watcher; \
+  uv_fs_event_cb cb; \
+  int fflags; \
+
+#elif defined(__sun)
+
+#include <sys/port.h>
+#include <port.h>
+
+#define UV_FS_EVENT_PRIVATE_FIELDS \
+  ev_io event_watcher; \
+  uv_fs_event_cb cb; \
+  file_obj_t fo; \
+
+#else
+
+/* Stub for platforms where the file watcher isn't implemented yet. */
+#define UV_FS_EVENT_PRIVATE_FIELDS
+
+#endif
+
+#endif /* UV_UNIX_H */
diff --git a/src/rt/libuv/include/uv-private/uv-win.h b/src/rt/libuv/include/uv-private/uv-win.h
new file mode 100644
index 00000000000..5d461090f15
--- /dev/null
+++ b/src/rt/libuv/include/uv-private/uv-win.h
@@ -0,0 +1,422 @@
+/* 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.
+ */
+
+#ifndef _WIN32_WINNT
+# define _WIN32_WINNT   0x0502
+#endif
+
+#include <stdint.h>
+#include <winsock2.h>
+#include <mswsock.h>
+#include <ws2tcpip.h>
+#include <windows.h>
+#include <sys/stat.h>
+
+#include "tree.h"
+
+#define MAX_PIPENAME_LEN 256
+
+/*
+ * Guids and typedefs for winsock extension functions
+ * Mingw32 doesn't have these :-(
+ */
+#ifndef WSAID_ACCEPTEX
+# define WSAID_ACCEPTEX                                        \
+         {0xb5367df1, 0xcbac, 0x11cf,                          \
+         {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
+
+# define WSAID_CONNECTEX                                       \
+         {0x25a207b9, 0xddf3, 0x4660,                          \
+         {0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e}}
+
+# define WSAID_GETACCEPTEXSOCKADDRS                            \
+         {0xb5367df2, 0xcbac, 0x11cf,                          \
+         {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
+
+# define WSAID_DISCONNECTEX                                    \
+         {0x7fda2e11, 0x8630, 0x436f,                          \
+         {0xa0, 0x31, 0xf5, 0x36, 0xa6, 0xee, 0xc1, 0x57}}
+
+# define WSAID_TRANSMITFILE                                    \
+         {0xb5367df0, 0xcbac, 0x11cf,                          \
+         {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
+
+  typedef BOOL PASCAL (*LPFN_ACCEPTEX)
+                      (SOCKET sListenSocket,
+                       SOCKET sAcceptSocket,
+                       PVOID lpOutputBuffer,
+                       DWORD dwReceiveDataLength,
+                       DWORD dwLocalAddressLength,
+                       DWORD dwRemoteAddressLength,
+                       LPDWORD lpdwBytesReceived,
+                       LPOVERLAPPED lpOverlapped);
+
+  typedef BOOL PASCAL (*LPFN_CONNECTEX)
+                      (SOCKET s,
+                       const struct sockaddr* name,
+                       int namelen,
+                       PVOID lpSendBuffer,
+                       DWORD dwSendDataLength,
+                       LPDWORD lpdwBytesSent,
+                       LPOVERLAPPED lpOverlapped);
+
+  typedef void PASCAL (*LPFN_GETACCEPTEXSOCKADDRS)
+                      (PVOID lpOutputBuffer,
+                       DWORD dwReceiveDataLength,
+                       DWORD dwLocalAddressLength,
+                       DWORD dwRemoteAddressLength,
+                       LPSOCKADDR* LocalSockaddr,
+                       LPINT LocalSockaddrLength,
+                       LPSOCKADDR* RemoteSockaddr,
+                       LPINT RemoteSockaddrLength);
+
+  typedef BOOL PASCAL (*LPFN_DISCONNECTEX)
+                      (SOCKET hSocket,
+                       LPOVERLAPPED lpOverlapped,
+                       DWORD dwFlags,
+                       DWORD reserved);
+
+  typedef BOOL PASCAL (*LPFN_TRANSMITFILE)
+                      (SOCKET hSocket,
+                       HANDLE hFile,
+                       DWORD nNumberOfBytesToWrite,
+                       DWORD nNumberOfBytesPerSend,
+                       LPOVERLAPPED lpOverlapped,
+                       LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers,
+                       DWORD dwFlags);
+#endif
+
+typedef int (WSAAPI* LPFN_WSARECV)
+            (SOCKET socket,
+             LPWSABUF buffers,
+             DWORD buffer_count,
+             LPDWORD bytes,
+             LPDWORD flags,
+             LPWSAOVERLAPPED overlapped,
+             LPWSAOVERLAPPED_COMPLETION_ROUTINE
+             completion_routine);
+
+typedef int (WSAAPI* LPFN_WSARECVFROM)
+            (SOCKET socket,
+             LPWSABUF buffers,
+             DWORD buffer_count,
+             LPDWORD bytes,
+             LPDWORD flags,
+             struct sockaddr* addr,
+             LPINT addr_len,
+             LPWSAOVERLAPPED overlapped,
+             LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine);
+
+
+/**
+ * It should be possible to cast uv_buf_t[] to WSABUF[]
+ * see http://msdn.microsoft.com/en-us/library/ms741542(v=vs.85).aspx
+ */
+typedef struct uv_buf_t {
+  ULONG len;
+  char* base;
+} uv_buf_t;
+
+typedef int uv_file;
+
+/* Platform-specific definitions for uv_dlopen support. */
+typedef HMODULE uv_lib_t;
+#define UV_DYNAMIC FAR WINAPI
+
+RB_HEAD(uv_timer_tree_s, uv_timer_s);
+
+#define UV_LOOP_PRIVATE_FIELDS                                                \
+    /* The loop's I/O completion port */                                      \
+  HANDLE iocp;                                                                \
+  /* Reference count that keeps the event loop alive */                       \
+  int refs;                                                                   \
+  /* The current time according to the event loop. in msecs. */               \
+  int64_t time;                                                               \
+  /* Tail of a single-linked circular queue of pending reqs. If the queue */  \
+  /* is empty, tail_ is NULL. If there is only one item, */                   \
+  /* tail_->next_req == tail_ */                                              \
+  uv_req_t* pending_reqs_tail;                                                \
+  /* Head of a single-linked list of closed handles */                        \
+  uv_handle_t* endgame_handles;                                               \
+  /* The head of the timers tree */                                           \
+  struct uv_timer_tree_s timers;                                              \
+    /* Lists of active loop (prepare / check / idle) watchers */              \
+  uv_prepare_t* prepare_handles;                                              \
+  uv_check_t* check_handles;                                                  \
+  uv_idle_t* idle_handles;                                                    \
+  /* This pointer will refer to the prepare/check/idle handle whose */        \
+  /* callback is scheduled to be called next. This is needed to allow */      \
+  /* safe removal from one of the lists above while that list being */        \
+  /* iterated over. */                                                        \
+  uv_prepare_t* next_prepare_handle;                                          \
+  uv_check_t* next_check_handle;                                              \
+  uv_idle_t* next_idle_handle;                                                \
+  ares_channel ares_chan;                                                     \
+  int ares_active_sockets;                                                    \
+  uv_timer_t ares_polling_timer;
+
+#define UV_REQ_TYPE_PRIVATE               \
+  /* TODO: remove the req suffix */       \
+  UV_ARES_EVENT_REQ,                      \
+  UV_ARES_CLEANUP_REQ,                    \
+  UV_GETADDRINFO_REQ,                     \
+  UV_PROCESS_EXIT,                        \
+  UV_PROCESS_CLOSE,                       \
+  UV_UDP_RECV,                            \
+  UV_FS_EVENT_REQ
+
+#define UV_REQ_PRIVATE_FIELDS             \
+  union {                                 \
+    /* Used by I/O operations */          \
+    struct {                              \
+      OVERLAPPED overlapped;              \
+      size_t queued_bytes;                \
+    };                                    \
+  };                                      \
+  struct uv_req_s* next_req;
+
+#define UV_WRITE_PRIVATE_FIELDS           \
+  int ipc_header;                         \
+  uv_buf_t write_buffer;                  \
+  HANDLE event_handle;                    \
+  HANDLE wait_handle;
+
+#define UV_CONNECT_PRIVATE_FIELDS         \
+  /* empty */
+
+#define UV_SHUTDOWN_PRIVATE_FIELDS        \
+  /* empty */
+
+#define UV_UDP_SEND_PRIVATE_FIELDS        \
+  /* empty */
+
+#define UV_PRIVATE_REQ_TYPES              \
+  typedef struct uv_pipe_accept_s {       \
+    UV_REQ_FIELDS                         \
+    HANDLE pipeHandle;                    \
+    struct uv_pipe_accept_s* next_pending; \
+  } uv_pipe_accept_t;                     \
+                                          \
+  typedef struct uv_tcp_accept_s {        \
+    UV_REQ_FIELDS                         \
+    SOCKET accept_socket;                 \
+    char accept_buffer[sizeof(struct sockaddr_storage) * 2 + 32]; \
+    HANDLE event_handle;                  \
+    HANDLE wait_handle;                   \
+    struct uv_tcp_accept_s* next_pending; \
+  } uv_tcp_accept_t;                      \
+                                          \
+  typedef struct uv_read_s {              \
+    UV_REQ_FIELDS                         \
+    HANDLE event_handle;                  \
+    HANDLE wait_handle;                   \
+  } uv_read_t;
+
+#define uv_stream_connection_fields       \
+  unsigned int write_reqs_pending;        \
+  uv_shutdown_t* shutdown_req;
+
+#define uv_stream_server_fields           \
+  uv_connection_cb connection_cb;
+
+#define UV_STREAM_PRIVATE_FIELDS          \
+  unsigned int reqs_pending;              \
+  uv_read_t read_req;                     \
+  union {                                 \
+    struct { uv_stream_connection_fields };  \
+    struct { uv_stream_server_fields     };  \
+  };
+
+#define uv_tcp_server_fields              \
+  uv_tcp_accept_t* accept_reqs;           \
+  unsigned int processed_accepts;         \
+  uv_tcp_accept_t* pending_accepts;       \
+  LPFN_ACCEPTEX func_acceptex;
+
+#define uv_tcp_connection_fields          \
+  uv_buf_t read_buffer;                   \
+  LPFN_CONNECTEX func_connectex;
+
+#define UV_TCP_PRIVATE_FIELDS             \
+  SOCKET socket;                          \
+  int bind_error;                         \
+  union {                                 \
+    struct { uv_tcp_server_fields };      \
+    struct { uv_tcp_connection_fields };  \
+  };
+
+#define UV_UDP_PRIVATE_FIELDS             \
+  SOCKET socket;                          \
+  unsigned int reqs_pending;              \
+  uv_req_t recv_req;                      \
+  uv_buf_t recv_buffer;                   \
+  struct sockaddr_storage recv_from;      \
+  int recv_from_len;                      \
+  uv_udp_recv_cb recv_cb;                 \
+  uv_alloc_cb alloc_cb;                   \
+  LPFN_WSARECV func_wsarecv;              \
+  LPFN_WSARECVFROM func_wsarecvfrom;
+
+#define uv_pipe_server_fields             \
+  uv_pipe_accept_t accept_reqs[4];        \
+  uv_pipe_accept_t* pending_accepts;
+
+#define uv_pipe_connection_fields         \
+  uv_timer_t* eof_timer;                  \
+  uv_write_t ipc_header_write_req;        \
+  int ipc_pid;                            \
+  uint64_t remaining_ipc_rawdata_bytes;   \
+  WSAPROTOCOL_INFOW* pending_socket_info; \
+  uv_write_t* non_overlapped_writes_tail;
+
+#define UV_PIPE_PRIVATE_FIELDS            \
+  HANDLE handle;                          \
+  wchar_t* name;                          \
+  union {                                 \
+    struct { uv_pipe_server_fields };     \
+    struct { uv_pipe_connection_fields }; \
+  };
+
+/* TODO: put the parser states in an union - TTY handles are always */
+/* half-duplex so read-state can safely overlap write-state. */
+#define UV_TTY_PRIVATE_FIELDS             \
+  HANDLE handle;                          \
+  HANDLE read_line_handle;                \
+  uv_buf_t read_line_buffer;              \
+  HANDLE read_raw_wait;                   \
+  DWORD original_console_mode;            \
+  /* Fields used for translating win */   \
+  /* keystrokes into vt100 characters */  \
+  char last_key[8];                       \
+  unsigned char last_key_offset;          \
+  unsigned char last_key_len;             \
+  INPUT_RECORD last_input_record;         \
+  WCHAR last_utf16_high_surrogate;        \
+  /* utf8-to-utf16 conversion state */    \
+  unsigned char utf8_bytes_left;          \
+  unsigned int utf8_codepoint;            \
+  /* eol conversion state */              \
+  unsigned char previous_eol;             \
+  /* ansi parser state */                 \
+  unsigned char ansi_parser_state;        \
+  unsigned char ansi_csi_argc;            \
+  unsigned short ansi_csi_argv[4];        \
+  COORD saved_position;                   \
+  WORD saved_attributes;
+
+#define UV_TIMER_PRIVATE_FIELDS           \
+  RB_ENTRY(uv_timer_s) tree_entry;        \
+  int64_t due;                            \
+  int64_t repeat;                         \
+  uv_timer_cb timer_cb;
+
+#define UV_ASYNC_PRIVATE_FIELDS           \
+  struct uv_req_s async_req;              \
+  uv_async_cb async_cb;                   \
+  /* char to avoid alignment issues */    \
+  char volatile async_sent;
+
+#define UV_PREPARE_PRIVATE_FIELDS         \
+  uv_prepare_t* prepare_prev;             \
+  uv_prepare_t* prepare_next;             \
+  uv_prepare_cb prepare_cb;
+
+#define UV_CHECK_PRIVATE_FIELDS           \
+  uv_check_t* check_prev;                 \
+  uv_check_t* check_next;                 \
+  uv_check_cb check_cb;
+
+#define UV_IDLE_PRIVATE_FIELDS            \
+  uv_idle_t* idle_prev;                   \
+  uv_idle_t* idle_next;                   \
+  uv_idle_cb idle_cb;
+
+#define UV_HANDLE_PRIVATE_FIELDS          \
+  uv_handle_t* endgame_next;              \
+  unsigned int flags;
+
+#define UV_ARES_TASK_PRIVATE_FIELDS       \
+  struct uv_req_s ares_req;               \
+  SOCKET sock;                            \
+  HANDLE h_wait;                          \
+  WSAEVENT h_event;                       \
+  HANDLE h_close_event;
+
+#define UV_GETADDRINFO_PRIVATE_FIELDS     \
+  struct uv_req_s getadddrinfo_req;       \
+  uv_getaddrinfo_cb getaddrinfo_cb;       \
+  void* alloc;                            \
+  wchar_t* node;                          \
+  wchar_t* service;                       \
+  struct addrinfoW* hints;                \
+  struct addrinfoW* res;                  \
+  int retcode;
+
+#define UV_PROCESS_PRIVATE_FIELDS         \
+  struct uv_process_exit_s {              \
+    UV_REQ_FIELDS                         \
+  } exit_req;                             \
+  struct uv_process_close_s {             \
+    UV_REQ_FIELDS                         \
+  } close_req;                            \
+  HANDLE child_stdio[3];                  \
+  int exit_signal;                        \
+  DWORD spawn_errno;                      \
+  HANDLE wait_handle;                     \
+  HANDLE process_handle;                  \
+  HANDLE close_handle;
+
+#define UV_FS_PRIVATE_FIELDS              \
+  wchar_t* pathw;                         \
+  int flags;                              \
+  int last_error;                         \
+  struct _stati64 stat;                   \
+  void* arg0;                             \
+  union {                                 \
+    struct {                              \
+      void* arg1;                         \
+      void* arg2;                         \
+      void* arg3;                         \
+    };                                    \
+    struct {                              \
+      ssize_t arg4;                       \
+      ssize_t arg5;                       \
+    };                                    \
+  };
+
+#define UV_WORK_PRIVATE_FIELDS            \
+
+#define UV_FS_EVENT_PRIVATE_FIELDS        \
+  struct uv_fs_event_req_s {              \
+    UV_REQ_FIELDS                         \
+  } req;                                  \
+  HANDLE dir_handle;                      \
+  int req_pending;                        \
+  uv_fs_event_cb cb;                      \
+  wchar_t* filew;                         \
+  wchar_t* short_filew;                   \
+  int is_path_dir;                        \
+  char* buffer;
+
+int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size,
+    char* utf8Buffer, size_t utf8Size);
+int uv_utf8_to_utf16(const char* utf8Buffer, wchar_t* utf16Buffer,
+    size_t utf16Size);
diff --git a/src/rt/libuv/include/uv.h b/src/rt/libuv/include/uv.h
new file mode 100644
index 00000000000..88afed448d9
--- /dev/null
+++ b/src/rt/libuv/include/uv.h
@@ -0,0 +1,1317 @@
+/* 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.
+ */
+
+/* See uv_loop_new for an introduction. */
+
+#ifndef UV_H
+#define UV_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _WIN32
+  /* Windows - set up dll import/export decorators. */
+# if defined(BUILDING_UV_SHARED)
+    /* Building shared library. Export everything from c-ares as well. */
+#   define UV_EXTERN __declspec(dllexport)
+#   define CARES_BUILDING_LIBRARY 1
+# elif defined(USING_UV_SHARED)
+    /* Using shared library. Use shared c-ares as well. */
+#   define UV_EXTERN __declspec(dllimport)
+# else
+    /* Building static library. Build c-ares statically as well. */
+#   define UV_EXTERN /* nothing */
+#   define CARES_STATICLIB 1
+# endif
+#else
+  /* Unix. TODO: symbol hiding */
+# define UV_EXTERN /* nothing */
+#endif
+
+
+#define UV_VERSION_MAJOR 0
+#define UV_VERSION_MINOR 1
+
+
+#include <stdint.h> /* int64_t */
+#include <sys/types.h> /* size_t */
+
+#include "ares.h"
+
+#ifndef _SSIZE_T_
+typedef intptr_t ssize_t;
+#endif
+
+#if defined(__unix__) || defined(__POSIX__) || defined(__APPLE__)
+# include "uv-private/uv-unix.h"
+#else
+# include "uv-private/uv-win.h"
+#endif
+
+/* Expand this list if necessary. */
+typedef enum {
+  UV_UNKNOWN = -1,
+  UV_OK = 0,
+  UV_EOF,
+  UV_EADDRINFO,
+  UV_EACCES,
+  UV_EAGAIN,
+  UV_EADDRINUSE,
+  UV_EADDRNOTAVAIL,
+  UV_EAFNOSUPPORT,
+  UV_EALREADY,
+  UV_EBADF,
+  UV_EBUSY,
+  UV_ECONNABORTED,
+  UV_ECONNREFUSED,
+  UV_ECONNRESET,
+  UV_EDESTADDRREQ,
+  UV_EFAULT,
+  UV_EHOSTUNREACH,
+  UV_EINTR,
+  UV_EINVAL,
+  UV_EISCONN,
+  UV_EMFILE,
+  UV_EMSGSIZE,
+  UV_ENETDOWN,
+  UV_ENETUNREACH,
+  UV_ENFILE,
+  UV_ENOBUFS,
+  UV_ENOMEM,
+  UV_ENOTDIR,
+  UV_EISDIR,
+  UV_ENONET,
+  UV_ENOPROTOOPT,
+  UV_ENOTCONN,
+  UV_ENOTSOCK,
+  UV_ENOTSUP,
+  UV_ENOENT,
+  UV_ENOSYS,
+  UV_EPIPE,
+  UV_EPROTO,
+  UV_EPROTONOSUPPORT,
+  UV_EPROTOTYPE,
+  UV_ETIMEDOUT,
+  UV_ECHARSET,
+  UV_EAIFAMNOSUPPORT,
+  UV_EAINONAME,
+  UV_EAISERVICE,
+  UV_EAISOCKTYPE,
+  UV_ESHUTDOWN,
+  UV_EEXIST
+} uv_err_code;
+
+typedef enum {
+  UV_UNKNOWN_HANDLE = 0,
+  UV_TCP,
+  UV_UDP,
+  UV_NAMED_PIPE,
+  UV_TTY,
+  UV_FILE,
+  UV_TIMER,
+  UV_PREPARE,
+  UV_CHECK,
+  UV_IDLE,
+  UV_ASYNC,
+  UV_ARES_TASK,
+  UV_ARES_EVENT,
+  UV_PROCESS,
+  UV_FS_EVENT
+} uv_handle_type;
+
+typedef enum {
+  UV_UNKNOWN_REQ = 0,
+  UV_CONNECT,
+  UV_ACCEPT,
+  UV_READ,
+  UV_WRITE,
+  UV_SHUTDOWN,
+  UV_WAKEUP,
+  UV_UDP_SEND,
+  UV_FS,
+  UV_WORK,
+  UV_GETADDRINFO,
+  UV_REQ_TYPE_PRIVATE
+} uv_req_type;
+
+
+
+typedef struct uv_loop_s uv_loop_t;
+typedef struct uv_ares_task_s uv_ares_task_t;
+typedef struct uv_err_s uv_err_t;
+typedef struct uv_handle_s uv_handle_t;
+typedef struct uv_stream_s uv_stream_t;
+typedef struct uv_tcp_s uv_tcp_t;
+typedef struct uv_udp_s uv_udp_t;
+typedef struct uv_pipe_s uv_pipe_t;
+typedef struct uv_tty_s uv_tty_t;
+typedef struct uv_timer_s uv_timer_t;
+typedef struct uv_prepare_s uv_prepare_t;
+typedef struct uv_check_s uv_check_t;
+typedef struct uv_idle_s uv_idle_t;
+typedef struct uv_async_s uv_async_t;
+typedef struct uv_getaddrinfo_s uv_getaddrinfo_t;
+typedef struct uv_process_s uv_process_t;
+typedef struct uv_counters_s uv_counters_t;
+/* Request types */
+typedef struct uv_req_s uv_req_t;
+typedef struct uv_shutdown_s uv_shutdown_t;
+typedef struct uv_write_s uv_write_t;
+typedef struct uv_connect_s uv_connect_t;
+typedef struct uv_udp_send_s uv_udp_send_t;
+typedef struct uv_fs_s uv_fs_t;
+/* uv_fs_event_t is a subclass of uv_handle_t. */
+typedef struct uv_fs_event_s uv_fs_event_t;
+typedef struct uv_work_s uv_work_t;
+
+
+/*
+ * This function must be called before any other functions in libuv.
+ *
+ * All functions besides uv_run() are non-blocking.
+ *
+ * All callbacks in libuv are made asynchronously. That is they are never
+ * made by the function that takes them as a parameter.
+ */
+UV_EXTERN uv_loop_t* uv_loop_new(void);
+UV_EXTERN void uv_loop_delete(uv_loop_t*);
+
+
+/*
+ * Returns the default loop.
+ */
+UV_EXTERN uv_loop_t* uv_default_loop(void);
+
+/*
+ * This function starts the event loop. It blocks until the reference count
+ * of the loop drops to zero.
+ */
+UV_EXTERN int uv_run (uv_loop_t*);
+
+/*
+ * Manually modify the event loop's reference count. Useful if the user wants
+ * to have a handle or timeout that doesn't keep the loop alive.
+ */
+UV_EXTERN void uv_ref(uv_loop_t*);
+UV_EXTERN void uv_unref(uv_loop_t*);
+
+UV_EXTERN void uv_update_time(uv_loop_t*);
+UV_EXTERN int64_t uv_now(uv_loop_t*);
+
+
+/*
+ * The status parameter is 0 if the request completed successfully,
+ * and should be -1 if the request was cancelled or failed.
+ * For uv_close_cb, -1 means that the handle was closed due to an error.
+ * Error details can be obtained by calling uv_last_error().
+ *
+ * In the case of uv_read_cb the uv_buf_t returned should be freed by the
+ * user.
+ */
+typedef uv_buf_t (*uv_alloc_cb)(uv_handle_t* handle, size_t suggested_size);
+typedef void (*uv_read_cb)(uv_stream_t* stream, ssize_t nread, uv_buf_t buf);
+/*
+ * Just like the uv_read_cb except that if the pending parameter is true
+ * then you can use uv_accept() to pull the new handle into the process.
+ * If no handle is pending then pending will be UV_UNKNOWN_HANDLE.
+ */
+typedef void (*uv_read2_cb)(uv_pipe_t* pipe, ssize_t nread, uv_buf_t buf,
+    uv_handle_type pending);
+typedef void (*uv_write_cb)(uv_write_t* req, int status);
+typedef void (*uv_connect_cb)(uv_connect_t* req, int status);
+typedef void (*uv_shutdown_cb)(uv_shutdown_t* req, int status);
+typedef void (*uv_connection_cb)(uv_stream_t* server, int status);
+typedef void (*uv_close_cb)(uv_handle_t* handle);
+typedef void (*uv_timer_cb)(uv_timer_t* handle, int status);
+/* TODO: do these really need a status argument? */
+typedef void (*uv_async_cb)(uv_async_t* handle, int status);
+typedef void (*uv_prepare_cb)(uv_prepare_t* handle, int status);
+typedef void (*uv_check_cb)(uv_check_t* handle, int status);
+typedef void (*uv_idle_cb)(uv_idle_t* handle, int status);
+typedef void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* handle, int status,
+    struct addrinfo* res);
+typedef void (*uv_exit_cb)(uv_process_t*, int exit_status, int term_signal);
+typedef void (*uv_fs_cb)(uv_fs_t* req);
+typedef void (*uv_work_cb)(uv_work_t* req);
+typedef void (*uv_after_work_cb)(uv_work_t* req);
+
+/*
+* This will be called repeatedly after the uv_fs_event_t is initialized.
+* If uv_fs_event_t was initialized with a directory the filename parameter
+* will be a relative path to a file contained in the directory.
+* The events paramenter is an ORed mask of enum uv_fs_event elements.
+*/
+typedef void (*uv_fs_event_cb)(uv_fs_event_t* handle, const char* filename,
+    int events, int status);
+
+typedef enum {
+  UV_LEAVE_GROUP = 0,
+  UV_JOIN_GROUP
+} uv_membership;
+
+
+struct uv_err_s {
+  /* read-only */
+  uv_err_code code;
+  /* private */
+  int sys_errno_;
+};
+
+
+/*
+ * Most functions return boolean: 0 for success and -1 for failure.
+ * On error the user should then call uv_last_error() to determine
+ * the error code.
+ */
+UV_EXTERN uv_err_t uv_last_error(uv_loop_t*);
+UV_EXTERN const char* uv_strerror(uv_err_t err);
+UV_EXTERN const char* uv_err_name(uv_err_t err);
+
+
+#define UV_REQ_FIELDS \
+  /* read-only */ \
+  uv_req_type type; \
+  /* public */ \
+  void* data; \
+  /* private */ \
+  UV_REQ_PRIVATE_FIELDS
+
+/* Abstract base class of all requests. */
+struct uv_req_s {
+  UV_REQ_FIELDS
+};
+
+
+/* Platform-specific request types */
+UV_PRIVATE_REQ_TYPES
+
+
+/*
+ * uv_shutdown_t is a subclass of uv_req_t
+ *
+ * Shutdown the outgoing (write) side of a duplex stream. It waits for
+ * pending write requests to complete. The handle should refer to a
+ * initialized stream. req should be an uninitalized shutdown request
+ * struct. The cb is a called after shutdown is complete.
+ */
+UV_EXTERN int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle,
+    uv_shutdown_cb cb);
+
+struct uv_shutdown_s {
+  UV_REQ_FIELDS
+  uv_stream_t* handle;
+  uv_shutdown_cb cb;
+  UV_SHUTDOWN_PRIVATE_FIELDS
+};
+
+
+#define UV_HANDLE_FIELDS \
+  /* read-only */ \
+  uv_loop_t* loop; \
+  uv_handle_type type; \
+  /* public */ \
+  uv_close_cb close_cb; \
+  void* data; \
+  /* private */ \
+  UV_HANDLE_PRIVATE_FIELDS
+
+/* The abstract base class of all handles.  */
+struct uv_handle_s {
+  UV_HANDLE_FIELDS
+};
+
+/*
+ * Returns 1 if the prepare/check/idle handle has been started, 0 otherwise.
+ * For other handle types this always returns 1.
+ */
+UV_EXTERN int uv_is_active(uv_handle_t* handle);
+
+/*
+ * Request handle to be closed. close_cb will be called asynchronously after
+ * this call. This MUST be called on each handle before memory is released.
+ *
+ * Note that handles that wrap file descriptors are closed immediately but
+ * close_cb will still be deferred to the next iteration of the event loop.
+ * It gives you a chance to free up any resources associated with the handle.
+ */
+UV_EXTERN void uv_close(uv_handle_t* handle, uv_close_cb close_cb);
+
+
+/*
+ * Constructor for uv_buf_t.
+ * Due to platform differences the user cannot rely on the ordering of the
+ * base and len members of the uv_buf_t struct. The user is responsible for
+ * freeing base after the uv_buf_t is done. Return struct passed by value.
+ */
+UV_EXTERN uv_buf_t uv_buf_init(char* base, size_t len);
+
+
+#define UV_STREAM_FIELDS \
+  /* number of bytes queued for writing */ \
+  size_t write_queue_size; \
+  uv_alloc_cb alloc_cb; \
+  uv_read_cb read_cb; \
+  uv_read2_cb read2_cb; \
+  /* private */ \
+  UV_STREAM_PRIVATE_FIELDS
+
+/*
+ * uv_stream_t is a subclass of uv_handle_t
+ *
+ * uv_stream is an abstract class.
+ *
+ * uv_stream_t is the parent class of uv_tcp_t, uv_pipe_t, uv_tty_t, and
+ * soon uv_file_t.
+ */
+struct uv_stream_s {
+  UV_HANDLE_FIELDS
+  UV_STREAM_FIELDS
+};
+
+UV_EXTERN int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb);
+
+/*
+ * This call is used in conjunction with uv_listen() to accept incoming
+ * connections. Call uv_accept after receiving a uv_connection_cb to accept
+ * the connection. Before calling uv_accept use uv_*_init() must be
+ * called on the client. Non-zero return value indicates an error.
+ *
+ * When the uv_connection_cb is called it is guaranteed that uv_accept will
+ * complete successfully the first time. If you attempt to use it more than
+ * once, it may fail. It is suggested to only call uv_accept once per
+ * uv_connection_cb call.
+ */
+UV_EXTERN int uv_accept(uv_stream_t* server, uv_stream_t* client);
+
+/*
+ * Read data from an incoming stream. The callback will be made several
+ * several times until there is no more data to read or uv_read_stop is
+ * called. When we've reached EOF nread will be set to -1 and the error is
+ * set to UV_EOF. When nread == -1 the buf parameter might not point to a
+ * valid buffer; in that case buf.len and buf.base are both set to 0.
+ * Note that nread might also be 0, which does *not* indicate an error or
+ * eof; it happens when libuv requested a buffer through the alloc callback
+ * but then decided that it didn't need that buffer.
+ */
+UV_EXTERN int uv_read_start(uv_stream_t*, uv_alloc_cb alloc_cb,
+    uv_read_cb read_cb);
+
+UV_EXTERN int uv_read_stop(uv_stream_t*);
+
+/*
+ * Extended read methods for receiving handles over a pipe. The pipe must be
+ * initialized with ipc == 1.
+ */
+UV_EXTERN int uv_read2_start(uv_stream_t*, uv_alloc_cb alloc_cb,
+    uv_read2_cb read_cb);
+
+
+/*
+ * Write data to stream. Buffers are written in order. Example:
+ *
+ *   uv_buf_t a[] = {
+ *     { .base = "1", .len = 1 },
+ *     { .base = "2", .len = 1 }
+ *   };
+ *
+ *   uv_buf_t b[] = {
+ *     { .base = "3", .len = 1 },
+ *     { .base = "4", .len = 1 }
+ *   };
+ *
+ *   // writes "1234"
+ *   uv_write(req, stream, a, 2);
+ *   uv_write(req, stream, b, 2);
+ *
+ */
+UV_EXTERN int uv_write(uv_write_t* req, uv_stream_t* handle,
+    uv_buf_t bufs[], int bufcnt, uv_write_cb cb);
+
+UV_EXTERN int uv_write2(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[],
+    int bufcnt, uv_stream_t* send_handle, uv_write_cb cb);
+
+/* uv_write_t is a subclass of uv_req_t */
+struct uv_write_s {
+  UV_REQ_FIELDS
+  uv_write_cb cb;
+  uv_stream_t* send_handle;
+  uv_stream_t* handle;
+  UV_WRITE_PRIVATE_FIELDS
+};
+
+
+
+/*
+ * uv_tcp_t is a subclass of uv_stream_t
+ *
+ * Represents a TCP stream or TCP server.
+ */
+struct uv_tcp_s {
+  UV_HANDLE_FIELDS
+  UV_STREAM_FIELDS
+  UV_TCP_PRIVATE_FIELDS
+};
+
+UV_EXTERN int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle);
+
+/* Enable/disable Nagle's algorithm. */
+UV_EXTERN int uv_tcp_nodelay(uv_tcp_t* handle, int enable);
+
+/* Enable/disable TCP keep-alive.
+ *
+ * `ms` is the initial delay in seconds, ignored when `enable` is zero.
+ */
+UV_EXTERN int uv_tcp_keepalive(uv_tcp_t* handle, int enable,
+    unsigned int delay);
+
+/*
+ * This setting applies to Windows only.
+ * Enable/disable simultaneous asynchronous accept requests that are
+ * queued by the operating system when listening for new tcp connections.
+ * This setting is used to tune a tcp server for the desired performance.
+ * Having simultaneous accepts can significantly improve the rate of
+ * accepting connections (which is why it is enabled by default).
+ */
+UV_EXTERN int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable);
+
+UV_EXTERN int uv_tcp_bind(uv_tcp_t* handle, struct sockaddr_in);
+UV_EXTERN int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6);
+UV_EXTERN int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name,
+    int* namelen);
+UV_EXTERN int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name,
+    int* namelen);
+
+/*
+ * uv_tcp_connect, uv_tcp_connect6
+ * These functions establish IPv4 and IPv6 TCP connections. Provide an
+ * initialized TCP handle and an uninitialized uv_connect_t*. The callback
+ * will be made when the connection is estabished.
+ */
+UV_EXTERN int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle,
+    struct sockaddr_in address, uv_connect_cb cb);
+UV_EXTERN int uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle,
+    struct sockaddr_in6 address, uv_connect_cb cb);
+
+/* uv_connect_t is a subclass of uv_req_t */
+struct uv_connect_s {
+  UV_REQ_FIELDS
+  uv_connect_cb cb;
+  uv_stream_t* handle;
+  UV_CONNECT_PRIVATE_FIELDS
+};
+
+
+/*
+ * UDP support.
+ */
+
+enum uv_udp_flags {
+  /* Disables dual stack mode. Used with uv_udp_bind6(). */
+  UV_UDP_IPV6ONLY = 1,
+  /*
+   * Indicates message was truncated because read buffer was too small. The
+   * remainder was discarded by the OS. Used in uv_udp_recv_cb.
+   */
+  UV_UDP_PARTIAL = 2
+};
+
+/*
+ * Called after a uv_udp_send() or uv_udp_send6(). status 0 indicates
+ * success otherwise error.
+ */
+typedef void (*uv_udp_send_cb)(uv_udp_send_t* req, int status);
+
+/*
+ * Callback that is invoked when a new UDP datagram is received.
+ *
+ *  handle  UDP handle.
+ *  nread   Number of bytes that have been received.
+ *          0 if there is no more data to read. You may
+ *          discard or repurpose the read buffer.
+ *          -1 if a transmission error was detected.
+ *  buf     uv_buf_t with the received data.
+ *  addr    struct sockaddr_in or struct sockaddr_in6.
+ *          Valid for the duration of the callback only.
+ *  flags   One or more OR'ed UV_UDP_* constants.
+ *          Right now only UV_UDP_PARTIAL is used.
+ */
+typedef void (*uv_udp_recv_cb)(uv_udp_t* handle, ssize_t nread, uv_buf_t buf,
+    struct sockaddr* addr, unsigned flags);
+
+/* uv_udp_t is a subclass of uv_handle_t */
+struct uv_udp_s {
+  UV_HANDLE_FIELDS
+  UV_UDP_PRIVATE_FIELDS
+};
+
+/* uv_udp_send_t is a subclass of uv_req_t */
+struct uv_udp_send_s {
+  UV_REQ_FIELDS
+  uv_udp_t* handle;
+  uv_udp_send_cb cb;
+  UV_UDP_SEND_PRIVATE_FIELDS
+};
+
+/*
+ * Initialize a new UDP handle. The actual socket is created lazily.
+ * Returns 0 on success.
+ */
+UV_EXTERN int uv_udp_init(uv_loop_t*, uv_udp_t* handle);
+
+/*
+ * Bind to a IPv4 address and port.
+ *
+ * Arguments:
+ *  handle    UDP handle. Should have been initialized with `uv_udp_init`.
+ *  addr      struct sockaddr_in with the address and port to bind to.
+ *  flags     Unused.
+ *
+ * Returns:
+ *  0 on success, -1 on error.
+ */
+UV_EXTERN int uv_udp_bind(uv_udp_t* handle, struct sockaddr_in addr,
+    unsigned flags);
+
+/*
+ * Bind to a IPv6 address and port.
+ *
+ * Arguments:
+ *  handle    UDP handle. Should have been initialized with `uv_udp_init`.
+ *  addr      struct sockaddr_in with the address and port to bind to.
+ *  flags     Should be 0 or UV_UDP_IPV6ONLY.
+ *
+ * Returns:
+ *  0 on success, -1 on error.
+ */
+UV_EXTERN int uv_udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr,
+    unsigned flags);
+UV_EXTERN int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name,
+    int* namelen);
+
+/*
+ * Set membership for a multicast address
+ *
+ * Arguments:
+ *  handle              UDP handle. Should have been initialized with
+ *                      `uv_udp_init`.
+ *  multicast_addr      multicast address to set membership for
+ *  interface_addr      interface address
+ *  membership          Should be UV_JOIN_GROUP or UV_LEAVE_GROUP
+ *
+ * Returns:
+ *  0 on success, -1 on error.
+ */
+UV_EXTERN int uv_udp_set_membership(uv_udp_t* handle,
+    const char* multicast_addr, const char* interface_addr,
+    uv_membership membership);
+
+/*
+ * Send data. If the socket has not previously been bound with `uv_udp_bind`
+ * or `uv_udp_bind6`, it is bound to 0.0.0.0 (the "all interfaces" address)
+ * and a random port number.
+ *
+ * Arguments:
+ *  req       UDP request handle. Need not be initialized.
+ *  handle    UDP handle. Should have been initialized with `uv_udp_init`.
+ *  bufs      List of buffers to send.
+ *  bufcnt    Number of buffers in `bufs`.
+ *  addr      Address of the remote peer. See `uv_ip4_addr`.
+ *  send_cb   Callback to invoke when the data has been sent out.
+ *
+ * Returns:
+ *  0 on success, -1 on error.
+ */
+UV_EXTERN int uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle,
+    uv_buf_t bufs[], int bufcnt, struct sockaddr_in addr,
+    uv_udp_send_cb send_cb);
+
+/*
+ * Send data. If the socket has not previously been bound with `uv_udp_bind6`,
+ * it is bound to ::0 (the "all interfaces" address) and a random port number.
+ *
+ * Arguments:
+ *  req       UDP request handle. Need not be initialized.
+ *  handle    UDP handle. Should have been initialized with `uv_udp_init`.
+ *  bufs      List of buffers to send.
+ *  bufcnt    Number of buffers in `bufs`.
+ *  addr      Address of the remote peer. See `uv_ip6_addr`.
+ *  send_cb   Callback to invoke when the data has been sent out.
+ *
+ * Returns:
+ *  0 on success, -1 on error.
+ */
+UV_EXTERN int uv_udp_send6(uv_udp_send_t* req, uv_udp_t* handle,
+    uv_buf_t bufs[], int bufcnt, struct sockaddr_in6 addr,
+    uv_udp_send_cb send_cb);
+
+/*
+ * Receive data. If the socket has not previously been bound with `uv_udp_bind`
+ * or `uv_udp_bind6`, it is bound to 0.0.0.0 (the "all interfaces" address)
+ * and a random port number.
+ *
+ * Arguments:
+ *  handle    UDP handle. Should have been initialized with `uv_udp_init`.
+ *  alloc_cb  Callback to invoke when temporary storage is needed.
+ *  recv_cb   Callback to invoke with received data.
+ *
+ * Returns:
+ *  0 on success, -1 on error.
+ */
+UV_EXTERN int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
+    uv_udp_recv_cb recv_cb);
+
+/*
+ * Stop listening for incoming datagrams.
+ *
+ * Arguments:
+ *  handle    UDP handle. Should have been initialized with `uv_udp_init`.
+ *
+ * Returns:
+ *  0 on success, -1 on error.
+ */
+UV_EXTERN int uv_udp_recv_stop(uv_udp_t* handle);
+
+
+/*
+ * uv_tty_t is a subclass of uv_stream_t
+ *
+ * Representing a stream for the console.
+ */
+struct uv_tty_s {
+  UV_HANDLE_FIELDS
+  UV_STREAM_FIELDS
+  UV_TTY_PRIVATE_FIELDS
+};
+
+/*
+ * Initialize a new TTY stream with the given file descriptor. Usually the
+ * file descriptor will be
+ *   0 = stdin
+ *   1 = stdout
+ *   2 = stderr
+ * The last argument, readable, specifies if you plan on calling
+ * uv_read_start with this stream. stdin is readable, stdout is not.
+ *
+ * TTY streams which are not readable have blocking writes.
+ */
+UV_EXTERN int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int readable);
+
+/*
+ * Set mode. 0 for normal, 1 for raw.
+ */
+UV_EXTERN int uv_tty_set_mode(uv_tty_t*, int mode);
+
+/*
+ * To be called when the program exits. Resets TTY settings to default
+ * values for the next process to take over.
+ */
+UV_EXTERN void uv_tty_reset_mode();
+
+/*
+ * Gets the current Window size. On success zero is returned.
+ */
+UV_EXTERN int uv_tty_get_winsize(uv_tty_t*, int* width, int* height);
+
+/*
+ * Used to detect what type of stream should be used with a given file
+ * descriptor. Usually this will be used during initialization to guess the
+ * type of the stdio streams.
+ * For isatty() functionality use this function and test for UV_TTY.
+ */
+UV_EXTERN uv_handle_type uv_guess_handle(uv_file file);
+
+/*
+ * uv_pipe_t is a subclass of uv_stream_t
+ *
+ * Representing a pipe stream or pipe server. On Windows this is a Named
+ * Pipe. On Unix this is a UNIX domain socket.
+ */
+struct uv_pipe_s {
+  UV_HANDLE_FIELDS
+  UV_STREAM_FIELDS
+  UV_PIPE_PRIVATE_FIELDS
+  int ipc; /* non-zero if this pipe is used for passing handles */
+};
+
+/*
+ * Initialize a pipe. The last argument is a boolean to indicate if
+ * this pipe will be used for handle passing between processes.
+ */
+UV_EXTERN int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle, int ipc);
+
+/*
+ * Opens an existing file descriptor or HANDLE as a pipe.
+ */
+UV_EXTERN void uv_pipe_open(uv_pipe_t*, uv_file file);
+
+UV_EXTERN int uv_pipe_bind(uv_pipe_t* handle, const char* name);
+
+UV_EXTERN void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
+    const char* name, uv_connect_cb cb);
+
+
+/*
+ * uv_prepare_t is a subclass of uv_handle_t.
+ *
+ * libev wrapper. Every active prepare handle gets its callback called
+ * exactly once per loop iteration, just before the system blocks to wait
+ * for completed i/o.
+ */
+struct uv_prepare_s {
+  UV_HANDLE_FIELDS
+  UV_PREPARE_PRIVATE_FIELDS
+};
+
+UV_EXTERN int uv_prepare_init(uv_loop_t*, uv_prepare_t* prepare);
+
+UV_EXTERN int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb);
+
+UV_EXTERN int uv_prepare_stop(uv_prepare_t* prepare);
+
+
+/*
+ * uv_check_t is a subclass of uv_handle_t.
+ *
+ * libev wrapper. Every active check handle gets its callback called exactly
+ * once per loop iteration, just after the system returns from blocking.
+ */
+struct uv_check_s {
+  UV_HANDLE_FIELDS
+  UV_CHECK_PRIVATE_FIELDS
+};
+
+UV_EXTERN int uv_check_init(uv_loop_t*, uv_check_t* check);
+
+UV_EXTERN int uv_check_start(uv_check_t* check, uv_check_cb cb);
+
+UV_EXTERN int uv_check_stop(uv_check_t* check);
+
+
+/*
+ * uv_idle_t is a subclass of uv_handle_t.
+ *
+ * libev wrapper. Every active idle handle gets its callback called
+ * repeatedly until it is stopped. This happens after all other types of
+ * callbacks are processed.  When there are multiple "idle" handles active,
+ * their callbacks are called in turn.
+ */
+struct uv_idle_s {
+  UV_HANDLE_FIELDS
+  UV_IDLE_PRIVATE_FIELDS
+};
+
+UV_EXTERN int uv_idle_init(uv_loop_t*, uv_idle_t* idle);
+
+UV_EXTERN int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb);
+
+UV_EXTERN int uv_idle_stop(uv_idle_t* idle);
+
+
+/*
+ * uv_async_t is a subclass of uv_handle_t.
+ *
+ * libev wrapper. uv_async_send wakes up the event
+ * loop and calls the async handle's callback There is no guarantee that
+ * every uv_async_send call leads to exactly one invocation of the callback;
+ * The only guarantee is that the callback function is  called at least once
+ * after the call to async_send. Unlike all other libuv functions,
+ * uv_async_send can be called from another thread.
+ */
+struct uv_async_s {
+  UV_HANDLE_FIELDS
+  UV_ASYNC_PRIVATE_FIELDS
+};
+
+UV_EXTERN int uv_async_init(uv_loop_t*, uv_async_t* async,
+    uv_async_cb async_cb);
+
+/*
+ * This can be called from other threads to wake up a libuv thread.
+ *
+ * libuv is single threaded at the moment.
+ */
+UV_EXTERN int uv_async_send(uv_async_t* async);
+
+
+/*
+ * uv_timer_t is a subclass of uv_handle_t.
+ *
+ * Wraps libev's ev_timer watcher. Used to get woken up at a specified time
+ * in the future.
+ */
+struct uv_timer_s {
+  UV_HANDLE_FIELDS
+  UV_TIMER_PRIVATE_FIELDS
+};
+
+UV_EXTERN int uv_timer_init(uv_loop_t*, uv_timer_t* timer);
+
+UV_EXTERN int uv_timer_start(uv_timer_t* timer, uv_timer_cb cb,
+    int64_t timeout, int64_t repeat);
+
+UV_EXTERN int uv_timer_stop(uv_timer_t* timer);
+
+/*
+ * Stop the timer, and if it is repeating restart it using the repeat value
+ * as the timeout. If the timer has never been started before it returns -1 and
+ * sets the error to UV_EINVAL.
+ */
+UV_EXTERN int uv_timer_again(uv_timer_t* timer);
+
+/*
+ * Set the repeat value. Note that if the repeat value is set from a timer
+ * callback it does not immediately take effect. If the timer was nonrepeating
+ * before, it will have been stopped. If it was repeating, then the old repeat
+ * value will have been used to schedule the next timeout.
+ */
+UV_EXTERN void uv_timer_set_repeat(uv_timer_t* timer, int64_t repeat);
+
+UV_EXTERN int64_t uv_timer_get_repeat(uv_timer_t* timer);
+
+
+/* c-ares integration initialize and terminate */
+UV_EXTERN  int uv_ares_init_options(uv_loop_t*,
+    ares_channel *channelptr, struct ares_options *options, int optmask);
+
+/* TODO remove the loop argument from this function? */
+UV_EXTERN void uv_ares_destroy(uv_loop_t*, ares_channel channel);
+
+
+/*
+ * uv_getaddrinfo_t is a subclass of uv_req_t
+ *
+ * Request object for uv_getaddrinfo.
+ */
+struct uv_getaddrinfo_s {
+  UV_REQ_FIELDS
+  /* read-only */
+  uv_loop_t* loop; \
+  UV_GETADDRINFO_PRIVATE_FIELDS
+};
+
+
+/*
+ * Asynchronous getaddrinfo(3).
+ *
+ * Return code 0 means that request is accepted and callback will be called
+ * with result. Other return codes mean that there will not be a callback.
+ * Input arguments may be released after return from this call.
+ *
+ * uv_freeaddrinfo() must be called after completion to free the addrinfo
+ * structure.
+ *
+ * On error NXDOMAIN the status code will be non-zero and UV_ENOENT returned.
+ */
+UV_EXTERN int uv_getaddrinfo(uv_loop_t*, uv_getaddrinfo_t* handle,
+    uv_getaddrinfo_cb getaddrinfo_cb, const char* node, const char* service,
+    const struct addrinfo* hints);
+
+UV_EXTERN void uv_freeaddrinfo(struct addrinfo* ai);
+
+/* uv_spawn() options */
+typedef struct uv_process_options_s {
+  uv_exit_cb exit_cb; /* Called after the process exits. */
+  const char* file; /* Path to program to execute. */
+  /*
+   * Command line arguments. args[0] should be the path to the program. On
+   * Windows this uses CreateProcess which concatinates the arguments into a
+   * string this can cause some strange errors. See the note at
+   * windows_verbatim_arguments.
+   */
+  char** args;
+  /*
+   * This will be set as the environ variable in the subprocess. If this is
+   * NULL then the parents environ will be used.
+   */
+  char** env;
+  /*
+   * If non-null this represents a directory the subprocess should execute
+   * in. Stands for current working directory.
+   */
+  char* cwd;
+
+  /*
+   * TODO describe how this works.
+   */
+  int windows_verbatim_arguments;
+
+  /*
+   * The user should supply pointers to initialized uv_pipe_t structs for
+   * stdio. This is used to to send or receive input from the subprocess.
+   * The user is reponsible for calling uv_close on them.
+   */
+  uv_pipe_t* stdin_stream;
+  uv_pipe_t* stdout_stream;
+  uv_pipe_t* stderr_stream;
+} uv_process_options_t;
+
+/*
+ * uv_process_t is a subclass of uv_handle_t
+ */
+struct uv_process_s {
+  UV_HANDLE_FIELDS
+  uv_exit_cb exit_cb;
+  int pid;
+  UV_PROCESS_PRIVATE_FIELDS
+};
+
+/* Initializes uv_process_t and starts the process. */
+UV_EXTERN int uv_spawn(uv_loop_t*, uv_process_t*,
+    uv_process_options_t options);
+
+/*
+ * Kills the process with the specified signal. The user must still
+ * call uv_close on the process.
+ */
+UV_EXTERN int uv_process_kill(uv_process_t*, int signum);
+
+
+/* Kills the process with the specified signal. */
+UV_EXTERN uv_err_t uv_kill(int pid, int signum);
+
+
+/*
+ * uv_work_t is a subclass of uv_req_t
+ */
+struct uv_work_s {
+  UV_REQ_FIELDS
+  uv_loop_t* loop;
+  uv_work_cb work_cb;
+  uv_after_work_cb after_work_cb;
+  UV_WORK_PRIVATE_FIELDS
+};
+
+/* Queues a work request to execute asynchronously on the thread pool. */
+UV_EXTERN int uv_queue_work(uv_loop_t* loop, uv_work_t* req,
+    uv_work_cb work_cb, uv_after_work_cb after_work_cb);
+
+
+
+
+/*
+ * File System Methods.
+ *
+ * The uv_fs_* functions execute a blocking system call asynchronously (in a
+ * thread pool) and call the specified callback in the specified loop after
+ * completion. If the user gives NULL as the callback the blocking system
+ * call will be called synchronously. req should be a pointer to an
+ * uninitialized uv_fs_t object.
+ *
+ * uv_fs_req_cleanup() must be called after completion of the uv_fs_
+ * function to free any internal memory allocations associted with the
+ * request.
+ */
+
+typedef enum {
+  UV_FS_UNKNOWN = -1,
+  UV_FS_CUSTOM,
+  UV_FS_OPEN,
+  UV_FS_CLOSE,
+  UV_FS_READ,
+  UV_FS_WRITE,
+  UV_FS_SENDFILE,
+  UV_FS_STAT,
+  UV_FS_LSTAT,
+  UV_FS_FSTAT,
+  UV_FS_FTRUNCATE,
+  UV_FS_UTIME,
+  UV_FS_FUTIME,
+  UV_FS_CHMOD,
+  UV_FS_FCHMOD,
+  UV_FS_FSYNC,
+  UV_FS_FDATASYNC,
+  UV_FS_UNLINK,
+  UV_FS_RMDIR,
+  UV_FS_MKDIR,
+  UV_FS_RENAME,
+  UV_FS_READDIR,
+  UV_FS_LINK,
+  UV_FS_SYMLINK,
+  UV_FS_READLINK,
+  UV_FS_CHOWN,
+  UV_FS_FCHOWN
+} uv_fs_type;
+
+/* uv_fs_t is a subclass of uv_req_t */
+struct uv_fs_s {
+  UV_REQ_FIELDS
+  uv_loop_t* loop;
+  uv_fs_type fs_type;
+  uv_fs_cb cb;
+  ssize_t result;
+  void* ptr;
+  char* path;
+  int errorno;
+  UV_FS_PRIVATE_FIELDS
+};
+
+UV_EXTERN void uv_fs_req_cleanup(uv_fs_t* req);
+
+UV_EXTERN int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+    uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    int flags, int mode, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+    void* buf, size_t length, off_t offset, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+    void* buf, size_t length, off_t offset, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    int mode, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req,
+    const char* path, int flags, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+    uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    const char* new_path, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+    uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+    uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+    off_t offset, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd,
+    uv_file in_fd, off_t in_offset, size_t length, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    int mode, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    double atime, double mtime, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+    double atime, double mtime, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    const char* new_path, uv_fs_cb cb);
+
+/*
+ * This flag can be used with uv_fs_symlink on Windows
+ * to specify whether path argument points to a directory.
+ */
+#define UV_FS_SYMLINK_DIR          0x0001
+
+UV_EXTERN int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    const char* new_path, int flags, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+    int mode, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    int uid, int gid, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+    int uid, int gid, uv_fs_cb cb);
+
+
+enum uv_fs_event {
+  UV_RENAME = 1,
+  UV_CHANGE = 2
+};
+
+
+struct uv_fs_event_s {
+  UV_HANDLE_FIELDS
+  char* filename;
+  UV_FS_EVENT_PRIVATE_FIELDS
+};
+
+
+/*
+ * Gets load avg
+ * See: http://en.wikipedia.org/wiki/Load_(computing)
+ * (Returns [0,0,0] for windows and cygwin)
+ */
+UV_EXTERN void uv_loadavg(double avg[3]);
+
+
+/*
+ * Flags to be passed to uv_fs_event_init.
+ */
+enum uv_fs_event_flags {
+  /*
+   * By default, if the fs event watcher is given a directory name, we will
+   * watch for all events in that directory. This flags overrides this behavior
+   * and makes fs_event report only changes to the directory entry itself. This
+   * flag does not affect individual files watched.
+   * This flag is currently not implemented yet on any backend.
+   */
+ UV_FS_EVENT_WATCH_ENTRY = 1,
+
+  /*
+   * By default uv_fs_event will try to use a kernel interface such as inotify
+   * or kqueue to detect events. This may not work on remote filesystems such
+   * as NFS mounts. This flag makes fs_event fall back to calling stat() on a
+   * regular interval.
+   * This flag is currently not implemented yet on any backend.
+   */
+  UV_FS_EVENT_STAT = 2
+};
+
+
+UV_EXTERN int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle,
+    const char* filename, uv_fs_event_cb cb, int flags);
+
+/* Utility */
+
+/* Convert string ip addresses to binary structures */
+UV_EXTERN struct sockaddr_in uv_ip4_addr(const char* ip, int port);
+UV_EXTERN struct sockaddr_in6 uv_ip6_addr(const char* ip, int port);
+
+/* Convert binary addresses to strings */
+UV_EXTERN int uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size);
+UV_EXTERN int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size);
+
+/* Gets the executable path */
+UV_EXTERN int uv_exepath(char* buffer, size_t* size);
+
+/* Gets memory info in bytes */
+UV_EXTERN uint64_t uv_get_free_memory(void);
+UV_EXTERN uint64_t uv_get_total_memory(void);
+
+/*
+ * Returns the current high-resolution real time. This is expressed in
+ * nanoseconds. It is relative to an arbitrary time in the past. It is not
+ * related to the time of day and therefore not subject to clock drift. The
+ * primary use is for measuring performance between intervals.
+ *
+ * Note not every platform can support nanosecond resolution; however, this
+ * value will always be in nanoseconds.
+ */
+UV_EXTERN extern uint64_t uv_hrtime(void);
+
+
+/*
+ * Opens a shared library. The filename is in utf-8. On success, -1 is
+ * and the variable pointed by library receives a handle to the library.
+ */
+UV_EXTERN uv_err_t uv_dlopen(const char* filename, uv_lib_t* library);
+UV_EXTERN uv_err_t uv_dlclose(uv_lib_t library);
+
+/*
+ * Retrieves a data pointer from a dynamic library.
+ */
+UV_EXTERN uv_err_t uv_dlsym(uv_lib_t library, const char* name, void** ptr);
+
+
+/* the presence of these unions force similar struct layout */
+union uv_any_handle {
+  uv_tcp_t tcp;
+  uv_pipe_t pipe;
+  uv_prepare_t prepare;
+  uv_check_t check;
+  uv_idle_t idle;
+  uv_async_t async;
+  uv_timer_t timer;
+  uv_getaddrinfo_t getaddrinfo;
+  uv_fs_event_t fs_event;
+};
+
+union uv_any_req {
+  uv_req_t req;
+  uv_write_t write;
+  uv_connect_t connect;
+  uv_shutdown_t shutdown;
+  uv_fs_t fs_req;
+  uv_work_t work_req;
+};
+
+
+struct uv_counters_s {
+  uint64_t eio_init;
+  uint64_t req_init;
+  uint64_t handle_init;
+  uint64_t stream_init;
+  uint64_t tcp_init;
+  uint64_t udp_init;
+  uint64_t pipe_init;
+  uint64_t tty_init;
+  uint64_t prepare_init;
+  uint64_t check_init;
+  uint64_t idle_init;
+  uint64_t async_init;
+  uint64_t timer_init;
+  uint64_t process_init;
+  uint64_t fs_event_init;
+};
+
+
+struct uv_loop_s {
+  UV_LOOP_PRIVATE_FIELDS
+  /* list used for ares task handles */
+  uv_ares_task_t* uv_ares_handles_;
+  /* Various thing for libeio. */
+  uv_async_t uv_eio_want_poll_notifier;
+  uv_async_t uv_eio_done_poll_notifier;
+  uv_idle_t uv_eio_poller;
+  /* Diagnostic counters */
+  uv_counters_t counters;
+  /* The last error */
+  uv_err_t last_err;
+  /* User data - use this for whatever. */
+  void* data;
+};
+
+
+/* Don't export the private CPP symbols. */
+#undef UV_REQ_TYPE_PRIVATE
+#undef UV_REQ_PRIVATE_FIELDS
+#undef UV_STREAM_PRIVATE_FIELDS
+#undef UV_TCP_PRIVATE_FIELDS
+#undef UV_PREPARE_PRIVATE_FIELDS
+#undef UV_CHECK_PRIVATE_FIELDS
+#undef UV_IDLE_PRIVATE_FIELDS
+#undef UV_ASYNC_PRIVATE_FIELDS
+#undef UV_TIMER_PRIVATE_FIELDS
+#undef UV_GETADDRINFO_PRIVATE_FIELDS
+#undef UV_FS_REQ_PRIVATE_FIELDS
+#undef UV_WORK_PRIVATE_FIELDS
+#undef UV_FS_EVENT_PRIVATE_FIELDS
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* UV_H */