summaryrefslogtreecommitdiff
path: root/deps/uv
diff options
context:
space:
mode:
authorSaúl Ibarra Corretgé <saghul@gmail.com>2016-05-17 00:25:23 +0200
committerSaúl Ibarra Corretgé <saghul@gmail.com>2016-05-17 02:28:48 +0200
commitb78a7043699093c46d5d71992184f4c40ab5c4b5 (patch)
tree7ee0fc8474ae60c4be545965ae18882ef1964027 /deps/uv
parentf293d0b0c85b2d1b9e0d3938dd38cf1cacac6970 (diff)
downloadandroid-node-v8-b78a7043699093c46d5d71992184f4c40ab5c4b5.tar.gz
android-node-v8-b78a7043699093c46d5d71992184f4c40ab5c4b5.tar.bz2
android-node-v8-b78a7043699093c46d5d71992184f4c40ab5c4b5.zip
deps: upgrade libuv to 1.9.1
Fixes: https://github.com/nodejs/node/issues/4002 Fixes: https://github.com/nodejs/node/issues/5384 Fixes: https://github.com/nodejs/node/issues/6563 Refs: https://github.com/nodejs/node/issues/2680#issuecomment-213521708 PR-URL: https://github.com/nodejs/node/pull/6796 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Johan Bergström <bugs@bergstroem.nu> Reviewed-By: Myles Borins <myles.borins@gmail.com>
Diffstat (limited to 'deps/uv')
-rw-r--r--deps/uv/AUTHORS4
-rw-r--r--deps/uv/ChangeLog89
-rw-r--r--deps/uv/Makefile.am13
-rw-r--r--deps/uv/Makefile.mingw1
-rw-r--r--deps/uv/README.md5
-rwxr-xr-xdeps/uv/android-configure4
-rw-r--r--deps/uv/appveyor.yml2
-rw-r--r--deps/uv/common.gypi7
-rw-r--r--deps/uv/configure.ac5
-rw-r--r--deps/uv/docs/src/poll.rst6
-rw-r--r--deps/uv/include/pthread-barrier.h64
-rw-r--r--deps/uv/include/uv-unix.h21
-rw-r--r--deps/uv/include/uv-version.h2
-rw-r--r--deps/uv/include/uv-win.h3
-rw-r--r--deps/uv/src/unix/aix.c82
-rw-r--r--deps/uv/src/unix/async.c4
-rw-r--r--deps/uv/src/unix/core.c10
-rw-r--r--deps/uv/src/unix/freebsd.c8
-rw-r--r--deps/uv/src/unix/fs.c15
-rw-r--r--deps/uv/src/unix/internal.h58
-rw-r--r--deps/uv/src/unix/kqueue.c38
-rw-r--r--deps/uv/src/unix/linux-core.c69
-rw-r--r--deps/uv/src/unix/linux-inotify.c2
-rw-r--r--deps/uv/src/unix/linux-syscalls.h8
-rw-r--r--deps/uv/src/unix/openbsd.c4
-rw-r--r--deps/uv/src/unix/pipe.c4
-rw-r--r--deps/uv/src/unix/poll.c14
-rw-r--r--deps/uv/src/unix/pthread-barrier.c120
-rw-r--r--deps/uv/src/unix/pthread-fixes.c70
-rw-r--r--deps/uv/src/unix/signal.c2
-rw-r--r--deps/uv/src/unix/stream.c70
-rw-r--r--deps/uv/src/unix/sunos.c20
-rw-r--r--deps/uv/src/unix/tcp.c4
-rw-r--r--deps/uv/src/unix/thread.c109
-rw-r--r--deps/uv/src/unix/udp.c20
-rw-r--r--deps/uv/src/uv-common.c29
-rw-r--r--deps/uv/src/win/fs-event.c61
-rw-r--r--deps/uv/src/win/fs.c18
-rw-r--r--deps/uv/src/win/internal.h3
-rw-r--r--deps/uv/src/win/tty.c174
-rw-r--r--deps/uv/src/win/util.c108
-rw-r--r--deps/uv/test/test-emfile.c7
-rw-r--r--deps/uv/test/test-fs-event.c11
-rw-r--r--deps/uv/test/test-fs.c4
-rw-r--r--deps/uv/test/test-get-passwd.c10
-rw-r--r--deps/uv/test/test-homedir.c14
-rw-r--r--deps/uv/test/test-list.h6
-rw-r--r--deps/uv/test/test-platform-output.c5
-rw-r--r--deps/uv/test/test-poll.c11
-rw-r--r--deps/uv/test/test-tcp-create-socket-early.c3
-rw-r--r--deps/uv/test/test-tcp-write-queue-order.c2
-rw-r--r--deps/uv/test/test-tty.c69
-rw-r--r--deps/uv/test/test-udp-create-socket-early.c3
-rw-r--r--deps/uv/uv.gyp7
-rw-r--r--deps/uv/vcbuild.bat10
55 files changed, 962 insertions, 550 deletions
diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS
index 9a9e9c2a22..7acee7c533 100644
--- a/deps/uv/AUTHORS
+++ b/deps/uv/AUTHORS
@@ -253,3 +253,7 @@ Robert Chiras <robert.chiras@intel.com>
Kári Tristan Helgason <kthelgason@gmail.com>
Krishnaraj Bhat <krrishnarraj@gmail.com>
Enno Boland <g@s01.de>
+Michael Fero <michael.fero@datastax.com>
+Robert Jefe Lindstaedt <robert.lindstaedt@gmail.com>
+Myles Borins <myles.borins@gmail.com>
+Tony Theodore <tonyt@logyst.com>
diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog
index 85d40113e4..3f376de6ba 100644
--- a/deps/uv/ChangeLog
+++ b/deps/uv/ChangeLog
@@ -1,3 +1,92 @@
+2016.05.17, Version 1.9.1 (Stable), d989902ac658b4323a4f4020446e6f4dc449e25c
+
+Changes since version 1.9.0:
+
+* test: handle root home directories (cjihrig)
+
+* unix: implement uv__fs_futime for AIX 7.1 (Imran Iqbal)
+
+* test: skip early bind tests if no IPv6 is supported (Saúl Ibarra Corretgé)
+
+* win: fix var declaration to be C89 compliant (Michael Fero)
+
+* unix: use POLL{IN,OUT,etc} constants directly (Ben Noordhuis)
+
+* doc: add ability to live reload and regenerate HTML (Saúl Ibarra Corretgé)
+
+* Revert "win,build: remove unused build defines" (cjihrig)
+
+* linux: fix fd leaks in uv_cpu_info() error paths (Ben Noordhuis)
+
+* linux: don't abort on malformed /proc/stat (Ben Noordhuis)
+
+* linux: fix long lines in linux-core.c (Ben Noordhuis)
+
+* test: fix fs_event_watch_file_current_dir for AIX (Imran Iqbal)
+
+* unix,fs: code cleanup of uv_fs_event_start for AIX (Imran Iqbal)
+
+* unix: delay signal handling until after normal i/o (Ben Noordhuis)
+
+* android: pthread_sigmask() does not set errno (Oguz Bastemur)
+
+* win: work around sharepoint scandir bug (Ben Noordhuis)
+
+* unix: guard against clobbering errno in uv__free() (Ben Noordhuis)
+
+* unix: remove unneeded SAVE_ERRNO wrappers (Ben Noordhuis)
+
+* test: skip fs_event_close_in_callback on AIX (Imran Iqbal)
+
+* win: add maxrss, pagefaults to uv_getrusage() (Robert Jefe Lindstaedt)
+
+* test: set a big send buffer size for tcp_write_queue_order (Andrius Bentkus)
+
+* unix: error on realpath if PATH_MAX is undefined (Myles Borins)
+
+* unix: fix bug in barrier fallback implementation (Kári Tristan Helgason)
+
+* build: bump android ndk version (Kári Tristan Helgason)
+
+* build: always compile with -fvisibility=hidden (Ben Noordhuis)
+
+* test: fix -Wformat warnings in platform test (Ben Noordhuis)
+
+* win: clarify fsevents handling code (Saúl Ibarra Corretgé)
+
+* test: fix POLLHDRUP related failures for AIX (Imran Iqbal)
+
+* build, mingw: set LIBS in configure.ac (Tony Theodore)
+
+* win: improve uv__convert_utf16_to_utf8 (Saúl Ibarra Corretgé)
+
+* win: simplified UTF16 -> UTF8 conversions (Saúl Ibarra Corretgé)
+
+* win: remove unneeded condition (Saúl Ibarra Corretgé)
+
+* darwin: work around condition variable kernel bug (Ben Noordhuis)
+
+* darwin: make thread stack multiple of page size (Ben Noordhuis)
+
+* build,win: rename platform to msbuild_platform (João Reis)
+
+* gitignore: ignore VS temporary database files (João Reis)
+
+* test: skip emfile on AIX (Imran Iqbal)
+
+* unix: use system allocator for scandir() (cjihrig)
+
+* common: release uv_fs_scandir() array (cjihrig)
+
+* win: call uv__fs_scandir_cleanup() (cjihrig)
+
+* win,tty: fix read stop in line mode (João Reis)
+
+* win,tty: don't duplicate handle for line reads (João Reis)
+
+* win,tty: restore cursor after canceling line read (Alexis Campailla)
+
+
2016.04.08, Version 1.9.0 (Stable), 229b3a4cc150aebd6561e6bd43076eafa7a03756
Changes since version 1.8.0:
diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am
index dfd4353a31..05ccd58ac9 100644
--- a/deps/uv/Makefile.am
+++ b/deps/uv/Makefile.am
@@ -43,8 +43,8 @@ if WINNT
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 -luserenv
libuv_la_SOURCES += src/win/async.c \
src/win/atomicops-inl.h \
src/win/core.c \
@@ -290,20 +290,23 @@ endif
if ANDROID
include_HEADERS += include/android-ifaddrs.h \
- include/pthread-fixes.h
+ include/pthread-barrier.h
libuv_la_SOURCES += src/unix/android-ifaddrs.c \
- src/unix/pthread-fixes.c
+ src/unix/pthread-fixes.c \
+ src/unix/pthread-barrier.c
endif
if DARWIN
-include_HEADERS += include/uv-darwin.h
+include_HEADERS += include/uv-darwin.h \
+ include/pthread-barrier.h
libuv_la_CFLAGS += -D_DARWIN_USE_64_BIT_INODE=1
libuv_la_CFLAGS += -D_DARWIN_UNLIMITED_SELECT=1
libuv_la_SOURCES += src/unix/darwin.c \
src/unix/darwin-proctitle.c \
src/unix/fsevents.c \
src/unix/kqueue.c \
- src/unix/proctitle.c
+ src/unix/proctitle.c \
+ src/unix/pthread-barrier.c
test_run_tests_LDFLAGS += -lutil
endif
diff --git a/deps/uv/Makefile.mingw b/deps/uv/Makefile.mingw
index 3130bac473..156f15dab1 100644
--- a/deps/uv/Makefile.mingw
+++ b/deps/uv/Makefile.mingw
@@ -20,6 +20,7 @@ CFLAGS += -Wall \
-Iinclude \
-Isrc \
-Isrc/win \
+ -DWIN32_LEAN_AND_MEAN \
-D_WIN32_WINNT=0x0600
INCLUDES = include/stdint-msvc2008.h \
diff --git a/deps/uv/README.md b/deps/uv/README.md
index 17304a7ab5..e94fcc902f 100644
--- a/deps/uv/README.md
+++ b/deps/uv/README.md
@@ -60,6 +60,11 @@ Build documentation as HTML:
$ make html
+Build documentation as HTML and live reload it when it changes (this requires
+sphinx-autobuild to be installed and is only supported on Unix):
+
+ $ make livehtml
+
Build documentation as man pages:
$ make man
diff --git a/deps/uv/android-configure b/deps/uv/android-configure
index e0b250fb63..7ffc035c1b 100755
--- a/deps/uv/android-configure
+++ b/deps/uv/android-configure
@@ -3,7 +3,7 @@
export TOOLCHAIN=$PWD/android-toolchain
mkdir -p $TOOLCHAIN
$1/build/tools/make-standalone-toolchain.sh \
- --toolchain=arm-linux-androideabi-4.8 \
+ --toolchain=arm-linux-androideabi-4.9 \
--arch=arm \
--install-dir=$TOOLCHAIN \
--platform=android-21
@@ -14,7 +14,7 @@ export CXX=arm-linux-androideabi-g++
export LINK=arm-linux-androideabi-g++
export PLATFORM=android
-if [ $2 -a $2 == 'gyp' ]
+if [[ $2 == 'gyp' ]]
then
./gyp_uv.py -Dtarget_arch=arm -DOS=android -f make-android
fi
diff --git a/deps/uv/appveyor.yml b/deps/uv/appveyor.yml
index 835730b924..c7ea736502 100644
--- a/deps/uv/appveyor.yml
+++ b/deps/uv/appveyor.yml
@@ -1,4 +1,4 @@
-version: v1.9.0.build{build}
+version: v1.9.1.build{build}
install:
- cinst -y nsis
diff --git a/deps/uv/common.gypi b/deps/uv/common.gypi
index 7cebcde5f8..56bca2948d 100644
--- a/deps/uv/common.gypi
+++ b/deps/uv/common.gypi
@@ -1,6 +1,5 @@
{
'variables': {
- 'visibility%': 'hidden', # V8's visibility setting
'target_arch%': 'ia32', # set v8's target architecture
'host_arch%': 'ia32', # set v8's host architecture
'uv_library%': 'static_library', # allow override to 'shared_library' for DLL/.so builds
@@ -156,9 +155,6 @@
'cflags': [ '-pthread' ],
'ldflags': [ '-pthread' ],
}],
- [ 'visibility=="hidden"', {
- 'cflags': [ '-fvisibility=hidden' ],
- }],
],
}],
['OS=="mac"', {
@@ -170,9 +166,6 @@
'GCC_ENABLE_CPP_EXCEPTIONS': 'NO', # -fno-exceptions
'GCC_ENABLE_CPP_RTTI': 'NO', # -fno-rtti
'GCC_ENABLE_PASCAL_STRINGS': 'NO', # No -mpascal-strings
- # GCC_INLINES_ARE_PRIVATE_EXTERN maps to -fvisibility-inlines-hidden
- 'GCC_INLINES_ARE_PRIVATE_EXTERN': 'YES',
- 'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden
'GCC_THREADSAFE_STATICS': 'NO', # -fno-threadsafe-statics
'PREBINDING': 'NO', # No -Wl,-prebind
'USE_HEADERMAP': 'NO',
diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac
index 2d5a3b9de5..d9251f3198 100644
--- a/deps/uv/configure.ac
+++ b/deps/uv/configure.ac
@@ -13,7 +13,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_PREREQ(2.57)
-AC_INIT([libuv], [1.9.0], [https://github.com/libuv/libuv/issues])
+AC_INIT([libuv], [1.9.1], [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,9 @@ 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])])
+AS_CASE([$host_os],[mingw*], [
+ LIBS="$LIBS -lws2_32 -lpsapi -liphlpapi -lshell32 -luserenv -luser32"
+])
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"])
diff --git a/deps/uv/docs/src/poll.rst b/deps/uv/docs/src/poll.rst
index 69d45be6d3..004ff4b92e 100644
--- a/deps/uv/docs/src/poll.rst
+++ b/deps/uv/docs/src/poll.rst
@@ -31,6 +31,8 @@ closed immediately after a call to :c:func:`uv_poll_stop` or :c:func:`uv_close`.
On windows only sockets can be polled with poll handles. On Unix any file
descriptor that would be accepted by :man:`poll(2)` can be used.
+.. note::
+ On AIX, watching for disconnection is not supported.
Data types
----------
@@ -101,6 +103,10 @@ API
Calling :c:func:`uv_poll_start` on a handle that is already active is fine. Doing so
will update the events mask that is being watched for.
+ .. note::
+ Though UV_DISCONNECT can be set, it is unsupported on AIX and as such will not be set
+ on the `events` field in the callback.
+
.. versionchanged:: 1.9.0 Added the UV_DISCONNECT event.
.. c:function:: int uv_poll_stop(uv_poll_t* poll)
diff --git a/deps/uv/include/pthread-barrier.h b/deps/uv/include/pthread-barrier.h
new file mode 100644
index 0000000000..084e1c2d55
--- /dev/null
+++ b/deps/uv/include/pthread-barrier.h
@@ -0,0 +1,64 @@
+/*
+Copyright (c) 2016, Kari Tristan Helgason <kthelgason@gmail.com>
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#ifndef _UV_PTHREAD_BARRIER_
+#define _UV_PTHREAD_BARRIER_
+#include <errno.h>
+#include <pthread.h>
+#include <semaphore.h> /* sem_t */
+
+#define PTHREAD_BARRIER_SERIAL_THREAD 0x12345
+
+/*
+ * To maintain ABI compatibility with
+ * libuv v1.x struct is padded according
+ * to target platform
+ */
+#if defined(__ANDROID__)
+# define UV_BARRIER_STRUCT_PADDING \
+ sizeof(pthread_mutex_t) + \
+ sizeof(pthread_cond_t) + \
+ sizeof(unsigned int) - \
+ sizeof(void *)
+#elif defined(__APPLE__)
+# define UV_BARRIER_STRUCT_PADDING \
+ sizeof(pthread_mutex_t) + \
+ 2 * sizeof(sem_t) + \
+ 2 * sizeof(unsigned int) - \
+ sizeof(void *)
+#endif
+
+typedef struct {
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ unsigned threshold;
+ unsigned in;
+ unsigned out;
+} _uv_barrier;
+
+typedef struct {
+ _uv_barrier* b;
+ char _pad[UV_BARRIER_STRUCT_PADDING];
+} pthread_barrier_t;
+
+int pthread_barrier_init(pthread_barrier_t* barrier,
+ const void* barrier_attr,
+ unsigned count);
+
+int pthread_barrier_wait(pthread_barrier_t* barrier);
+int pthread_barrier_destroy(pthread_barrier_t *barrier);
+
+#endif /* _UV_PTHREAD_BARRIER_ */
diff --git a/deps/uv/include/uv-unix.h b/deps/uv/include/uv-unix.h
index 82d193bdca..a852c40e49 100644
--- a/deps/uv/include/uv-unix.h
+++ b/deps/uv/include/uv-unix.h
@@ -38,9 +38,6 @@
#include <semaphore.h>
#include <pthread.h>
-#ifdef __ANDROID__
-#include "pthread-fixes.h"
-#endif
#include <signal.h>
#include "uv-threadpool.h"
@@ -60,6 +57,10 @@
# include "uv-bsd.h"
#endif
+#ifndef PTHREAD_BARRIER_SERIAL_THREAD
+# include "pthread-barrier.h"
+#endif
+
#ifndef NI_MAXHOST
# define NI_MAXHOST 1025
#endif
@@ -136,22 +137,8 @@ typedef pthread_rwlock_t uv_rwlock_t;
typedef UV_PLATFORM_SEM_T uv_sem_t;
typedef pthread_cond_t uv_cond_t;
typedef pthread_key_t uv_key_t;
-
-#if defined(__APPLE__) && defined(__MACH__)
-
-typedef struct {
- unsigned int n;
- unsigned int count;
- uv_mutex_t mutex;
- uv_sem_t turnstile1;
- uv_sem_t turnstile2;
-} uv_barrier_t;
-
-#else /* defined(__APPLE__) && defined(__MACH__) */
-
typedef pthread_barrier_t uv_barrier_t;
-#endif /* defined(__APPLE__) && defined(__MACH__) */
/* Platform-specific definitions for uv_spawn support. */
typedef gid_t uv_gid_t;
diff --git a/deps/uv/include/uv-version.h b/deps/uv/include/uv-version.h
index cb66618289..08ad0edaa7 100644
--- a/deps/uv/include/uv-version.h
+++ b/deps/uv/include/uv-version.h
@@ -32,7 +32,7 @@
#define UV_VERSION_MAJOR 1
#define UV_VERSION_MINOR 9
-#define UV_VERSION_PATCH 0
+#define UV_VERSION_PATCH 1
#define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX ""
diff --git a/deps/uv/include/uv-win.h b/deps/uv/include/uv-win.h
index 6b537fed0d..a75dba8d1c 100644
--- a/deps/uv/include/uv-win.h
+++ b/deps/uv/include/uv-win.h
@@ -483,7 +483,8 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
union { \
struct { \
/* Used for readable TTY handles */ \
- HANDLE read_line_handle; \
+ /* TODO: remove me in v2.x. */ \
+ HANDLE unused_; \
uv_buf_t read_line_buffer; \
HANDLE read_raw_wait; \
/* Fields used for translating win keystrokes into vt100 characters */ \
diff --git a/deps/uv/src/unix/aix.c b/deps/uv/src/unix/aix.c
index bcaa5ee50b..2276985fc0 100644
--- a/deps/uv/src/unix/aix.c
+++ b/deps/uv/src/unix/aix.c
@@ -118,6 +118,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
uv__io_t* w;
uint64_t base;
uint64_t diff;
+ int have_signals;
int nevents;
int count;
int nfds;
@@ -225,6 +226,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
goto update_timeout;
}
+ have_signals = 0;
nevents = 0;
assert(loop->watchers != NULL);
@@ -255,13 +257,26 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
continue;
}
- w->cb(loop, w, pe->revents);
+ /* Run signal watchers last. This also affects child process watchers
+ * because those are implemented in terms of signal watchers.
+ */
+ if (w == &loop->signal_io_watcher)
+ have_signals = 1;
+ else
+ w->cb(loop, w, pe->revents);
+
nevents++;
}
+ if (have_signals != 0)
+ loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
+
loop->watchers[loop->nwatchers] = NULL;
loop->watchers[loop->nwatchers + 1] = NULL;
+ if (have_signals != 0)
+ return; /* Event loop should cycle now so don't poll again. */
+
if (nevents != 0) {
if (nfds == ARRAY_SIZE(events) && --count != 0) {
/* Poll for more events but don't block this time. */
@@ -782,53 +797,30 @@ int uv_fs_event_start(uv_fs_event_t* handle,
const char* filename,
unsigned int flags) {
#ifdef HAVE_SYS_AHAFS_EVPRODS_H
- int fd, rc, i = 0, res = 0;
+ int fd, rc, str_offset = 0;
char cwd[PATH_MAX];
char absolute_path[PATH_MAX];
- char fname[PATH_MAX];
- char *p;
+ char readlink_cwd[PATH_MAX];
- /* Clean all the buffers*/
- for(i = 0; i < PATH_MAX; i++) {
- cwd[i] = 0;
- absolute_path[i] = 0;
- fname[i] = 0;
- }
- i = 0;
/* Figure out whether filename is absolute or not */
if (filename[0] == '/') {
- /* We have absolute pathname, create the relative pathname*/
- sprintf(absolute_path, filename);
- p = strrchr(filename, '/');
- p++;
+ /* We have absolute pathname */
+ snprintf(absolute_path, sizeof(absolute_path), "%s", filename);
} else {
- if (filename[0] == '.' && filename[1] == '/') {
- /* We have a relative pathname, compose the absolute pathname */
- sprintf(fname, filename);
- snprintf(cwd, PATH_MAX-1, "/proc/%lu/cwd", (unsigned long) getpid());
- res = readlink(cwd, absolute_path, sizeof(absolute_path) - 1);
- if (res < 0)
- return res;
- p = strrchr(absolute_path, '/');
- p++;
- p++;
- } else {
- /* We have a relative pathname, compose the absolute pathname */
- sprintf(fname, filename);
- snprintf(cwd, PATH_MAX-1, "/proc/%lu/cwd", (unsigned long) getpid());
- res = readlink(cwd, absolute_path, sizeof(absolute_path) - 1);
- if (res < 0)
- return res;
- p = strrchr(absolute_path, '/');
- p++;
- }
- /* Copy to filename buffer */
- while(filename[i] != NULL) {
- *p = filename[i];
- i++;
- p++;
- }
+ /* We have a relative pathname, compose the absolute pathname */
+ snprintf(cwd, sizeof(cwd), "/proc/%lu/cwd", (unsigned long) getpid());
+ rc = readlink(cwd, readlink_cwd, sizeof(readlink_cwd) - 1);
+ if (rc < 0)
+ return rc;
+ /* readlink does not null terminate our string */
+ readlink_cwd[rc] = '\0';
+
+ if (filename[0] == '.' && filename[1] == '/')
+ str_offset = 2;
+
+ snprintf(absolute_path, sizeof(absolute_path), "%s%s", readlink_cwd,
+ filename + str_offset);
}
if (uv__is_ahafs_mounted() < 0) /* /aha checks failed */
@@ -845,7 +837,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
handle->path = uv__strdup(filename);
handle->cb = cb;
- uv__io_start(handle->loop, &handle->event_watcher, UV__POLLIN);
+ uv__io_start(handle->loop, &handle->event_watcher, POLLIN);
return 0;
#else
@@ -1036,14 +1028,14 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
}
if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) {
- SAVE_ERRNO(uv__close(sockfd));
+ uv__close(sockfd);
return -errno;
}
ifc.ifc_req = (struct ifreq*)uv__malloc(size);
ifc.ifc_len = size;
if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
- SAVE_ERRNO(uv__close(sockfd));
+ uv__close(sockfd);
return -errno;
}
@@ -1062,7 +1054,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
- SAVE_ERRNO(uv__close(sockfd));
+ uv__close(sockfd);
return -errno;
}
diff --git a/deps/uv/src/unix/async.c b/deps/uv/src/unix/async.c
index 184b598126..393cdebd4e 100644
--- a/deps/uv/src/unix/async.c
+++ b/deps/uv/src/unix/async.c
@@ -223,7 +223,7 @@ int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb) {
return err;
uv__io_init(&wa->io_watcher, uv__async_io, pipefd[0]);
- uv__io_start(loop, &wa->io_watcher, UV__POLLIN);
+ uv__io_start(loop, &wa->io_watcher, POLLIN);
wa->wfd = pipefd[1];
wa->cb = cb;
@@ -241,7 +241,7 @@ void uv__async_stop(uv_loop_t* loop, struct uv__async* wa) {
wa->wfd = -1;
}
- uv__io_stop(loop, &wa->io_watcher, UV__POLLIN);
+ uv__io_stop(loop, &wa->io_watcher, POLLIN);
uv__close(wa->io_watcher.fd);
wa->io_watcher.fd = -1;
}
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
index 9aaca84187..cdcd0b504f 100644
--- a/deps/uv/src/unix/core.c
+++ b/deps/uv/src/unix/core.c
@@ -762,7 +762,7 @@ static int uv__run_pending(uv_loop_t* loop) {
QUEUE_REMOVE(q);
QUEUE_INIT(q);
w = QUEUE_DATA(q, uv__io_t, pending_queue);
- w->cb(loop, w, UV__POLLOUT);
+ w->cb(loop, w, POLLOUT);
}
return 1;
@@ -833,7 +833,7 @@ void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd) {
void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
- assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT | UV__POLLRDHUP)));
+ assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP)));
assert(0 != events);
assert(w->fd >= 0);
assert(w->fd < INT_MAX);
@@ -866,7 +866,7 @@ void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
- assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT | UV__POLLRDHUP)));
+ assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP)));
assert(0 != events);
if (w->fd == -1)
@@ -898,7 +898,7 @@ void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
void uv__io_close(uv_loop_t* loop, uv__io_t* w) {
- uv__io_stop(loop, w, UV__POLLIN | UV__POLLOUT | UV__POLLRDHUP);
+ uv__io_stop(loop, w, POLLIN | POLLOUT | UV__POLLRDHUP);
QUEUE_REMOVE(&w->pending_queue);
/* Remove stale events for this file descriptor */
@@ -913,7 +913,7 @@ void uv__io_feed(uv_loop_t* loop, uv__io_t* w) {
int uv__io_active(const uv__io_t* w, unsigned int events) {
- assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT | UV__POLLRDHUP)));
+ assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP)));
assert(0 != events);
return 0 != (w->pevents & events);
}
diff --git a/deps/uv/src/unix/freebsd.c b/deps/uv/src/unix/freebsd.c
index b747abdf5b..adc95235ce 100644
--- a/deps/uv/src/unix/freebsd.c
+++ b/deps/uv/src/unix/freebsd.c
@@ -292,7 +292,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(uv__free(*cpu_infos));
+ uv__free(*cpu_infos);
return -errno;
}
@@ -301,7 +301,7 @@ 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(uv__free(*cpu_infos));
+ uv__free(*cpu_infos);
return -errno;
}
@@ -314,8 +314,8 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
}
if (sysctlbyname(cptimes_key, cp_times, &size, NULL, 0)) {
- SAVE_ERRNO(uv__free(cp_times));
- SAVE_ERRNO(uv__free(*cpu_infos));
+ uv__free(cp_times);
+ uv__free(*cpu_infos);
return -errno;
}
diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c
index 8936ad9d83..085970a06d 100644
--- a/deps/uv/src/unix/fs.c
+++ b/deps/uv/src/unix/fs.c
@@ -33,6 +33,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <limits.h> /* PATH_MAX */
#include <sys/types.h>
#include <sys/socket.h>
@@ -205,6 +206,13 @@ skip:
# else
return futimes(req->file, tv);
# endif
+#elif defined(_AIX71)
+ struct timespec ts[2];
+ ts[0].tv_sec = req->atime;
+ ts[0].tv_nsec = (unsigned long)(req->atime * 1000000) % 1000000 * 1000;
+ ts[1].tv_sec = req->mtime;
+ ts[1].tv_nsec = (unsigned long)(req->mtime * 1000000) % 1000000 * 1000;
+ return futimens(req->file, ts);
#else
errno = ENOSYS;
return -1;
@@ -362,9 +370,10 @@ out:
if (dents != NULL) {
int i;
+ /* Memory was allocated using the system allocator, so use free() here. */
for (i = 0; i < n; i++)
- uv__free(dents[i]);
- uv__free(dents);
+ free(dents[i]);
+ free(dents);
}
errno = saved_errno;
@@ -383,7 +392,7 @@ static ssize_t uv__fs_pathmax_size(const char* path) {
#if defined(PATH_MAX)
return PATH_MAX;
#else
- return 4096;
+#error "PATH_MAX undefined in the current platform"
#endif
}
diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h
index 938e76f1d1..670b14bc2a 100644
--- a/deps/uv/src/unix/internal.h
+++ b/deps/uv/src/unix/internal.h
@@ -44,15 +44,25 @@
#endif /* __sun */
#if defined(_AIX)
-#define reqevents events
-#define rtnevents revents
-#include <sys/poll.h>
+# define reqevents events
+# define rtnevents revents
+# include <sys/poll.h>
+#else
+# include <poll.h>
#endif /* _AIX */
#if defined(__APPLE__) && !TARGET_OS_IPHONE
# include <CoreServices/CoreServices.h>
#endif
+#if defined(__ANDROID__)
+int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset);
+# ifdef pthread_sigmask
+# undef pthread_sigmask
+# endif
+# define pthread_sigmask(how, set, oldset) uv__pthread_sigmask(how, set, oldset)
+#endif
+
#define ACCESS_ONCE(type, var) \
(*(volatile type*) &(var))
@@ -89,43 +99,11 @@
# define UV_UNUSED(declaration) declaration
#endif
-#if defined(__linux__)
-# define UV__POLLIN UV__EPOLLIN
-# define UV__POLLOUT UV__EPOLLOUT
-# define UV__POLLERR UV__EPOLLERR
-# define UV__POLLHUP UV__EPOLLHUP
-# define UV__POLLRDHUP UV__EPOLLRDHUP
-#endif
-
-#if defined(__sun) || defined(_AIX)
-# define UV__POLLIN POLLIN
-# define UV__POLLOUT POLLOUT
-# define UV__POLLERR POLLERR
-# define UV__POLLHUP POLLHUP
-#endif
-
-#ifndef UV__POLLIN
-# define UV__POLLIN 1
-#endif
-
-#ifndef UV__POLLOUT
-# define UV__POLLOUT 2
-#endif
-
-#ifndef UV__POLLERR
-# define UV__POLLERR 4
-#endif
-
-#ifndef UV__POLLHUP
-# define UV__POLLHUP 8
-#endif
-
-#ifndef UV__POLLRDHUP
-# ifdef POLLRDHUP
-# define UV__POLLRDHUP POLLRDHUP
-# else
-# define UV__POLLRDHUP 0x200
-# endif
+/* Leans on the fact that, on Linux, POLLRDHUP == EPOLLRDHUP. */
+#ifdef POLLRDHUP
+# define UV__POLLRDHUP POLLRDHUP
+#else
+# define UV__POLLRDHUP 0x2000
#endif
#if !defined(O_CLOEXEC) && defined(__FreeBSD__)
diff --git a/deps/uv/src/unix/kqueue.c b/deps/uv/src/unix/kqueue.c
index 400b4a4b7c..fffd4626f1 100644
--- a/deps/uv/src/unix/kqueue.c
+++ b/deps/uv/src/unix/kqueue.c
@@ -78,6 +78,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
sigset_t set;
uint64_t base;
uint64_t diff;
+ int have_signals;
int filter;
int fflags;
int count;
@@ -103,7 +104,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
assert(w->fd >= 0);
assert(w->fd < (int) loop->nwatchers);
- if ((w->events & UV__POLLIN) == 0 && (w->pevents & UV__POLLIN) != 0) {
+ if ((w->events & POLLIN) == 0 && (w->pevents & POLLIN) != 0) {
filter = EVFILT_READ;
fflags = 0;
op = EV_ADD;
@@ -124,7 +125,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
}
}
- if ((w->events & UV__POLLOUT) == 0 && (w->pevents & UV__POLLOUT) != 0) {
+ if ((w->events & POLLOUT) == 0 && (w->pevents & POLLOUT) != 0) {
EV_SET(events + nevents, w->fd, EVFILT_WRITE, EV_ADD, 0, 0, 0);
if (++nevents == ARRAY_SIZE(events)) {
@@ -192,6 +193,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
goto update_timeout;
}
+ have_signals = 0;
nevents = 0;
assert(loop->watchers != NULL);
@@ -219,8 +221,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
}
if (ev->filter == EVFILT_VNODE) {
- assert(w->events == UV__POLLIN);
- assert(w->pevents == UV__POLLIN);
+ assert(w->events == POLLIN);
+ assert(w->pevents == POLLIN);
w->cb(loop, w, ev->fflags); /* XXX always uv__fs_event() */
nevents++;
continue;
@@ -229,8 +231,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
revents = 0;
if (ev->filter == EVFILT_READ) {
- if (w->pevents & UV__POLLIN) {
- revents |= UV__POLLIN;
+ if (w->pevents & POLLIN) {
+ revents |= POLLIN;
w->rcount = ev->data;
} else {
/* TODO batch up */
@@ -243,8 +245,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
}
if (ev->filter == EVFILT_WRITE) {
- if (w->pevents & UV__POLLOUT) {
- revents |= UV__POLLOUT;
+ if (w->pevents & POLLOUT) {
+ revents |= POLLOUT;
w->wcount = ev->data;
} else {
/* TODO batch up */
@@ -257,7 +259,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
}
if (ev->flags & EV_ERROR)
- revents |= UV__POLLERR;
+ revents |= POLLERR;
if ((ev->flags & EV_EOF) && (w->pevents & UV__POLLRDHUP))
revents |= UV__POLLRDHUP;
@@ -265,12 +267,26 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
if (revents == 0)
continue;
- w->cb(loop, w, revents);
+ /* Run signal watchers last. This also affects child process watchers
+ * because those are implemented in terms of signal watchers.
+ */
+ if (w == &loop->signal_io_watcher)
+ have_signals = 1;
+ else
+ w->cb(loop, w, revents);
+
nevents++;
}
+
+ if (have_signals != 0)
+ loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
+
loop->watchers[loop->nwatchers] = NULL;
loop->watchers[loop->nwatchers + 1] = NULL;
+ if (have_signals != 0)
+ return; /* Event loop should cycle now so don't poll again. */
+
if (nevents != 0) {
if (nfds == ARRAY_SIZE(events) && --count != 0) {
/* Poll for more events but don't block this time. */
@@ -409,7 +425,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
fallback:
#endif /* defined(__APPLE__) */
- uv__io_start(handle->loop, &handle->event_watcher, UV__POLLIN);
+ uv__io_start(handle->loop, &handle->event_watcher, POLLIN);
return 0;
}
diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c
index fb8ac3f237..b48a111170 100644
--- a/deps/uv/src/unix/linux-core.c
+++ b/deps/uv/src/unix/linux-core.c
@@ -18,6 +18,11 @@
* IN THE SOFTWARE.
*/
+/* We lean on the fact that POLL{IN,OUT,ERR,HUP} correspond with their
+ * EPOLL* counterparts. We use the POLL* variants in this file because that
+ * is what libuv uses elsewhere and it avoids a dependency on <sys/epoll.h>.
+ */
+
#include "uv.h"
#include "internal.h"
@@ -69,7 +74,9 @@
#endif
static int read_models(unsigned int numcpus, uv_cpu_info_t* ci);
-static int read_times(FILE* statfile_fp, unsigned int numcpus, uv_cpu_info_t* ci);
+static int read_times(FILE* statfile_fp,
+ unsigned int numcpus,
+ uv_cpu_info_t* ci);
static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci);
static unsigned long read_cpufreq(unsigned int cpunum);
@@ -102,7 +109,7 @@ int uv__platform_loop_init(uv_loop_t* loop) {
void uv__platform_loop_delete(uv_loop_t* loop) {
if (loop->inotify_fd == -1) return;
- uv__io_stop(loop, &loop->inotify_read_watcher, UV__POLLIN);
+ uv__io_stop(loop, &loop->inotify_read_watcher, POLLIN);
uv__close(loop->inotify_fd);
loop->inotify_fd = -1;
}
@@ -144,7 +151,7 @@ int uv__io_check_fd(uv_loop_t* loop, int fd) {
struct uv__epoll_event e;
int rc;
- e.events = UV__EPOLLIN;
+ e.events = POLLIN;
e.data = -1;
rc = 0;
@@ -181,6 +188,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
sigset_t sigset;
uint64_t sigmask;
uint64_t base;
+ int have_signals;
int nevents;
int count;
int nfds;
@@ -308,6 +316,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
goto update_timeout;
}
+ have_signals = 0;
nevents = 0;
assert(loop->watchers != NULL);
@@ -341,7 +350,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
* the current watcher. Also, filters out events that users has not
* requested us to watch.
*/
- pe->events &= w->pevents | UV__POLLERR | UV__POLLHUP;
+ pe->events &= w->pevents | POLLERR | POLLHUP;
/* Work around an epoll quirk where it sometimes reports just the
* EPOLLERR or EPOLLHUP event. In order to force the event loop to
@@ -358,17 +367,31 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
* needs to remember the error/hangup event. We should get that for
* free when we switch over to edge-triggered I/O.
*/
- if (pe->events == UV__EPOLLERR || pe->events == UV__EPOLLHUP)
- pe->events |= w->pevents & (UV__EPOLLIN | UV__EPOLLOUT);
+ if (pe->events == POLLERR || pe->events == POLLHUP)
+ pe->events |= w->pevents & (POLLIN | POLLOUT);
if (pe->events != 0) {
- w->cb(loop, w, pe->events);
+ /* Run signal watchers last. This also affects child process watchers
+ * because those are implemented in terms of signal watchers.
+ */
+ if (w == &loop->signal_io_watcher)
+ have_signals = 1;
+ else
+ w->cb(loop, w, pe->events);
+
nevents++;
}
}
+
+ if (have_signals != 0)
+ loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
+
loop->watchers[loop->nwatchers] = NULL;
loop->watchers[loop->nwatchers + 1] = NULL;
+ if (have_signals != 0)
+ return; /* Event loop should cycle now so don't poll again. */
+
if (nevents != 0) {
if (nfds == ARRAY_SIZE(events) && --count != 0) {
/* Poll for more events but don't block this time. */
@@ -557,7 +580,7 @@ static int uv__cpu_num(FILE* statfile_fp, unsigned int* numcpus) {
char buf[1024];
if (!fgets(buf, sizeof(buf), statfile_fp))
- abort();
+ return -EIO;
num = 0;
while (fgets(buf, sizeof(buf), statfile_fp)) {
@@ -566,6 +589,9 @@ static int uv__cpu_num(FILE* statfile_fp, unsigned int* numcpus) {
num++;
}
+ if (num == 0)
+ return -EIO;
+
*numcpus = num;
return 0;
}
@@ -586,26 +612,20 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
err = uv__cpu_num(statfile_fp, &numcpus);
if (err < 0)
- return err;
-
- assert(numcpus != (unsigned int) -1);
- assert(numcpus != 0);
+ goto out;
+ err = -ENOMEM;
ci = uv__calloc(numcpus, sizeof(*ci));
if (ci == NULL)
- return -ENOMEM;
+ goto out;
err = read_models(numcpus, ci);
if (err == 0)
err = read_times(statfile_fp, numcpus, ci);
- if (fclose(statfile_fp))
- if (errno != EINTR && errno != EINPROGRESS)
- abort();
-
if (err) {
uv_free_cpu_info(ci, numcpus);
- return err;
+ goto out;
}
/* read_models() on x86 also reads the CPU speed from /proc/cpuinfo.
@@ -616,8 +636,15 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
*cpu_infos = ci;
*count = numcpus;
+ err = 0;
- return 0;
+out:
+
+ if (fclose(statfile_fp))
+ if (errno != EINTR && errno != EINPROGRESS)
+ abort();
+
+ return err;
}
@@ -727,7 +754,9 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
}
-static int read_times(FILE* statfile_fp, unsigned int numcpus, uv_cpu_info_t* ci) {
+static int read_times(FILE* statfile_fp,
+ unsigned int numcpus,
+ uv_cpu_info_t* ci) {
unsigned long clock_ticks;
struct uv_cpu_times_s ts;
unsigned long user;
diff --git a/deps/uv/src/unix/linux-inotify.c b/deps/uv/src/unix/linux-inotify.c
index 282912115d..4708c051d3 100644
--- a/deps/uv/src/unix/linux-inotify.c
+++ b/deps/uv/src/unix/linux-inotify.c
@@ -102,7 +102,7 @@ static int init_inotify(uv_loop_t* loop) {
loop->inotify_fd = err;
uv__io_init(&loop->inotify_read_watcher, uv__inotify_read, loop->inotify_fd);
- uv__io_start(loop, &loop->inotify_read_watcher, UV__POLLIN);
+ uv__io_start(loop, &loop->inotify_read_watcher, POLLIN);
return 0;
}
diff --git a/deps/uv/src/unix/linux-syscalls.h b/deps/uv/src/unix/linux-syscalls.h
index 4260df111f..4c095e9b53 100644
--- a/deps/uv/src/unix/linux-syscalls.h
+++ b/deps/uv/src/unix/linux-syscalls.h
@@ -72,14 +72,6 @@
#define UV__EPOLL_CTL_DEL 2
#define UV__EPOLL_CTL_MOD 3
-#define UV__EPOLLIN 1
-#define UV__EPOLLOUT 4
-#define UV__EPOLLERR 8
-#define UV__EPOLLHUP 16
-#define UV__EPOLLRDHUP 0x2000
-#define UV__EPOLLONESHOT 0x40000000
-#define UV__EPOLLET 0x80000000
-
/* inotify flags */
#define UV__IN_ACCESS 0x001
#define UV__IN_MODIFY 0x002
diff --git a/deps/uv/src/unix/openbsd.c b/deps/uv/src/unix/openbsd.c
index 6a3909a666..8c40bde40f 100644
--- a/deps/uv/src/unix/openbsd.c
+++ b/deps/uv/src/unix/openbsd.c
@@ -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(uv__free(*cpu_infos));
+ 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(uv__free(*cpu_infos));
+ uv__free(*cpu_infos);
return -errno;
}
diff --git a/deps/uv/src/unix/pipe.c b/deps/uv/src/unix/pipe.c
index d4fdfa9d5a..c8d163dcc7 100644
--- a/deps/uv/src/unix/pipe.c
+++ b/deps/uv/src/unix/pipe.c
@@ -102,7 +102,7 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
handle->connection_cb = cb;
handle->io_watcher.cb = uv__server_io;
- uv__io_start(handle->loop, &handle->io_watcher, UV__POLLIN);
+ uv__io_start(handle->loop, &handle->io_watcher, POLLIN);
return 0;
}
@@ -185,7 +185,7 @@ void uv_pipe_connect(uv_connect_t* req,
}
if (err == 0)
- uv__io_start(handle->loop, &handle->io_watcher, UV__POLLIN | UV__POLLOUT);
+ uv__io_start(handle->loop, &handle->io_watcher, POLLIN | POLLOUT);
out:
handle->delayed_error = err;
diff --git a/deps/uv/src/unix/poll.c b/deps/uv/src/unix/poll.c
index e5efb17160..0d5944b0af 100644
--- a/deps/uv/src/unix/poll.c
+++ b/deps/uv/src/unix/poll.c
@@ -33,17 +33,17 @@ static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
handle = container_of(w, uv_poll_t, io_watcher);
- if (events & UV__POLLERR) {
- uv__io_stop(loop, w, UV__POLLIN | UV__POLLOUT | UV__POLLRDHUP);
+ if (events & POLLERR) {
+ uv__io_stop(loop, w, POLLIN | POLLOUT | UV__POLLRDHUP);
uv__handle_stop(handle);
handle->poll_cb(handle, -EBADF, 0);
return;
}
pevents = 0;
- if (events & UV__POLLIN)
+ if (events & POLLIN)
pevents |= UV_READABLE;
- if (events & UV__POLLOUT)
+ if (events & POLLOUT)
pevents |= UV_WRITABLE;
if (events & UV__POLLRDHUP)
pevents |= UV_DISCONNECT;
@@ -79,7 +79,7 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
static void uv__poll_stop(uv_poll_t* handle) {
uv__io_stop(handle->loop,
&handle->io_watcher,
- UV__POLLIN | UV__POLLOUT | UV__POLLRDHUP);
+ POLLIN | POLLOUT | UV__POLLRDHUP);
uv__handle_stop(handle);
}
@@ -104,9 +104,9 @@ int uv_poll_start(uv_poll_t* handle, int pevents, uv_poll_cb poll_cb) {
events = 0;
if (pevents & UV_READABLE)
- events |= UV__POLLIN;
+ events |= POLLIN;
if (pevents & UV_WRITABLE)
- events |= UV__POLLOUT;
+ events |= POLLOUT;
if (pevents & UV_DISCONNECT)
events |= UV__POLLRDHUP;
diff --git a/deps/uv/src/unix/pthread-barrier.c b/deps/uv/src/unix/pthread-barrier.c
new file mode 100644
index 0000000000..f57bf25080
--- /dev/null
+++ b/deps/uv/src/unix/pthread-barrier.c
@@ -0,0 +1,120 @@
+/*
+Copyright (c) 2016, Kari Tristan Helgason <kthelgason@gmail.com>
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+#include "uv-common.h"
+#include "pthread-barrier.h"
+
+#include <stdlib.h>
+#include <assert.h>
+
+/* TODO: support barrier_attr */
+int pthread_barrier_init(pthread_barrier_t* barrier,
+ const void* barrier_attr,
+ unsigned count) {
+ int rc;
+ _uv_barrier* b;
+
+ if (barrier == NULL || count == 0)
+ return EINVAL;
+
+ if (barrier_attr != NULL)
+ return ENOTSUP;
+
+ b = uv__malloc(sizeof(*b));
+ if (b == NULL)
+ return ENOMEM;
+
+ b->in = 0;
+ b->out = 0;
+ b->threshold = count;
+
+ if ((rc = pthread_mutex_init(&b->mutex, NULL)) != 0)
+ goto error2;
+ if ((rc = pthread_cond_init(&b->cond, NULL)) != 0)
+ goto error;
+
+ barrier->b = b;
+ return 0;
+
+error:
+ pthread_mutex_destroy(&b->mutex);
+error2:
+ uv__free(b);
+ return rc;
+}
+
+int pthread_barrier_wait(pthread_barrier_t* barrier) {
+ int rc;
+ _uv_barrier* b;
+
+ if (barrier == NULL || barrier->b == NULL)
+ return EINVAL;
+
+ b = barrier->b;
+ /* Lock the mutex*/
+ if ((rc = pthread_mutex_lock(&b->mutex)) != 0)
+ return rc;
+
+ /* Increment the count. If this is the first thread to reach the threshold,
+ wake up waiters, unlock the mutex, then return
+ PTHREAD_BARRIER_SERIAL_THREAD. */
+ if (++b->in == b->threshold) {
+ b->in = 0;
+ b->out = b->threshold - 1;
+ assert(pthread_cond_signal(&b->cond) == 0);
+
+ pthread_mutex_unlock(&b->mutex);
+ return PTHREAD_BARRIER_SERIAL_THREAD;
+ }
+ /* Otherwise, wait for other threads until in is set to 0,
+ then return 0 to indicate this is not the first thread. */
+ do {
+ if ((rc = pthread_cond_wait(&b->cond, &b->mutex)) != 0)
+ break;
+ } while (b->in != 0);
+
+ /* mark thread exit */
+ b->out--;
+ pthread_cond_signal(&b->cond);
+ pthread_mutex_unlock(&b->mutex);
+ return rc;
+}
+
+int pthread_barrier_destroy(pthread_barrier_t* barrier) {
+ int rc;
+ _uv_barrier* b;
+
+ if (barrier == NULL || barrier->b == NULL)
+ return EINVAL;
+
+ b = barrier->b;
+
+ if ((rc = pthread_mutex_lock(&b->mutex)) != 0)
+ return rc;
+
+ if (b->in > 0 || b->out > 0)
+ rc = EBUSY;
+
+ pthread_mutex_unlock(&b->mutex);
+
+ if (rc)
+ return rc;
+
+ pthread_cond_destroy(&b->cond);
+ pthread_mutex_destroy(&b->mutex);
+ uv__free(barrier->b);
+ barrier->b = NULL;
+ return 0;
+}
diff --git a/deps/uv/src/unix/pthread-fixes.c b/deps/uv/src/unix/pthread-fixes.c
index 3a71eb5aae..fb17995846 100644
--- a/deps/uv/src/unix/pthread-fixes.c
+++ b/deps/uv/src/unix/pthread-fixes.c
@@ -29,76 +29,28 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* Android versions < 4.1 have a broken pthread_sigmask.
- * Note that this block of code must come before any inclusion of
- * pthread-fixes.h so that the real pthread_sigmask can be referenced.
- * */
+/* Android versions < 4.1 have a broken pthread_sigmask. */
#include <errno.h>
#include <pthread.h>
#include <signal.h>
int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset) {
static int workaround;
+ int err;
if (workaround) {
return sigprocmask(how, set, oset);
- } else if (pthread_sigmask(how, set, oset)) {
- if (errno == EINVAL && sigprocmask(how, set, oset) == 0) {
- workaround = 1;
- return 0;
- } else {
- return -1;
- }
} else {
- return 0;
- }
-}
-
-/*Android doesn't provide pthread_barrier_t for now.*/
-#ifndef PTHREAD_BARRIER_SERIAL_THREAD
-
-#include "pthread-fixes.h"
-
-int pthread_barrier_init(pthread_barrier_t* barrier,
- const void* barrier_attr,
- unsigned count) {
- barrier->count = count;
- pthread_mutex_init(&barrier->mutex, NULL);
- pthread_cond_init(&barrier->cond, NULL);
- return 0;
-}
-
-int pthread_barrier_wait(pthread_barrier_t* barrier) {
- /* Lock the mutex*/
- pthread_mutex_lock(&barrier->mutex);
- /* Decrement the count. If this is the first thread to reach 0, wake up
- waiters, unlock the mutex, then return PTHREAD_BARRIER_SERIAL_THREAD.*/
- if (--barrier->count == 0) {
- /* First thread to reach the barrier */
- pthread_cond_broadcast(&barrier->cond);
- pthread_mutex_unlock(&barrier->mutex);
- return PTHREAD_BARRIER_SERIAL_THREAD;
+ err = pthread_sigmask(how, set, oset);
+ if (err) {
+ if (err == EINVAL && sigprocmask(how, set, oset) == 0) {
+ workaround = 1;
+ return 0;
+ } else {
+ return -1;
+ }
+ }
}
- /* Otherwise, wait for other threads until the count reaches 0, then
- return 0 to indicate this is not the first thread.*/
- do {
- pthread_cond_wait(&barrier->cond, &barrier->mutex);
- } while (barrier->count > 0);
-
- pthread_mutex_unlock(&barrier->mutex);
- return 0;
-}
-
-int pthread_barrier_destroy(pthread_barrier_t *barrier) {
- barrier->count = 0;
- pthread_cond_destroy(&barrier->cond);
- pthread_mutex_destroy(&barrier->mutex);
- return 0;
-}
-
-#endif /* defined(PTHREAD_BARRIER_SERIAL_THREAD) */
-int pthread_yield(void) {
- sched_yield();
return 0;
}
diff --git a/deps/uv/src/unix/signal.c b/deps/uv/src/unix/signal.c
index edd9085d3f..d82b9b7cf8 100644
--- a/deps/uv/src/unix/signal.c
+++ b/deps/uv/src/unix/signal.c
@@ -222,7 +222,7 @@ static int uv__signal_loop_once_init(uv_loop_t* loop) {
uv__io_init(&loop->signal_io_watcher,
uv__signal_event,
loop->signal_pipefd[0]);
- uv__io_start(loop, &loop->signal_io_watcher, UV__POLLIN);
+ uv__io_start(loop, &loop->signal_io_watcher, POLLIN);
return 0;
}
diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c
index 9043664dfc..7dbc556f74 100644
--- a/deps/uv/src/unix/stream.c
+++ b/deps/uv/src/unix/stream.c
@@ -159,9 +159,9 @@ static void uv__stream_osx_select(void* arg) {
memset(s->sread, 0, s->sread_sz);
memset(s->swrite, 0, s->swrite_sz);
- if (uv__io_active(&stream->io_watcher, UV__POLLIN))
+ if (uv__io_active(&stream->io_watcher, POLLIN))
FD_SET(fd, s->sread);
- if (uv__io_active(&stream->io_watcher, UV__POLLOUT))
+ if (uv__io_active(&stream->io_watcher, POLLOUT))
FD_SET(fd, s->swrite);
FD_SET(s->int_fd, s->sread);
@@ -202,9 +202,9 @@ static void uv__stream_osx_select(void* arg) {
/* Handle events */
events = 0;
if (FD_ISSET(fd, s->sread))
- events |= UV__POLLIN;
+ events |= POLLIN;
if (FD_ISSET(fd, s->swrite))
- events |= UV__POLLOUT;
+ events |= POLLOUT;
assert(events != 0 || FD_ISSET(s->int_fd, s->sread));
if (events != 0) {
@@ -233,14 +233,14 @@ static void uv__stream_osx_select_cb(uv_async_t* handle) {
ACCESS_ONCE(int, s->events) = 0;
assert(events != 0);
- assert(events == (events & (UV__POLLIN | UV__POLLOUT)));
+ assert(events == (events & (POLLIN | POLLOUT)));
/* Invoke callback on event-loop */
- if ((events & UV__POLLIN) && uv__io_active(&stream->io_watcher, UV__POLLIN))
- uv__stream_io(stream->loop, &stream->io_watcher, UV__POLLIN);
+ if ((events & POLLIN) && uv__io_active(&stream->io_watcher, POLLIN))
+ uv__stream_io(stream->loop, &stream->io_watcher, POLLIN);
- if ((events & UV__POLLOUT) && uv__io_active(&stream->io_watcher, UV__POLLOUT))
- uv__stream_io(stream->loop, &stream->io_watcher, UV__POLLOUT);
+ if ((events & POLLOUT) && uv__io_active(&stream->io_watcher, POLLOUT))
+ uv__stream_io(stream->loop, &stream->io_watcher, POLLOUT);
if (stream->flags & UV_CLOSING)
return;
@@ -437,7 +437,7 @@ void uv__stream_flush_write_queue(uv_stream_t* stream, int error) {
void uv__stream_destroy(uv_stream_t* stream) {
- assert(!uv__io_active(&stream->io_watcher, UV__POLLIN | UV__POLLOUT));
+ assert(!uv__io_active(&stream->io_watcher, POLLIN | POLLOUT));
assert(stream->flags & UV_CLOSED);
if (stream->connect_req) {
@@ -511,11 +511,11 @@ void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
int err;
stream = container_of(w, uv_stream_t, io_watcher);
- assert(events == UV__POLLIN);
+ assert(events == POLLIN);
assert(stream->accepted_fd == -1);
assert(!(stream->flags & UV_CLOSING));
- uv__io_start(stream->loop, &stream->io_watcher, UV__POLLIN);
+ uv__io_start(stream->loop, &stream->io_watcher, POLLIN);
/* connection_cb can close the server socket while we're
* in the loop so check it on each iteration.
@@ -552,7 +552,7 @@ void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
if (stream->accepted_fd != -1) {
/* The user hasn't yet accepted called uv_accept() */
- uv__io_stop(loop, &stream->io_watcher, UV__POLLIN);
+ uv__io_stop(loop, &stream->io_watcher, POLLIN);
return;
}
@@ -626,7 +626,7 @@ done:
} else {
server->accepted_fd = -1;
if (err == 0)
- uv__io_start(server->loop, &server->io_watcher, UV__POLLIN);
+ uv__io_start(server->loop, &server->io_watcher, POLLIN);
}
return err;
}
@@ -660,7 +660,7 @@ static void uv__drain(uv_stream_t* stream) {
int err;
assert(QUEUE_EMPTY(&stream->write_queue));
- uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT);
+ uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT);
uv__stream_osx_interrupt_select(stream);
/* Shutdown? */
@@ -846,8 +846,8 @@ start:
/* Error */
req->error = -errno;
uv__write_req_finish(req);
- uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT);
- if (!uv__io_active(&stream->io_watcher, UV__POLLIN))
+ uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT);
+ if (!uv__io_active(&stream->io_watcher, POLLIN))
uv__handle_stop(stream);
uv__stream_osx_interrupt_select(stream);
return;
@@ -910,7 +910,7 @@ start:
assert(!(stream->flags & UV_STREAM_BLOCKING));
/* We're not done. */
- uv__io_start(stream->loop, &stream->io_watcher, UV__POLLOUT);
+ uv__io_start(stream->loop, &stream->io_watcher, POLLOUT);
/* Notify select() thread about state change */
uv__stream_osx_interrupt_select(stream);
@@ -989,8 +989,8 @@ uv_handle_type uv__handle_type(int fd) {
static void uv__stream_eof(uv_stream_t* stream, const uv_buf_t* buf) {
stream->flags |= UV_STREAM_READ_EOF;
- uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLIN);
- if (!uv__io_active(&stream->io_watcher, UV__POLLOUT))
+ uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
+ if (!uv__io_active(&stream->io_watcher, POLLOUT))
uv__handle_stop(stream);
uv__stream_osx_interrupt_select(stream);
stream->read_cb(stream, UV_EOF, buf);
@@ -1159,7 +1159,7 @@ static void uv__read(uv_stream_t* stream) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
/* Wait for the next one. */
if (stream->flags & UV_STREAM_READING) {
- uv__io_start(stream->loop, &stream->io_watcher, UV__POLLIN);
+ uv__io_start(stream->loop, &stream->io_watcher, POLLIN);
uv__stream_osx_interrupt_select(stream);
}
stream->read_cb(stream, 0, &buf);
@@ -1168,8 +1168,8 @@ static void uv__read(uv_stream_t* stream) {
stream->read_cb(stream, -errno, &buf);
if (stream->flags & UV_STREAM_READING) {
stream->flags &= ~UV_STREAM_READING;
- uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLIN);
- if (!uv__io_active(&stream->io_watcher, UV__POLLOUT))
+ uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
+ if (!uv__io_active(&stream->io_watcher, POLLOUT))
uv__handle_stop(stream);
uv__stream_osx_interrupt_select(stream);
}
@@ -1230,7 +1230,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) {
stream->shutdown_req = req;
stream->flags |= UV_STREAM_SHUTTING;
- uv__io_start(stream->loop, &stream->io_watcher, UV__POLLOUT);
+ uv__io_start(stream->loop, &stream->io_watcher, POLLOUT);
uv__stream_osx_interrupt_select(stream);
return 0;
@@ -1255,7 +1255,7 @@ static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
assert(uv__stream_fd(stream) >= 0);
/* Ignore POLLHUP here. Even it it's set, there may still be data to read. */
- if (events & (UV__POLLIN | UV__POLLERR | UV__POLLHUP))
+ if (events & (POLLIN | POLLERR | POLLHUP))
uv__read(stream);
if (uv__stream_fd(stream) == -1)
@@ -1267,7 +1267,7 @@ static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
* have to do anything. If the partial read flag is not set, we can't
* report the EOF yet because there is still data to read.
*/
- if ((events & UV__POLLHUP) &&
+ if ((events & POLLHUP) &&
(stream->flags & UV_STREAM_READING) &&
(stream->flags & UV_STREAM_READ_PARTIAL) &&
!(stream->flags & UV_STREAM_READ_EOF)) {
@@ -1278,7 +1278,7 @@ static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
if (uv__stream_fd(stream) == -1)
return; /* read_cb closed stream. */
- if (events & (UV__POLLOUT | UV__POLLERR | UV__POLLHUP)) {
+ if (events & (POLLOUT | POLLERR | POLLHUP)) {
uv__write(stream);
uv__write_callbacks(stream);
@@ -1327,7 +1327,7 @@ static void uv__stream_connect(uv_stream_t* stream) {
uv__req_unregister(stream->loop, req);
if (error < 0 || QUEUE_EMPTY(&stream->write_queue)) {
- uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT);
+ uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT);
}
if (req->cb)
@@ -1422,7 +1422,7 @@ int uv_write2(uv_write_t* req,
* sufficiently flushed in uv__write.
*/
assert(!(stream->flags & UV_STREAM_BLOCKING));
- uv__io_start(stream->loop, &stream->io_watcher, UV__POLLOUT);
+ uv__io_start(stream->loop, &stream->io_watcher, POLLOUT);
uv__stream_osx_interrupt_select(stream);
}
@@ -1461,7 +1461,7 @@ int uv_try_write(uv_stream_t* stream,
if (stream->connect_req != NULL || stream->write_queue_size != 0)
return -EAGAIN;
- has_pollout = uv__io_active(&stream->io_watcher, UV__POLLOUT);
+ has_pollout = uv__io_active(&stream->io_watcher, POLLOUT);
r = uv_write(&req, stream, bufs, nbufs, uv_try_write_cb);
if (r != 0)
@@ -1485,7 +1485,7 @@ int uv_try_write(uv_stream_t* stream,
/* Do not poll for writable, if we wasn't before calling this */
if (!has_pollout) {
- uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT);
+ uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT);
uv__stream_osx_interrupt_select(stream);
}
@@ -1520,7 +1520,7 @@ int uv_read_start(uv_stream_t* stream,
stream->read_cb = read_cb;
stream->alloc_cb = alloc_cb;
- uv__io_start(stream->loop, &stream->io_watcher, UV__POLLIN);
+ uv__io_start(stream->loop, &stream->io_watcher, POLLIN);
uv__handle_start(stream);
uv__stream_osx_interrupt_select(stream);
@@ -1533,8 +1533,8 @@ int uv_read_stop(uv_stream_t* stream) {
return 0;
stream->flags &= ~UV_STREAM_READING;
- uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLIN);
- if (!uv__io_active(&stream->io_watcher, UV__POLLOUT))
+ uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
+ if (!uv__io_active(&stream->io_watcher, POLLOUT))
uv__handle_stop(stream);
uv__stream_osx_interrupt_select(stream);
@@ -1621,7 +1621,7 @@ void uv__stream_close(uv_stream_t* handle) {
handle->queued_fds = NULL;
}
- assert(!uv__io_active(&handle->io_watcher, UV__POLLIN | UV__POLLOUT));
+ assert(!uv__io_active(&handle->io_watcher, POLLIN | POLLOUT));
}
diff --git a/deps/uv/src/unix/sunos.c b/deps/uv/src/unix/sunos.c
index 9a6cc42b5b..e67be8fcf8 100644
--- a/deps/uv/src/unix/sunos.c
+++ b/deps/uv/src/unix/sunos.c
@@ -140,6 +140,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
unsigned int nfds;
unsigned int i;
int saved_errno;
+ int have_signals;
int nevents;
int count;
int err;
@@ -230,6 +231,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
return;
}
+ have_signals = 0;
nevents = 0;
assert(loop->watchers != NULL);
@@ -252,7 +254,14 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
if (w == NULL)
continue;
- w->cb(loop, w, pe->portev_events);
+ /* Run signal watchers last. This also affects child process watchers
+ * because those are implemented in terms of signal watchers.
+ */
+ if (w == &loop->signal_io_watcher)
+ have_signals = 1;
+ else
+ w->cb(loop, w, pe->portev_events);
+
nevents++;
if (w != loop->watchers[fd])
@@ -262,9 +271,16 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
if (w->pevents != 0 && QUEUE_EMPTY(&w->watcher_queue))
QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue);
}
+
+ if (have_signals != 0)
+ loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
+
loop->watchers[loop->nwatchers] = NULL;
loop->watchers[loop->nwatchers + 1] = NULL;
+ if (have_signals != 0)
+ return; /* Event loop should cycle now so don't poll again. */
+
if (nevents != 0) {
if (nfds == ARRAY_SIZE(events) && --count != 0) {
/* Poll for more events but don't block this time. */
@@ -456,7 +472,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
if (first_run) {
uv__io_init(&handle->loop->fs_event_watcher, uv__fs_event_read, portfd);
- uv__io_start(handle->loop, &handle->loop->fs_event_watcher, UV__POLLIN);
+ uv__io_start(handle->loop, &handle->loop->fs_event_watcher, POLLIN);
}
return 0;
diff --git a/deps/uv/src/unix/tcp.c b/deps/uv/src/unix/tcp.c
index 6d213a4977..793e4c7d60 100644
--- a/deps/uv/src/unix/tcp.c
+++ b/deps/uv/src/unix/tcp.c
@@ -181,7 +181,7 @@ int uv__tcp_connect(uv_connect_t* req,
QUEUE_INIT(&req->queue);
handle->connect_req = req;
- uv__io_start(handle->loop, &handle->io_watcher, UV__POLLOUT);
+ uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);
if (handle->delayed_error)
uv__io_feed(handle->loop, &handle->io_watcher);
@@ -273,7 +273,7 @@ int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
/* Start listening for connections. */
tcp->io_watcher.cb = uv__server_io;
- uv__io_start(tcp->loop, &tcp->io_watcher, UV__POLLIN);
+ uv__io_start(tcp->loop, &tcp->io_watcher, POLLIN);
return 0;
}
diff --git a/deps/uv/src/unix/thread.c b/deps/uv/src/unix/thread.c
index c35bc926bf..236f591393 100644
--- a/deps/uv/src/unix/thread.c
+++ b/deps/uv/src/unix/thread.c
@@ -28,13 +28,13 @@
#include <sys/time.h>
#include <sys/resource.h> /* getrlimit() */
+#include <unistd.h> /* getpagesize() */
#include <limits.h>
#undef NANOSEC
#define NANOSEC ((uint64_t) 1e9)
-
struct thread_ctx {
void (*entry)(void* arg);
void* arg;
@@ -82,10 +82,13 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
if (pthread_attr_init(attr))
abort();
- if (lim.rlim_cur != RLIM_INFINITY &&
- lim.rlim_cur >= PTHREAD_STACK_MIN) {
- if (pthread_attr_setstacksize(attr, lim.rlim_cur))
- abort();
+ if (lim.rlim_cur != RLIM_INFINITY) {
+ /* pthread_attr_setstacksize() expects page-aligned values. */
+ lim.rlim_cur -= lim.rlim_cur % (rlim_t) getpagesize();
+
+ if (lim.rlim_cur >= PTHREAD_STACK_MIN)
+ if (pthread_attr_setstacksize(attr, lim.rlim_cur))
+ abort();
}
#else
attr = NULL;
@@ -393,6 +396,35 @@ error2:
#endif /* defined(__APPLE__) && defined(__MACH__) */
void uv_cond_destroy(uv_cond_t* cond) {
+#if defined(__APPLE__) && defined(__MACH__)
+ /* It has been reported that destroying condition variables that have been
+ * signalled but not waited on can sometimes result in application crashes.
+ * See https://codereview.chromium.org/1323293005.
+ */
+ pthread_mutex_t mutex;
+ struct timespec ts;
+ int err;
+
+ if (pthread_mutex_init(&mutex, NULL))
+ abort();
+
+ if (pthread_mutex_lock(&mutex))
+ abort();
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 1;
+
+ err = pthread_cond_timedwait_relative_np(cond, &mutex, &ts);
+ if (err != 0 && err != ETIMEDOUT)
+ abort();
+
+ if (pthread_mutex_unlock(&mutex))
+ abort();
+
+ if (pthread_mutex_destroy(&mutex))
+ abort();
+#endif /* defined(__APPLE__) && defined(__MACH__) */
+
if (pthread_cond_destroy(cond))
abort();
}
@@ -448,72 +480,6 @@ int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) {
}
-#if defined(__APPLE__) && defined(__MACH__)
-
-int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
- int err;
-
- barrier->n = count;
- barrier->count = 0;
-
- err = uv_mutex_init(&barrier->mutex);
- if (err)
- return -err;
-
- err = uv_sem_init(&barrier->turnstile1, 0);
- if (err)
- goto error2;
-
- err = uv_sem_init(&barrier->turnstile2, 1);
- if (err)
- goto error;
-
- return 0;
-
-error:
- uv_sem_destroy(&barrier->turnstile1);
-error2:
- uv_mutex_destroy(&barrier->mutex);
- return -err;
-
-}
-
-
-void uv_barrier_destroy(uv_barrier_t* barrier) {
- uv_sem_destroy(&barrier->turnstile2);
- uv_sem_destroy(&barrier->turnstile1);
- uv_mutex_destroy(&barrier->mutex);
-}
-
-
-int uv_barrier_wait(uv_barrier_t* barrier) {
- int serial_thread;
-
- uv_mutex_lock(&barrier->mutex);
- if (++barrier->count == barrier->n) {
- uv_sem_wait(&barrier->turnstile2);
- uv_sem_post(&barrier->turnstile1);
- }
- uv_mutex_unlock(&barrier->mutex);
-
- uv_sem_wait(&barrier->turnstile1);
- uv_sem_post(&barrier->turnstile1);
-
- uv_mutex_lock(&barrier->mutex);
- serial_thread = (--barrier->count == 0);
- if (serial_thread) {
- uv_sem_wait(&barrier->turnstile1);
- uv_sem_post(&barrier->turnstile2);
- }
- uv_mutex_unlock(&barrier->mutex);
-
- uv_sem_wait(&barrier->turnstile2);
- uv_sem_post(&barrier->turnstile2);
- return serial_thread;
-}
-
-#else /* !(defined(__APPLE__) && defined(__MACH__)) */
-
int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
return -pthread_barrier_init(barrier, NULL, count);
}
@@ -532,7 +498,6 @@ int uv_barrier_wait(uv_barrier_t* barrier) {
return r == PTHREAD_BARRIER_SERIAL_THREAD;
}
-#endif /* defined(__APPLE__) && defined(__MACH__) */
int uv_key_create(uv_key_t* key) {
return -pthread_key_create(key, NULL);
diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c
index 39ade8de33..4527bba1f1 100644
--- a/deps/uv/src/unix/udp.c
+++ b/deps/uv/src/unix/udp.c
@@ -61,7 +61,7 @@ void uv__udp_finish_close(uv_udp_t* handle) {
uv_udp_send_t* req;
QUEUE* q;
- assert(!uv__io_active(&handle->io_watcher, UV__POLLIN | UV__POLLOUT));
+ assert(!uv__io_active(&handle->io_watcher, POLLIN | POLLOUT));
assert(handle->io_watcher.fd == -1);
while (!QUEUE_EMPTY(&handle->write_queue)) {
@@ -120,8 +120,8 @@ static void uv__udp_run_completed(uv_udp_t* handle) {
if (QUEUE_EMPTY(&handle->write_queue)) {
/* Pending queue and completion queue empty, stop watcher. */
- uv__io_stop(handle->loop, &handle->io_watcher, UV__POLLOUT);
- if (!uv__io_active(&handle->io_watcher, UV__POLLIN))
+ uv__io_stop(handle->loop, &handle->io_watcher, POLLOUT);
+ if (!uv__io_active(&handle->io_watcher, POLLIN))
uv__handle_stop(handle);
}
@@ -135,10 +135,10 @@ static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents) {
handle = container_of(w, uv_udp_t, io_watcher);
assert(handle->type == UV_UDP);
- if (revents & UV__POLLIN)
+ if (revents & POLLIN)
uv__udp_recvmsg(handle);
- if (revents & UV__POLLOUT) {
+ if (revents & POLLOUT) {
uv__udp_sendmsg(handle);
uv__udp_run_completed(handle);
}
@@ -424,7 +424,7 @@ int uv__udp_send(uv_udp_send_t* req,
if (empty_queue && !(handle->flags & UV_UDP_PROCESSING)) {
uv__udp_sendmsg(handle);
} else {
- uv__io_start(handle->loop, &handle->io_watcher, UV__POLLOUT);
+ uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);
}
return 0;
@@ -843,7 +843,7 @@ int uv__udp_recv_start(uv_udp_t* handle,
if (alloc_cb == NULL || recv_cb == NULL)
return -EINVAL;
- if (uv__io_active(&handle->io_watcher, UV__POLLIN))
+ if (uv__io_active(&handle->io_watcher, POLLIN))
return -EALREADY; /* FIXME(bnoordhuis) Should be -EBUSY. */
err = uv__udp_maybe_deferred_bind(handle, AF_INET, 0);
@@ -853,7 +853,7 @@ int uv__udp_recv_start(uv_udp_t* handle,
handle->alloc_cb = alloc_cb;
handle->recv_cb = recv_cb;
- uv__io_start(handle->loop, &handle->io_watcher, UV__POLLIN);
+ uv__io_start(handle->loop, &handle->io_watcher, POLLIN);
uv__handle_start(handle);
return 0;
@@ -861,9 +861,9 @@ int uv__udp_recv_start(uv_udp_t* handle,
int uv__udp_recv_stop(uv_udp_t* handle) {
- uv__io_stop(handle->loop, &handle->io_watcher, UV__POLLIN);
+ uv__io_stop(handle->loop, &handle->io_watcher, POLLIN);
- if (!uv__io_active(&handle->io_watcher, UV__POLLOUT))
+ if (!uv__io_active(&handle->io_watcher, POLLOUT))
uv__handle_stop(handle);
handle->alloc_cb = NULL;
diff --git a/deps/uv/src/uv-common.c b/deps/uv/src/uv-common.c
index 6b8c584fbe..ba26446915 100644
--- a/deps/uv/src/uv-common.c
+++ b/deps/uv/src/uv-common.c
@@ -22,10 +22,11 @@
#include "uv.h"
#include "uv-common.h"
-#include <stdio.h>
#include <assert.h>
+#include <errno.h>
#include <stdarg.h>
#include <stddef.h> /* NULL */
+#include <stdio.h>
#include <stdlib.h> /* malloc */
#include <string.h> /* memset */
@@ -75,7 +76,14 @@ void* uv__malloc(size_t size) {
}
void uv__free(void* ptr) {
+ int saved_errno;
+
+ /* Libuv expects that free() does not clobber errno. The system allocator
+ * honors that assumption but custom allocators may not be so careful.
+ */
+ saved_errno = errno;
uv__allocator.local_free(ptr);
+ errno = saved_errno;
}
void* uv__calloc(size_t count, size_t size) {
@@ -475,6 +483,16 @@ static unsigned int* uv__get_nbufs(uv_fs_t* req) {
#endif
}
+/* uv_fs_scandir() uses the system allocator to allocate memory on non-Windows
+ * systems. So, the memory should be released using free(). On Windows,
+ * uv__malloc() is used, so use uv__free() to free memory.
+*/
+#ifdef _WIN32
+# define uv__fs_scandir_free uv__free
+#else
+# define uv__fs_scandir_free free
+#endif
+
void uv__fs_scandir_cleanup(uv_fs_t* req) {
uv__dirent_t** dents;
@@ -484,7 +502,10 @@ 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)++)
- uv__free(dents[*nbufs]);
+ uv__fs_scandir_free(dents[*nbufs]);
+
+ uv__fs_scandir_free(req->ptr);
+ req->ptr = NULL;
}
@@ -498,11 +519,11 @@ int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent) {
/* Free previous entity */
if (*nbufs > 0)
- uv__free(dents[*nbufs - 1]);
+ uv__fs_scandir_free(dents[*nbufs - 1]);
/* End was already reached */
if (*nbufs == (unsigned int) req->result) {
- uv__free(dents);
+ uv__fs_scandir_free(dents);
req->ptr = NULL;
return UV_EOF;
}
diff --git a/deps/uv/src/win/fs-event.c b/deps/uv/src/win/fs-event.c
index 77c935a2d8..e79a48d0e9 100644
--- a/deps/uv/src/win/fs-event.c
+++ b/deps/uv/src/win/fs-event.c
@@ -66,11 +66,12 @@ static void uv_fs_event_queue_readdirchanges(uv_loop_t* loop,
static void uv_relative_path(const WCHAR* filename,
const WCHAR* dir,
WCHAR** relpath) {
+ size_t relpathlen;
+ size_t filenamelen = wcslen(filename);
size_t dirlen = wcslen(dir);
if (dirlen > 0 && dir[dirlen - 1] == '\\')
dirlen--;
- size_t filenamelen = wcslen(filename);
- size_t relpathlen = filenamelen - dirlen - 1;
+ relpathlen = filenamelen - dirlen - 1;
*relpath = uv__malloc((relpathlen + 1) * sizeof(WCHAR));
if (!*relpath)
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
@@ -348,7 +349,8 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
FILE_NOTIFY_INFORMATION* file_info;
int err, sizew, size;
char* filename = NULL;
- WCHAR* filenamew, *long_filenamew = NULL;
+ WCHAR* filenamew = NULL;
+ WCHAR* long_filenamew = NULL;
DWORD offset = 0;
assert(req->type == UV_FS_EVENT_REQ);
@@ -373,6 +375,7 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
do {
file_info = (FILE_NOTIFY_INFORMATION*)((char*)file_info + offset);
assert(!filename);
+ assert(!filenamew);
assert(!long_filenamew);
/*
@@ -437,14 +440,17 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
uv__free(long_filenamew);
long_filenamew = filenamew;
sizew = -1;
+ } else {
+ /* We couldn't get the long filename, use the one reported. */
+ filenamew = file_info->FileName;
+ sizew = file_info->FileNameLength / sizeof(WCHAR);
}
- }
- /*
- * Removed or renamed events cannot be resolved to the long form.
- * We therefore use the name given by ReadDirectoryChangesW.
- * This may be the long form or the 8.3 short name in some cases.
- */
- if (!long_filenamew) {
+ } else {
+ /*
+ * Removed or renamed events cannot be resolved to the long form.
+ * We therefore use the name given by ReadDirectoryChangesW.
+ * This may be the long form or the 8.3 short name in some cases.
+ */
filenamew = file_info->FileName;
sizew = file_info->FileNameLength / sizeof(WCHAR);
}
@@ -454,38 +460,8 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
sizew = -1;
}
- if (filenamew) {
- /* Convert the filename to utf8. */
- size = WideCharToMultiByte(CP_UTF8,
- 0,
- filenamew,
- sizew,
- NULL,
- 0,
- NULL,
- NULL);
- if (size) {
- filename = (char*)uv__malloc(size + 1);
- if (!filename) {
- uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
- }
-
- size = WideCharToMultiByte(CP_UTF8,
- 0,
- filenamew,
- sizew,
- filename,
- size,
- NULL,
- NULL);
- if (size) {
- filename[size] = '\0';
- } else {
- uv__free(filename);
- filename = NULL;
- }
- }
- }
+ /* Convert the filename to utf8. */
+ uv__convert_utf16_to_utf8(filenamew, sizew, &filename);
switch (file_info->Action) {
case FILE_ACTION_ADDED:
@@ -504,6 +480,7 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
filename = NULL;
uv__free(long_filenamew);
long_filenamew = NULL;
+ filenamew = NULL;
}
offset = file_info->NextEntryOffset;
diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c
index 16e3ae7cf1..54dfea7240 100644
--- a/deps/uv/src/win/fs.c
+++ b/deps/uv/src/win/fs.c
@@ -901,7 +901,15 @@ void fs__scandir(uv_fs_t* req) {
/* Compute the length of the filename in WCHARs. */
wchar_len = info->FileNameLength / sizeof info->FileName[0];
- /* Skip over '.' and '..' entries. */
+ /* Skip over '.' and '..' entries. It has been reported that
+ * the SharePoint driver includes the terminating zero byte in
+ * the filename length. Strip those first.
+ */
+ while (wchar_len > 0 && info->FileName[wchar_len - 1] == L'\0')
+ wchar_len -= 1;
+
+ if (wchar_len == 0)
+ continue;
if (wchar_len == 1 && info->FileName[0] == L'.')
continue;
if (wchar_len == 2 && info->FileName[0] == L'.' &&
@@ -1870,8 +1878,12 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
if (req->flags & UV_FS_FREE_PATHS)
uv__free(req->file.pathw);
- if (req->flags & UV_FS_FREE_PTR)
- uv__free(req->ptr);
+ if (req->flags & UV_FS_FREE_PTR) {
+ if (req->fs_type == UV_FS_SCANDIR && req->ptr != NULL)
+ uv__fs_scandir_cleanup(req);
+ else
+ uv__free(req->ptr);
+ }
req->path = NULL;
req->file.pathw = NULL;
diff --git a/deps/uv/src/win/internal.h b/deps/uv/src/win/internal.h
index c724793bf0..0a7c9404fa 100644
--- a/deps/uv/src/win/internal.h
+++ b/deps/uv/src/win/internal.h
@@ -83,6 +83,7 @@ extern UV_THREAD_LOCAL int uv__crt_assert_enabled;
#define UV_HANDLE_ZERO_READ 0x00080000
#define UV_HANDLE_EMULATE_IOCP 0x00100000
#define UV_HANDLE_BLOCKING_WRITES 0x00200000
+#define UV_HANDLE_CANCELLATION_PENDING 0x00400000
/* Used by uv_tcp_t and uv_udp_t handles */
#define UV_HANDLE_IPV6 0x01000000
@@ -329,7 +330,7 @@ int uv_parent_pid();
int uv_current_pid();
__declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall);
int uv__getpwuid_r(uv_passwd_t* pwd);
-int uv__convert_utf16_to_utf8(const WCHAR* utf16, char** utf8);
+int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8);
/*
diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c
index 1b27f60a6f..9b96377844 100644
--- a/deps/uv/src/win/tty.c
+++ b/deps/uv/src/win/tty.c
@@ -57,11 +57,23 @@
static void uv_tty_capture_initial_style(CONSOLE_SCREEN_BUFFER_INFO* info);
static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info);
+static int uv__cancel_read_console(uv_tty_t* handle);
/* Null uv_buf_t */
static const uv_buf_t uv_null_buf_ = { 0, NULL };
+enum uv__read_console_status_e {
+ NOT_STARTED,
+ IN_PROGRESS,
+ TRAP_REQUESTED,
+ COMPLETED
+};
+
+static volatile LONG uv__read_console_status = NOT_STARTED;
+static volatile LONG uv__restore_screen_state;
+static CONSOLE_SCREEN_BUFFER_INFO uv__saved_screen_state;
+
/*
* The console virtual window.
@@ -173,7 +185,8 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
if (readable) {
/* Initialize TTY input specific fields. */
tty->flags |= UV_HANDLE_TTY_READABLE | UV_HANDLE_READABLE;
- tty->tty.rd.read_line_handle = NULL;
+ /* TODO: remove me in v2.x. */
+ tty->tty.rd.unused_ = NULL;
tty->tty.rd.read_line_buffer = uv_null_buf_;
tty->tty.rd.read_raw_wait = NULL;
@@ -398,6 +411,8 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
DWORD bytes, read_bytes;
WCHAR utf16[MAX_INPUT_BUFFER_LENGTH / 3];
DWORD chars, read_chars;
+ LONG status;
+ COORD pos;
assert(data);
@@ -419,7 +434,15 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
/* One utf-16 codeunit never takes more than 3 utf-8 codeunits to encode */
chars = bytes / 3;
- if (ReadConsoleW(handle->tty.rd.read_line_handle,
+ status = InterlockedExchange(&uv__read_console_status, IN_PROGRESS);
+ if (status == TRAP_REQUESTED) {
+ SET_REQ_SUCCESS(req);
+ req->u.io.overlapped.InternalHigh = 0;
+ POST_COMPLETION_FOR_REQ(loop, req);
+ return 0;
+ }
+
+ if (ReadConsoleW(handle->handle,
(void*) utf16,
chars,
&read_chars,
@@ -438,6 +461,33 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
SET_REQ_ERROR(req, GetLastError());
}
+ InterlockedExchange(&uv__read_console_status, COMPLETED);
+
+ /* If we canceled the read by sending a VK_RETURN event, restore the screen
+ state to undo the visual effect of the VK_RETURN*/
+ if (InterlockedOr(&uv__restore_screen_state, 0)) {
+ HANDLE active_screen_buffer = CreateFileA("conout$",
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (active_screen_buffer != INVALID_HANDLE_VALUE) {
+ pos = uv__saved_screen_state.dwCursorPosition;
+
+ /* If the cursor was at the bottom line of the screen buffer, the
+ VK_RETURN would have caused the buffer contents to scroll up by
+ one line. The right position to reset the cursor to is therefore one
+ line higher */
+ if (pos.Y == uv__saved_screen_state.dwSize.Y - 1)
+ pos.Y--;
+
+ SetConsoleCursorPosition(active_screen_buffer, pos);
+ CloseHandle(active_screen_buffer);
+ }
+ }
+
POST_COMPLETION_FOR_REQ(loop, req);
return 0;
}
@@ -463,25 +513,11 @@ static void uv_tty_queue_read_line(uv_loop_t* loop, uv_tty_t* handle) {
}
assert(handle->tty.rd.read_line_buffer.base != NULL);
- /* Duplicate the console handle, so if we want to cancel the read, we can */
- /* just close this handle duplicate. */
- if (handle->tty.rd.read_line_handle == NULL) {
- HANDLE this_process = GetCurrentProcess();
- r = DuplicateHandle(this_process,
- handle->handle,
- this_process,
- &handle->tty.rd.read_line_handle,
- 0,
- 0,
- DUPLICATE_SAME_ACCESS);
- if (!r) {
- handle->tty.rd.read_line_handle = NULL;
- SET_REQ_ERROR(req, GetLastError());
- uv_insert_pending_req(loop, (uv_req_t*)req);
- goto out;
- }
- }
-
+ /* Reset flags No locking is required since there cannot be a line read
+ in progress. We are also relying on the memory barrier provided by
+ QueueUserWorkItem*/
+ uv__restore_screen_state = FALSE;
+ uv__read_console_status = NOT_STARTED;
r = QueueUserWorkItem(uv_tty_line_read_thread,
(void*) req,
WT_EXECUTELONGFUNCTION);
@@ -490,7 +526,6 @@ static void uv_tty_queue_read_line(uv_loop_t* loop, uv_tty_t* handle) {
uv_insert_pending_req(loop, (uv_req_t*)req);
}
- out:
handle->flags |= UV_HANDLE_READ_PENDING;
handle->reqs_pending++;
}
@@ -857,8 +892,7 @@ void uv_process_tty_read_line_req(uv_loop_t* loop, uv_tty_t* handle,
if (!REQ_SUCCESS(req)) {
/* Read was not successful */
- if ((handle->flags & UV_HANDLE_READING) &&
- handle->tty.rd.read_line_handle != NULL) {
+ if (handle->flags & UV_HANDLE_READING) {
/* Real error */
handle->flags &= ~UV_HANDLE_READING;
DECREASE_ACTIVE_COUNT(loop, handle);
@@ -871,10 +905,15 @@ void uv_process_tty_read_line_req(uv_loop_t* loop, uv_tty_t* handle,
}
} else {
- /* Read successful */
- /* TODO: read unicode, convert to utf-8 */
- DWORD bytes = req->u.io.overlapped.InternalHigh;
- handle->read_cb((uv_stream_t*) handle, bytes, &buf);
+ if (!(handle->flags & UV_HANDLE_CANCELLATION_PENDING)) {
+ /* Read successful */
+ /* TODO: read unicode, convert to utf-8 */
+ DWORD bytes = req->u.io.overlapped.InternalHigh;
+ handle->read_cb((uv_stream_t*) handle, bytes, &buf);
+ } else {
+ handle->flags &= ~UV_HANDLE_CANCELLATION_PENDING;
+ handle->read_cb((uv_stream_t*) handle, 0, &buf);
+ }
}
/* Wait for more input events. */
@@ -937,30 +976,82 @@ int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb,
int uv_tty_read_stop(uv_tty_t* handle) {
+ INPUT_RECORD record;
+ DWORD written, err;
+
handle->flags &= ~UV_HANDLE_READING;
DECREASE_ACTIVE_COUNT(handle->loop, handle);
- /* Cancel raw read */
- if ((handle->flags & UV_HANDLE_READ_PENDING) &&
- (handle->flags & UV_HANDLE_TTY_RAW)) {
+ if (!(handle->flags & UV_HANDLE_READ_PENDING))
+ return 0;
+
+ if (handle->flags & UV_HANDLE_TTY_RAW) {
+ /* Cancel raw read */
/* Write some bullshit event to force the console wait to return. */
- INPUT_RECORD record;
- DWORD written;
memset(&record, 0, sizeof record);
if (!WriteConsoleInputW(handle->handle, &record, 1, &written)) {
return GetLastError();
}
+ } else if (!(handle->flags & UV_HANDLE_CANCELLATION_PENDING)) {
+ /* Cancel line-buffered read if not already pending */
+ err = uv__cancel_read_console(handle);
+ if (err)
+ return err;
+
+ handle->flags |= UV_HANDLE_CANCELLATION_PENDING;
+ }
+
+ return 0;
+}
+
+static int uv__cancel_read_console(uv_tty_t* handle) {
+ HANDLE active_screen_buffer = INVALID_HANDLE_VALUE;
+ INPUT_RECORD record;
+ DWORD written;
+ DWORD err = 0;
+ LONG status;
+
+ assert(!(handle->flags & UV_HANDLE_CANCELLATION_PENDING));
+
+ status = InterlockedExchange(&uv__read_console_status, TRAP_REQUESTED);
+ if (status != IN_PROGRESS) {
+ /* Either we have managed to set a trap for the other thread before
+ ReadConsole is called, or ReadConsole has returned because the user
+ has pressed ENTER. In either case, there is nothing else to do. */
+ return 0;
}
- /* Cancel line-buffered read */
- if (handle->tty.rd.read_line_handle != NULL) {
- /* Closing this handle will cancel the ReadConsole operation */
- CloseHandle(handle->tty.rd.read_line_handle);
- handle->tty.rd.read_line_handle = NULL;
+ /* Save screen state before sending the VK_RETURN event */
+ active_screen_buffer = CreateFileA("conout$",
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (active_screen_buffer != INVALID_HANDLE_VALUE &&
+ GetConsoleScreenBufferInfo(active_screen_buffer,
+ &uv__saved_screen_state)) {
+ InterlockedOr(&uv__restore_screen_state, 1);
}
+ /* Write enter key event to force the console wait to return. */
+ record.EventType = KEY_EVENT;
+ record.Event.KeyEvent.bKeyDown = TRUE;
+ record.Event.KeyEvent.wRepeatCount = 1;
+ record.Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
+ record.Event.KeyEvent.wVirtualScanCode =
+ MapVirtualKeyW(VK_RETURN, MAPVK_VK_TO_VSC);
+ record.Event.KeyEvent.uChar.UnicodeChar = L'\r';
+ record.Event.KeyEvent.dwControlKeyState = 0;
+ if (!WriteConsoleInputW(handle->handle, &record, 1, &written))
+ err = GetLastError();
- return 0;
+ if (active_screen_buffer != INVALID_HANDLE_VALUE)
+ CloseHandle(active_screen_buffer);
+
+ return err;
}
@@ -2045,11 +2136,6 @@ void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) {
if (handle->flags & UV__HANDLE_CLOSING &&
handle->reqs_pending == 0) {
- /* The console handle duplicate used for line reading should be destroyed */
- /* by uv_tty_read_stop. */
- assert(!(handle->flags & UV_HANDLE_TTY_READABLE) ||
- handle->tty.rd.read_line_handle == NULL);
-
/* The wait handle used for raw reading should be unregistered when the */
/* wait callback runs. */
assert(!(handle->flags & UV_HANDLE_TTY_READABLE) ||
diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c
index 1788b1780e..4cebad3908 100644
--- a/deps/uv/src/win/util.c
+++ b/deps/uv/src/win/util.c
@@ -124,7 +124,7 @@ int uv_exepath(char* buffer, size_t* size_ptr) {
utf16_buffer,
-1,
buffer,
- *size_ptr > INT_MAX ? INT_MAX : (int) *size_ptr,
+ (int) *size_ptr,
NULL,
NULL);
if (utf8_len == 0) {
@@ -403,36 +403,13 @@ done:
static int uv__get_process_title() {
WCHAR title_w[MAX_TITLE_LENGTH];
- int length;
if (!GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR))) {
return -1;
}
- /* Find out what the size of the buffer is that we need */
- length = WideCharToMultiByte(CP_UTF8, 0, title_w, -1, NULL, 0, NULL, NULL);
- if (!length) {
- return -1;
- }
-
- assert(!process_title);
- process_title = (char*)uv__malloc(length);
- if (!process_title) {
- uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
- }
-
- /* Do utf16 -> utf8 conversion here */
- if (!WideCharToMultiByte(CP_UTF8,
- 0,
- title_w,
- -1,
- process_title,
- length,
- NULL,
- NULL)) {
- uv__free(process_title);
+ if (uv__convert_utf16_to_utf8(title_w, -1, &process_title) != 0)
return -1;
- }
return 0;
}
@@ -704,43 +681,9 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) {
cpu_info->cpu_times.irq = sppi[i].InterruptTime.QuadPart / 10000;
cpu_info->cpu_times.nice = 0;
-
- len = WideCharToMultiByte(CP_UTF8,
- 0,
- cpu_brand,
+ uv__convert_utf16_to_utf8(cpu_brand,
cpu_brand_size / sizeof(WCHAR),
- NULL,
- 0,
- NULL,
- NULL);
- if (len == 0) {
- err = GetLastError();
- goto error;
- }
-
- assert(len > 0);
-
- /* Allocate 1 extra byte for the null terminator. */
- cpu_info->model = uv__malloc(len + 1);
- if (cpu_info->model == NULL) {
- err = ERROR_OUTOFMEMORY;
- goto error;
- }
-
- if (WideCharToMultiByte(CP_UTF8,
- 0,
- cpu_brand,
- cpu_brand_size / sizeof(WCHAR),
- cpu_info->model,
- len,
- NULL,
- NULL) == 0) {
- err = GetLastError();
- goto error;
- }
-
- /* Ensure that cpu_info->model is null terminated. */
- cpu_info->model[len] = '\0';
+ &(cpu_info->model));
}
uv__free(sppi);
@@ -1118,6 +1061,7 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
int uv_getrusage(uv_rusage_t *uv_rusage) {
FILETIME createTime, exitTime, kernelTime, userTime;
SYSTEMTIME kernelSystemTime, userSystemTime;
+ PROCESS_MEMORY_COUNTERS memCounters;
int ret;
ret = GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &kernelTime, &userTime);
@@ -1135,6 +1079,13 @@ int uv_getrusage(uv_rusage_t *uv_rusage) {
return uv_translate_sys_error(GetLastError());
}
+ ret = GetProcessMemoryInfo(GetCurrentProcess(),
+ &memCounters,
+ sizeof(memCounters));
+ if (ret == 0) {
+ return uv_translate_sys_error(GetLastError());
+ }
+
memset(uv_rusage, 0, sizeof(*uv_rusage));
uv_rusage->ru_utime.tv_sec = userSystemTime.wHour * 3600 +
@@ -1147,6 +1098,9 @@ int uv_getrusage(uv_rusage_t *uv_rusage) {
kernelSystemTime.wSecond;
uv_rusage->ru_stime.tv_usec = kernelSystemTime.wMilliseconds * 1000;
+ uv_rusage->ru_majflt = (uint64_t) memCounters.PageFaultCount;
+ uv_rusage->ru_maxrss = (uint64_t) memCounters.PeakWorkingSetSize / 1024;
+
return 0;
}
@@ -1288,20 +1242,36 @@ void uv_os_free_passwd(uv_passwd_t* pwd) {
}
-int uv__convert_utf16_to_utf8(const WCHAR* utf16, char** utf8) {
+/*
+ * Converts a UTF-16 string into a UTF-8 one. The resulting string is
+ * null-terminated.
+ *
+ * If utf16 is null terminated, utf16len can be set to -1, otherwise it must
+ * be specified.
+ */
+int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8) {
DWORD bufsize;
if (utf16 == NULL)
return UV_EINVAL;
/* Check how much space we need */
- bufsize = WideCharToMultiByte(CP_UTF8, 0, utf16, -1, NULL, 0, NULL, NULL);
+ bufsize = WideCharToMultiByte(CP_UTF8,
+ 0,
+ utf16,
+ utf16len,
+ NULL,
+ 0,
+ NULL,
+ NULL);
if (bufsize == 0)
return uv_translate_sys_error(GetLastError());
- /* Allocate the destination buffer */
- *utf8 = uv__malloc(bufsize);
+ /* Allocate the destination buffer adding an extra byte for the terminating
+ * NULL. If utf16len is not -1 WideCharToMultiByte will not add it, so
+ * we do it ourselves always, just in case. */
+ *utf8 = uv__malloc(bufsize + 1);
if (*utf8 == NULL)
return UV_ENOMEM;
@@ -1310,7 +1280,7 @@ int uv__convert_utf16_to_utf8(const WCHAR* utf16, char** utf8) {
bufsize = WideCharToMultiByte(CP_UTF8,
0,
utf16,
- -1,
+ utf16len,
*utf8,
bufsize,
NULL,
@@ -1318,9 +1288,11 @@ int uv__convert_utf16_to_utf8(const WCHAR* utf16, char** utf8) {
if (bufsize == 0) {
uv__free(*utf8);
+ *utf8 = NULL;
return uv_translate_sys_error(GetLastError());
}
+ (*utf8)[bufsize] = '\0';
return 0;
}
@@ -1366,13 +1338,13 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
}
pwd->homedir = NULL;
- r = uv__convert_utf16_to_utf8(path, &pwd->homedir);
+ r = uv__convert_utf16_to_utf8(path, -1, &pwd->homedir);
if (r != 0)
return r;
pwd->username = NULL;
- r = uv__convert_utf16_to_utf8(username, &pwd->username);
+ r = uv__convert_utf16_to_utf8(username, -1, &pwd->username);
if (r != 0) {
uv__free(pwd->homedir);
diff --git a/deps/uv/test/test-emfile.c b/deps/uv/test/test-emfile.c
index dd35f785b4..5f4dd9efdf 100644
--- a/deps/uv/test/test-emfile.c
+++ b/deps/uv/test/test-emfile.c
@@ -38,6 +38,13 @@ static uv_tcp_t client_handle;
TEST_IMPL(emfile) {
+#ifdef _AIX
+ /* On AIX, if a 'accept' call fails ECONNRESET is set on the socket
+ * which causes uv__emfile_trick to not work as intended and this test
+ * to fail.
+ */
+ RETURN_SKIP("uv__emfile_trick does not work on AIX");
+#endif
struct sockaddr_in addr;
struct rlimit limits;
uv_connect_t connect_req;
diff --git a/deps/uv/test/test-fs-event.c b/deps/uv/test/test-fs-event.c
index 35583529e5..353c43b0de 100644
--- a/deps/uv/test/test-fs-event.c
+++ b/deps/uv/test/test-fs-event.c
@@ -511,7 +511,7 @@ TEST_IMPL(fs_event_watch_file_current_dir) {
r = uv_timer_init(loop, &timer);
ASSERT(r == 0);
- r = uv_timer_start(&timer, timer_cb_touch, 10, 0);
+ r = uv_timer_start(&timer, timer_cb_touch, 100, 0);
ASSERT(r == 0);
ASSERT(timer_cb_touch_called == 0);
@@ -698,18 +698,19 @@ TEST_IMPL(fs_event_close_with_pending_event) {
return 0;
}
-#if defined(HAVE_KQUEUE)
+#if defined(HAVE_KQUEUE) || defined(_AIX)
/* kqueue doesn't register fs events if you don't have an active watcher.
* The file descriptor needs to be part of the kqueue set of interest and
* that's not the case until we actually enter the event loop.
+ * This is also observed on AIX with ahafs.
*/
TEST_IMPL(fs_event_close_in_callback) {
- fprintf(stderr, "Skipping test, doesn't work with kqueue.\n");
+ fprintf(stderr, "Skipping test, doesn't work with kqueue and AIX.\n");
return 0;
}
-#else /* !HAVE_KQUEUE */
+#else /* !HAVE_KQUEUE || !_AIX */
static void fs_event_cb_close(uv_fs_event_t* handle, const char* filename,
int events, int status) {
@@ -766,7 +767,7 @@ TEST_IMPL(fs_event_close_in_callback) {
return 0;
}
-#endif /* HAVE_KQUEUE */
+#endif /* HAVE_KQUEUE || _AIX */
TEST_IMPL(fs_event_start_and_close) {
uv_loop_t* loop;
diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c
index cf37ac4909..1cc1a7c064 100644
--- a/deps/uv/test/test-fs.c
+++ b/deps/uv/test/test-fs.c
@@ -2033,6 +2033,9 @@ TEST_IMPL(fs_stat_root) {
TEST_IMPL(fs_futime) {
+#if defined(_AIX) && !defined(_AIX71)
+ RETURN_SKIP("futime is not implemented for AIX versions below 7.1");
+#else
utime_check_t checkme;
const char* path = "test_file";
double atime;
@@ -2087,6 +2090,7 @@ TEST_IMPL(fs_futime) {
MAKE_VALGRIND_HAPPY();
return 0;
+#endif
}
diff --git a/deps/uv/test/test-get-passwd.c b/deps/uv/test/test-get-passwd.c
index 58d9c73c69..8e16fb83c8 100644
--- a/deps/uv/test/test-get-passwd.c
+++ b/deps/uv/test/test-get-passwd.c
@@ -45,9 +45,15 @@ TEST_IMPL(get_passwd) {
ASSERT(len > 0);
#ifdef _WIN32
- ASSERT(pwd.homedir[len - 1] != '\\');
+ if (len == 3 && pwd.homedir[1] == ':')
+ ASSERT(pwd.homedir[2] == '\\');
+ else
+ ASSERT(pwd.homedir[len - 1] != '\\');
#else
- ASSERT(pwd.homedir[len - 1] != '/');
+ if (len == 1)
+ ASSERT(pwd.homedir[0] == '/');
+ else
+ ASSERT(pwd.homedir[len - 1] != '/');
#endif
#ifdef _WIN32
diff --git a/deps/uv/test/test-homedir.c b/deps/uv/test/test-homedir.c
index 5027d44c1e..856534a40c 100644
--- a/deps/uv/test/test-homedir.c
+++ b/deps/uv/test/test-homedir.c
@@ -29,7 +29,6 @@
TEST_IMPL(homedir) {
char homedir[PATHMAX];
size_t len;
- char last;
int r;
/* Test the normal case */
@@ -42,14 +41,17 @@ TEST_IMPL(homedir) {
ASSERT(len > 0);
ASSERT(homedir[len] == '\0');
- if (len > 1) {
- last = homedir[len - 1];
#ifdef _WIN32
- ASSERT(last != '\\');
+ if (len == 3 && homedir[1] == ':')
+ ASSERT(homedir[2] == '\\');
+ else
+ ASSERT(homedir[len - 1] != '\\');
#else
- ASSERT(last != '/');
+ if (len == 1)
+ ASSERT(homedir[0] == '/');
+ else
+ ASSERT(homedir[len - 1] != '/');
#endif
- }
/* Test the case where the buffer is too small */
len = SMALLPATH;
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
index 8b10f1a5f6..c93f081992 100644
--- a/deps/uv/test/test-list.h
+++ b/deps/uv/test/test-list.h
@@ -43,6 +43,9 @@ TEST_DECLARE (semaphore_1)
TEST_DECLARE (semaphore_2)
TEST_DECLARE (semaphore_3)
TEST_DECLARE (tty)
+#ifdef _WIN32
+TEST_DECLARE (tty_raw)
+#endif
TEST_DECLARE (tty_file)
TEST_DECLARE (tty_pty)
TEST_DECLARE (stdio_over_pipes)
@@ -387,6 +390,9 @@ TASK_LIST_START
#endif
TEST_ENTRY (pipe_set_non_blocking)
TEST_ENTRY (tty)
+#ifdef _WIN32
+ TEST_ENTRY (tty_raw)
+#endif
TEST_ENTRY (tty_file)
TEST_ENTRY (tty_pty)
TEST_ENTRY (stdio_over_pipes)
diff --git a/deps/uv/test/test-platform-output.c b/deps/uv/test/test-platform-output.c
index 2c4740550a..bd61454fa7 100644
--- a/deps/uv/test/test-platform-output.c
+++ b/deps/uv/test/test-platform-output.c
@@ -61,6 +61,8 @@ TEST_IMPL(platform_output) {
ASSERT(rusage.ru_utime.tv_usec >= 0);
ASSERT(rusage.ru_stime.tv_sec >= 0);
ASSERT(rusage.ru_stime.tv_usec >= 0);
+ ASSERT(rusage.ru_majflt >= 0);
+ ASSERT(rusage.ru_maxrss >= 0);
printf("uv_getrusage:\n");
printf(" user: %llu sec %llu microsec\n",
(unsigned long long) rusage.ru_utime.tv_sec,
@@ -68,6 +70,9 @@ TEST_IMPL(platform_output) {
printf(" system: %llu sec %llu microsec\n",
(unsigned long long) rusage.ru_stime.tv_sec,
(unsigned long long) rusage.ru_stime.tv_usec);
+ printf(" page faults: %llu\n", (unsigned long long) rusage.ru_majflt);
+ printf(" maximum resident set size: %llu\n",
+ (unsigned long long) rusage.ru_maxrss);
err = uv_cpu_info(&cpus, &count);
ASSERT(err == 0);
diff --git a/deps/uv/test/test-poll.c b/deps/uv/test/test-poll.c
index bfb75af133..f3cfe79777 100644
--- a/deps/uv/test/test-poll.c
+++ b/deps/uv/test/test-poll.c
@@ -72,8 +72,9 @@ static int closed_connections = 0;
static int valid_writable_wakeups = 0;
static int spurious_writable_wakeups = 0;
+#ifndef _AIX
static int disconnects = 0;
-
+#endif /* !_AIX */
static int got_eagain(void) {
#ifdef _WIN32
@@ -377,7 +378,7 @@ static void connection_poll_cb(uv_poll_t* handle, int status, int events) {
new_events &= ~UV_WRITABLE;
}
}
-
+#ifndef _AIX
if (events & UV_DISCONNECT) {
context->got_disconnect = 1;
++disconnects;
@@ -385,6 +386,9 @@ static void connection_poll_cb(uv_poll_t* handle, int status, int events) {
}
if (context->got_fin && context->sent_fin && context->got_disconnect) {
+#else /* _AIX */
+ if (context->got_fin && context->sent_fin) {
+#endif /* !_AIx */
/* Sent and received FIN. Close and destroy context. */
close_socket(context->sock);
destroy_connection_context(context);
@@ -552,8 +556,9 @@ static void start_poll_test(void) {
spurious_writable_wakeups > 20);
ASSERT(closed_connections == NUM_CLIENTS * 2);
+#ifndef _AIX
ASSERT(disconnects == NUM_CLIENTS * 2);
-
+#endif
MAKE_VALGRIND_HAPPY();
}
diff --git a/deps/uv/test/test-tcp-create-socket-early.c b/deps/uv/test/test-tcp-create-socket-early.c
index 65650adcc2..1a508e474a 100644
--- a/deps/uv/test/test-tcp-create-socket-early.c
+++ b/deps/uv/test/test-tcp-create-socket-early.c
@@ -139,6 +139,9 @@ TEST_IMPL(tcp_create_early_bad_bind) {
uv_os_fd_t fd;
int r;
+ if (!can_ipv6())
+ RETURN_SKIP("IPv6 not supported");
+
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
r = uv_tcp_init_ex(uv_default_loop(), &client, AF_INET6);
diff --git a/deps/uv/test/test-tcp-write-queue-order.c b/deps/uv/test/test-tcp-write-queue-order.c
index aa4d2acc24..8a98ab8366 100644
--- a/deps/uv/test/test-tcp-write-queue-order.c
+++ b/deps/uv/test/test-tcp-write-queue-order.c
@@ -107,6 +107,7 @@ static void start_server(void) {
TEST_IMPL(tcp_write_queue_order) {
uv_connect_t connect_req;
struct sockaddr_in addr;
+ int buffer_size = 16 * 1024;
start_server();
@@ -117,6 +118,7 @@ TEST_IMPL(tcp_write_queue_order) {
&client,
(struct sockaddr*) &addr,
connect_cb));
+ ASSERT(0 == uv_send_buffer_size((uv_handle_t*) &client, &buffer_size));
ASSERT(0 == uv_timer_init(uv_default_loop(), &timer));
ASSERT(0 == uv_timer_start(&timer, timer_cb, 100, 0));
diff --git a/deps/uv/test/test-tty.c b/deps/uv/test/test-tty.c
index 461d194135..55cc016752 100644
--- a/deps/uv/test/test-tty.c
+++ b/deps/uv/test/test-tty.c
@@ -146,6 +146,75 @@ TEST_IMPL(tty) {
}
+#ifdef _WIN32
+static void tty_raw_alloc(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
+ buf->base = malloc(size);
+ buf->len = size;
+}
+
+static void tty_raw_read(uv_stream_t* tty_in, ssize_t nread, const uv_buf_t* buf) {
+ if (nread > 0) {
+ ASSERT(nread == 1);
+ ASSERT(buf->base[0] == ' ');
+ uv_close((uv_handle_t*) tty_in, NULL);
+ } else {
+ ASSERT(nread == 0);
+ }
+}
+
+TEST_IMPL(tty_raw) {
+ int r;
+ int ttyin_fd;
+ uv_tty_t tty_in;
+ uv_loop_t* loop = uv_default_loop();
+ HANDLE handle;
+ INPUT_RECORD record;
+ DWORD written;
+
+ /* Make sure we have an FD that refers to a tty */
+ handle = CreateFileA("conin$",
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ ASSERT(handle != INVALID_HANDLE_VALUE);
+ ttyin_fd = _open_osfhandle((intptr_t) handle, 0);
+ ASSERT(ttyin_fd >= 0);
+ ASSERT(UV_TTY == uv_guess_handle(ttyin_fd));
+
+ r = uv_tty_init(uv_default_loop(), &tty_in, ttyin_fd, 1); /* Readable. */
+ ASSERT(r == 0);
+
+ r = uv_read_start((uv_stream_t*)&tty_in, tty_raw_alloc, tty_raw_read);
+ ASSERT(r == 0);
+
+ /* Give uv_tty_line_read_thread time to block on ReadConsoleW */
+ Sleep(100);
+
+ /* Turn on raw mode. */
+ r = uv_tty_set_mode(&tty_in, UV_TTY_MODE_RAW);
+ ASSERT(r == 0);
+
+ /* Write ' ' that should be read in raw mode */
+ record.EventType = KEY_EVENT;
+ record.Event.KeyEvent.bKeyDown = TRUE;
+ record.Event.KeyEvent.wRepeatCount = 1;
+ record.Event.KeyEvent.wVirtualKeyCode = VK_SPACE;
+ record.Event.KeyEvent.wVirtualScanCode = MapVirtualKeyW(VK_SPACE, MAPVK_VK_TO_VSC);
+ record.Event.KeyEvent.uChar.UnicodeChar = L' ';
+ record.Event.KeyEvent.dwControlKeyState = 0;
+ WriteConsoleInputW(handle, &record, 1, &written);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+#endif
+
+
TEST_IMPL(tty_file) {
#ifndef _WIN32
uv_loop_t loop;
diff --git a/deps/uv/test/test-udp-create-socket-early.c b/deps/uv/test/test-udp-create-socket-early.c
index 3d0152428b..3f30274047 100644
--- a/deps/uv/test/test-udp-create-socket-early.c
+++ b/deps/uv/test/test-udp-create-socket-early.c
@@ -79,6 +79,9 @@ TEST_IMPL(udp_create_early_bad_bind) {
uv_os_fd_t fd;
int r;
+ if (!can_ipv6())
+ RETURN_SKIP("IPv6 not supported");
+
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
r = uv_udp_init_ex(uv_default_loop(), &client, AF_INET6);
diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp
index 757540193d..2fdd59ac78 100644
--- a/deps/uv/uv.gyp
+++ b/deps/uv/uv.gyp
@@ -17,6 +17,7 @@
}],
],
'xcode_settings': {
+ 'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden
'WARNING_CFLAGS': [ '-Wall', '-Wextra', '-Wno-unused-parameter' ],
'OTHER_CFLAGS': [ '-g', '--std=gnu89', '-pedantic' ],
}
@@ -111,12 +112,14 @@
'-liphlpapi',
'-lpsapi',
'-lshell32',
+ '-luser32',
'-luserenv',
'-lws2_32'
],
},
}, { # Not Windows i.e. POSIX
'cflags': [
+ '-fvisibility=hidden',
'-g',
'--std=gnu89',
'-pedantic',
@@ -184,6 +187,7 @@
'src/unix/darwin.c',
'src/unix/fsevents.c',
'src/unix/darwin-proctitle.c',
+ 'src/unix/pthread-barrier.c'
],
'defines': [
'_DARWIN_USE_64_BIT_INODE=1',
@@ -214,7 +218,8 @@
'src/unix/linux-syscalls.c',
'src/unix/linux-syscalls.h',
'src/unix/pthread-fixes.c',
- 'src/unix/android-ifaddrs.c'
+ 'src/unix/android-ifaddrs.c',
+ 'src/unix/pthread-barrier.c'
],
'link_settings': {
'libraries': [ '-ldl' ],
diff --git a/deps/uv/vcbuild.bat b/deps/uv/vcbuild.bat
index 9a7ed4b8c5..91f45b7219 100644
--- a/deps/uv/vcbuild.bat
+++ b/deps/uv/vcbuild.bat
@@ -19,7 +19,7 @@ set nobuild=
set run=
set target_arch=ia32
set vs_toolset=x86
-set platform=WIN32
+set msbuild_platform=WIN32
set library=static_library
:next-arg
@@ -31,9 +31,9 @@ if /i "%1"=="bench" set run=run-benchmarks.exe&goto arg-ok
if /i "%1"=="clean" set target=Clean&goto arg-ok
if /i "%1"=="noprojgen" set noprojgen=1&goto arg-ok
if /i "%1"=="nobuild" set nobuild=1&goto arg-ok
-if /i "%1"=="x86" set target_arch=ia32&set platform=WIN32&set vs_toolset=x86&goto arg-ok
-if /i "%1"=="ia32" set target_arch=ia32&set platform=WIN32&set vs_toolset=x86&goto arg-ok
-if /i "%1"=="x64" set target_arch=x64&set platform=x64&set vs_toolset=x64&goto arg-ok
+if /i "%1"=="x86" set target_arch=ia32&set msbuild_platform=WIN32&set vs_toolset=x86&goto arg-ok
+if /i "%1"=="ia32" set target_arch=ia32&set msbuild_platform=WIN32&set vs_toolset=x86&goto arg-ok
+if /i "%1"=="x64" set target_arch=x64&set msbuild_platform=x64&set vs_toolset=x64&goto arg-ok
if /i "%1"=="shared" set library=shared_library&goto arg-ok
if /i "%1"=="static" set library=static_library&goto arg-ok
:arg-ok
@@ -132,7 +132,7 @@ goto run
@rem Build the sln with msbuild.
:msbuild-found
-msbuild uv.sln /t:%target% /p:Configuration=%config% /p:Platform="%platform%" /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo
+msbuild uv.sln /t:%target% /p:Configuration=%config% /p:Platform="%msbuild_platform%" /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo
if errorlevel 1 exit /b 1
:run