deps: update libuv to version 1.6.0
authorSaúl Ibarra Corretgé <saghul@gmail.com>
Wed, 3 Jun 2015 19:18:55 +0000 (21:18 +0200)
committerBen Noordhuis <info@bnoordhuis.nl>
Wed, 3 Jun 2015 22:09:05 +0000 (00:09 +0200)
Fixes: https://github.com/joyent/node/issues/9310
PR-URL: https://github.com/nodejs/io.js/pull/1889
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
53 files changed:
deps/uv/AUTHORS
deps/uv/ChangeLog
deps/uv/Makefile.am
deps/uv/README.md
deps/uv/checksparse.sh
deps/uv/configure.ac
deps/uv/docs/src/misc.rst
deps/uv/docs/src/tcp.rst
deps/uv/include/uv-version.h
deps/uv/include/uv.h
deps/uv/src/fs-poll.c
deps/uv/src/threadpool.c
deps/uv/src/unix/aix.c
deps/uv/src/unix/android-ifaddrs.c
deps/uv/src/unix/core.c
deps/uv/src/unix/darwin.c
deps/uv/src/unix/dl.c
deps/uv/src/unix/freebsd.c
deps/uv/src/unix/fs.c
deps/uv/src/unix/fsevents.c
deps/uv/src/unix/getaddrinfo.c
deps/uv/src/unix/internal.h
deps/uv/src/unix/kqueue.c
deps/uv/src/unix/linux-core.c
deps/uv/src/unix/linux-inotify.c
deps/uv/src/unix/loop.c
deps/uv/src/unix/netbsd.c
deps/uv/src/unix/openbsd.c
deps/uv/src/unix/pipe.c
deps/uv/src/unix/process.c
deps/uv/src/unix/proctitle.c
deps/uv/src/unix/stream.c
deps/uv/src/unix/sunos.c
deps/uv/src/unix/thread.c
deps/uv/src/unix/udp.c
deps/uv/src/uv-common.c
deps/uv/src/uv-common.h
deps/uv/src/win/fs-event.c
deps/uv/src/win/fs.c
deps/uv/src/win/getaddrinfo.c
deps/uv/src/win/pipe.c
deps/uv/src/win/process-stdio.c
deps/uv/src/win/process.c
deps/uv/src/win/tcp.c
deps/uv/src/win/thread.c
deps/uv/src/win/util.c
deps/uv/test/task.h
deps/uv/test/test-homedir.c [new file with mode: 0644]
deps/uv/test/test-list.h
deps/uv/test/test-pipe-connect-prepare.c [new file with mode: 0644]
deps/uv/test/test-platform-output.c
deps/uv/uv.gyp
deps/uv/vcbuild.bat

index a0e3dd4..bbb8f4d 100644 (file)
@@ -197,3 +197,6 @@ Daryl Haresign <github@daryl.haresign.com>
 Rui Abreu Ferreira <raf-ep@gmx.com>
 João Reis <reis@janeasystems.com>
 farblue68 <farblue68@gmail.com>
+Jason Williams <necmon@yahoo.com>
+Igor Soarez <igorsoarez@gmail.com>
+Miodrag Milanovic <mmicko@gmail.com>
index e5c7980..147a80f 100644 (file)
@@ -1,3 +1,34 @@
+2015.06.04, Version 1.6.0 (Stable), adfccad76456061dfcf79b8df8e7dbfee51791d7
+
+Changes since version 1.5.0:
+
+* aix: fix setsockopt for multicast options (Michael)
+
+* unix: don't block for io if any io handle is primed (Saúl Ibarra Corretgé)
+
+* windows: MSVC 2015 has snprintf() (Rui Abreu Ferreira)
+
+* windows: Add VS2015 support to vcbuild.bat (Jason Williams)
+
+* doc: fix typo in tcp.rst (Igor Soarez)
+
+* linux: work around epoll bug in kernels < 2.6.37 (Ben Noordhuis)
+
+* unix,win: add uv_os_homedir() (cjihrig)
+
+* stream: fix `select()` race condition (Fedor Indutny)
+
+* unix: prevent infinite loop in uv__run_pending (Saúl Ibarra Corretgé)
+
+* unix: make sure UDP send callbacks are asynchronous (Saúl Ibarra Corretgé)
+
+* test: fix `platform_output` netmask printing. (Andrew Paprocki)
+
+* aix: add ahafs autoconf detection and README notes (Andrew Paprocki)
+
+* core: add ability to customize memory allocator (Saúl Ibarra Corretgé)
+
+
 2015.05.07, Version 1.5.0 (Stable), 4e77f74c7b95b639b3397095db1bc5bcc016c203
 
 Changes since version 1.4.2:
index b9fb80c..e9814d7 100644 (file)
@@ -45,7 +45,7 @@ include_HEADERS += include/uv-win.h include/tree.h
 AM_CPPFLAGS += -I$(top_srcdir)/src/win \
                -DWIN32_LEAN_AND_MEAN \
                -D_WIN32_WINNT=0x0600
-LIBS += -lws2_32 -lpsapi -liphlpapi -lshell32
+LIBS += -lws2_32 -lpsapi -liphlpapi -lshell32 -luserenv
 libuv_la_SOURCES += src/win/async.c \
                     src/win/atomicops-inl.h \
                     src/win/core.c \
@@ -165,6 +165,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
                          test/test-getnameinfo.c \
                          test/test-getsockname.c \
                          test/test-handle-fileno.c \
+                         test/test-homedir.c \
                          test/test-hrtime.c \
                          test/test-idle.c \
                          test/test-ip4-addr.c \
@@ -185,6 +186,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
                          test/test-ping-pong.c \
                          test/test-pipe-bind-error.c \
                          test/test-pipe-connect-error.c \
+                         test/test-pipe-connect-prepare.c \
                          test/test-pipe-getsockname.c \
                          test/test-pipe-sendmsg.c \
                          test/test-pipe-server-close.c \
index a7da8b8..f9a7a1e 100644 (file)
@@ -185,6 +185,18 @@ OS X using the GCC or XCode toolchain.
 
 Solaris 121 and later using GCC toolchain.
 
+AIX 6 and later using GCC toolchain (see notes).
+
+### AIX Notes
+
+AIX support for filesystem events requires the non-default IBM `bos.ahafs`
+package to be installed.  This package provides the AIX Event Infrastructure
+that is detected by `autoconf`.
+[IBM documentation](http://www.ibm.com/developerworks/aix/library/au-aix_event_infrastructure/)
+describes the package in more detail.
+
+AIX support for filesystem events is not compiled when building with `gyp`.
+
 ## Patches
 
 See the [guidelines for contributing][].
index 9442c20..619cf6f 100755 (executable)
@@ -103,6 +103,7 @@ test/test-get-loadavg.c
 test/test-get-memory.c
 test/test-getaddrinfo.c
 test/test-getsockname.c
+test/test-homedir.c
 test/test-hrtime.c
 test/test-idle.c
 test/test-ip6-addr.c
index 71cb470..3fa01a2 100644 (file)
@@ -13,7 +13,7 @@
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 AC_PREREQ(2.57)
-AC_INIT([libuv], [1.5.0], [https://github.com/libuv/libuv/issues])
+AC_INIT([libuv], [1.6.0], [https://github.com/libuv/libuv/issues])
 AC_CONFIG_MACRO_DIR([m4])
 m4_include([m4/libuv-extra-automake-flags.m4])
 m4_include([m4/as_case.m4])
@@ -58,6 +58,7 @@ AM_CONDITIONAL([NETBSD],   [AS_CASE([$host_os],[netbsd*],       [true], [false])
 AM_CONDITIONAL([OPENBSD],  [AS_CASE([$host_os],[openbsd*],      [true], [false])])
 AM_CONDITIONAL([SUNOS],    [AS_CASE([$host_os],[solaris*],      [true], [false])])
 AM_CONDITIONAL([WINNT],    [AS_CASE([$host_os],[mingw*],        [true], [false])])
+AC_CHECK_HEADERS([sys/ahafs_evProds.h])
 AC_CHECK_PROG(PKG_CONFIG, pkg-config, yes)
 AM_CONDITIONAL([HAVE_PKG_CONFIG], [test "x$PKG_CONFIG" != "x"])
 AS_IF([test "x$PKG_CONFIG" != "x"], [
index bb97a26..9708c5d 100644 (file)
@@ -26,6 +26,26 @@ Data types
         .. note::
             On Windows this field is ULONG.
 
+.. c:type:: void* (*uv_malloc_func)(size_t size)
+
+        Replacement function for :man:`malloc(3)`.
+        See :c:func:`uv_replace_allocator`.
+
+.. c:type::  void* (*uv_realloc_func)(void* ptr, size_t size)
+
+        Replacement function for :man:`realloc(3)`.
+        See :c:func:`uv_replace_allocator`.
+
+.. c:type::  void* (*uv_calloc_func)(size_t count, size_t size)
+
+        Replacement function for :man:`calloc(3)`.
+        See :c:func:`uv_replace_allocator`.
+
+.. c:type:: void (*uv_free_func)(void* ptr)
+
+        Replacement function for :man:`free(3)`.
+        See :c:func:`uv_replace_allocator`.
+
 .. c:type:: uv_file
 
     Cross platform representation of a file handle.
@@ -126,6 +146,26 @@ API
     Returns the libuv version number as a string. For non-release versions
     "-pre" is appended, so the version number could be "1.2.3-pre".
 
+.. c:function:: int uv_replace_allocator(uv_malloc_func malloc_func, uv_realloc_func realloc_func, uv_calloc_func calloc_func, uv_free_func free_func)
+
+    .. versionadded:: 1.6.0
+
+    Override the use of the standard library's :man:`malloc(3)`,
+    :man:`calloc(3)`, :man:`realloc(3)`, :man:`free(3)`, memory allocation
+    functions.
+
+    This function must be called before any other libuv function is called or
+    after all resources have been freed and thus libuv doesn't reference
+    any allocated memory chunk.
+
+    On success, it returns 0, if any of the function pointers is NULL it
+    returns UV_EINVAL.
+
+    .. warning:: There is no protection against changing the allocator multiple
+                 times. If the user changes it they are responsible for making
+                 sure the allocator is changed while no memory was allocated with
+                 the previous allocator, or that they are compatible.
+
 .. c:function:: uv_buf_t uv_buf_init(char* base, unsigned int len)
 
     Constructor for :c:type:`uv_buf_t`.
@@ -227,6 +267,23 @@ API
 
     Changes the current working directory.
 
+.. c:function:: int uv_os_homedir(char* buffer, size_t* size)
+
+    Gets the current user's home directory. On Windows, `uv_os_homedir()` first
+    checks the `USERPROFILE` environment variable using
+    `GetEnvironmentVariableW()`. If `USERPROFILE` is not set,
+    `GetUserProfileDirectoryW()` is called. On all other operating systems,
+    `uv_os_homedir()` first checks the `HOME` environment variable using
+    :man:`getenv(3)`. If `HOME` is not set, :man:`getpwuid_r(3)` is called. The
+    user's home directory is stored in `buffer`. When `uv_os_homedir()` is
+    called, `size` indicates the maximum size of `buffer`. On success or
+    `UV_ENOBUFS` failure, `size` is set to the string length of `buffer`.
+
+    .. warning::
+        `uv_os_homedir()` is not thread safe.
+
+    .. versionadded:: 1.6.0
+
 .. uint64_t uv_get_free_memory(void)
 .. c:function:: uint64_t uv_get_total_memory(void)
 
index 2b5d268..dd746fe 100644 (file)
@@ -72,7 +72,7 @@ API
     not guarantee that the call to :c:func:`uv_listen` or :c:func:`uv_tcp_connect`
     will succeed as well.
 
-    `flags` con contain ``UV_TCP_IPV6ONLY``, in which case dual-stack support
+    `flags` can contain ``UV_TCP_IPV6ONLY``, in which case dual-stack support
     is disabled and only IPv6 is used.
 
 .. c:function:: int uv_tcp_getsockname(const uv_tcp_t* handle, struct sockaddr* name, int* namelen)
index 0b4e6d7..2e2311e 100644 (file)
@@ -31,7 +31,7 @@
  */
 
 #define UV_VERSION_MAJOR 1
-#define UV_VERSION_MINOR 5
+#define UV_VERSION_MINOR 6
 #define UV_VERSION_PATCH 0
 #define UV_VERSION_IS_RELEASE 1
 #define UV_VERSION_SUFFIX ""
index 75b3a4a..564af5f 100644 (file)
@@ -244,6 +244,16 @@ typedef enum {
 UV_EXTERN unsigned int uv_version(void);
 UV_EXTERN const char* uv_version_string(void);
 
+typedef void* (*uv_malloc_func)(size_t size);
+typedef void* (*uv_realloc_func)(void* ptr, size_t size);
+typedef void* (*uv_calloc_func)(size_t count, size_t size);
+typedef void (*uv_free_func)(void* ptr);
+
+UV_EXTERN int uv_replace_allocator(uv_malloc_func malloc_func,
+                                   uv_realloc_func realloc_func,
+                                   uv_calloc_func calloc_func,
+                                   uv_free_func free_func);
+
 UV_EXTERN uv_loop_t* uv_default_loop(void);
 UV_EXTERN int uv_loop_init(uv_loop_t* loop);
 UV_EXTERN int uv_loop_close(uv_loop_t* loop);
@@ -1028,6 +1038,8 @@ typedef struct {
 
 UV_EXTERN int uv_getrusage(uv_rusage_t* rusage);
 
+UV_EXTERN int uv_os_homedir(char* buffer, size_t* size);
+
 UV_EXTERN int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count);
 UV_EXTERN void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count);
 
index 1145e5f..44d47b8 100644 (file)
@@ -67,7 +67,7 @@ int uv_fs_poll_start(uv_fs_poll_t* handle,
 
   loop = handle->loop;
   len = strlen(path);
-  ctx = calloc(1, sizeof(*ctx) + len);
+  ctx = uv__calloc(1, sizeof(*ctx) + len);
 
   if (ctx == NULL)
     return UV_ENOMEM;
@@ -96,7 +96,7 @@ int uv_fs_poll_start(uv_fs_poll_t* handle,
   return 0;
 
 error:
-  free(ctx);
+  uv__free(ctx);
   return err;
 }
 
@@ -219,7 +219,7 @@ out:
 
 
 static void timer_close_cb(uv_handle_t* handle) {
-  free(container_of(handle, struct poll_ctx, timer_handle));
+  uv__free(container_of(handle, struct poll_ctx, timer_handle));
 }
 
 
index 33890f0..debaf5c 100644 (file)
@@ -122,7 +122,7 @@ UV_DESTRUCTOR(static void cleanup(void)) {
       abort();
 
   if (threads != default_threads)
-    free(threads);
+    uv__free(threads);
 
   uv_mutex_destroy(&mutex);
   uv_cond_destroy(&cond);
@@ -149,7 +149,7 @@ static void init_once(void) {
 
   threads = default_threads;
   if (nthreads > ARRAY_SIZE(default_threads)) {
-    threads = malloc(nthreads * sizeof(threads[0]));
+    threads = uv__malloc(nthreads * sizeof(threads[0]));
     if (threads == NULL) {
       nthreads = ARRAY_SIZE(default_threads);
       threads = default_threads;
index e21a9cc..a2b0744 100644 (file)
@@ -50,7 +50,9 @@
 
 #include <sys/pollset.h>
 #include <ctype.h>
+#ifdef HAVE_SYS_AHAFS_EVPRODS_H
 #include <sys/ahafs_evProds.h>
+#endif
 
 #include <sys/mntctl.h>
 #include <sys/vmount.h>
@@ -501,6 +503,7 @@ void uv_loadavg(double avg[3]) {
 }
 
 
+#ifdef HAVE_SYS_AHAFS_EVPRODS_H
 static char *uv__rawname(char *cp) {
   static char rawbuf[FILENAME_MAX+1];
   char *dp = rindex(cp, '/');
@@ -550,7 +553,7 @@ static int uv__is_ahafs_mounted(void){
   const char *dev = "/aha";
   char *obj, *stub;
 
-  p = malloc(siz);
+  p = uv__malloc(siz);
   if (p == NULL)
     return -errno;
 
@@ -561,8 +564,8 @@ static int uv__is_ahafs_mounted(void){
   if (rv == 0) {
     /* buffer was not large enough, reallocate to correct size */
     siz = *(int*)p;
-    free(p);
-    p = malloc(siz);
+    uv__free(p);
+    p = uv__malloc(siz);
     if (p == NULL)
       return -errno;
     rv = mntctl(MCTL_QUERY, siz, (char*)p);
@@ -576,7 +579,7 @@ static int uv__is_ahafs_mounted(void){
     stub = vmt2dataptr(vmt, VMT_STUB);      /* mount point */
 
     if (EQ(obj, dev) || EQ(uv__rawname(obj), dev) || EQ(stub, dev)) {
-      free(p);  /* Found a match */
+      uv__free(p);  /* Found a match */
       return 0;
     }
     vmt = (struct vmount *) ((char *) vmt + vmt->vmt_length);
@@ -781,7 +784,7 @@ static int uv__parse_data(char *buf, int *events, uv_fs_event_t* handle) {
 
         /* Scan out the name of the file that triggered the event*/
         if (sscanf(p, "BEGIN_EVPROD_INFO\n%sEND_EVPROD_INFO", filename) == 1) {
-          handle->dir_filename = strdup((const char*)&filename);
+          handle->dir_filename = uv__strdup((const char*)&filename);
         } else
           return -1;
         }
@@ -859,11 +862,16 @@ static void uv__ahafs_event(uv_loop_t* loop, uv__io_t* event_watch, unsigned int
   else /* Call the actual JavaScript callback function */
     handle->cb(handle, (const char*)&fname, events, 0);
 }
+#endif
 
 
 int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
+#ifdef HAVE_SYS_AHAFS_EVPRODS_H
   uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
   return 0;
+#else
+  return -ENOSYS;
+#endif
 }
 
 
@@ -871,6 +879,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
                       uv_fs_event_cb cb,
                       const char* filename,
                       unsigned int flags) {
+#ifdef HAVE_SYS_AHAFS_EVPRODS_H
   int  fd, rc, i = 0, res = 0;
   char cwd[PATH_MAX];
   char absolute_path[PATH_MAX];
@@ -931,17 +940,20 @@ int uv_fs_event_start(uv_fs_event_t* handle,
   /* Setup/Initialize all the libuv routines */
   uv__handle_start(handle);
   uv__io_init(&handle->event_watcher, uv__ahafs_event, fd);
-  handle->path = strdup((const char*)&absolute_path);
+  handle->path = uv__strdup((const char*)&absolute_path);
   handle->cb = cb;
 
   uv__io_start(handle->loop, &handle->event_watcher, UV__POLLIN);
 
   return 0;
+#else
+  return -ENOSYS;
+#endif
 }
 
 
 int uv_fs_event_stop(uv_fs_event_t* handle) {
-
+#ifdef HAVE_SYS_AHAFS_EVPRODS_H
   if (!uv__is_active(handle))
     return 0;
 
@@ -949,21 +961,28 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
   uv__handle_stop(handle);
 
   if (uv__path_is_a_directory(handle->path) == 0) {
-    free(handle->dir_filename);
+    uv__free(handle->dir_filename);
     handle->dir_filename = NULL;
   }
 
-  free(handle->path);
+  uv__free(handle->path);
   handle->path = NULL;
   uv__close(handle->event_watcher.fd);
   handle->event_watcher.fd = -1;
 
   return 0;
+#else
+  return -ENOSYS;
+#endif
 }
 
 
 void uv__fs_event_close(uv_fs_event_t* handle) {
+#ifdef HAVE_SYS_AHAFS_EVPRODS_H
   uv_fs_event_stop(handle);
+#else
+  UNREACHABLE();
+#endif
 }
 
 
@@ -1052,7 +1071,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
     return -ENOSYS;
   }
 
-  ps_cpus = (perfstat_cpu_t*) malloc(ncpus * sizeof(perfstat_cpu_t));
+  ps_cpus = (perfstat_cpu_t*) uv__malloc(ncpus * sizeof(perfstat_cpu_t));
   if (!ps_cpus) {
     return -ENOMEM;
   }
@@ -1060,13 +1079,13 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
   strcpy(cpu_id.name, FIRST_CPU);
   result = perfstat_cpu(&cpu_id, ps_cpus, sizeof(perfstat_cpu_t), ncpus);
   if (result == -1) {
-    free(ps_cpus);
+    uv__free(ps_cpus);
     return -ENOSYS;
   }
 
-  *cpu_infos = (uv_cpu_info_t*) malloc(ncpus * sizeof(uv_cpu_info_t));
+  *cpu_infos = (uv_cpu_info_t*) uv__malloc(ncpus * sizeof(uv_cpu_info_t));
   if (!*cpu_infos) {
-    free(ps_cpus);
+    uv__free(ps_cpus);
     return -ENOMEM;
   }
 
@@ -1075,7 +1094,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
   cpu_info = *cpu_infos;
   while (idx < ncpus) {
     cpu_info->speed = (int)(ps_total.processorHZ / 1000000);
-    cpu_info->model = strdup(ps_total.description);
+    cpu_info->model = uv__strdup(ps_total.description);
     cpu_info->cpu_times.user = ps_cpus[idx].user;
     cpu_info->cpu_times.sys = ps_cpus[idx].sys;
     cpu_info->cpu_times.idle = ps_cpus[idx].idle;
@@ -1085,7 +1104,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
     idx++;
   }
 
-  free(ps_cpus);
+  uv__free(ps_cpus);
   return 0;
 }
 
@@ -1094,10 +1113,10 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
   int i;
 
   for (i = 0; i < count; ++i) {
-    free(cpu_infos[i].model);
+    uv__free(cpu_infos[i].model);
   }
 
-  free(cpu_infos);
+  uv__free(cpu_infos);
 }
 
 
@@ -1119,7 +1138,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
     return -errno;
   }
 
-  ifc.ifc_req = (struct ifreq*)malloc(size);
+  ifc.ifc_req = (struct ifreq*)uv__malloc(size);
   ifc.ifc_len = size;
   if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
     SAVE_ERRNO(uv__close(sockfd));
@@ -1153,7 +1172,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
 
   /* Alloc the return interface structs */
   *addresses = (uv_interface_address_t*)
-    malloc(*count * sizeof(uv_interface_address_t));
+    uv__malloc(*count * sizeof(uv_interface_address_t));
   if (!(*addresses)) {
     uv__close(sockfd);
     return -ENOMEM;
@@ -1181,7 +1200,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
 
     /* All conditions above must match count loop */
 
-    address->name = strdup(p->ifr_name);
+    address->name = uv__strdup(p->ifr_name);
 
     if (p->ifr_addr.sa_family == AF_INET6) {
       address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr);
@@ -1208,10 +1227,10 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
   int i;
 
   for (i = 0; i < count; ++i) {
-    free(addresses[i].name);
+    uv__free(addresses[i].name);
   }
 
-  free(addresses);
+  uv__free(addresses);
 }
 
 void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
index a99b019..71f7290 100644 (file)
@@ -137,8 +137,8 @@ static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_don
     {
         int l_read;
 
-        free(l_buffer);
-        l_buffer = malloc(l_size);
+        uv__free(l_buffer);
+        l_buffer = uv__malloc(l_size);
         if (l_buffer == NULL)
         {
             return NULL;
@@ -148,7 +148,7 @@ static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_don
         *p_size = l_read;
         if(l_read == -2)
         {
-            free(l_buffer);
+            uv__free(l_buffer);
             return NULL;
         }
         if(l_read >= 0)
@@ -170,7 +170,7 @@ static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_don
 
                 if(l_hdr->nlmsg_type == NLMSG_ERROR)
                 {
-                    free(l_buffer);
+                    uv__free(l_buffer);
                     return NULL;
                 }
             }
@@ -183,7 +183,7 @@ static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_don
 
 static NetlinkList *newListItem(struct nlmsghdr *p_data, unsigned int p_size)
 {
-    NetlinkList *l_item = malloc(sizeof(NetlinkList));
+    NetlinkList *l_item = uv__malloc(sizeof(NetlinkList));
     if (l_item == NULL)
     {
         return NULL;
@@ -202,8 +202,8 @@ static void freeResultList(NetlinkList *p_list)
     {
         l_cur = p_list;
         p_list = p_list->m_next;
-        free(l_cur->m_data);
-        free(l_cur);
+        uv__free(l_cur->m_data);
+        uv__free(l_cur);
     }
 }
 
@@ -349,7 +349,7 @@ static int interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList)
         }
     }
 
-    l_entry = malloc(sizeof(struct ifaddrs) + sizeof(int) + l_nameSize + l_addrSize + l_dataSize);
+    l_entry = uv__malloc(sizeof(struct ifaddrs) + sizeof(int) + l_nameSize + l_addrSize + l_dataSize);
     if (l_entry == NULL)
     {
         return -1;
@@ -478,7 +478,7 @@ static int interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList,
         }
     }
 
-    l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize);
+    l_entry = uv__malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize);
     if (l_entry == NULL)
     {
         return -1;
@@ -698,6 +698,6 @@ void freeifaddrs(struct ifaddrs *ifa)
     {
         l_cur = ifa;
         ifa = ifa->ifa_next;
-        free(l_cur);
+        uv__free(l_cur);
     }
 }
index 6f284ff..cfb7630 100644 (file)
@@ -38,6 +38,7 @@
 #include <limits.h> /* INT_MAX, PATH_MAX */
 #include <sys/uio.h> /* writev */
 #include <sys/resource.h> /* getrusage */
+#include <pwd.h>
 
 #ifdef __linux__
 # include <sys/ioctl.h>
@@ -282,6 +283,9 @@ int uv_backend_timeout(const uv_loop_t* loop) {
   if (!QUEUE_EMPTY(&loop->idle_handles))
     return 0;
 
+  if (!QUEUE_EMPTY(&loop->pending_queue))
+    return 0;
+
   if (loop->closing_handles)
     return 0;
 
@@ -696,16 +700,20 @@ int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) {
 
 static int uv__run_pending(uv_loop_t* loop) {
   QUEUE* q;
+  QUEUE pq;
   uv__io_t* w;
 
   if (QUEUE_EMPTY(&loop->pending_queue))
     return 0;
 
-  while (!QUEUE_EMPTY(&loop->pending_queue)) {
-    q = QUEUE_HEAD(&loop->pending_queue);
+  QUEUE_INIT(&pq);
+  q = QUEUE_HEAD(&loop->pending_queue);
+  QUEUE_SPLIT(&loop->pending_queue, q, &pq);
+
+  while (!QUEUE_EMPTY(&pq)) {
+    q = QUEUE_HEAD(&pq);
     QUEUE_REMOVE(q);
     QUEUE_INIT(q);
-
     w = QUEUE_DATA(q, uv__io_t, pending_queue);
     w->cb(loop, w, UV__POLLOUT);
   }
@@ -745,8 +753,8 @@ static void maybe_resize(uv_loop_t* loop, unsigned int len) {
   }
 
   nwatchers = next_power_of_two(len + 2) - 2;
-  watchers = realloc(loop->watchers,
-                     (nwatchers + 2) * sizeof(loop->watchers[0]));
+  watchers = uv__realloc(loop->watchers,
+                         (nwatchers + 2) * sizeof(loop->watchers[0]));
 
   if (watchers == NULL)
     abort();
@@ -983,3 +991,82 @@ int uv__dup2_cloexec(int oldfd, int newfd) {
     return r;
   }
 }
+
+
+int uv_os_homedir(char* buffer, size_t* size) {
+  struct passwd pw;
+  struct passwd* result;
+  char* buf;
+  uid_t uid;
+  size_t bufsize;
+  size_t len;
+  int r;
+
+  if (buffer == NULL || size == NULL || *size == 0)
+    return -EINVAL;
+
+  /* Check if the HOME environment variable is set first */
+  buf = getenv("HOME");
+
+  if (buf != NULL) {
+    len = strlen(buf);
+
+    if (len >= *size) {
+      *size = len;
+      return -ENOBUFS;
+    }
+
+    memcpy(buffer, buf, len + 1);
+    *size = len;
+
+    return 0;
+  }
+
+  /* HOME is not set, so call getpwuid() */
+  bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+
+  if (bufsize <= 0)
+    return -EIO;
+
+  uid = getuid();
+  buf = NULL;
+
+  for (;;) {
+    uv__free(buf);
+    buf = uv__malloc(bufsize);
+
+    if (buf == NULL)
+      return -ENOMEM;
+
+    r = getpwuid_r(uid, &pw, buf, bufsize, &result);
+
+    if (r != ERANGE)
+      break;
+
+    bufsize *= 2;
+  }
+
+  if (r != 0) {
+    uv__free(buf);
+    return -r;
+  }
+
+  if (result == NULL) {
+    uv__free(buf);
+    return -ENOENT;
+  }
+
+  len = strlen(pw.pw_dir);
+
+  if (len >= *size) {
+    *size = len;
+    uv__free(buf);
+    return -ENOBUFS;
+  }
+
+  memcpy(buffer, pw.pw_dir, len + 1);
+  *size = len;
+  uv__free(buf);
+
+  return 0;
+}
index d276ada..718a81e 100644 (file)
@@ -198,7 +198,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
     return -EINVAL;  /* FIXME(bnoordhuis) Translate error. */
   }
 
-  *cpu_infos = malloc(numcpus * sizeof(**cpu_infos));
+  *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
   if (!(*cpu_infos))
     return -ENOMEM;  /* FIXME(bnoordhuis) Deallocate info? */
 
@@ -213,7 +213,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
     cpu_info->cpu_times.idle = (uint64_t)(info[i].cpu_ticks[2]) * multiplier;
     cpu_info->cpu_times.irq = 0;
 
-    cpu_info->model = strdup(model);
+    cpu_info->model = uv__strdup(model);
     cpu_info->speed = cpuspeed/1000000;
   }
   vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type);
@@ -226,10 +226,10 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
   int i;
 
   for (i = 0; i < count; i++) {
-    free(cpu_infos[i].model);
+    uv__free(cpu_infos[i].model);
   }
 
-  free(cpu_infos);
+  uv__free(cpu_infos);
 }
 
 
@@ -255,7 +255,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
     (*count)++;
   }
 
-  *addresses = malloc(*count * sizeof(**addresses));
+  *addresses = uv__malloc(*count * sizeof(**addresses));
   if (!(*addresses))
     return -ENOMEM;
 
@@ -275,7 +275,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
     if (ent->ifa_addr->sa_family == AF_LINK)
       continue;
 
-    address->name = strdup(ent->ifa_name);
+    address->name = uv__strdup(ent->ifa_name);
 
     if (ent->ifa_addr->sa_family == AF_INET6) {
       address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
@@ -324,8 +324,8 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
   int i;
 
   for (i = 0; i < count; i++) {
-    free(addresses[i].name);
+    uv__free(addresses[i].name);
   }
 
-  free(addresses);
+  uv__free(addresses);
 }
index ad45fc8..7c6d41c 100644 (file)
@@ -40,7 +40,7 @@ int uv_dlopen(const char* filename, uv_lib_t* lib) {
 
 void uv_dlclose(uv_lib_t* lib) {
   if (lib->errmsg) {
-    free(lib->errmsg);
+    uv__free(lib->errmsg);
     lib->errmsg = NULL;
   }
 
@@ -68,12 +68,12 @@ static int uv__dlerror(uv_lib_t* lib) {
   const char* errmsg;
 
   if (lib->errmsg)
-    free(lib->errmsg);
+    uv__free(lib->errmsg);
 
   errmsg = dlerror();
 
   if (errmsg) {
-    lib->errmsg = strdup(errmsg);
+    lib->errmsg = uv__strdup(errmsg);
     return -1;
   }
   else {
index 2dbb1ec..44976f7 100644 (file)
@@ -151,7 +151,7 @@ void uv_loadavg(double avg[3]) {
 
 
 char** uv_setup_args(int argc, char** argv) {
-  process_title = argc ? strdup(argv[0]) : NULL;
+  process_title = argc ? uv__strdup(argv[0]) : NULL;
   return argv;
 }
 
@@ -159,8 +159,8 @@ char** uv_setup_args(int argc, char** argv) {
 int uv_set_process_title(const char* title) {
   int oid[4];
 
-  if (process_title) free(process_title);
-  process_title = strdup(title);
+  if (process_title) uv__free(process_title);
+  process_title = uv__strdup(title);
 
   oid[0] = CTL_KERN;
   oid[1] = KERN_PROC;
@@ -271,7 +271,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
   if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0))
     return -errno;
 
-  *cpu_infos = malloc(numcpus * sizeof(**cpu_infos));
+  *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
   if (!(*cpu_infos))
     return -ENOMEM;
 
@@ -279,7 +279,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
 
   size = sizeof(cpuspeed);
   if (sysctlbyname("hw.clockrate", &cpuspeed, &size, NULL, 0)) {
-    SAVE_ERRNO(free(*cpu_infos));
+    SAVE_ERRNO(uv__free(*cpu_infos));
     return -errno;
   }
 
@@ -288,21 +288,21 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
    */
   size = sizeof(maxcpus);
   if (sysctlbyname(maxcpus_key, &maxcpus, &size, NULL, 0)) {
-    SAVE_ERRNO(free(*cpu_infos));
+    SAVE_ERRNO(uv__free(*cpu_infos));
     return -errno;
   }
 
   size = maxcpus * CPUSTATES * sizeof(long);
 
-  cp_times = malloc(size);
+  cp_times = uv__malloc(size);
   if (cp_times == NULL) {
-    free(*cpu_infos);
+    uv__free(*cpu_infos);
     return -ENOMEM;
   }
 
   if (sysctlbyname(cptimes_key, cp_times, &size, NULL, 0)) {
-    SAVE_ERRNO(free(cp_times));
-    SAVE_ERRNO(free(*cpu_infos));
+    SAVE_ERRNO(uv__free(cp_times));
+    SAVE_ERRNO(uv__free(*cpu_infos));
     return -errno;
   }
 
@@ -315,13 +315,13 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
     cpu_info->cpu_times.idle = (uint64_t)(cp_times[CP_IDLE+cur]) * multiplier;
     cpu_info->cpu_times.irq = (uint64_t)(cp_times[CP_INTR+cur]) * multiplier;
 
-    cpu_info->model = strdup(model);
+    cpu_info->model = uv__strdup(model);
     cpu_info->speed = cpuspeed;
 
     cur+=CPUSTATES;
   }
 
-  free(cp_times);
+  uv__free(cp_times);
   return 0;
 }
 
@@ -330,10 +330,10 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
   int i;
 
   for (i = 0; i < count; i++) {
-    free(cpu_infos[i].model);
+    uv__free(cpu_infos[i].model);
   }
 
-  free(cpu_infos);
+  uv__free(cpu_infos);
 }
 
 
@@ -359,7 +359,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
     (*count)++;
   }
 
-  *addresses = malloc(*count * sizeof(**addresses));
+  *addresses = uv__malloc(*count * sizeof(**addresses));
   if (!(*addresses))
     return -ENOMEM;
 
@@ -379,7 +379,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
     if (ent->ifa_addr->sa_family == AF_LINK)
       continue;
 
-    address->name = strdup(ent->ifa_name);
+    address->name = uv__strdup(ent->ifa_name);
 
     if (ent->ifa_addr->sa_family == AF_INET6) {
       address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
@@ -428,8 +428,8 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
   int i;
 
   for (i = 0; i < count; i++) {
-    free(addresses[i].name);
+    uv__free(addresses[i].name);
   }
 
-  free(addresses);
+  uv__free(addresses);
 }
index 7792801..9dab202 100644 (file)
@@ -73,7 +73,7 @@
 
 #define PATH                                                                  \
   do {                                                                        \
-    (req)->path = strdup(path);                                               \
+    (req)->path = uv__strdup(path);                                           \
     if ((req)->path == NULL)                                                  \
       return -ENOMEM;                                                         \
   }                                                                           \
@@ -85,7 +85,7 @@
     size_t new_path_len;                                                      \
     path_len = strlen((path)) + 1;                                            \
     new_path_len = strlen((new_path)) + 1;                                    \
-    (req)->path = malloc(path_len + new_path_len);                            \
+    (req)->path = uv__malloc(path_len + new_path_len);                        \
     if ((req)->path == NULL)                                                  \
       return -ENOMEM;                                                         \
     (req)->new_path = (req)->path + path_len;                                 \
@@ -310,7 +310,7 @@ static ssize_t uv__fs_read(uv_fs_t* req) {
 
 done:
   if (req->bufs != req->bufsml)
-    free(req->bufs);
+    uv__free(req->bufs);
   return result;
 }
 
@@ -350,8 +350,8 @@ out:
     int i;
 
     for (i = 0; i < n; i++)
-      free(dents[i]);
-    free(dents);
+      uv__free(dents[i]);
+    uv__free(dents);
   }
   errno = saved_errno;
 
@@ -375,7 +375,7 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) {
 #endif
   }
 
-  buf = malloc(len + 1);
+  buf = uv__malloc(len + 1);
 
   if (buf == NULL) {
     errno = ENOMEM;
@@ -385,7 +385,7 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) {
   len = readlink(req->path, buf, len);
 
   if (len == -1) {
-    free(buf);
+    uv__free(buf);
     return -1;
   }
 
@@ -671,7 +671,7 @@ done:
 #endif
 
   if (req->bufs != req->bufsml)
-    free(req->bufs);
+    uv__free(req->bufs);
 
   return r;
 }
@@ -1008,7 +1008,7 @@ int uv_fs_mkdtemp(uv_loop_t* loop,
                   const char* tpl,
                   uv_fs_cb cb) {
   INIT(MKDTEMP);
-  req->path = strdup(tpl);
+  req->path = uv__strdup(tpl);
   if (req->path == NULL)
     return -ENOMEM;
   POST;
@@ -1041,7 +1041,7 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req,
   req->nbufs = nbufs;
   req->bufs = req->bufsml;
   if (nbufs > ARRAY_SIZE(req->bufsml))
-    req->bufs = malloc(nbufs * sizeof(*bufs));
+    req->bufs = uv__malloc(nbufs * sizeof(*bufs));
 
   if (req->bufs == NULL)
     return -ENOMEM;
@@ -1163,7 +1163,7 @@ int uv_fs_write(uv_loop_t* loop,
   req->nbufs = nbufs;
   req->bufs = req->bufsml;
   if (nbufs > ARRAY_SIZE(req->bufsml))
-    req->bufs = malloc(nbufs * sizeof(*bufs));
+    req->bufs = uv__malloc(nbufs * sizeof(*bufs));
 
   if (req->bufs == NULL)
     return -ENOMEM;
@@ -1176,7 +1176,7 @@ int uv_fs_write(uv_loop_t* loop,
 
 
 void uv_fs_req_cleanup(uv_fs_t* req) {
-  free((void*) req->path);
+  uv__free((void*)req->path);
   req->path = NULL;
   req->new_path = NULL;
 
@@ -1184,6 +1184,6 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
     uv__fs_scandir_cleanup(req);
 
   if (req->ptr != &req->statbuf)
-    free(req->ptr);
+    uv__free(req->ptr);
   req->ptr = NULL;
 }
index 4908530..8143f7c 100644 (file)
@@ -169,7 +169,7 @@ static void (*pFSEventStreamStop)(FSEventStreamRef);
         if (!uv__is_closing((handle)) && uv__is_active((handle)))             \
           block                                                               \
         /* Free allocated data */                                             \
-        free(event);                                                          \
+        uv__free(event);                                                      \
       }                                                                       \
       if (err != 0 && !uv__is_closing((handle)) && uv__is_active((handle)))   \
         (handle)->cb((handle), NULL, 0, err);                                 \
@@ -280,7 +280,7 @@ static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
       len = 0;
 #endif /* MAC_OS_X_VERSION_10_7 */
 
-      event = malloc(sizeof(*event) + len);
+      event = uv__malloc(sizeof(*event) + len);
       if (event == NULL)
         break;
 
@@ -425,7 +425,7 @@ static void uv__fsevents_reschedule(uv_fs_event_t* handle) {
   uv_mutex_lock(&state->fsevent_mutex);
   path_count = state->fsevent_handle_count;
   if (path_count != 0) {
-    paths = malloc(sizeof(*paths) * path_count);
+    paths = uv__malloc(sizeof(*paths) * path_count);
     if (paths == NULL) {
       uv_mutex_unlock(&state->fsevent_mutex);
       goto final;
@@ -465,7 +465,7 @@ final:
     if (cf_paths == NULL) {
       while (i != 0)
         pCFRelease(paths[--i]);
-      free(paths);
+      uv__free(paths);
     } else {
       /* CFArray takes ownership of both strings and original C-array */
       pCFRelease(cf_paths);
@@ -584,7 +584,7 @@ static int uv__fsevents_loop_init(uv_loop_t* loop) {
   if (err)
     return err;
 
-  state = calloc(1, sizeof(*state));
+  state = uv__calloc(1, sizeof(*state));
   if (state == NULL)
     return -ENOMEM;
 
@@ -662,7 +662,7 @@ fail_sem_init:
   uv_mutex_destroy(&loop->cf_mutex);
 
 fail_mutex_init:
-  free(state);
+  uv__free(state);
   return err;
 }
 
@@ -688,7 +688,7 @@ void uv__fsevents_loop_delete(uv_loop_t* loop) {
     q = QUEUE_HEAD(&loop->cf_signals);
     s = QUEUE_DATA(q, uv__cf_loop_signal_t, member);
     QUEUE_REMOVE(q);
-    free(s);
+    uv__free(s);
   }
 
   /* Destroy state */
@@ -696,7 +696,7 @@ void uv__fsevents_loop_delete(uv_loop_t* loop) {
   uv_sem_destroy(&state->fsevent_sem);
   uv_mutex_destroy(&state->fsevent_mutex);
   pCFRelease(state->signal_source);
-  free(state);
+  uv__free(state);
   loop->cf_state = NULL;
 }
 
@@ -756,7 +756,7 @@ static void uv__cf_loop_cb(void* arg) {
       uv__fsevents_reschedule(s->handle);
 
     QUEUE_REMOVE(item);
-    free(s);
+    uv__free(s);
   }
 }
 
@@ -766,7 +766,7 @@ int uv__cf_loop_signal(uv_loop_t* loop, uv_fs_event_t* handle) {
   uv__cf_loop_signal_t* item;
   uv__cf_loop_state_t* state;
 
-  item = malloc(sizeof(*item));
+  item = uv__malloc(sizeof(*item));
   if (item == NULL)
     return -ENOMEM;
 
@@ -808,7 +808,7 @@ int uv__fsevents_init(uv_fs_event_t* handle) {
    * Events will occur in other thread.
    * Initialize callback for getting them back into event loop's thread
    */
-  handle->cf_cb = malloc(sizeof(*handle->cf_cb));
+  handle->cf_cb = uv__malloc(sizeof(*handle->cf_cb));
   if (handle->cf_cb == NULL) {
     err = -ENOMEM;
     goto fail_cf_cb_malloc;
@@ -843,11 +843,11 @@ fail_loop_signal:
   uv_mutex_destroy(&handle->cf_mutex);
 
 fail_cf_mutex_init:
-  free(handle->cf_cb);
+  uv__free(handle->cf_cb);
   handle->cf_cb = NULL;
 
 fail_cf_cb_malloc:
-  free(handle->realpath);
+  uv__free(handle->realpath);
   handle->realpath = NULL;
   handle->realpath_len = 0;
 
@@ -880,7 +880,7 @@ int uv__fsevents_close(uv_fs_event_t* handle) {
   /* Wait for deinitialization */
   uv_sem_wait(&state->fsevent_sem);
 
-  uv_close((uv_handle_t*) handle->cf_cb, (uv_close_cb) free);
+  uv_close((uv_handle_t*) handle->cf_cb, (uv_close_cb) uv__free);
   handle->cf_cb = NULL;
 
   /* Free data in queue */
@@ -889,7 +889,7 @@ int uv__fsevents_close(uv_fs_event_t* handle) {
   });
 
   uv_mutex_destroy(&handle->cf_mutex);
-  free(handle->realpath);
+  uv__free(handle->realpath);
   handle->realpath = NULL;
   handle->realpath_len = 0;
 
index 0d684e2..2049aea 100644 (file)
@@ -112,11 +112,11 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) {
 
   /* See initialization in uv_getaddrinfo(). */
   if (req->hints)
-    free(req->hints);
+    uv__free(req->hints);
   else if (req->service)
-    free(req->service);
+    uv__free(req->service);
   else if (req->hostname)
-    free(req->hostname);
+    uv__free(req->hostname);
   else
     assert(0);
 
@@ -152,7 +152,7 @@ int uv_getaddrinfo(uv_loop_t* loop,
   hostname_len = hostname ? strlen(hostname) + 1 : 0;
   service_len = service ? strlen(service) + 1 : 0;
   hints_len = hints ? sizeof(*hints) : 0;
-  buf = malloc(hostname_len + service_len + hints_len);
+  buf = uv__malloc(hostname_len + service_len + hints_len);
 
   if (buf == NULL)
     return -ENOMEM;
index 31db5e2..c31e549 100644 (file)
@@ -143,7 +143,8 @@ enum {
   UV_TCP_NODELAY          = 0x400,  /* Disable Nagle. */
   UV_TCP_KEEPALIVE        = 0x800,  /* Turn on keep-alive. */
   UV_TCP_SINGLE_ACCEPT    = 0x1000, /* Only accept() when idle. */
-  UV_HANDLE_IPV6          = 0x10000 /* Handle is bound to a IPv6 socket. */
+  UV_HANDLE_IPV6          = 0x10000, /* Handle is bound to a IPv6 socket. */
+  UV_UDP_PROCESSING       = 0x20000  /* Handle is running the send callback queue. */
 };
 
 /* loop flags */
index aaadcd8..424236a 100644 (file)
@@ -363,7 +363,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
 
   uv__handle_start(handle);
   uv__io_init(&handle->event_watcher, uv__fs_event, fd);
-  handle->path = strdup(path);
+  handle->path = uv__strdup(path);
   handle->cb = cb;
 
 #if defined(__APPLE__)
@@ -403,7 +403,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
     uv__io_close(handle->loop, &handle->event_watcher);
   }
 
-  free(handle->path);
+  uv__free(handle->path);
   handle->path = NULL;
 
   uv__close(handle->event_watcher.fd);
index d07494d..e6e6828 100644 (file)
@@ -141,17 +141,26 @@ void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
 
 
 void uv__io_poll(uv_loop_t* loop, int timeout) {
+  /* A bug in kernels < 2.6.37 makes timeouts larger than ~30 minutes
+   * effectively infinite on 32 bits architectures.  To avoid blocking
+   * indefinitely, we cap the timeout and poll again if necessary.
+   *
+   * Note that "30 minutes" is a simplification because it depends on
+   * the value of CONFIG_HZ.  The magic constant assumes CONFIG_HZ=1200,
+   * that being the largest value I have seen in the wild (and only once.)
+   */
+  static const int max_safe_timeout = 1789569;
   static int no_epoll_pwait;
   static int no_epoll_wait;
   struct uv__epoll_event events[1024];
   struct uv__epoll_event* pe;
   struct uv__epoll_event e;
+  int real_timeout;
   QUEUE* q;
   uv__io_t* w;
   sigset_t sigset;
   uint64_t sigmask;
   uint64_t base;
-  uint64_t diff;
   int nevents;
   int count;
   int nfds;
@@ -209,8 +218,15 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
   assert(timeout >= -1);
   base = loop->time;
   count = 48; /* Benchmarks suggest this gives the best throughput. */
+  real_timeout = timeout;
 
   for (;;) {
+    /* See the comment for max_safe_timeout for an explanation of why
+     * this is necessary.  Executive summary: kernel bug workaround.
+     */
+    if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout)
+      timeout = max_safe_timeout;
+
     if (sigmask != 0 && no_epoll_pwait != 0)
       if (pthread_sigmask(SIG_BLOCK, &sigset, NULL))
         abort();
@@ -244,6 +260,11 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
 
     if (nfds == 0) {
       assert(timeout != -1);
+
+      timeout = real_timeout - timeout;
+      if (timeout > 0)
+        continue;
+
       return;
     }
 
@@ -346,11 +367,11 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
 update_timeout:
     assert(timeout > 0);
 
-    diff = loop->time - base;
-    if (diff >= (uint64_t) timeout)
+    real_timeout -= (loop->time - base);
+    if (real_timeout <= 0)
       return;
 
-    timeout -= diff;
+    timeout = real_timeout;
   }
 }
 
@@ -523,7 +544,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
   assert(numcpus != (unsigned int) -1);
   assert(numcpus != 0);
 
-  ci = calloc(numcpus, sizeof(*ci));
+  ci = uv__calloc(numcpus, sizeof(*ci));
   if (ci == NULL)
     return -ENOMEM;
 
@@ -595,7 +616,7 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
     if (model_idx < numcpus) {
       if (strncmp(buf, model_marker, sizeof(model_marker) - 1) == 0) {
         model = buf + sizeof(model_marker) - 1;
-        model = strndup(model, strlen(model) - 1);  /* Strip newline. */
+        model = uv__strndup(model, strlen(model) - 1);  /* Strip newline. */
         if (model == NULL) {
           fclose(fp);
           return -ENOMEM;
@@ -614,7 +635,7 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
 #endif
       if (strncmp(buf, model_marker, sizeof(model_marker) - 1) == 0) {
         model = buf + sizeof(model_marker) - 1;
-        model = strndup(model, strlen(model) - 1);  /* Strip newline. */
+        model = uv__strndup(model, strlen(model) - 1);  /* Strip newline. */
         if (model == NULL) {
           fclose(fp);
           return -ENOMEM;
@@ -645,7 +666,7 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
     inferred_model = ci[model_idx - 1].model;
 
   while (model_idx < numcpus) {
-    model = strndup(inferred_model, strlen(inferred_model));
+    model = uv__strndup(inferred_model, strlen(inferred_model));
     if (model == NULL)
       return -ENOMEM;
     ci[model_idx++].model = model;
@@ -755,10 +776,10 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
   int i;
 
   for (i = 0; i < count; i++) {
-    free(cpu_infos[i].model);
+    uv__free(cpu_infos[i].model);
   }
 
-  free(cpu_infos);
+  uv__free(cpu_infos);
 }
 
 
@@ -792,7 +813,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
   if (*count == 0)
     return 0;
 
-  *addresses = malloc(*count * sizeof(**addresses));
+  *addresses = uv__malloc(*count * sizeof(**addresses));
   if (!(*addresses))
     return -ENOMEM;
 
@@ -812,7 +833,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
     if (ent->ifa_addr->sa_family == PF_PACKET)
       continue;
 
-    address->name = strdup(ent->ifa_name);
+    address->name = uv__strdup(ent->ifa_name);
 
     if (ent->ifa_addr->sa_family == AF_INET6) {
       address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
@@ -862,10 +883,10 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
   int i;
 
   for (i = 0; i < count; i++) {
-    free(addresses[i].name);
+    uv__free(addresses[i].name);
   }
 
-  free(addresses);
+  uv__free(addresses);
 }
 
 
index 2ecc5eb..d9ed9f4 100644 (file)
@@ -207,7 +207,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
   if (w)
     goto no_insert;
 
-  w = malloc(sizeof(*w) + strlen(path) + 1);
+  w = uv__malloc(sizeof(*w) + strlen(path) + 1);
   if (w == NULL)
     return -ENOMEM;
 
@@ -245,7 +245,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
     /* No watchers left for this path. Clean up. */
     RB_REMOVE(watcher_root, CAST(&handle->loop->inotify_watchers), w);
     uv__inotify_rm_watch(handle->loop->inotify_fd, w->wd);
-    free(w);
+    uv__free(w);
   }
 
   return 0;
index 7e167d0..aa9146b 100644 (file)
@@ -117,7 +117,7 @@ void uv__loop_close(uv_loop_t* loop) {
   assert(loop->nfds == 0);
 #endif
 
-  free(loop->watchers);
+  uv__free(loop->watchers);
   loop->watchers = NULL;
   loop->nwatchers = 0;
 }
index 9eb0679..29f2a4d 100644 (file)
@@ -131,15 +131,15 @@ uint64_t uv_get_total_memory(void) {
 
 
 char** uv_setup_args(int argc, char** argv) {
-  process_title = argc ? strdup(argv[0]) : NULL;
+  process_title = argc ? uv__strdup(argv[0]) : NULL;
   return argv;
 }
 
 
 int uv_set_process_title(const char* title) {
-  if (process_title) free(process_title);
+  if (process_title) uv__free(process_title);
 
-  process_title = strdup(title);
+  process_title = uv__strdup(title);
   setproctitle("%s", title);
 
   return 0;
@@ -234,17 +234,17 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
     cpuspeed = 0;
 
   size = numcpus * CPUSTATES * sizeof(*cp_times);
-  cp_times = malloc(size);
+  cp_times = uv__malloc(size);
   if (cp_times == NULL)
     return -ENOMEM;
 
   if (sysctlbyname("kern.cp_time", cp_times, &size, NULL, 0))
     return -errno;
 
-  *cpu_infos = malloc(numcpus * sizeof(**cpu_infos));
+  *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
   if (!(*cpu_infos)) {
-    free(cp_times);
-    free(*cpu_infos);
+    uv__free(cp_times);
+    uv__free(*cpu_infos);
     return -ENOMEM;
   }
 
@@ -255,11 +255,11 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
     cpu_info->cpu_times.sys = (uint64_t)(cp_times[CP_SYS+cur]) * multiplier;
     cpu_info->cpu_times.idle = (uint64_t)(cp_times[CP_IDLE+cur]) * multiplier;
     cpu_info->cpu_times.irq = (uint64_t)(cp_times[CP_INTR+cur]) * multiplier;
-    cpu_info->model = strdup(model);
+    cpu_info->model = uv__strdup(model);
     cpu_info->speed = (int)(cpuspeed/(uint64_t) 1e6);
     cur += CPUSTATES;
   }
-  free(cp_times);
+  uv__free(cp_times);
   return 0;
 }
 
@@ -268,10 +268,10 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
   int i;
 
   for (i = 0; i < count; i++) {
-    free(cpu_infos[i].model);
+    uv__free(cpu_infos[i].model);
   }
 
-  free(cpu_infos);
+  uv__free(cpu_infos);
 }
 
 
@@ -296,7 +296,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
     (*count)++;
   }
 
-  *addresses = malloc(*count * sizeof(**addresses));
+  *addresses = uv__malloc(*count * sizeof(**addresses));
 
   if (!(*addresses))
     return -ENOMEM;
@@ -313,7 +313,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
     if (ent->ifa_addr->sa_family != PF_INET)
       continue;
 
-    address->name = strdup(ent->ifa_name);
+    address->name = uv__strdup(ent->ifa_name);
 
     if (ent->ifa_addr->sa_family == AF_INET6) {
       address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
@@ -361,8 +361,8 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) {
   int i;
 
   for (i = 0; i < count; i++) {
-    free(addresses[i].name);
+    uv__free(addresses[i].name);
   }
 
-  free(addresses);
+  uv__free(addresses);
 }
index 859bc0c..c8d5459 100644 (file)
@@ -91,7 +91,7 @@ int uv_exepath(char* buffer, size_t* size) {
   mypid = getpid();
   for (;;) {
     err = -ENOMEM;
-    argsbuf_tmp = realloc(argsbuf, argsbuf_size);
+    argsbuf_tmp = uv__realloc(argsbuf, argsbuf_size);
     if (argsbuf_tmp == NULL)
       goto out;
     argsbuf = argsbuf_tmp;
@@ -124,7 +124,7 @@ int uv_exepath(char* buffer, size_t* size) {
   err = 0;
 
 out:
-  free(argsbuf);
+  uv__free(argsbuf);
 
   return err;
 }
@@ -155,14 +155,14 @@ uint64_t uv_get_total_memory(void) {
 
 
 char** uv_setup_args(int argc, char** argv) {
-  process_title = argc ? strdup(argv[0]) : NULL;
+  process_title = argc ? uv__strdup(argv[0]) : NULL;
   return argv;
 }
 
 
 int uv_set_process_title(const char* title) {
-  if (process_title) free(process_title);
-  process_title = strdup(title);
+  if (process_title) uv__free(process_title);
+  process_title = uv__strdup(title);
   setproctitle(title);
   return 0;
 }
@@ -238,7 +238,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
   if (sysctl(which, 2, &numcpus, &size, NULL, 0))
     return -errno;
 
-  *cpu_infos = malloc(numcpus * sizeof(**cpu_infos));
+  *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
   if (!(*cpu_infos))
     return -ENOMEM;
 
@@ -247,7 +247,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
   which[1] = HW_CPUSPEED;
   size = sizeof(cpuspeed);
   if (sysctl(which, 2, &cpuspeed, &size, NULL, 0)) {
-    SAVE_ERRNO(free(*cpu_infos));
+    SAVE_ERRNO(uv__free(*cpu_infos));
     return -errno;
   }
 
@@ -258,7 +258,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
     which[2] = i;
     size = sizeof(info);
     if (sysctl(which, 3, &info, &size, NULL, 0)) {
-      SAVE_ERRNO(free(*cpu_infos));
+      SAVE_ERRNO(uv__free(*cpu_infos));
       return -errno;
     }
 
@@ -270,7 +270,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
     cpu_info->cpu_times.idle = (uint64_t)(info[CP_IDLE]) * multiplier;
     cpu_info->cpu_times.irq = (uint64_t)(info[CP_INTR]) * multiplier;
 
-    cpu_info->model = strdup(model);
+    cpu_info->model = uv__strdup(model);
     cpu_info->speed = cpuspeed;
   }
 
@@ -282,10 +282,10 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
   int i;
 
   for (i = 0; i < count; i++) {
-    free(cpu_infos[i].model);
+    uv__free(cpu_infos[i].model);
   }
 
-  free(cpu_infos);
+  uv__free(cpu_infos);
 }
 
 
@@ -311,7 +311,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
     (*count)++;
   }
 
-  *addresses = malloc(*count * sizeof(**addresses));
+  *addresses = uv__malloc(*count * sizeof(**addresses));
 
   if (!(*addresses))
     return -ENOMEM;
@@ -328,7 +328,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
     if (ent->ifa_addr->sa_family != PF_INET)
       continue;
 
-    address->name = strdup(ent->ifa_name);
+    address->name = uv__strdup(ent->ifa_name);
 
     if (ent->ifa_addr->sa_family == AF_INET6) {
       address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
@@ -377,8 +377,8 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
   int i;
 
   for (i = 0; i < count; i++) {
-    free(addresses[i].name);
+    uv__free(addresses[i].name);
   }
 
-  free(addresses);
+  uv__free(addresses);
 }
index bc8b856..7f87a71 100644 (file)
@@ -54,7 +54,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
     return -EINVAL;
 
   /* Make a copy of the file name, it outlives this function's scope. */
-  pipe_fname = strdup(name);
+  pipe_fname = uv__strdup(name);
   if (pipe_fname == NULL)
     return -ENOMEM;
 
@@ -88,7 +88,7 @@ err_bind:
   uv__close(sockfd);
 
 err_socket:
-  free((void*)pipe_fname);
+  uv__free((void*)pipe_fname);
   return err;
 }
 
@@ -116,7 +116,7 @@ void uv__pipe_close(uv_pipe_t* handle) {
      * another thread or process.
      */
     unlink(handle->pipe_fname);
-    free((void*)handle->pipe_fname);
+    uv__free((void*)handle->pipe_fname);
     handle->pipe_fname = NULL;
   }
 
index 380f3db..f2a8375 100644 (file)
@@ -404,7 +404,7 @@ int uv_spawn(uv_loop_t* loop,
     stdio_count = 3;
 
   err = -ENOMEM;
-  pipes = malloc(stdio_count * sizeof(*pipes));
+  pipes = uv__malloc(stdio_count * sizeof(*pipes));
   if (pipes == NULL)
     goto error;
 
@@ -509,7 +509,7 @@ int uv_spawn(uv_loop_t* loop,
   process->pid = pid;
   process->exit_cb = options->exit_cb;
 
-  free(pipes);
+  uv__free(pipes);
   return exec_errorno;
 
 error:
@@ -523,7 +523,7 @@ error:
       if (pipes[i][1] != -1)
         close(pipes[i][1]);
     }
-    free(pipes);
+    uv__free(pipes);
   }
 
   return err;
index 16b0523..19214e5 100644 (file)
@@ -55,7 +55,7 @@ char** uv_setup_args(int argc, char** argv) {
   /* Add space for the argv pointers. */
   size += (argc + 1) * sizeof(char*);
 
-  new_argv = malloc(size);
+  new_argv = uv__malloc(size);
   if (new_argv == NULL)
     return argv;
   args_mem = new_argv;
@@ -97,6 +97,6 @@ int uv_get_process_title(char* buffer, size_t size) {
 
 
 UV_DESTRUCTOR(static void free_args_mem(void)) {
-  free(args_mem);  /* Keep valgrind happy. */
+  uv__free(args_mem);  /* Keep valgrind happy. */
   args_mem = NULL;
 }
index 48827b6..7ad1658 100644 (file)
@@ -231,7 +231,6 @@ static void uv__stream_osx_select_cb(uv_async_t* handle) {
   /* Get and reset stream's events */
   events = s->events;
   ACCESS_ONCE(int, s->events) = 0;
-  uv_sem_post(&s->async_sem);
 
   assert(events != 0);
   assert(events == (events & (UV__POLLIN | UV__POLLOUT)));
@@ -242,6 +241,14 @@ static void uv__stream_osx_select_cb(uv_async_t* handle) {
 
   if ((events & UV__POLLOUT) && uv__io_active(&stream->io_watcher, UV__POLLOUT))
     uv__stream_io(stream->loop, &stream->io_watcher, UV__POLLOUT);
+
+  if (stream->flags & UV_CLOSING)
+    return;
+
+  /* NOTE: It is important to do it here, otherwise `select()` might be called
+   * before the actual `uv__read()`, leading to the blocking syscall
+   */
+  uv_sem_post(&s->async_sem);
 }
 
 
@@ -249,7 +256,7 @@ static void uv__stream_osx_cb_close(uv_handle_t* async) {
   uv__stream_select_t* s;
 
   s = container_of(async, uv__stream_select_t, async);
-  free(s);
+  uv__free(s);
 }
 
 
@@ -309,7 +316,7 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
   sread_sz = ROUND_UP(max_fd + 1, sizeof(uint32_t) * NBBY) / NBBY;
   swrite_sz = sread_sz;
 
-  s = malloc(sizeof(*s) + sread_sz + swrite_sz);
+  s = uv__malloc(sizeof(*s) + sread_sz + swrite_sz);
   if (s == NULL) {
     err = -ENOMEM;
     goto failed_malloc;
@@ -368,7 +375,7 @@ failed_close_sem_init:
   return err;
 
 failed_async_init:
-  free(s);
+  uv__free(s);
 
 failed_malloc:
   uv__close(fds[0]);
@@ -605,7 +612,7 @@ done:
     /* All read, free */
     assert(queued_fds->offset > 0);
     if (--queued_fds->offset == 0) {
-      free(queued_fds);
+      uv__free(queued_fds);
       server->queued_fds = NULL;
     } else {
       /* Shift rest */
@@ -703,7 +710,7 @@ static void uv__write_req_finish(uv_write_t* req) {
    */
   if (req->error == 0) {
     if (req->bufs != req->bufsml)
-      free(req->bufs);
+      uv__free(req->bufs);
     req->bufs = NULL;
   }
 
@@ -914,7 +921,7 @@ static void uv__write_callbacks(uv_stream_t* stream) {
     if (req->bufs != NULL) {
       stream->write_queue_size -= uv__write_req_size(req);
       if (req->bufs != req->bufsml)
-        free(req->bufs);
+        uv__free(req->bufs);
       req->bufs = NULL;
     }
 
@@ -979,8 +986,8 @@ static int uv__stream_queue_fd(uv_stream_t* stream, int fd) {
   queued_fds = stream->queued_fds;
   if (queued_fds == NULL) {
     queue_size = 8;
-    queued_fds = malloc((queue_size - 1) * sizeof(*queued_fds->fds) +
-                        sizeof(*queued_fds));
+    queued_fds = uv__malloc((queue_size - 1) * sizeof(*queued_fds->fds) +
+                            sizeof(*queued_fds));
     if (queued_fds == NULL)
       return -ENOMEM;
     queued_fds->size = queue_size;
@@ -990,9 +997,9 @@ static int uv__stream_queue_fd(uv_stream_t* stream, int fd) {
     /* Grow */
   } else if (queued_fds->size == queued_fds->offset) {
     queue_size = queued_fds->size + 8;
-    queued_fds = realloc(queued_fds,
-                         (queue_size - 1) * sizeof(*queued_fds->fds) +
-                             sizeof(*queued_fds));
+    queued_fds = uv__realloc(queued_fds,
+                             (queue_size - 1) * sizeof(*queued_fds->fds) +
+                              sizeof(*queued_fds));
 
     /*
      * Allocation failure, report back.
@@ -1357,7 +1364,7 @@ int uv_write2(uv_write_t* req,
 
   req->bufs = req->bufsml;
   if (nbufs > ARRAY_SIZE(req->bufsml))
-    req->bufs = malloc(nbufs * sizeof(bufs[0]));
+    req->bufs = uv__malloc(nbufs * sizeof(bufs[0]));
 
   if (req->bufs == NULL)
     return -ENOMEM;
@@ -1445,7 +1452,7 @@ int uv_try_write(uv_stream_t* stream,
   QUEUE_REMOVE(&req.queue);
   uv__req_unregister(stream->loop, &req);
   if (req.bufs != req.bufsml)
-    free(req.bufs);
+    uv__free(req.bufs);
   req.bufs = NULL;
 
   /* Do not poll for writable, if we wasn't before calling this */
@@ -1582,7 +1589,7 @@ void uv__stream_close(uv_stream_t* handle) {
     queued_fds = handle->queued_fds;
     for (i = 0; i < queued_fds->offset; i++)
       uv__close(queued_fds->fds[i]);
-    free(handle->queued_fds);
+    uv__free(handle->queued_fds);
     handle->queued_fds = NULL;
   }
 
index c41d0f0..05b7a11 100644 (file)
@@ -433,7 +433,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
   }
 
   uv__handle_start(handle);
-  handle->path = strdup(path);
+  handle->path = uv__strdup(path);
   handle->fd = PORT_UNUSED;
   handle->cb = cb;
 
@@ -463,7 +463,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
   }
 
   handle->fd = PORT_DELETED;
-  free(handle->path);
+  uv__free(handle->path);
   handle->path = NULL;
   handle->fo.fo_name = NULL;
   uv__handle_stop(handle);
@@ -582,7 +582,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
     lookup_instance++;
   }
 
-  *cpu_infos =  malloc(lookup_instance * sizeof(**cpu_infos));
+  *cpu_infos = uv__malloc(lookup_instance * sizeof(**cpu_infos));
   if (!(*cpu_infos)) {
     kstat_close(kc);
     return -ENOMEM;
@@ -605,7 +605,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
 
       knp = kstat_data_lookup(ksp, (char*) "brand");
       assert(knp->data_type == KSTAT_DATA_STRING);
-      cpu_info->model = strdup(KSTAT_NAMED_STR_PTR(knp));
+      cpu_info->model = uv__strdup(KSTAT_NAMED_STR_PTR(knp));
     }
 
     lookup_instance++;
@@ -659,10 +659,10 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
   int i;
 
   for (i = 0; i < count; i++) {
-    free(cpu_infos[i].model);
+    uv__free(cpu_infos[i].model);
   }
 
-  free(cpu_infos);
+  uv__free(cpu_infos);
 }
 
 
@@ -692,7 +692,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
     (*count)++;
   }
 
-  *addresses = malloc(*count * sizeof(**addresses));
+  *addresses = uv__malloc(*count * sizeof(**addresses));
   if (!(*addresses))
     return -ENOMEM;
 
@@ -705,7 +705,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
     if (ent->ifa_addr == NULL)
       continue;
 
-    address->name = strdup(ent->ifa_name);
+    address->name = uv__strdup(ent->ifa_name);
 
     if (ent->ifa_addr->sa_family == AF_INET6) {
       address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
@@ -756,8 +756,8 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
   int i;
 
   for (i = 0; i < count; i++) {
-    free(addresses[i].name);
+    uv__free(addresses[i].name);
   }
 
-  free(addresses);
+  uv__free(addresses);
 }
index ea8563f..6080cf5 100644 (file)
@@ -45,7 +45,7 @@ static void* uv__thread_start(void *arg)
 
   ctx_p = arg;
   ctx = *ctx_p;
-  free(ctx_p);
+  uv__free(ctx_p);
   ctx.entry(ctx.arg);
 
   return 0;
@@ -56,7 +56,7 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
   struct thread_ctx* ctx;
   int err;
 
-  ctx = malloc(sizeof(*ctx));
+  ctx = uv__malloc(sizeof(*ctx));
   if (ctx == NULL)
     return UV_ENOMEM;
 
@@ -66,7 +66,7 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
   err = pthread_create(tid, NULL, uv__thread_start, ctx);
 
   if (err)
-    free(ctx);
+    uv__free(ctx);
 
   return -err;
 }
index 22c2e13..f85ab14 100644 (file)
@@ -89,6 +89,9 @@ static void uv__udp_run_completed(uv_udp_t* handle) {
   uv_udp_send_t* req;
   QUEUE* q;
 
+  assert(!(handle->flags & UV_UDP_PROCESSING));
+  handle->flags |= UV_UDP_PROCESSING;
+
   while (!QUEUE_EMPTY(&handle->write_completed_queue)) {
     q = QUEUE_HEAD(&handle->write_completed_queue);
     QUEUE_REMOVE(q);
@@ -100,7 +103,7 @@ static void uv__udp_run_completed(uv_udp_t* handle) {
     handle->send_queue_count--;
 
     if (req->bufs != req->bufsml)
-      free(req->bufs);
+      uv__free(req->bufs);
     req->bufs = NULL;
 
     if (req->send_cb == NULL)
@@ -121,6 +124,8 @@ static void uv__udp_run_completed(uv_udp_t* handle) {
     if (!uv__io_active(&handle->io_watcher, UV__POLLIN))
       uv__handle_stop(handle);
   }
+
+  handle->flags &= ~UV_UDP_PROCESSING;
 }
 
 
@@ -399,7 +404,7 @@ int uv__udp_send(uv_udp_send_t* req,
 
   req->bufs = req->bufsml;
   if (nbufs > ARRAY_SIZE(req->bufsml))
-    req->bufs = malloc(nbufs * sizeof(bufs[0]));
+    req->bufs = uv__malloc(nbufs * sizeof(bufs[0]));
 
   if (req->bufs == NULL)
     return -ENOMEM;
@@ -410,10 +415,11 @@ int uv__udp_send(uv_udp_send_t* req,
   QUEUE_INSERT_TAIL(&handle->write_queue, &req->queue);
   uv__handle_start(handle);
 
-  if (empty_queue)
+  if (empty_queue && !(handle->flags & UV_UDP_PROCESSING)) {
     uv__udp_sendmsg(handle);
-  else
+  } else {
     uv__io_start(handle->loop, &handle->io_watcher, UV__POLLOUT);
+  }
 
   return 0;
 }
@@ -666,13 +672,13 @@ int uv_udp_set_ttl(uv_udp_t* handle, int ttl) {
  * so hardcode the size of these options on this platform,
  * and use the general uv__setsockopt_maybe_char call on other platforms.
  */
-#if defined(__sun)
+#if defined(__sun) || defined(_AIX)
   return uv__setsockopt(handle,
                         IP_TTL,
                         IPV6_UNICAST_HOPS,
                         &ttl,
                         sizeof(ttl));
-#endif /* defined(__sun) */
+#endif /* defined(__sun) || defined(_AIX) */
 
   return uv__setsockopt_maybe_char(handle,
                                    IP_TTL,
@@ -688,14 +694,14 @@ int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) {
  * IP_MULTICAST_TTL, so hardcode the size of the option in the IPv6 case,
  * and use the general uv__setsockopt_maybe_char call otherwise.
  */
-#if defined(__sun)
+#if defined(__sun) || defined(_AIX)
   if (handle->flags & UV_HANDLE_IPV6)
     return uv__setsockopt(handle,
                           IP_MULTICAST_TTL,
                           IPV6_MULTICAST_HOPS,
                           &ttl,
                           sizeof(ttl));
-#endif /* defined(__sun) */
+#endif /* defined(__sun) || defined(_AIX) */
 
   return uv__setsockopt_maybe_char(handle,
                                    IP_MULTICAST_TTL,
@@ -711,14 +717,14 @@ int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) {
  * IP_MULTICAST_LOOP, so hardcode the size of the option in the IPv6 case,
  * and use the general uv__setsockopt_maybe_char call otherwise.
  */
-#if defined(__sun)
+#if defined(__sun) || defined(_AIX)
   if (handle->flags & UV_HANDLE_IPV6)
     return uv__setsockopt(handle,
                           IP_MULTICAST_LOOP,
                           IPV6_MULTICAST_LOOP,
                           &on,
                           sizeof(on));
-#endif /* defined(__sun) */
+#endif /* defined(__sun) || defined(_AIX) */
 
   return uv__setsockopt_maybe_char(handle,
                                    IP_MULTICAST_LOOP,
index 02341f8..77879b9 100644 (file)
 # include <net/if.h> /* if_nametoindex */
 #endif
 
+
+typedef struct {
+  uv_malloc_func local_malloc;
+  uv_realloc_func local_realloc;
+  uv_calloc_func local_calloc;
+  uv_free_func local_free;
+} uv__allocator_t;
+
+static uv__allocator_t uv__allocator = {
+  malloc,
+  realloc,
+  calloc,
+  free,
+};
+
+char* uv__strdup(const char* s) {
+  size_t len = strlen(s) + 1;
+  char* m = uv__malloc(len);
+  if (m == NULL)
+    return NULL;
+  return memcpy(m, s, len);
+}
+
+char* uv__strndup(const char* s, size_t n) {
+  char* m;
+  size_t len = strlen(s);
+  if (n < len)
+    len = n;
+  m = uv__malloc(len + 1);
+  if (m == NULL)
+    return NULL;
+  m[len] = '\0';
+  return memcpy(m, s, len);
+}
+
+void* uv__malloc(size_t size) {
+  return uv__allocator.local_malloc(size);
+}
+
+void uv__free(void* ptr) {
+  uv__allocator.local_free(ptr);
+}
+
+void* uv__calloc(size_t count, size_t size) {
+  return uv__allocator.local_calloc(count, size);
+}
+
+void* uv__realloc(void* ptr, size_t size) {
+  return uv__allocator.local_realloc(ptr, size);
+}
+
+int uv_replace_allocator(uv_malloc_func malloc_func,
+                         uv_realloc_func realloc_func,
+                         uv_calloc_func calloc_func,
+                         uv_free_func free_func) {
+  if (malloc_func == NULL || realloc_func == NULL ||
+      calloc_func == NULL || free_func == NULL) {
+    return UV_EINVAL;
+  }
+
+  uv__allocator.local_malloc = malloc_func;
+  uv__allocator.local_realloc = realloc_func;
+  uv__allocator.local_calloc = calloc_func;
+  uv__allocator.local_free = free_func;
+
+  return 0;
+}
+
 #define XX(uc, lc) case UV_##uc: return sizeof(uv_##lc##_t);
 
 size_t uv_handle_size(uv_handle_type type) {
@@ -400,7 +468,7 @@ void uv__fs_scandir_cleanup(uv_fs_t* req) {
   if (*nbufs > 0 && *nbufs != (unsigned int) req->result)
     (*nbufs)--;
   for (; *nbufs < (unsigned int) req->result; (*nbufs)++)
-    free(dents[*nbufs]);
+    uv__free(dents[*nbufs]);
 }
 
 
@@ -414,11 +482,11 @@ int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent) {
 
   /* Free previous entity */
   if (*nbufs > 0)
-    free(dents[*nbufs - 1]);
+    uv__free(dents[*nbufs - 1]);
 
   /* End was already reached */
   if (*nbufs == (unsigned int) req->result) {
-    free(dents);
+    uv__free(dents);
     req->ptr = NULL;
     return UV_EOF;
   }
@@ -492,12 +560,12 @@ uv_loop_t* uv_default_loop(void) {
 uv_loop_t* uv_loop_new(void) {
   uv_loop_t* loop;
 
-  loop = malloc(sizeof(*loop));
+  loop = uv__malloc(sizeof(*loop));
   if (loop == NULL)
     return NULL;
 
   if (uv_loop_init(loop)) {
-    free(loop);
+    uv__free(loop);
     return NULL;
   }
 
@@ -540,5 +608,5 @@ void uv_loop_delete(uv_loop_t* loop) {
   (void) err;    /* Squelch compiler warnings. */
   assert(err == 0);
   if (loop != default_loop)
-    free(loop);
+    uv__free(loop);
 }
index 463caba..8258d7a 100644 (file)
@@ -211,4 +211,13 @@ void uv__fs_scandir_cleanup(uv_fs_t* req);
   }                                                                           \
   while (0)
 
+
+/* Allocator prototypes */
+void *uv__calloc(size_t count, size_t size);
+char *uv__strdup(const char* s);
+char *uv__strndup(const char* s, size_t n);
+void* uv__malloc(size_t size);
+void uv__free(void* ptr);
+void* uv__realloc(void* ptr, size_t size);
+
 #endif /* UV_COMMON_H_ */
index 640651b..eb205d3 100644 (file)
@@ -72,13 +72,13 @@ static int uv_split_path(const WCHAR* filename, WCHAR** dir,
 
   if (i == 0) {
     if (dir) {
-      *dir = (WCHAR*)malloc((MAX_PATH + 1) * sizeof(WCHAR));
+      *dir = (WCHAR*)uv__malloc((MAX_PATH + 1) * sizeof(WCHAR));
       if (!*dir) {
-        uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+        uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
       }
 
       if (!GetCurrentDirectoryW(MAX_PATH, *dir)) {
-        free(*dir);
+        uv__free(*dir);
         *dir = NULL;
         return -1;
       }
@@ -87,17 +87,17 @@ static int uv_split_path(const WCHAR* filename, WCHAR** dir,
     *file = wcsdup(filename);
   } else {
     if (dir) {
-      *dir = (WCHAR*)malloc((i + 1) * sizeof(WCHAR));
+      *dir = (WCHAR*)uv__malloc((i + 1) * sizeof(WCHAR));
       if (!*dir) {
-        uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+        uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
       }
       wcsncpy(*dir, filename, i);
       (*dir)[i] = L'\0';
     }
 
-    *file = (WCHAR*)malloc((len - i) * sizeof(WCHAR));
+    *file = (WCHAR*)uv__malloc((len - i) * sizeof(WCHAR));
     if (!*file) {
-      uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+      uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
     }
     wcsncpy(*file, filename + i + 1, len - i - 1);
     (*file)[len - i - 1] = L'\0';
@@ -137,18 +137,18 @@ int uv_fs_event_start(uv_fs_event_t* handle,
     return UV_EINVAL;
 
   handle->cb = cb;
-  handle->path = strdup(path);
+  handle->path = uv__strdup(path);
   if (!handle->path) {
-    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
   }
 
   uv__handle_start(handle);
 
   /* Convert name to UTF16. */
   name_size = uv_utf8_to_utf16(path, NULL, 0) * sizeof(WCHAR);
-  pathw = (WCHAR*)malloc(name_size);
+  pathw = (WCHAR*)uv__malloc(name_size);
   if (!pathw) {
-    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
   }
 
   if (!uv_utf8_to_utf16(path, pathw,
@@ -192,7 +192,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
     }
 
     dir_to_watch = dir;
-    free(pathw);
+    uv__free(pathw);
     pathw = NULL;
   }
 
@@ -207,7 +207,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
                                    NULL);
 
   if (dir) {
-    free(dir);
+    uv__free(dir);
     dir = NULL;
   }
 
@@ -225,11 +225,10 @@ int uv_fs_event_start(uv_fs_event_t* handle,
   }
 
   if (!handle->buffer) {
-    handle->buffer = (char*)_aligned_malloc(uv_directory_watcher_buffer_size,
-                                            sizeof(DWORD));
+    handle->buffer = (char*)uv__malloc(uv_directory_watcher_buffer_size);
   }
   if (!handle->buffer) {
-    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
   }
 
   memset(&(handle->req.u.io.overlapped), 0,
@@ -259,21 +258,21 @@ int uv_fs_event_start(uv_fs_event_t* handle,
 
 error:
   if (handle->path) {
-    free(handle->path);
+    uv__free(handle->path);
     handle->path = NULL;
   }
 
   if (handle->filew) {
-    free(handle->filew);
+    uv__free(handle->filew);
     handle->filew = NULL;
   }
 
   if (handle->short_filew) {
-    free(handle->short_filew);
+    uv__free(handle->short_filew);
     handle->short_filew = NULL;
   }
 
-  free(pathw);
+  uv__free(pathw);
 
   if (handle->dir_handle != INVALID_HANDLE_VALUE) {
     CloseHandle(handle->dir_handle);
@@ -281,7 +280,7 @@ error:
   }
 
   if (handle->buffer) {
-    _aligned_free(handle->buffer);
+    uv__free(handle->buffer);
     handle->buffer = NULL;
   }
 
@@ -301,22 +300,22 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
   uv__handle_stop(handle);
 
   if (handle->filew) {
-    free(handle->filew);
+    uv__free(handle->filew);
     handle->filew = NULL;
   }
 
   if (handle->short_filew) {
-    free(handle->short_filew);
+    uv__free(handle->short_filew);
     handle->short_filew = NULL;
   }
 
   if (handle->path) {
-    free(handle->path);
+    uv__free(handle->path);
     handle->path = NULL;
   }
 
   if (handle->dirw) {
-    free(handle->dirw);
+    uv__free(handle->dirw);
     handle->dirw = NULL;
   }
 
@@ -378,9 +377,9 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
               size = wcslen(handle->dirw) +
                 file_info->FileNameLength / sizeof(WCHAR) + 2;
 
-              filenamew = (WCHAR*)malloc(size * sizeof(WCHAR));
+              filenamew = (WCHAR*)uv__malloc(size * sizeof(WCHAR));
               if (!filenamew) {
-                uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+                uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
               }
 
               _snwprintf(filenamew, size, L"%s\\%.*s", handle->dirw,
@@ -393,26 +392,26 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
               size = GetLongPathNameW(filenamew, NULL, 0);
 
               if (size) {
-                long_filenamew = (WCHAR*)malloc(size * sizeof(WCHAR));
+                long_filenamew = (WCHAR*)uv__malloc(size * sizeof(WCHAR));
                 if (!long_filenamew) {
-                  uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+                  uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
                 }
 
                 size = GetLongPathNameW(filenamew, long_filenamew, size);
                 if (size) {
                   long_filenamew[size] = '\0';
                 } else {
-                  free(long_filenamew);
+                  uv__free(long_filenamew);
                   long_filenamew = NULL;
                 }
               }
 
-              free(filenamew);
+              uv__free(filenamew);
 
               if (long_filenamew) {
                 /* Get the file name out of the long path. */
                 result = uv_split_path(long_filenamew, NULL, &filenamew);
-                free(long_filenamew);
+                uv__free(long_filenamew);
 
                 if (result == 0) {
                   long_filenamew = filenamew;
@@ -447,9 +446,9 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
                                     NULL,
                                     0);
             if (size) {
-              filename = (char*)malloc(size + 1);
+              filename = (char*)uv__malloc(size + 1);
               if (!filename) {
-                uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+                uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
               }
 
               size = uv_utf16_to_utf8(filenamew,
@@ -459,7 +458,7 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
               if (size) {
                 filename[size] = '\0';
               } else {
-                free(filename);
+                uv__free(filename);
                 filename = NULL;
               }
             }
@@ -478,9 +477,9 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
               break;
           }
 
-          free(filename);
+          uv__free(filename);
           filename = NULL;
-          free(long_filenamew);
+          uv__free(long_filenamew);
           long_filenamew = NULL;
         }
 
@@ -519,7 +518,7 @@ void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle) {
     assert(!(handle->flags & UV_HANDLE_CLOSED));
 
     if (handle->buffer) {
-      _aligned_free(handle->buffer);
+      uv__free(handle->buffer);
       handle->buffer = NULL;
     }
 
index af7ec74..00d0197 100644 (file)
@@ -166,7 +166,7 @@ INLINE static int fs__capture_path(uv_loop_t* loop, uv_fs_t* req,
     return 0;
   }
 
-  buf = (char*) malloc(buf_sz);
+  buf = (char*) uv__malloc(buf_sz);
   if (buf == NULL) {
     return ERROR_OUTOFMEMORY;
   }
@@ -352,7 +352,7 @@ INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr,
   /* If requested, allocate memory and convert to UTF8. */
   if (target_ptr != NULL) {
     int r;
-    target = (char*) malloc(target_len + 1);
+    target = (char*) uv__malloc(target_len + 1);
     if (target == NULL) {
       SetLastError(ERROR_OUTOFMEMORY);
       return -1;
@@ -896,7 +896,7 @@ void fs__scandir(uv_fs_t* req) {
         size_t new_dirents_size =
             dirents_size == 0 ? dirents_initial_size : dirents_size << 1;
         uv__dirent_t** new_dirents =
-            realloc(dirents, new_dirents_size * sizeof *dirents);
+            uv__realloc(dirents, new_dirents_size * sizeof *dirents);
 
         if (new_dirents == NULL)
           goto out_of_memory_error;
@@ -909,7 +909,7 @@ void fs__scandir(uv_fs_t* req) {
        * includes room for the first character of the filename, but `utf8_len`
        * doesn't count the NULL terminator at this point.
        */
-      dirent = malloc(sizeof *dirent + utf8_len);
+      dirent = uv__malloc(sizeof *dirent + utf8_len);
       if (dirent == NULL)
         goto out_of_memory_error;
 
@@ -998,9 +998,9 @@ cleanup:
   if (dir_handle != INVALID_HANDLE_VALUE)
     CloseHandle(dir_handle);
   while (dirents_used > 0)
-    free(dirents[--dirents_used]);
+    uv__free(dirents[--dirents_used]);
   if (dirents != NULL)
-    free(dirents);
+    uv__free(dirents);
 }
 
 
@@ -1281,9 +1281,9 @@ static void fs__sendfile(uv_fs_t* req) {
   size_t buf_size = length < max_buf_size ? length : max_buf_size;
   int n, result = 0;
   int64_t result_offset = 0;
-  char* buf = (char*) malloc(buf_size);
+  char* buf = (char*) uv__malloc(buf_size);
   if (!buf) {
-    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
   }
 
   if (offset != -1) {
@@ -1314,7 +1314,7 @@ static void fs__sendfile(uv_fs_t* req) {
     }
   }
 
-  free(buf);
+  uv__free(buf);
 
   SET_REQ_RESULT(req, result);
 }
@@ -1504,9 +1504,9 @@ static void fs__create_junction(uv_fs_t* req, const WCHAR* path,
       2 * (target_len + 2) * sizeof(WCHAR);
 
   /* Allocate the buffer */
-  buffer = (REPARSE_DATA_BUFFER*)malloc(needed_buf_size);
+  buffer = (REPARSE_DATA_BUFFER*)uv__malloc(needed_buf_size);
   if (!buffer) {
-    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
   }
 
   /* Grab a pointer to the part of the buffer where filenames go */
@@ -1620,13 +1620,13 @@ static void fs__create_junction(uv_fs_t* req, const WCHAR* path,
 
   /* Clean up */
   CloseHandle(handle);
-  free(buffer);
+  uv__free(buffer);
 
   SET_REQ_RESULT(req, 0);
   return;
 
 error:
-  free(buffer);
+  uv__free(buffer);
 
   if (handle != INVALID_HANDLE_VALUE) {
     CloseHandle(handle);
@@ -1764,10 +1764,10 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
     return;
 
   if (req->flags & UV_FS_FREE_PATHS)
-    free(req->file.pathw);
+    uv__free(req->file.pathw);
 
   if (req->flags & UV_FS_FREE_PTR)
-    free(req->ptr);
+    uv__free(req->ptr);
 
   req->path = NULL;
   req->file.pathw = NULL;
@@ -1830,7 +1830,7 @@ int uv_fs_read(uv_loop_t* loop,
   req->fs.info.nbufs = nbufs;
   req->fs.info.bufs = req->fs.info.bufsml;
   if (nbufs > ARRAY_SIZE(req->fs.info.bufsml))
-    req->fs.info.bufs = malloc(nbufs * sizeof(*bufs));
+    req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs));
 
   if (req->fs.info.bufs == NULL)
     return UV_ENOMEM;
@@ -1863,7 +1863,7 @@ int uv_fs_write(uv_loop_t* loop,
   req->fs.info.nbufs = nbufs;
   req->fs.info.bufs = req->fs.info.bufsml;
   if (nbufs > ARRAY_SIZE(req->fs.info.bufsml))
-    req->fs.info.bufs = malloc(nbufs * sizeof(*bufs));
+    req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs));
 
   if (req->fs.info.bufs == NULL)
     return UV_ENOMEM;
index f3802cd..3d23660 100644 (file)
@@ -110,7 +110,7 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) {
 
   /* release input parameter memory */
   if (req->alloc != NULL) {
-    free(req->alloc);
+    uv__free(req->alloc);
     req->alloc = NULL;
   }
 
@@ -139,7 +139,7 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) {
     }
 
     /* allocate memory for addrinfo results */
-    alloc_ptr = (char*)malloc(addrinfo_len);
+    alloc_ptr = (char*)uv__malloc(addrinfo_len);
 
     /* do conversions */
     if (alloc_ptr != NULL) {
@@ -220,7 +220,7 @@ void uv_freeaddrinfo(struct addrinfo* ai) {
 
   /* release copied result memory */
   if (alloc_ptr != NULL) {
-    free(alloc_ptr);
+    uv__free(alloc_ptr);
   }
 }
 
@@ -285,7 +285,7 @@ int uv_getaddrinfo(uv_loop_t* loop,
   }
 
   /* allocate memory for inputs, and partition it as needed */
-  alloc_ptr = (char*)malloc(nodesize + servicesize + hintssize);
+  alloc_ptr = (char*)uv__malloc(nodesize + servicesize + hintssize);
   if (!alloc_ptr) {
     err = WSAENOBUFS;
     goto error;
@@ -355,7 +355,7 @@ int uv_getaddrinfo(uv_loop_t* loop,
 
 error:
   if (req != NULL && req->alloc != NULL) {
-    free(req->alloc);
+    uv__free(req->alloc);
   }
   return uv_translate_sys_error(err);
 }
index 5a0e542..d232efa 100644 (file)
@@ -423,7 +423,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
                             &item->socket_info_ex.socket_info,
                             0,
                             WSA_FLAG_OVERLAPPED);
-        free(item);
+        uv__free(item);
 
         if (socket != INVALID_SOCKET)
           closesocket(socket);
@@ -444,7 +444,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
 
     if (handle->flags & UV_HANDLE_PIPESERVER) {
       assert(handle->pipe.serv.accept_reqs);
-      free(handle->pipe.serv.accept_reqs);
+      uv__free(handle->pipe.serv.accept_reqs);
       handle->pipe.serv.accept_reqs = NULL;
     }
 
@@ -478,9 +478,9 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
   }
 
   handle->pipe.serv.accept_reqs = (uv_pipe_accept_t*)
-    malloc(sizeof(uv_pipe_accept_t) * handle->pipe.serv.pending_instances);
+    uv__malloc(sizeof(uv_pipe_accept_t) * handle->pipe.serv.pending_instances);
   if (!handle->pipe.serv.accept_reqs) {
-    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
   }
 
   for (i = 0; i < handle->pipe.serv.pending_instances; i++) {
@@ -494,9 +494,9 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
 
   /* Convert name to UTF16. */
   nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR);
-  handle->name = (WCHAR*)malloc(nameSize);
+  handle->name = (WCHAR*)uv__malloc(nameSize);
   if (!handle->name) {
-    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
   }
 
   if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) {
@@ -540,7 +540,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
 
 error:
   if (handle->name) {
-    free(handle->name);
+    uv__free(handle->name);
     handle->name = NULL;
   }
 
@@ -607,9 +607,9 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
 
   /* Convert name to UTF16. */
   nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR);
-  handle->name = (WCHAR*)malloc(nameSize);
+  handle->name = (WCHAR*)uv__malloc(nameSize);
   if (!handle->name) {
-    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
   }
 
   if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) {
@@ -656,7 +656,7 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
 
 error:
   if (handle->name) {
-    free(handle->name);
+    uv__free(handle->name);
     handle->name = NULL;
   }
 
@@ -717,7 +717,7 @@ void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) {
   uv__pipe_stop_read(handle);
 
   if (handle->name) {
-    free(handle->name);
+    uv__free(handle->name);
     handle->name = NULL;
   }
 
@@ -845,7 +845,7 @@ int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) {
     if (err != 0)
       return err;
 
-    free(item);
+    uv__free(item);
 
   } else {
     pipe_client = (uv_pipe_t*)client;
@@ -1261,9 +1261,9 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
       if (handle->pipe.conn.ipc_header_write_req.type != UV_WRITE) {
         ipc_header_req = (uv_write_t*)&handle->pipe.conn.ipc_header_write_req;
       } else {
-        ipc_header_req = (uv_write_t*)malloc(sizeof(uv_write_t));
+        ipc_header_req = (uv_write_t*)uv__malloc(sizeof(uv_write_t));
         if (!ipc_header_req) {
-          uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+          uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
         }
       }
 
@@ -1498,9 +1498,9 @@ void uv__pipe_insert_pending_socket(uv_pipe_t* handle,
                                     int tcp_connection) {
   uv__ipc_queue_item_t* item;
 
-  item = (uv__ipc_queue_item_t*) malloc(sizeof(*item));
+  item = (uv__ipc_queue_item_t*) uv__malloc(sizeof(*item));
   if (item == NULL)
-    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
 
   memcpy(&item->socket_info_ex, info, sizeof(item->socket_info_ex));
   item->tcp_connection = tcp_connection;
@@ -1667,7 +1667,7 @@ void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
     if (req == &handle->pipe.conn.ipc_header_write_req) {
       req->type = UV_UNKNOWN_REQ;
     } else {
-      free(req);
+      uv__free(req);
     }
   } else {
     if (req->cb) {
@@ -1788,7 +1788,7 @@ static void eof_timer_init(uv_pipe_t* pipe) {
   assert(pipe->pipe.conn.eof_timer == NULL);
   assert(pipe->flags & UV_HANDLE_CONNECTION);
 
-  pipe->pipe.conn.eof_timer = (uv_timer_t*) malloc(sizeof *pipe->pipe.conn.eof_timer);
+  pipe->pipe.conn.eof_timer = (uv_timer_t*) uv__malloc(sizeof *pipe->pipe.conn.eof_timer);
 
   r = uv_timer_init(pipe->loop, pipe->pipe.conn.eof_timer);
   assert(r == 0); /* timers can't fail */
@@ -1863,7 +1863,7 @@ static void eof_timer_destroy(uv_pipe_t* pipe) {
 
 static void eof_timer_close_cb(uv_handle_t* handle) {
   assert(handle->type == UV_TIMER);
-  free(handle);
+  uv__free(handle);
 }
 
 
@@ -1941,7 +1941,7 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size)
                                       FileNameInformation);
   if (nt_status == STATUS_BUFFER_OVERFLOW) {
     name_size = sizeof(*name_info) + tmp_name_info.FileNameLength;
-    name_info = malloc(name_size);
+    name_info = uv__malloc(name_size);
     if (!name_info) {
       *size = 0;
       err = UV_ENOMEM;
@@ -2020,7 +2020,7 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size)
   goto cleanup;
 
 error:
-  free(name_info);
+  uv__free(name_info);
 
 cleanup:
   uv__pipe_unpause_read((uv_pipe_t*)handle); /* cast away const warning */
index 98566da..e81f799 100644 (file)
@@ -279,7 +279,7 @@ int uv__stdio_create(uv_loop_t* loop,
   }
 
   /* Allocate the child stdio buffer */
-  buffer = (BYTE*) malloc(CHILD_STDIO_SIZE(count));
+  buffer = (BYTE*) uv__malloc(CHILD_STDIO_SIZE(count));
   if (buffer == NULL) {
     return ERROR_OUTOFMEMORY;
   }
@@ -459,7 +459,7 @@ void uv__stdio_destroy(BYTE* buffer) {
     }
   }
 
-  free(buffer);
+  uv__free(buffer);
 }
 
 
index 887595f..855c374 100644 (file)
@@ -25,8 +25,8 @@
 #include <stdlib.h>
 #include <signal.h>
 #include <limits.h>
-#include <malloc.h>
 #include <wchar.h>
+#include <malloc.h>    /* alloca */
 
 #include "uv.h"
 #include "internal.h"
@@ -120,7 +120,7 @@ static int uv_utf8_to_utf16_alloc(const char* s, WCHAR** ws_ptr) {
     return GetLastError();
   }
 
-  ws = (WCHAR*) malloc(ws_len * sizeof(WCHAR));
+  ws = (WCHAR*) uv__malloc(ws_len * sizeof(WCHAR));
   if (ws == NULL) {
     return ERROR_OUTOFMEMORY;
   }
@@ -197,7 +197,7 @@ static WCHAR* search_path_join_test(const WCHAR* dir,
   }
 
   /* Allocate buffer for output */
-  result = result_pos = (WCHAR*)malloc(sizeof(WCHAR) *
+  result = result_pos = (WCHAR*)uv__malloc(sizeof(WCHAR) *
       (cwd_len + 1 + dir_len + 1 + name_len + 1 + ext_len + 1));
 
   /* Copy cwd */
@@ -246,7 +246,7 @@ static WCHAR* search_path_join_test(const WCHAR* dir,
     return result;
   }
 
-  free(result);
+  uv__free(result);
   return NULL;
 }
 
@@ -555,14 +555,14 @@ int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) {
   dst_len = dst_len * 2 + arg_count * 2;
 
   /* Allocate buffer for the final command line. */
-  dst = (WCHAR*) malloc(dst_len * sizeof(WCHAR));
+  dst = (WCHAR*) uv__malloc(dst_len * sizeof(WCHAR));
   if (dst == NULL) {
     err = ERROR_OUTOFMEMORY;
     goto error;
   }
 
   /* Allocate temporary working buffer. */
-  temp_buffer = (WCHAR*) malloc(temp_buffer_len * sizeof(WCHAR));
+  temp_buffer = (WCHAR*) uv__malloc(temp_buffer_len * sizeof(WCHAR));
   if (temp_buffer == NULL) {
     err = ERROR_OUTOFMEMORY;
     goto error;
@@ -596,14 +596,14 @@ int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) {
     *pos++ = *(arg + 1) ? L' ' : L'\0';
   }
 
-  free(temp_buffer);
+  uv__free(temp_buffer);
 
   *dst_ptr = dst;
   return 0;
 
 error:
-  free(dst);
-  free(temp_buffer);
+  uv__free(dst);
+  uv__free(temp_buffer);
   return err;
 }
 
@@ -707,7 +707,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
   }
 
   /* second pass: copy to UTF-16 environment block */
-  dst_copy = malloc(env_len * sizeof(WCHAR));
+  dst_copy = (WCHAR*)uv__malloc(env_len * sizeof(WCHAR));
   if (!dst_copy) {
     return ERROR_OUTOFMEMORY;
   }
@@ -725,7 +725,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
                                 (int) (env_len - (ptr - dst_copy)));
       if (len <= 0) {
         DWORD err = GetLastError();
-        free(dst_copy);
+        uv__free(dst_copy);
         return err;
       }
       *ptr_copy++ = ptr;
@@ -765,9 +765,9 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
   }
 
   /* final pass: copy, in sort order, and inserting required variables */
-  dst = malloc((1+env_len) * sizeof(WCHAR));
+  dst = uv__malloc((1+env_len) * sizeof(WCHAR));
   if (!dst) {
-    free(dst_copy);
+    uv__free(dst_copy);
     return ERROR_OUTOFMEMORY;
   }
 
@@ -812,7 +812,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
   assert(env_len == (ptr - dst));
   *ptr = L'\0';
 
-  free(dst_copy);
+  uv__free(dst_copy);
   *dst_ptr = dst;
   return 0;
 }
@@ -988,7 +988,7 @@ int uv_spawn(uv_loop_t* loop,
       goto done;
     }
 
-    cwd = (WCHAR*) malloc(cwd_len * sizeof(WCHAR));
+    cwd = (WCHAR*) uv__malloc(cwd_len * sizeof(WCHAR));
     if (cwd == NULL) {
       err = ERROR_OUTOFMEMORY;
       goto done;
@@ -1012,7 +1012,7 @@ int uv_spawn(uv_loop_t* loop,
       goto done;
     }
 
-    alloc_path = (WCHAR*) malloc(path_len * sizeof(WCHAR));
+    alloc_path = (WCHAR*) uv__malloc(path_len * sizeof(WCHAR));
     if (alloc_path == NULL) {
       err = ERROR_OUTOFMEMORY;
       goto done;
@@ -1146,12 +1146,12 @@ int uv_spawn(uv_loop_t* loop,
 
   /* Cleanup, whether we succeeded or failed. */
  done:
-  free(application);
-  free(application_path);
-  free(arguments);
-  free(cwd);
-  free(env);
-  free(alloc_path);
+  uv__free(application);
+  uv__free(application_path);
+  uv__free(arguments);
+  uv__free(cwd);
+  uv__free(env);
+  uv__free(alloc_path);
 
   if (process->child_stdio_buffer != NULL) {
     /* Clean up child stdio handles. */
index 8b0e18c..da89f28 100644 (file)
@@ -215,7 +215,7 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
         }
       }
 
-      free(handle->tcp.serv.accept_reqs);
+      uv__free(handle->tcp.serv.accept_reqs);
       handle->tcp.serv.accept_reqs = NULL;
     }
 
@@ -564,9 +564,9 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
 
   if(!handle->tcp.serv.accept_reqs) {
     handle->tcp.serv.accept_reqs = (uv_tcp_accept_t*)
-      malloc(uv_simultaneous_server_accepts * sizeof(uv_tcp_accept_t));
+      uv__malloc(uv_simultaneous_server_accepts * sizeof(uv_tcp_accept_t));
     if (!handle->tcp.serv.accept_reqs) {
-      uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+      uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
     }
 
     for (i = 0; i < simultaneous_accepts; i++) {
index 9d273a5..e91ae9b 100644 (file)
@@ -134,7 +134,7 @@ static UINT __stdcall uv__thread_start(void* arg) {
 
   ctx_p = arg;
   ctx = *ctx_p;
-  free(ctx_p);
+  uv__free(ctx_p);
 
   uv_once(&uv__current_thread_init_guard, uv__init_current_thread_key);
   uv_key_set(&uv__current_thread_key, (void*) ctx.self);
@@ -150,7 +150,7 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
   int err;
   HANDLE thread;
 
-  ctx = malloc(sizeof(*ctx));
+  ctx = uv__malloc(sizeof(*ctx));
   if (ctx == NULL)
     return UV_ENOMEM;
 
@@ -167,7 +167,7 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
                                    NULL);
   if (thread == NULL) {
     err = errno;
-    free(ctx);
+    uv__free(ctx);
   } else {
     err = 0;
     *tid = thread;
index 3697d5a..a0d1307 100644 (file)
@@ -36,6 +36,7 @@
 #include <psapi.h>
 #include <tlhelp32.h>
 #include <windows.h>
+#include <userenv.h>
 
 
 /*
@@ -72,7 +73,7 @@ void uv__util_init() {
   InitializeCriticalSection(&process_title_lock);
 
   /* Retrieve high-resolution timer frequency
-   * and precompute its reciprocal. 
+   * and precompute its reciprocal.
    */
   if (QueryPerformanceFrequency(&perf_frequency)) {
     hrtime_interval_ = 1.0 / perf_frequency.QuadPart;
@@ -122,7 +123,7 @@ int uv_exepath(char* buffer, size_t* size_ptr) {
     utf16_buffer_len = (int) *size_ptr;
   }
 
-  utf16_buffer = (WCHAR*) malloc(sizeof(WCHAR) * utf16_buffer_len);
+  utf16_buffer = (WCHAR*) uv__malloc(sizeof(WCHAR) * utf16_buffer_len);
   if (!utf16_buffer) {
     return UV_ENOMEM;
   }
@@ -151,7 +152,7 @@ int uv_exepath(char* buffer, size_t* size_ptr) {
     goto error;
   }
 
-  free(utf16_buffer);
+  uv__free(utf16_buffer);
 
   /* utf8_len *does* include the terminating null at this point, but the */
   /* returned size shouldn't. */
@@ -159,7 +160,7 @@ int uv_exepath(char* buffer, size_t* size_ptr) {
   return 0;
 
  error:
-  free(utf16_buffer);
+  uv__free(utf16_buffer);
   return uv_translate_sys_error(err);
 }
 
@@ -378,9 +379,9 @@ int uv_set_process_title(const char* title) {
   }
 
   /* Convert to wide-char string */
-  title_w = (WCHAR*)malloc(sizeof(WCHAR) * length);
+  title_w = (WCHAR*)uv__malloc(sizeof(WCHAR) * length);
   if (!title_w) {
-    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
   }
 
   length = uv_utf8_to_utf16(title, title_w, length);
@@ -400,14 +401,14 @@ int uv_set_process_title(const char* title) {
   }
 
   EnterCriticalSection(&process_title_lock);
-  free(process_title);
-  process_title = strdup(title);
+  uv__free(process_title);
+  process_title = uv__strdup(title);
   LeaveCriticalSection(&process_title_lock);
 
   err = 0;
 
 done:
-  free(title_w);
+  uv__free(title_w);
   return uv_translate_sys_error(err);
 }
 
@@ -427,14 +428,14 @@ static int uv__get_process_title() {
   }
 
   assert(!process_title);
-  process_title = (char*)malloc(length);
+  process_title = (char*)uv__malloc(length);
   if (!process_title) {
-    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
   }
 
   /* Do utf16 -> utf8 conversion here */
   if (!uv_utf16_to_utf8(title_w, -1, process_title, length)) {
-    free(process_title);
+    uv__free(process_title);
     return -1;
   }
 
@@ -540,9 +541,9 @@ int uv_uptime(double* uptime) {
       goto internalError;
     }
 
-    free(malloced_buffer);
+    uv__free(malloced_buffer);
 
-    buffer = malloced_buffer = (BYTE*) malloc(buffer_size);
+    buffer = malloced_buffer = (BYTE*) uv__malloc(buffer_size);
     if (malloced_buffer == NULL) {
       *uptime = 0;
       return UV_ENOMEM;
@@ -584,7 +585,7 @@ int uv_uptime(double* uptime) {
         uint64_t value = *((uint64_t*) address);
         *uptime = (double) (object_type->PerfTime.QuadPart - value) /
                   (double) object_type->PerfFreq.QuadPart;
-        free(malloced_buffer);
+        uv__free(malloced_buffer);
         return 0;
       }
     }
@@ -594,12 +595,12 @@ int uv_uptime(double* uptime) {
   }
 
   /* If we get here, the uptime value was not found. */
-  free(malloced_buffer);
+  uv__free(malloced_buffer);
   *uptime = 0;
   return UV_ENOSYS;
 
  internalError:
-  free(malloced_buffer);
+  uv__free(malloced_buffer);
   *uptime = 0;
   return UV_EIO;
 }
@@ -625,14 +626,14 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) {
   GetSystemInfo(&system_info);
   cpu_count = system_info.dwNumberOfProcessors;
 
-  cpu_infos = calloc(cpu_count, sizeof *cpu_infos);
+  cpu_infos = uv__calloc(cpu_count, sizeof *cpu_infos);
   if (cpu_infos == NULL) {
     err = ERROR_OUTOFMEMORY;
     goto error;
   }
 
   sppi_size = cpu_count * sizeof(*sppi);
-  sppi = malloc(sppi_size);
+  sppi = uv__malloc(sppi_size);
   if (sppi == NULL) {
     err = ERROR_OUTOFMEMORY;
     goto error;
@@ -725,7 +726,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) {
     assert(len > 0);
 
     /* Allocate 1 extra byte for the null terminator. */
-    cpu_info->model = malloc(len + 1);
+    cpu_info->model = uv__malloc(len + 1);
     if (cpu_info->model == NULL) {
       err = ERROR_OUTOFMEMORY;
       goto error;
@@ -747,7 +748,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) {
     cpu_info->model[len] = '\0';
   }
 
-  free(sppi);
+  uv__free(sppi);
 
   *cpu_count_ptr = cpu_count;
   *cpu_infos_ptr = cpu_infos;
@@ -757,10 +758,10 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) {
  error:
   /* This is safe because the cpu_infos array is zeroed on allocation. */
   for (i = 0; i < cpu_count; i++)
-    free(cpu_infos[i].model);
+    uv__free(cpu_infos[i].model);
 
-  free(cpu_infos);
-  free(sppi);
+  uv__free(cpu_infos);
+  uv__free(sppi);
 
   return uv_translate_sys_error(err);
 }
@@ -770,10 +771,10 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
   int i;
 
   for (i = 0; i < count; i++) {
-    free(cpu_infos[i].model);
+    uv__free(cpu_infos[i].model);
   }
 
-  free(cpu_infos);
+  uv__free(cpu_infos);
 }
 
 
@@ -801,8 +802,8 @@ static int is_windows_version_or_greater(DWORD os_major,
 
   /* Perform the test. */
   return (int) VerifyVersionInfo(
-    &osvi, 
-    VER_MAJORVERSION | VER_MINORVERSION | 
+    &osvi,
+    VER_MAJORVERSION | VER_MINORVERSION |
     VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
     condition_mask);
 }
@@ -870,7 +871,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
     flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
       GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_PREFIX;
   }
-  
+
 
   /* Fetch the size of the adapters reported by windows, and then get the */
   /* list itself. */
@@ -892,13 +893,13 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
     if (r == ERROR_SUCCESS)
       break;
 
-    free(win_address_buf);
+    uv__free(win_address_buf);
 
     switch (r) {
       case ERROR_BUFFER_OVERFLOW:
         /* This happens when win_address_buf is NULL or too small to hold */
         /* all adapters. */
-        win_address_buf = malloc(win_address_buf_size);
+        win_address_buf = uv__malloc(win_address_buf_size);
         if (win_address_buf == NULL)
           return UV_ENOMEM;
 
@@ -906,7 +907,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
 
       case ERROR_NO_DATA: {
         /* No adapters were found. */
-        uv_address_buf = malloc(1);
+        uv_address_buf = uv__malloc(1);
         if (uv_address_buf == NULL)
           return UV_ENOMEM;
 
@@ -966,7 +967,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
                                     NULL,
                                     FALSE);
     if (name_size <= 0) {
-      free(win_address_buf);
+      uv__free(win_address_buf);
       return uv_translate_sys_error(GetLastError());
     }
     uv_address_buf_size += name_size;
@@ -983,9 +984,9 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
   }
 
   /* Allocate space to store interface data plus adapter names. */
-  uv_address_buf = malloc(uv_address_buf_size);
+  uv_address_buf = uv__malloc(uv_address_buf_size);
   if (uv_address_buf == NULL) {
-    free(win_address_buf);
+    uv__free(win_address_buf);
     return UV_ENOMEM;
   }
 
@@ -1019,8 +1020,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
                                     NULL,
                                     FALSE);
     if (name_size <= 0) {
-      free(win_address_buf);
-      free(uv_address_buf);
+      uv__free(win_address_buf);
+      uv__free(uv_address_buf);
       return uv_translate_sys_error(GetLastError());
     }
 
@@ -1053,14 +1054,14 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
               prefix->PrefixLength <= prefix_len)
             continue;
 
-          if (address_prefix_match(sa->sa_family, sa, 
+          if (address_prefix_match(sa->sa_family, sa,
               prefix->Address.lpSockaddr, prefix->PrefixLength)) {
             prefix_len = prefix->PrefixLength;
           }
         }
 
         /* If there is no matching prefix information, return a single-host
-         * subnet mask (e.g. 255.255.255.255 for IPv4). 
+         * subnet mask (e.g. 255.255.255.255 for IPv4).
          */
         if (!prefix_len)
           prefix_len = (sa->sa_family == AF_INET6) ? 128 : 32;
@@ -1104,7 +1105,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
     name_buf += name_size;
   }
 
-  free(win_address_buf);
+  uv__free(win_address_buf);
 
   *addresses_ptr = uv_address_buf;
   *count_ptr = count;
@@ -1115,7 +1116,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
 
 void uv_free_interface_addresses(uv_interface_address_t* addresses,
     int count) {
-  free(addresses);
+  uv__free(addresses);
 }
 
 
@@ -1153,3 +1154,67 @@ int uv_getrusage(uv_rusage_t *uv_rusage) {
 
   return 0;
 }
+
+
+int uv_os_homedir(char* buffer, size_t* size) {
+  HANDLE token;
+  wchar_t path[MAX_PATH];
+  DWORD bufsize;
+  size_t len;
+  int r;
+
+  if (buffer == NULL || size == NULL || *size == 0)
+    return UV_EINVAL;
+
+  /* Check if the USERPROFILE environment variable is set first */
+  len = GetEnvironmentVariableW(L"USERPROFILE", path, MAX_PATH);
+
+  if (len == 0) {
+    r = GetLastError();
+    /* Don't return an error if USERPROFILE was not found */
+    if (r != ERROR_ENVVAR_NOT_FOUND)
+      return uv_translate_sys_error(r);
+  } else if (len > MAX_PATH) {
+    /* This should not be possible */
+    return UV_EIO;
+  } else {
+    goto convert_buffer;
+  }
+
+  /* USERPROFILE is not set, so call GetUserProfileDirectoryW() */
+  if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token) == 0)
+    return uv_translate_sys_error(GetLastError());
+
+  bufsize = MAX_PATH;
+  if (!GetUserProfileDirectoryW(token, path, &bufsize)) {
+    r = GetLastError();
+    CloseHandle(token);
+
+    /* This should not be possible */
+    if (r == ERROR_INSUFFICIENT_BUFFER)
+      return UV_EIO;
+
+    return uv_translate_sys_error(r);
+  }
+
+  CloseHandle(token);
+
+convert_buffer:
+
+  /* Check how much space we need */
+  bufsize = uv_utf16_to_utf8(path, -1, NULL, 0);
+  if (bufsize == 0) {
+    return uv_translate_sys_error(GetLastError());
+  } else if (bufsize > *size) {
+    *size = bufsize - 1;
+    return UV_ENOBUFS;
+  }
+
+  /* Convert to UTF-8 */
+  bufsize = uv_utf16_to_utf8(path, -1, buffer, *size);
+  if (bufsize == 0)
+    return uv_translate_sys_error(GetLastError());
+
+  *size = bufsize - 1;
+  return 0;
+}
index ea0503e..e06a50e 100644 (file)
@@ -184,7 +184,8 @@ enum test_status {
 #  define inline __inline
 # endif
 
-/* Emulate snprintf() on Windows, _snprintf() doesn't zero-terminate the buffer
+# if defined(_MSC_VER) && _MSC_VER < 1900
+/* Emulate snprintf() on MSVC<2015, _snprintf() doesn't zero-terminate the buffer
  * on overflow...
  */
 inline int snprintf(char* buf, size_t len, const char* fmt, ...) {
@@ -205,6 +206,7 @@ inline int snprintf(char* buf, size_t len, const char* fmt, ...) {
 
   return n;
 }
+# endif
 
 #endif
 
diff --git a/deps/uv/test/test-homedir.c b/deps/uv/test/test-homedir.c
new file mode 100644 (file)
index 0000000..cbc4756
--- /dev/null
@@ -0,0 +1,49 @@
+#include "uv.h"
+#include "task.h"
+#include <string.h>
+
+#define PATHMAX 1024
+#define SMALLPATH 1
+
+TEST_IMPL(homedir) {
+  char homedir[PATHMAX];
+  size_t len;
+  char last;
+  int r;
+
+  /* Test the normal case */
+  len = sizeof homedir;
+  homedir[0] = '\0';
+  ASSERT(strlen(homedir) == 0);
+  r = uv_os_homedir(homedir, &len);
+  ASSERT(r == 0);
+  ASSERT(strlen(homedir) == len);
+  ASSERT(len > 0);
+  ASSERT(homedir[len] == '\0');
+
+  if (len > 1) {
+    last = homedir[len - 1];
+#ifdef _WIN32
+    ASSERT(last != '\\');
+#else
+    ASSERT(last != '/');
+#endif
+  }
+
+  /* Test the case where the buffer is too small */
+  len = SMALLPATH;
+  r = uv_os_homedir(homedir, &len);
+  ASSERT(r == UV_ENOBUFS);
+  ASSERT(len > SMALLPATH);
+
+  /* Test invalid inputs */
+  r = uv_os_homedir(NULL, &len);
+  ASSERT(r == UV_EINVAL);
+  r = uv_os_homedir(homedir, NULL);
+  ASSERT(r == UV_EINVAL);
+  len = 0;
+  r = uv_os_homedir(homedir, &len);
+  ASSERT(r == UV_EINVAL);
+
+  return 0;
+}
index 1e3c13d..1e4018c 100644 (file)
@@ -117,6 +117,7 @@ TEST_DECLARE   (pipe_bind_error_inval)
 TEST_DECLARE   (pipe_listen_without_bind)
 TEST_DECLARE   (pipe_connect_bad_name)
 TEST_DECLARE   (pipe_connect_to_file)
+TEST_DECLARE   (pipe_connect_on_prepare)
 TEST_DECLARE   (pipe_getsockname)
 TEST_DECLARE   (pipe_getsockname_abstract)
 TEST_DECLARE   (pipe_getsockname_blocking)
@@ -182,6 +183,7 @@ TEST_DECLARE   (process_title)
 TEST_DECLARE   (cwd_and_chdir)
 TEST_DECLARE   (get_memory)
 TEST_DECLARE   (handle_fileno)
+TEST_DECLARE   (homedir)
 TEST_DECLARE   (hrtime)
 TEST_DECLARE   (getaddrinfo_fail)
 TEST_DECLARE   (getaddrinfo_fail_sync)
@@ -344,6 +346,7 @@ TASK_LIST_START
 
   TEST_ENTRY  (pipe_connect_bad_name)
   TEST_ENTRY  (pipe_connect_to_file)
+  TEST_ENTRY  (pipe_connect_on_prepare)
 
   TEST_ENTRY  (pipe_server_close)
 #ifndef _WIN32
@@ -540,6 +543,8 @@ TASK_LIST_START
 
   TEST_ENTRY  (handle_fileno)
 
+  TEST_ENTRY  (homedir)
+
   TEST_ENTRY  (hrtime)
 
   TEST_ENTRY_CUSTOM (getaddrinfo_fail, 0, 0, 10000)
diff --git a/deps/uv/test/test-pipe-connect-prepare.c b/deps/uv/test/test-pipe-connect-prepare.c
new file mode 100644 (file)
index 0000000..a86e728
--- /dev/null
@@ -0,0 +1,83 @@
+/* Copyright (c) 2015 Saúl Ibarra Corretgé <saghul@gmail.com>.
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#ifdef _WIN32
+# define BAD_PIPENAME "bad-pipe"
+#else
+# define BAD_PIPENAME "/path/to/unix/socket/that/really/should/not/be/there"
+#endif
+
+
+static int close_cb_called = 0;
+static int connect_cb_called = 0;
+
+static uv_pipe_t pipe_handle;
+static uv_prepare_t prepare_handle;
+static uv_connect_t conn_req;
+
+
+static void close_cb(uv_handle_t* handle) {
+  ASSERT(handle != NULL);
+  close_cb_called++;
+}
+
+
+static void connect_cb(uv_connect_t* connect_req, int status) {
+  ASSERT(status == UV_ENOENT);
+  connect_cb_called++;
+  uv_close((uv_handle_t*)&prepare_handle, close_cb);
+  uv_close((uv_handle_t*)&pipe_handle, close_cb);
+}
+
+
+static void prepare_cb(uv_prepare_t* handle) {
+  ASSERT(handle == &prepare_handle);
+  uv_pipe_connect(&conn_req, &pipe_handle, BAD_PIPENAME, connect_cb);
+}
+
+
+TEST_IMPL(pipe_connect_on_prepare) {
+  int r;
+
+  r = uv_pipe_init(uv_default_loop(), &pipe_handle, 0);
+  ASSERT(r == 0);
+
+  r = uv_prepare_init(uv_default_loop(), &prepare_handle);
+  ASSERT(r == 0);
+  r = uv_prepare_start(&prepare_handle, prepare_cb);
+  ASSERT(r == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  ASSERT(r == 0);
+
+  ASSERT(close_cb_called == 2);
+  ASSERT(connect_cb_called == 1);
+
+  MAKE_VALGRIND_HAPPY();
+  return 0;
+}
index dc6fa32..76495e1 100644 (file)
@@ -112,11 +112,13 @@ TEST_IMPL(platform_output) {
 
     if (interfaces[i].netmask.netmask4.sin_family == AF_INET) {
       uv_ip4_name(&interfaces[i].netmask.netmask4, buffer, sizeof(buffer));
+      printf("  netmask: %s\n", buffer);
     } else if (interfaces[i].netmask.netmask4.sin_family == AF_INET6) {
       uv_ip6_name(&interfaces[i].netmask.netmask6, buffer, sizeof(buffer));
+      printf("  netmask: %s\n", buffer);
+    } else {
+      printf("  netmask: none\n");
     }
-
-    printf("  netmask: %s\n", buffer);
   }
   uv_free_interface_addresses(interfaces, count);
 
index acaed86..7173a82 100644 (file)
               '-liphlpapi',
               '-lpsapi',
               '-lshell32',
+              '-luserenv',
               '-lws2_32'
             ],
           },
         'test/test-getnameinfo.c',
         'test/test-getsockname.c',
         'test/test-handle-fileno.c',
+        'test/test-homedir.c',
         'test/test-hrtime.c',
         'test/test-idle.c',
         'test/test-ip6-addr.c',
         'test/test-ping-pong.c',
         'test/test-pipe-bind-error.c',
         'test/test-pipe-connect-error.c',
+        'test/test-pipe-connect-prepare.c',
         'test/test-pipe-getsockname.c',
         'test/test-pipe-sendmsg.c',
         'test/test-pipe-server-close.c',
index 084ab95..696f0db 100644 (file)
@@ -44,6 +44,14 @@ goto next-arg
 if defined WindowsSDKDir goto select-target
 if defined VCINSTALLDIR goto select-target
 
+@rem Look for Visual Studio 2015
+if not defined VS140COMNTOOLS goto vc-set-2013
+if not exist "%VS140COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2013
+call "%VS140COMNTOOLS%\..\..\vc\vcvarsall.bat" %vs_toolset%
+set GYP_MSVS_VERSION=2015
+goto select-target
+
+:vc-set-2013
 @rem Look for Visual Studio 2013
 if not defined VS120COMNTOOLS goto vc-set-2012
 if not exist "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2012