diff --git a/deps/uv/common.gypi b/deps/uv/common.gypi index a222c3240d..0a60249582 100644 --- a/deps/uv/common.gypi +++ b/deps/uv/common.gypi @@ -15,7 +15,7 @@ 'configurations': { 'Debug': { 'defines': [ 'DEBUG', '_DEBUG' ], - 'cflags': [ '-g', '-O0' ], + 'cflags': [ '-g', '-O0', '-fwrapv' ], 'msvs_settings': { 'VCCLCompilerTool': { 'target_conditions': [ diff --git a/deps/uv/include/uv-private/uv-unix.h b/deps/uv/include/uv-private/uv-unix.h index 42e39fcccf..8f1c5e5cbd 100644 --- a/deps/uv/include/uv-private/uv-unix.h +++ b/deps/uv/include/uv-private/uv-unix.h @@ -156,7 +156,8 @@ typedef struct { struct uv_timer_s* rbh_root; \ } timer_handles; \ uint64_t time; \ - void* signal_ctx; \ + int signal_pipefd[2]; \ + uv__io_t signal_io_watcher; \ uv_signal_t child_watcher; \ int emfile_fd; \ UV_PLATFORM_LOOP_FIELDS \ @@ -242,7 +243,7 @@ typedef struct { ngx_queue_t queue; #define UV_TIMER_PRIVATE_FIELDS \ - /* RB_ENTRY(uv_timer_s) node; */ \ + /* RB_ENTRY(uv_timer_s) tree_entry; */ \ struct { \ struct uv_timer_s* rbe_left; \ struct uv_timer_s* rbe_right; \ @@ -289,7 +290,16 @@ typedef struct { int mode; #define UV_SIGNAL_PRIVATE_FIELDS \ - ngx_queue_t queue; + /* RB_ENTRY(uv_signal_s) tree_entry; */ \ + struct { \ + struct uv_signal_s* rbe_left; \ + struct uv_signal_s* rbe_right; \ + struct uv_signal_s* rbe_parent; \ + int rbe_color; \ + } tree_entry; \ + /* Use two counters here so we don have to fiddle with atomics. */ \ + unsigned int caught_signals; \ + unsigned int dispatched_signals; #define UV_FS_EVENT_PRIVATE_FIELDS \ uv_fs_event_cb cb; \ diff --git a/deps/uv/src/unix/async.c b/deps/uv/src/unix/async.c index 63bedf56f4..4d3cd94f17 100644 --- a/deps/uv/src/unix/async.c +++ b/deps/uv/src/unix/async.c @@ -30,7 +30,6 @@ static int uv__async_init(uv_loop_t* loop); static void uv__async_io(uv_loop_t* loop, uv__io_t* handle, int events); -__attribute__((always_inline)) static int uv__async_make_pending(volatile sig_atomic_t* ptr) { /* Do a cheap read first. */ if (*ptr) diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c index 2237070896..d7ccb68b0c 100644 --- a/deps/uv/src/unix/core.c +++ b/deps/uv/src/unix/core.c @@ -65,6 +65,9 @@ static uv_loop_t* default_loop_ptr; void uv_close(uv_handle_t* handle, uv_close_cb close_cb) { + assert(!(handle->flags & (UV_CLOSING | UV_CLOSED))); + + handle->flags |= UV_CLOSING; handle->close_cb = close_cb; switch (handle->type) { @@ -121,15 +124,22 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) { break; case UV_SIGNAL: - uv__signal_close((uv_signal_t*)handle); - break; + uv__signal_close((uv_signal_t*) handle); + /* Signal handles may not be closed immediately. The signal code will */ + /* itself close uv__make_close_pending whenever appropriate. */ + return; default: assert(0); } - handle->flags |= UV_CLOSING; + uv__make_close_pending(handle); +} + +void uv__make_close_pending(uv_handle_t* handle) { + assert(handle->flags & UV_CLOSING); + assert(!(handle->flags & UV_CLOSED)); handle->next_closing = handle->loop->closing_handles; handle->loop->closing_handles = handle; } diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h index 5685e1a84d..93e99b8da2 100644 --- a/deps/uv/src/unix/internal.h +++ b/deps/uv/src/unix/internal.h @@ -101,7 +101,6 @@ enum { }; __attribute__((unused)) -__attribute__((always_inline)) static void uv__req_init(uv_loop_t* loop, uv_req_t* req, uv_req_type type) { req->type = type; uv__req_register(loop, req); @@ -116,6 +115,7 @@ int uv__cloexec(int fd, int set); int uv__socket(int domain, int type, int protocol); int uv__dup(int fd); int uv_async_stop(uv_async_t* handle); +void uv__make_close_pending(uv_handle_t* handle); void uv__io_init(uv__io_t* handle, uv__io_cb cb, int fd, int events); void uv__io_set(uv__io_t* handle, uv__io_cb cb, int fd, int events); @@ -157,7 +157,8 @@ unsigned int uv__next_timeout(uv_loop_t* loop); /* signal */ void uv__signal_close(uv_signal_t* handle); -void uv__signal_unregister(uv_loop_t* loop); +void uv__signal_global_once_init(void); +void uv__signal_loop_cleanup(); /* thread pool */ void uv__work_submit(uv_loop_t* loop, diff --git a/deps/uv/src/unix/loop.c b/deps/uv/src/unix/loop.c index 7d41c005af..c70513f3a9 100644 --- a/deps/uv/src/unix/loop.c +++ b/deps/uv/src/unix/loop.c @@ -31,6 +31,8 @@ int uv__loop_init(uv_loop_t* loop, int default_loop) { unsigned int i; int flags; + uv__signal_global_once_init(); + #if HAVE_KQUEUE flags = EVBACKEND_KQUEUE; #else @@ -47,10 +49,11 @@ int uv__loop_init(uv_loop_t* loop, int default_loop) { ngx_queue_init(&loop->prepare_handles); ngx_queue_init(&loop->handle_queue); loop->closing_handles = NULL; - loop->signal_ctx = NULL; loop->time = uv_hrtime() / 1000000; loop->async_pipefd[0] = -1; loop->async_pipefd[1] = -1; + loop->signal_pipefd[0] = -1; + loop->signal_pipefd[1] = -1; loop->emfile_fd = -1; loop->ev = (default_loop ? ev_default_loop : ev_loop_new)(flags); ev_set_userdata(loop->ev, loop); @@ -79,8 +82,8 @@ int uv__loop_init(uv_loop_t* loop, int default_loop) { void uv__loop_delete(uv_loop_t* loop) { + uv__signal_loop_cleanup(loop); uv__platform_loop_delete(loop); - uv__signal_unregister(loop); ev_loop_destroy(loop->ev); if (loop->async_pipefd[0] != -1) { diff --git a/deps/uv/src/unix/signal.c b/deps/uv/src/unix/signal.c index 8ef640b6fa..45555b52b7 100644 --- a/deps/uv/src/unix/signal.c +++ b/deps/uv/src/unix/signal.c @@ -22,248 +22,432 @@ #include "internal.h" #include +#include +#include #include #include -#include #include -#include -struct signal_ctx { - int pipefd[2]; - uv__io_t io_watcher; - unsigned int nqueues; - ngx_queue_t queues[1]; /* variable length */ -}; -static void uv__signal_handler(int signum); -static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, int events); -static struct signal_ctx* uv__signal_ctx_new(uv_loop_t* loop); -static void uv__signal_ctx_delete(struct signal_ctx* ctx); -static void uv__signal_write(int fd, unsigned int val); -static unsigned int uv__signal_read(int fd); -static unsigned int uv__signal_max(void); +typedef struct { + uv_signal_t* handle; + int signum; +} uv__signal_msg_t; +RB_HEAD(uv__signal_tree_s, uv_signal_s); -int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) { - uv__handle_init(loop, (uv_handle_t*)handle, UV_SIGNAL); - handle->signum = 0; - return 0; + +static int uv__signal_unlock(); +static void uv__signal_event(uv_loop_t* loop, uv__io_t* watcher, int events); +static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2); +static void uv__signal_stop(uv_signal_t* handle); + + +static pthread_once_t uv__signal_global_init_guard = PTHREAD_ONCE_INIT; +static struct uv__signal_tree_s uv__signal_tree = + RB_INITIALIZER(uv__signal_tree); +static int uv__signal_lock_pipefd[2]; + + +RB_GENERATE_STATIC(uv__signal_tree_s, + uv_signal_s, tree_entry, + uv__signal_compare) + + +static void uv__signal_global_init() { + if (uv__make_pipe(uv__signal_lock_pipefd, 0)) + abort(); + + if (uv__signal_unlock()) + abort(); } -int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum_) { - struct signal_ctx* ctx; - struct sigaction sa; - unsigned int signum; - uv_loop_t* loop; - ngx_queue_t* q; +void uv__signal_global_once_init(void) { + pthread_once(&uv__signal_global_init_guard, uv__signal_global_init); +} - /* XXX doing this check in uv_signal_init() - the logical place for it - - * leads to an infinite loop when uv__loop_init() inits a signal watcher - */ - /* FIXME */ - assert(handle->loop == uv_default_loop() && - "uv_signal_t is currently only supported by the default loop"); - loop = handle->loop; - signum = signum_; - if (uv__is_active(handle)) - return uv__set_artificial_error(loop, UV_EBUSY); +static int uv__signal_lock() { + int r; + char data; + + do { + r = read(uv__signal_lock_pipefd[0], &data, sizeof data); + } while (r < 0 && errno == EINTR); + + return (r < 0) ? -1 : 0; +} + - if (signal_cb == NULL) - return uv__set_artificial_error(loop, UV_EINVAL); +static int uv__signal_unlock() { + int r; + char data = 42; - if (signum <= 0) - return uv__set_artificial_error(loop, UV_EINVAL); + do { + r = write(uv__signal_lock_pipefd[1], &data, sizeof data); + } while (r < 0 && errno == EINTR); + + return (r < 0) ? -1 : 0; +} - ctx = loop->signal_ctx; - if (ctx == NULL) { - ctx = uv__signal_ctx_new(loop); +static void uv__signal_block_and_lock(sigset_t* saved_sigmask) { + sigset_t new_mask; - if (ctx == NULL) - return uv__set_artificial_error(loop, UV_ENOMEM); + if (sigfillset(&new_mask)) + abort(); + + if (pthread_sigmask(SIG_SETMASK, &new_mask, saved_sigmask)) + abort(); + + if (uv__signal_lock()) + abort(); +} - loop->signal_ctx = ctx; + +static void uv__signal_unlock_and_unblock(sigset_t* saved_sigmask) { + if (uv__signal_unlock()) + abort(); + + if (pthread_sigmask(SIG_SETMASK, saved_sigmask, NULL)) + abort(); +} + + +inline static uv_signal_t* uv__signal_first_handle(int signum) { + /* This function must be called with the signal lock held. */ + uv_signal_t lookup; + uv_signal_t* handle; + + lookup.signum = signum; + lookup.loop = NULL; + + handle = RB_NFIND(uv__signal_tree_s, &uv__signal_tree, &lookup); + + if (handle != NULL && handle->signum == signum) + return handle; + + return NULL; +} + + +void uv__signal_handler(int signum) { + uv__signal_msg_t msg; + uv_signal_t* handle; + + memset(&msg, 0, sizeof msg); + + uv__signal_lock(); + + for (handle = uv__signal_first_handle(signum); + handle != NULL && handle->signum == signum; + handle = RB_NEXT(uv__signal_tree_s, &uv__signal_tree, handle)) { + int r; + + msg.signum = signum; + msg.handle = handle; + + /* write() should be atomic for small data chunks, so the entire message + * should be written at once. In theory the pipe could become full, in + * which case the user is out of luck. + */ + do { + r = write(handle->loop->signal_pipefd[1], &msg, sizeof msg); + } while (r == -1 && errno == EINTR); + + assert(r == sizeof msg || + (r == -1 && errno != EAGAIN && errno != EWOULDBLOCK)); + + if (r != -1) + handle->caught_signals++; } - if (signum > ctx->nqueues) - return uv__set_artificial_error(loop, UV_EINVAL); + uv__signal_unlock(); +} - q = ctx->queues + signum; - if (!ngx_queue_empty(q)) - goto skip; +static uv_err_t uv__signal_register_handler(int signum) { + /* When this function is called, the signal lock must be held. */ + struct sigaction sa; /* XXX use a separate signal stack? */ memset(&sa, 0, sizeof(sa)); + if (sigfillset(&sa.sa_mask)) + abort(); sa.sa_handler = uv__signal_handler; /* XXX save old action so we can restore it later on? */ if (sigaction(signum, &sa, NULL)) - return uv__set_artificial_error(loop, UV_EINVAL); + return uv__new_sys_error(errno); -skip: - ngx_queue_insert_tail(q, &handle->queue); - uv__handle_start(handle); - handle->signum = signum; - handle->signal_cb = signal_cb; - - return 0; + return uv_ok_; } -int uv_signal_stop(uv_signal_t* handle) { - struct signal_ctx* ctx; +static void uv__signal_unregister_handler(int signum) { + /* When this function is called, the signal lock must be held. */ struct sigaction sa; - unsigned int signum; - uv_loop_t* loop; + int r; - if (!uv__is_active(handle)) - return 0; + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_DFL; - signum = handle->signum; - loop = handle->loop; - ctx = loop->signal_ctx; - assert(signum > 0); - assert(signum <= ctx->nqueues); + r = sigaction(signum, &sa, NULL); + /* sigaction can only fail with EINVAL or EFAULT; an attempt to deregister a + * signal implies that it was successfully registered earlier, so EINVAL + * should never happen. + */ + assert(r == 0); +} - ngx_queue_remove(&handle->queue); - uv__handle_stop(handle); - handle->signum = 0; - if (!ngx_queue_empty(ctx->queues + signum)) - goto skip; +static int uv__signal_loop_once_init(uv_loop_t* loop) { + /* Return if already initialized. */ + if (loop->signal_pipefd[0] != -1) + return 0; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; /* XXX restore previous action? */ + if (uv__make_pipe(loop->signal_pipefd, UV__F_NONBLOCK)) + return -1; - if (sigaction(signum, &sa, NULL)) - return uv__set_artificial_error(loop, UV_EINVAL); + uv__io_init(&loop->signal_io_watcher, + uv__signal_event, + loop->signal_pipefd[0], + UV__IO_READ); + uv__io_start(loop, &loop->signal_io_watcher); -skip: return 0; } -void uv__signal_close(uv_signal_t* handle) { - uv_signal_stop(handle); -} +void uv__signal_loop_cleanup(uv_loop_t* loop) { + ngx_queue_t* q; + /* Stop all the signal watchers that are still attached to this loop. This + * ensures that the (shared) signal tree doesn't contain any invalid entries + * entries, and that signal handlers are removed when appropriate. + */ + ngx_queue_foreach(q, &loop->handle_queue) { + uv_handle_t* handle = ngx_queue_data(q, uv_handle_t, handle_queue); -void uv__signal_unregister(uv_loop_t* loop) { - uv__signal_ctx_delete(loop->signal_ctx); - loop->signal_ctx = NULL; + if (handle->type == UV_SIGNAL) + uv__signal_stop((uv_signal_t*) handle); + } + + if (loop->signal_pipefd[0] != -1) { + close(loop->signal_pipefd[0]); + loop->signal_pipefd[0] = -1; + } + + if (loop->signal_pipefd[1] != -1) { + close(loop->signal_pipefd[1]); + loop->signal_pipefd[1] = -1; + } } -static void uv__signal_handler(int signum) { - struct signal_ctx* ctx = uv_default_loop()->signal_ctx; - uv__signal_write(ctx->pipefd[1], (unsigned int) signum); +int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) { + if (uv__signal_loop_once_init(loop)) + return uv__set_sys_error(loop, errno); + + uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL); + handle->signum = 0; + handle->caught_signals = 0; + handle->dispatched_signals = 0; + + return 0; } -static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, int events) { - struct signal_ctx* ctx; - unsigned int signum; - uv_signal_t* h; - ngx_queue_t* q; +void uv__signal_close(uv_signal_t* handle) { - ctx = container_of(w, struct signal_ctx, io_watcher); - signum = uv__signal_read(ctx->pipefd[0]); - assert(signum > 0); - assert(signum <= ctx->nqueues); + uv__signal_stop(handle); - ngx_queue_foreach(q, ctx->queues + signum) { - h = ngx_queue_data(q, uv_signal_t, queue); - h->signal_cb(h, signum); + /* If there are any caught signals "trapped" in the signal pipe, we can't + * call the close callback yet. Otherwise, add the handle to the finish_close + * queue. + */ + if (handle->caught_signals == handle->dispatched_signals) { + uv__make_close_pending((uv_handle_t*) handle); } } -static struct signal_ctx* uv__signal_ctx_new(uv_loop_t* loop) { - struct signal_ctx* ctx; - unsigned int nqueues; - unsigned int i; +int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { + sigset_t saved_sigmask; + + assert(!(handle->flags & (UV_CLOSING | UV_CLOSED))); - nqueues = uv__signal_max(); - assert(nqueues > 0); + /* If the user supplies signum == 0, then return an error already. If the + * signum is otherwise invalid then uv__signal_register will find out + * eventually. + */ + if (signum == 0) { + uv__set_artificial_error(handle->loop, UV_EINVAL); + return -1; + } - /* The first ctx->queues entry is never used. It wastes a few bytes of memory - * but it saves us from having to substract 1 from the signum all the time - - * which inevitably someone will forget to do. + /* Short circuit: if the signal watcher is already watching {signum} don't + * go through the process of deregistering and registering the handler. + * Additionally, this avoids pending signals getting lost in the small time + * time frame that handle->signum == 0. */ - ctx = calloc(1, sizeof(*ctx) + sizeof(ctx->queues[0]) * (nqueues + 1)); - if (ctx == NULL) - return NULL; + if (signum == handle->signum) { + handle->signal_cb = signal_cb; + return 0; + } + + /* If the signal handler was already active, stop it first. */ + if (handle->signum != 0) { + uv__signal_stop(handle); + } + + uv__signal_block_and_lock(&saved_sigmask); - if (uv__make_pipe(ctx->pipefd, UV__F_NONBLOCK)) { - free(ctx); - return NULL; + /* If at this point there are no active signal watchers for this signum (in + * any of the loops), it's time to try and register a handler for it here. + */ + if (uv__signal_first_handle(signum) == NULL) { + uv_err_t err = uv__signal_register_handler(signum); + if (err.code != UV_OK) { + /* Registering the signal handler failed. Must be an invalid signal. */ + handle->loop->last_err = err; + uv__signal_unlock_and_unblock(&saved_sigmask); + return -1; + } } - uv__io_init(&ctx->io_watcher, uv__signal_event, ctx->pipefd[0], UV__IO_READ); - uv__io_start(loop, &ctx->io_watcher); - ctx->nqueues = nqueues; + handle->signum = signum; + RB_INSERT(uv__signal_tree_s, &uv__signal_tree, handle); - for (i = 1; i <= nqueues; i++) - ngx_queue_init(ctx->queues + i); + uv__signal_unlock_and_unblock(&saved_sigmask); - return ctx; + handle->signal_cb = signal_cb; + uv__handle_start(handle); + + return 0; } -static void uv__signal_ctx_delete(struct signal_ctx* ctx) { - if (ctx == NULL) return; - close(ctx->pipefd[0]); - close(ctx->pipefd[1]); - free(ctx); +static void uv__signal_event(uv_loop_t* loop, uv__io_t* watcher, int events) { + uv__signal_msg_t* msg; + uv_signal_t* handle; + char buf[sizeof(uv__signal_msg_t) * 32]; + size_t bytes, end, i; + int r; + + bytes = 0; + + do { + r = read(loop->signal_pipefd[0], buf + bytes, sizeof(buf) - bytes); + + if (r == -1 && errno == EINTR) + continue; + + if (r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) { + /* If there are bytes in the buffer already (which really is extremely + * unlikely if possible at all) we can't exit the function here. We'll + * spin until more bytes are read instead. + */ + if (bytes > 0) + continue; + + /* Otherwise, there was nothing there. */ + return; + } + + /* Other errors really should never happen. */ + if (r == -1) + abort(); + + bytes += r; + + /* `end` is rounded down to a multiple of sizeof(uv__signal_msg_t). */ + end = (bytes / sizeof(uv__signal_msg_t)) * sizeof(uv__signal_msg_t); + + for (i = 0; i < end; i += sizeof(uv__signal_msg_t)) { + msg = (uv__signal_msg_t*) (buf + i); + handle = msg->handle; + + if (msg->signum == handle->signum) { + assert(!(handle->flags & UV_CLOSING)); + handle->signal_cb(handle, handle->signum); + } + + handle->dispatched_signals++; + + /* If uv_close was called while there were caught signals that were not + * yet dispatched, the uv__finish_close was deferred. Make close pending + * now if this has happened. + */ + if ((handle->flags & UV_CLOSING) && + (handle->caught_signals == handle->dispatched_signals)) { + uv__make_close_pending((uv_handle_t*) handle); + } + } + + bytes -= end; + + /* If there are any "partial" messages left, move them to the start of the + * the buffer, and spin. This should not happen. + */ + if (bytes) { + memmove(buf, buf + end, bytes); + continue; + } + } while (end == sizeof buf); } -static void uv__signal_write(int fd, unsigned int val) { - ssize_t n; +static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) { + /* Compare signums first so all watchers with the same signnum end up + * adjacent. + */ + if (w1->signum < w2->signum) return -1; + if (w1->signum > w2->signum) return 1; - do - n = write(fd, &val, sizeof(val)); - while (n == -1 && errno == EINTR); + /* Sort by loop pointer, so we can easily look up the first item after + * { .signum = x, .loop = NULL }. + */ + if (w1->loop < w2->loop) return -1; + if (w1->loop > w2->loop) return 1; - if (n == sizeof(val)) - return; + if (w1 < w2) return -1; + if (w1 > w2) return 1; - if (n == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) - return; /* pipe full - nothing we can do about that */ + return 0; +} - abort(); + +int uv_signal_stop(uv_signal_t* handle) { + assert(!(handle->flags & (UV_CLOSING | UV_CLOSED))); + uv__signal_stop(handle); + return 0; } -static unsigned int uv__signal_read(int fd) { - unsigned int val; - ssize_t n; +static void uv__signal_stop(uv_signal_t* handle) { + uv_signal_t* removed_handle; + sigset_t saved_sigmask; - do - n = read(fd, &val, sizeof(val)); - while (n == -1 && errno == EINTR); + /* If the watcher wasn't started, this is a no-op. */ + if (handle->signum == 0) + return; - if (n == sizeof(val)) - return val; + uv__signal_block_and_lock(&saved_sigmask); - abort(); -} + removed_handle = RB_REMOVE(uv__signal_tree_s, &uv__signal_tree, handle); + assert(removed_handle == handle); + + /* Check if there are other active signal watchers observing this signal. If + * not, unregister the signal handler. + */ + if (uv__signal_first_handle(handle->signum) == NULL) + uv__signal_unregister_handler(handle->signum); + uv__signal_unlock_and_unblock(&saved_sigmask); -static unsigned int uv__signal_max(void) { -#if defined(_SC_RTSIG_MAX) - int max = sysconf(_SC_RTSIG_MAX); - if (max != -1) return max; -#endif -#if defined(SIGRTMAX) - return SIGRTMAX; -#elif defined(NSIG) - return NSIG; -#else - return 32; -#endif + handle->signum = 0; + uv__handle_stop(handle); } diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c index 9b920c817a..4a2d93624d 100644 --- a/deps/uv/src/win/fs.c +++ b/deps/uv/src/win/fs.c @@ -1137,12 +1137,9 @@ static void fs__utime(uv_fs_t* req) { if (fs__utime_handle(handle, req->atime, req->mtime) != 0) { SET_REQ_WIN32_ERROR(req, GetLastError()); - CloseHandle(handle); return; } - CloseHandle(handle); - req->result = 0; } diff --git a/deps/uv/test/benchmark-async-pummel.c b/deps/uv/test/benchmark-async-pummel.c index f6ce45efc5..c83821322e 100644 --- a/deps/uv/test/benchmark-async-pummel.c +++ b/deps/uv/test/benchmark-async-pummel.c @@ -73,6 +73,8 @@ static int test_async_pummel(int nthreads) { fmt(callbacks / (time / 1e9))); free(tids); + + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/benchmark-async.c b/deps/uv/test/benchmark-async.c index 2bf3040875..649b1c5b01 100644 --- a/deps/uv/test/benchmark-async.c +++ b/deps/uv/test/benchmark-async.c @@ -113,6 +113,7 @@ static int test_async(int nthreads) { free(threads); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/benchmark-fs-stat.c b/deps/uv/test/benchmark-fs-stat.c index ea5b597536..4404ab4c9e 100644 --- a/deps/uv/test/benchmark-fs-stat.c +++ b/deps/uv/test/benchmark-fs-stat.c @@ -131,5 +131,6 @@ BENCHMARK_IMPL(fs_stat) { warmup(path); sync_bench(path); async_bench(path); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/benchmark-getaddrinfo.c b/deps/uv/test/benchmark-getaddrinfo.c index 892c14d1e9..07dfa87a0d 100644 --- a/deps/uv/test/benchmark-getaddrinfo.c +++ b/deps/uv/test/benchmark-getaddrinfo.c @@ -90,5 +90,6 @@ BENCHMARK_IMPL(getaddrinfo) { LOGF("getaddrinfo: %.0f req/s\n", (double) calls_completed / (double) (end_time - start_time) * 1000.0); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/benchmark-loop-count.c b/deps/uv/test/benchmark-loop-count.c index a58181a2c5..ac3d16ad81 100644 --- a/deps/uv/test/benchmark-loop-count.c +++ b/deps/uv/test/benchmark-loop-count.c @@ -67,6 +67,7 @@ BENCHMARK_IMPL(loop_count) { ns / 1e9, NUM_TICKS / (ns / 1e9)); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -84,5 +85,6 @@ BENCHMARK_IMPL(loop_count_timed) { LOGF("loop_count: %lu ticks (%.0f ticks/s)\n", ticks, ticks / 5.0); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/benchmark-million-timers.c b/deps/uv/test/benchmark-million-timers.c index ae56b2bc6c..3f3fab783c 100644 --- a/deps/uv/test/benchmark-million-timers.c +++ b/deps/uv/test/benchmark-million-timers.c @@ -61,5 +61,6 @@ BENCHMARK_IMPL(million_timers) { LOGF("%.2f seconds\n", (after - before) / 1e9); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/benchmark-multi-accept.c b/deps/uv/test/benchmark-multi-accept.c index 3b2c16c3aa..a7847502a4 100644 --- a/deps/uv/test/benchmark-multi-accept.c +++ b/deps/uv/test/benchmark-multi-accept.c @@ -416,6 +416,7 @@ static int test_tcp(unsigned int num_servers, unsigned int num_clients) { free(clients); free(servers); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/benchmark-ping-pongs.c b/deps/uv/test/benchmark-ping-pongs.c index d42e70630d..4196b42ff9 100644 --- a/deps/uv/test/benchmark-ping-pongs.c +++ b/deps/uv/test/benchmark-ping-pongs.c @@ -209,5 +209,6 @@ BENCHMARK_IMPL(ping_pongs) { ASSERT(completed_pingers == 1); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/benchmark-pound.c b/deps/uv/test/benchmark-pound.c index 5c29a05b31..51f2ca2f61 100644 --- a/deps/uv/test/benchmark-pound.c +++ b/deps/uv/test/benchmark-pound.c @@ -300,6 +300,7 @@ static int pound_it(int concurrency, closed_streams / secs, conns_failed); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/benchmark-pump.c b/deps/uv/test/benchmark-pump.c index 52f295727c..613b0abc81 100644 --- a/deps/uv/test/benchmark-pump.c +++ b/deps/uv/test/benchmark-pump.c @@ -404,6 +404,7 @@ HELPER_IMPL(pipe_pump_server) { uv_run(loop); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -421,6 +422,8 @@ void tcp_pump(int n) { maybe_connect_some(); uv_run(loop); + + MAKE_VALGRIND_HAPPY(); } @@ -435,6 +438,8 @@ void pipe_pump(int n) { maybe_connect_some(); uv_run(loop); + + MAKE_VALGRIND_HAPPY(); } diff --git a/deps/uv/test/benchmark-spawn.c b/deps/uv/test/benchmark-spawn.c index 74cc3d238f..ccd250792f 100644 --- a/deps/uv/test/benchmark-spawn.c +++ b/deps/uv/test/benchmark-spawn.c @@ -158,5 +158,6 @@ BENCHMARK_IMPL(spawn) { LOGF("spawn: %.0f spawns/s\n", (double) N / (double) (end_time - start_time) * 1000.0); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/benchmark-tcp-write-batch.c b/deps/uv/test/benchmark-tcp-write-batch.c index 0b15f44b0a..a0793d5764 100644 --- a/deps/uv/test/benchmark-tcp-write-batch.c +++ b/deps/uv/test/benchmark-tcp-write-batch.c @@ -134,7 +134,8 @@ BENCHMARK_IMPL(tcp_write_batch) { printf("%ld write requests in %.2fs.\n", (long)NUM_WRITE_REQS, - (stop - start) / 10e8); + (stop - start) / 1e9); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/benchmark-udp-pummel.c b/deps/uv/test/benchmark-udp-pummel.c index 1a186c27ec..01f9a948dc 100644 --- a/deps/uv/test/benchmark-udp-pummel.c +++ b/deps/uv/test/benchmark-udp-pummel.c @@ -43,7 +43,8 @@ struct receiver_state { uv_udp_t udp_handle; }; -static unsigned int packet_counter = 1e6; /* not used in timed mode */ +/* not used in timed mode */ +static unsigned int packet_counter = (unsigned int) 1e6; static int n_senders_; static int n_receivers_; @@ -190,7 +191,8 @@ static int do_packet_storm(int n_senders, duration = uv_hrtime(); ASSERT(0 == uv_run(loop)); duration = uv_hrtime() - duration; - duration = duration / 1e6; /* convert from nanoseconds to milliseconds */ + /* convert from nanoseconds to milliseconds */ + duration = duration / (uint64_t) 1e6; printf("udp_packet_storm_%dv%d: %.0f/s received, %.0f/s sent. " "%u received, %u sent in %.1f seconds.\n", @@ -202,6 +204,7 @@ static int do_packet_storm(int n_senders, send_cb_called, duration / 1000.0); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/runner-win.c b/deps/uv/test/runner-win.c index 791b0ce4f6..8f534bcdb7 100644 --- a/deps/uv/test/runner-win.c +++ b/deps/uv/test/runner-win.c @@ -24,9 +24,8 @@ #include #include #include -#include #if !defined(__MINGW32__) -#include +# include #endif diff --git a/deps/uv/test/runner.c b/deps/uv/test/runner.c index d7098123b0..5925ec7524 100644 --- a/deps/uv/test/runner.c +++ b/deps/uv/test/runner.c @@ -300,7 +300,6 @@ int run_test_part(const char* test, const char* part) { if (strcmp(test, task->task_name) == 0 && strcmp(part, task->process_name) == 0) { r = task->main(); - uv_loop_delete(uv_default_loop()); return r; } } diff --git a/deps/uv/test/task.h b/deps/uv/test/task.h index 34d28a1e79..e06ae6470c 100644 --- a/deps/uv/test/task.h +++ b/deps/uv/test/task.h @@ -91,6 +91,11 @@ typedef enum { } \ } while (0) +/* This macro cleans up the main loop. This is used to avoid valgrind + * warnings about memory being "leaked" by the main event loop. + */ +#define MAKE_VALGRIND_HAPPY() \ + uv_loop_delete(uv_default_loop()) /* Just sugar for wrapping the main() for a task or helper. */ #define TEST_IMPL(name) \ diff --git a/deps/uv/test/test-active.c b/deps/uv/test/test-active.c index 9af4fd669c..910d7608db 100644 --- a/deps/uv/test/test-active.c +++ b/deps/uv/test/test-active.c @@ -78,5 +78,6 @@ TEST_IMPL(active) { ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-async.c b/deps/uv/test/test-async.c index 9b2ce7bcf1..efcfe15a24 100644 --- a/deps/uv/test/test-async.c +++ b/deps/uv/test/test-async.c @@ -116,5 +116,6 @@ TEST_IMPL(async) { ASSERT(0 == uv_thread_join(&thread)); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-callback-order.c b/deps/uv/test/test-callback-order.c index a6c40cbdf8..ed280e6228 100644 --- a/deps/uv/test/test-callback-order.c +++ b/deps/uv/test/test-callback-order.c @@ -72,5 +72,6 @@ TEST_IMPL(callback_order) { ASSERT(idle_cb_called == 1); ASSERT(timer_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-callback-stack.c b/deps/uv/test/test-callback-stack.c index 4983b651c2..044a3e3506 100644 --- a/deps/uv/test/test-callback-stack.c +++ b/deps/uv/test/test-callback-stack.c @@ -199,5 +199,6 @@ TEST_IMPL(callback_stack) { ASSERT(shutdown_cb_called == 1 && "shutdown_cb must be called exactly once"); ASSERT(close_cb_called == 2 && "close_cb must be called exactly twice"); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-connection-fail.c b/deps/uv/test/test-connection-fail.c index 1c5a31d127..4219f4c606 100644 --- a/deps/uv/test/test-connection-fail.c +++ b/deps/uv/test/test-connection-fail.c @@ -124,6 +124,7 @@ TEST_IMPL(connection_fail) { ASSERT(timer_close_cb_calls == 0); ASSERT(timer_cb_calls == 0); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -144,5 +145,6 @@ TEST_IMPL(connection_fail_doesnt_auto_close) { ASSERT(timer_close_cb_calls == 1); ASSERT(timer_cb_calls == 1); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-delayed-accept.c b/deps/uv/test/test-delayed-accept.c index 672672a900..064fb6a697 100644 --- a/deps/uv/test/test-delayed-accept.c +++ b/deps/uv/test/test-delayed-accept.c @@ -184,5 +184,6 @@ TEST_IMPL(delayed_accept) { ASSERT(connect_cb_called == 2); ASSERT(close_cb_called == 7); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-fs-event.c b/deps/uv/test/test-fs-event.c index dd10915fb8..d741b399bb 100644 --- a/deps/uv/test/test-fs-event.c +++ b/deps/uv/test/test-fs-event.c @@ -201,6 +201,7 @@ TEST_IMPL(fs_event_watch_dir) { remove("watch_dir/file1"); remove("watch_dir/"); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -234,6 +235,7 @@ TEST_IMPL(fs_event_watch_file) { remove("watch_dir/file1"); remove("watch_dir/"); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -252,6 +254,7 @@ TEST_IMPL(fs_event_watch_file_twice) { ASSERT(0 == uv_timer_start(&timer, timer_cb_watch_twice, 10, 0)); ASSERT(0 == uv_run(loop)); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -289,6 +292,7 @@ TEST_IMPL(fs_event_watch_file_current_dir) { /* Cleanup */ remove("watch_file"); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -321,6 +325,7 @@ TEST_IMPL(fs_event_no_callback_on_close) { remove("watch_dir/file1"); remove("watch_dir/"); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -361,6 +366,7 @@ TEST_IMPL(fs_event_immediate_close) { ASSERT(close_cb_called == 2); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -390,6 +396,7 @@ TEST_IMPL(fs_event_close_with_pending_event) { remove("watch_dir/file"); remove("watch_dir/"); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -455,6 +462,7 @@ TEST_IMPL(fs_event_close_in_callback) { remove("watch_dir/file5"); remove("watch_dir/"); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-fs-poll.c b/deps/uv/test/test-fs-poll.c index 4380b561ef..a3dede64e3 100644 --- a/deps/uv/test/test-fs-poll.c +++ b/deps/uv/test/test-fs-poll.c @@ -141,5 +141,6 @@ TEST_IMPL(fs_poll) { ASSERT(timer_cb_called == 2); ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c index e59e5ed11d..597ef9713a 100644 --- a/deps/uv/test/test-fs.c +++ b/deps/uv/test/test-fs.c @@ -482,6 +482,7 @@ TEST_IMPL(fs_file_noent) { /* TODO add EACCES test */ + MAKE_VALGRIND_HAPPY(); return 0; } @@ -508,6 +509,7 @@ TEST_IMPL(fs_file_nametoolong) { uv_run(loop); ASSERT(open_cb_count == 1); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -536,6 +538,7 @@ TEST_IMPL(fs_file_loop) { unlink("test_symlink"); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -653,6 +656,7 @@ TEST_IMPL(fs_file_async) { unlink("test_file"); unlink("test_file2"); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -737,6 +741,7 @@ TEST_IMPL(fs_file_sync) { unlink("test_file"); unlink("test_file2"); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -828,6 +833,7 @@ TEST_IMPL(fs_async_dir) { unlink("test_dir/file2"); rmdir("test_dir"); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -891,6 +897,7 @@ TEST_IMPL(fs_async_sendfile) { unlink("test_file"); unlink("test_file2"); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -946,6 +953,7 @@ TEST_IMPL(fs_fstat) { /* Cleanup. */ unlink("test_file"); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -1042,6 +1050,7 @@ TEST_IMPL(fs_chmod) { /* Cleanup. */ unlink("test_file"); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -1104,6 +1113,7 @@ TEST_IMPL(fs_chown) { /* Cleanup. */ unlink("test_file"); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -1186,6 +1196,7 @@ TEST_IMPL(fs_link) { unlink("test_file_link"); unlink("test_file_link2"); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -1208,6 +1219,7 @@ TEST_IMPL(fs_readlink) { ASSERT(req.errorno == UV_ENOENT); uv_fs_req_cleanup(&req); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -1329,6 +1341,7 @@ TEST_IMPL(fs_symlink) { unlink("test_file_symlink2"); unlink("test_file_symlink2_symlink"); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -1440,6 +1453,7 @@ TEST_IMPL(fs_symlink_dir) { rmdir("test_dir"); rmdir("test_dir_symlink"); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -1490,6 +1504,7 @@ TEST_IMPL(fs_utime) { /* Cleanup. */ unlink(path); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -1521,6 +1536,7 @@ TEST_IMPL(fs_stat_root) { r = uv_fs_stat(loop, &stat_req, "\\\\?\\C:\\", NULL); ASSERT(r == 0); + MAKE_VALGRIND_HAPPY(); return 0; } #endif @@ -1580,6 +1596,7 @@ TEST_IMPL(fs_futime) { /* Cleanup. */ unlink(path); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -1596,6 +1613,7 @@ TEST_IMPL(fs_stat_missing_path) { ASSERT(uv_last_error(loop).code == UV_ENOENT); uv_fs_req_cleanup(&req); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -1627,6 +1645,7 @@ TEST_IMPL(fs_readdir_empty_dir) { uv_fs_rmdir(loop, &req, path, NULL); uv_fs_req_cleanup(&req); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -1650,6 +1669,7 @@ TEST_IMPL(fs_readdir_file) { uv_run(loop); ASSERT(readdir_cb_count == 1); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -1679,6 +1699,7 @@ TEST_IMPL(fs_open_dir) { uv_run(loop); ASSERT(open_cb_count == 1); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -1747,6 +1768,7 @@ TEST_IMPL(fs_file_open_append) { /* Cleanup */ unlink("test_file"); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -1815,6 +1837,7 @@ TEST_IMPL(fs_rename_to_existing_file) { unlink("test_file"); unlink("test_file2"); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -1871,5 +1894,6 @@ TEST_IMPL(fs_read_file_eof) { /* Cleanup */ unlink("test_file"); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-getaddrinfo.c b/deps/uv/test/test-getaddrinfo.c index 2a8c94e755..b88d4b315f 100644 --- a/deps/uv/test/test-getaddrinfo.c +++ b/deps/uv/test/test-getaddrinfo.c @@ -88,6 +88,7 @@ TEST_IMPL(getaddrinfo_basic) { ASSERT(getaddrinfo_cbs == 1); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -118,5 +119,6 @@ TEST_IMPL(getaddrinfo_concurrent) { ASSERT(callback_counts[i] == 1); } + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-getsockname.c b/deps/uv/test/test-getsockname.c index 2bfb71ad56..a6f8a8126c 100644 --- a/deps/uv/test/test-getsockname.c +++ b/deps/uv/test/test-getsockname.c @@ -322,6 +322,7 @@ TEST_IMPL(getsockname_tcp) { ASSERT(getsocknamecount == 3); ASSERT(getpeernamecount == 3); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -338,5 +339,6 @@ TEST_IMPL(getsockname_udp) { ASSERT(getsocknamecount == 2); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-idle.c b/deps/uv/test/test-idle.c index 95ef3a9495..0a6e0dcc73 100644 --- a/deps/uv/test/test-idle.c +++ b/deps/uv/test/test-idle.c @@ -77,5 +77,6 @@ TEST_IMPL(idle_starvation) { ASSERT(timer_cb_called == 1); ASSERT(close_cb_called == 2); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-ipc-send-recv.c b/deps/uv/test/test-ipc-send-recv.c index 970bf1effe..799e4f5e36 100644 --- a/deps/uv/test/test-ipc-send-recv.c +++ b/deps/uv/test/test-ipc-send-recv.c @@ -123,7 +123,11 @@ TEST_IMPL(ipc_send_recv_pipe) { r = uv_pipe_bind(&ctx.send.pipe, TEST_PIPENAME); ASSERT(r == 0); - return run_test(); + r = run_test(); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; } @@ -138,7 +142,11 @@ TEST_IMPL(ipc_send_recv_tcp) { r = uv_tcp_bind(&ctx.send.tcp, uv_ip4_addr("127.0.0.1", TEST_PORT)); ASSERT(r == 0); - return run_test(); + r = run_test(); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; } @@ -205,5 +213,6 @@ int ipc_send_recv_helper(void) { r = uv_run(uv_default_loop()); ASSERT(r == 0); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-ipc.c b/deps/uv/test/test-ipc.c index 61add0b4b8..c37d15183e 100644 --- a/deps/uv/test/test-ipc.c +++ b/deps/uv/test/test-ipc.c @@ -321,6 +321,7 @@ static int run_ipc_test(const char* helper, uv_read2_cb read_cb) { r = uv_run(uv_default_loop()); ASSERT(r == 0); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -374,6 +375,7 @@ TEST_IMPL(listen_with_simultaneous_accepts) { ASSERT(r == 0); ASSERT(server.reqs_pending == 32); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -396,6 +398,7 @@ TEST_IMPL(listen_no_simultaneous_accepts) { ASSERT(r == 0); ASSERT(server.reqs_pending == 1); + MAKE_VALGRIND_HAPPY(); return 0; } #endif @@ -570,6 +573,7 @@ int ipc_helper(int listen_after_write) { ASSERT(connection_accepted == 1); ASSERT(close_cb_called == 3); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -616,5 +620,6 @@ int ipc_helper_tcp_connection() { ASSERT(tcp_conn_write_cb_called == 1); ASSERT(close_cb_called == 4); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index 28a13b2e23..fa05ca931e 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -192,8 +192,6 @@ TEST_DECLARE (dlerror) TEST_DECLARE (poll_duplex) TEST_DECLARE (poll_unidirectional) TEST_DECLARE (poll_close) -TEST_DECLARE (we_get_signal) -TEST_DECLARE (we_get_signals) #ifdef _WIN32 TEST_DECLARE (spawn_detect_pipe_name_collisions_on_windows) TEST_DECLARE (argument_escaping) @@ -203,6 +201,9 @@ TEST_DECLARE (listen_no_simultaneous_accepts) TEST_DECLARE (fs_stat_root) #else TEST_DECLARE (spawn_setuid_setgid) +TEST_DECLARE (we_get_signal) +TEST_DECLARE (we_get_signals) +TEST_DECLARE (signal_multiple_loops) #endif HELPER_DECLARE (tcp4_echo_server) HELPER_DECLARE (tcp6_echo_server) @@ -398,9 +399,6 @@ TASK_LIST_START TEST_ENTRY (fs_poll) TEST_ENTRY (kill) - TEST_ENTRY (we_get_signal) - TEST_ENTRY (we_get_signals) - #ifdef _WIN32 TEST_ENTRY (spawn_detect_pipe_name_collisions_on_windows) TEST_ENTRY (argument_escaping) @@ -410,6 +408,9 @@ TASK_LIST_START TEST_ENTRY (fs_stat_root) #else TEST_ENTRY (spawn_setuid_setgid) + TEST_ENTRY (we_get_signal) + TEST_ENTRY (we_get_signals) + TEST_ENTRY (signal_multiple_loops) #endif TEST_ENTRY (fs_file_noent) diff --git a/deps/uv/test/test-loop-handles.c b/deps/uv/test/test-loop-handles.c index 9972dfa1f3..f57efb08c6 100644 --- a/deps/uv/test/test-loop-handles.c +++ b/deps/uv/test/test-loop-handles.c @@ -332,5 +332,6 @@ TEST_IMPL(loop_handles) { ASSERT(idle_2_close_cb_called == idle_2_cb_started); ASSERT(idle_2_is_active == 0); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-multiple-listen.c b/deps/uv/test/test-multiple-listen.c index 0b5c887d69..18197d1826 100644 --- a/deps/uv/test/test-multiple-listen.c +++ b/deps/uv/test/test-multiple-listen.c @@ -98,5 +98,6 @@ TEST_IMPL(multiple_listen) { ASSERT(connect_cb_called == 1); ASSERT(close_cb_called == 2); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-ping-pong.c b/deps/uv/test/test-ping-pong.c index 92e40e550d..1b85fa8948 100644 --- a/deps/uv/test/test-ping-pong.c +++ b/deps/uv/test/test-ping-pong.c @@ -228,6 +228,7 @@ TEST_IMPL(tcp_ping_pong) { ASSERT(completed_pingers == 1); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -238,6 +239,7 @@ TEST_IMPL(tcp_ping_pong_v6) { ASSERT(completed_pingers == 1); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -248,5 +250,6 @@ TEST_IMPL(pipe_ping_pong) { ASSERT(completed_pingers == 1); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-pipe-bind-error.c b/deps/uv/test/test-pipe-bind-error.c index b84d20f1ea..2d45fb3ee9 100644 --- a/deps/uv/test/test-pipe-bind-error.c +++ b/deps/uv/test/test-pipe-bind-error.c @@ -71,6 +71,7 @@ TEST_IMPL(pipe_bind_error_addrinuse) { ASSERT(close_cb_called == 2); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -92,6 +93,7 @@ TEST_IMPL(pipe_bind_error_addrnotavail) { ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -115,6 +117,7 @@ TEST_IMPL(pipe_bind_error_inval) { ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -136,5 +139,6 @@ TEST_IMPL(pipe_listen_without_bind) { ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-pipe-connect-error.c b/deps/uv/test/test-pipe-connect-error.c index cc06d4293a..c70a3ef85d 100644 --- a/deps/uv/test/test-pipe-connect-error.c +++ b/deps/uv/test/test-pipe-connect-error.c @@ -73,6 +73,7 @@ TEST_IMPL(pipe_connect_bad_name) { ASSERT(close_cb_called == 1); ASSERT(connect_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -92,5 +93,6 @@ TEST_IMPL(pipe_connect_to_file) { ASSERT(close_cb_called == 1); ASSERT(connect_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-poll-close.c b/deps/uv/test/test-poll-close.c index 8389382740..9c80527b43 100644 --- a/deps/uv/test/test-poll-close.c +++ b/deps/uv/test/test-poll-close.c @@ -68,5 +68,6 @@ TEST_IMPL(poll_close) { ASSERT(close_cb_called == NUM_SOCKETS); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-poll.c b/deps/uv/test/test-poll.c index 5a20b9d521..b69f9f24c5 100644 --- a/deps/uv/test/test-poll.c +++ b/deps/uv/test/test-poll.c @@ -556,6 +556,8 @@ static void start_poll_test() { spurious_writable_wakeups > 20); ASSERT(closed_connections == NUM_CLIENTS * 2); + + MAKE_VALGRIND_HAPPY(); } diff --git a/deps/uv/test/test-ref.c b/deps/uv/test/test-ref.c index 95e92a86c4..484608acd8 100644 --- a/deps/uv/test/test-ref.c +++ b/deps/uv/test/test-ref.c @@ -96,6 +96,7 @@ static void connect_and_shutdown(uv_connect_t* req, int status) { TEST_IMPL(ref) { uv_run(uv_default_loop()); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -107,6 +108,7 @@ TEST_IMPL(idle_ref) { uv_unref((uv_handle_t*)&h); uv_run(uv_default_loop()); do_close(&h); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -117,6 +119,7 @@ TEST_IMPL(async_ref) { uv_unref((uv_handle_t*)&h); uv_run(uv_default_loop()); do_close(&h); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -128,6 +131,7 @@ TEST_IMPL(prepare_ref) { uv_unref((uv_handle_t*)&h); uv_run(uv_default_loop()); do_close(&h); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -139,6 +143,7 @@ TEST_IMPL(check_ref) { uv_unref((uv_handle_t*)&h); uv_run(uv_default_loop()); do_close(&h); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -156,6 +161,7 @@ TEST_IMPL(unref_in_prepare_cb) { uv_prepare_start(&h, prepare_cb); uv_run(uv_default_loop()); do_close(&h); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -166,6 +172,7 @@ TEST_IMPL(timer_ref) { uv_unref((uv_handle_t*)&h); uv_run(uv_default_loop()); do_close(&h); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -177,6 +184,7 @@ TEST_IMPL(timer_ref2) { uv_unref((uv_handle_t*)&h); uv_run(uv_default_loop()); do_close(&h); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -187,6 +195,7 @@ TEST_IMPL(fs_event_ref) { uv_unref((uv_handle_t*)&h); uv_run(uv_default_loop()); do_close(&h); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -198,6 +207,7 @@ TEST_IMPL(fs_poll_ref) { uv_unref((uv_handle_t*)&h); uv_run(uv_default_loop()); do_close(&h); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -208,6 +218,7 @@ TEST_IMPL(tcp_ref) { uv_unref((uv_handle_t*)&h); uv_run(uv_default_loop()); do_close(&h); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -219,6 +230,7 @@ TEST_IMPL(tcp_ref2) { uv_unref((uv_handle_t*)&h); uv_run(uv_default_loop()); do_close(&h); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -233,6 +245,7 @@ TEST_IMPL(tcp_ref3) { ASSERT(connect_cb_called == 1); ASSERT(shutdown_cb_called == 1); do_close(&h); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -248,6 +261,7 @@ TEST_IMPL(tcp_ref4) { ASSERT(write_cb_called == 1); ASSERT(shutdown_cb_called == 1); do_close(&h); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -258,6 +272,7 @@ TEST_IMPL(udp_ref) { uv_unref((uv_handle_t*)&h); uv_run(uv_default_loop()); do_close(&h); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -271,6 +286,7 @@ TEST_IMPL(udp_ref2) { uv_unref((uv_handle_t*)&h); uv_run(uv_default_loop()); do_close(&h); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -288,6 +304,7 @@ TEST_IMPL(udp_ref3) { ASSERT(req_cb_called == 1); do_close(&h); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -298,6 +315,7 @@ TEST_IMPL(pipe_ref) { uv_unref((uv_handle_t*)&h); uv_run(uv_default_loop()); do_close(&h); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -309,6 +327,7 @@ TEST_IMPL(pipe_ref2) { uv_unref((uv_handle_t*)&h); uv_run(uv_default_loop()); do_close(&h); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -322,6 +341,7 @@ TEST_IMPL(pipe_ref3) { ASSERT(connect_cb_called == 1); ASSERT(shutdown_cb_called == 1); do_close(&h); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -336,6 +356,7 @@ TEST_IMPL(pipe_ref4) { ASSERT(write_cb_called == 1); ASSERT(shutdown_cb_called == 1); do_close(&h); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -371,5 +392,6 @@ TEST_IMPL(process_ref) { do_close(&h); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-run-once.c b/deps/uv/test/test-run-once.c index f74e9f37a5..b425a42305 100644 --- a/deps/uv/test/test-run-once.c +++ b/deps/uv/test/test-run-once.c @@ -44,5 +44,6 @@ TEST_IMPL(run_once) { while (uv_run_once(uv_default_loop())); ASSERT(idle_counter == NUM_TICKS); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-shutdown-close.c b/deps/uv/test/test-shutdown-close.c index 6ce46b2454..6a372330c5 100644 --- a/deps/uv/test/test-shutdown-close.c +++ b/deps/uv/test/test-shutdown-close.c @@ -81,6 +81,7 @@ TEST_IMPL(shutdown_close_tcp) { ASSERT(shutdown_cb_called == 1); ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -99,5 +100,6 @@ TEST_IMPL(shutdown_close_pipe) { ASSERT(shutdown_cb_called == 1); ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-shutdown-eof.c b/deps/uv/test/test-shutdown-eof.c index 9d4f2cce74..22f6da53e9 100644 --- a/deps/uv/test/test-shutdown-eof.c +++ b/deps/uv/test/test-shutdown-eof.c @@ -178,6 +178,7 @@ TEST_IMPL(shutdown_eof) { ASSERT(called_timer_close_cb == 1); ASSERT(called_timer_cb == 1); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-signal-multiple-loops.c b/deps/uv/test/test-signal-multiple-loops.c new file mode 100644 index 0000000000..d0223d5632 --- /dev/null +++ b/deps/uv/test/test-signal-multiple-loops.c @@ -0,0 +1,270 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + + +/* This test does not pretend to be cross-platform. */ +#ifndef _WIN32 + +#include "uv.h" +#include "task.h" + +#include +#include +#include +#include +#include +#include +#include + + +#define NUM_SIGNAL_HANDLING_THREADS 25 +#define NUM_LOOP_CREATING_THREADS 10 + + +static uv_sem_t sem; +static uv_mutex_t counter_lock; +static volatile int stop = 0; + +static volatile int signal1_cb_counter = 0; +static volatile int signal2_cb_counter = 0; +static volatile int loop_creation_counter = 0; + + +static void increment_counter(volatile int* counter) { + uv_mutex_lock(&counter_lock); + ++(*counter); + uv_mutex_unlock(&counter_lock); +} + + +static void signal1_cb(uv_signal_t* handle, int signum) { + ASSERT(signum == SIGUSR1); + increment_counter(&signal1_cb_counter); + uv_signal_stop(handle); +} + + +static void signal2_cb(uv_signal_t* handle, int signum) { + ASSERT(signum == SIGUSR2); + increment_counter(&signal2_cb_counter); + uv_signal_stop(handle); +} + + +static void signal_handling_worker(void* context) { + uintptr_t mask = (uintptr_t) context; + uv_loop_t* loop; + uv_signal_t signal1a; + uv_signal_t signal1b; + uv_signal_t signal2; + int r; + + loop = uv_loop_new(); + ASSERT(loop != NULL); + + /* Setup the signal watchers and start them. */ + if (mask & SIGUSR1) { + r = uv_signal_init(loop, &signal1a); + ASSERT(r == 0); + r = uv_signal_start(&signal1a, signal1_cb, SIGUSR1); + ASSERT(r == 0); + r = uv_signal_init(loop, &signal1b); + ASSERT(r == 0); + r = uv_signal_start(&signal1b, signal1_cb, SIGUSR1); + ASSERT(r == 0); + } + if (mask & SIGUSR2) { + r = uv_signal_init(loop, &signal2); + ASSERT(r == 0); + r = uv_signal_start(&signal2, signal2_cb, SIGUSR2); + ASSERT(r == 0); + } + + /* Signal watchers are now set up. */ + uv_sem_post(&sem); + + /* Wait for all signals. The signal callbacks stop the watcher, so uv_run + * will return when all signal watchers caught a signal. + */ + r = uv_run(loop); + ASSERT(r == 0); + + /* Restart the signal watchers. */ + if (mask & SIGUSR1) { + r = uv_signal_start(&signal1a, signal1_cb, SIGUSR1); + ASSERT(r == 0); + r = uv_signal_start(&signal1b, signal1_cb, SIGUSR1); + ASSERT(r == 0); + } + if (mask & SIGUSR2) { + r = uv_signal_start(&signal2, signal2_cb, SIGUSR2); + ASSERT(r == 0); + } + + /* Wait for signals once more. */ + uv_sem_post(&sem); + + r = uv_run(loop); + ASSERT(r == 0); + + /* Close the watchers. */ + if (mask & SIGUSR1) { + uv_close((uv_handle_t*) &signal1a, NULL); + uv_close((uv_handle_t*) &signal1b, NULL); + } + if (mask & SIGUSR2) { + uv_close((uv_handle_t*) &signal2, NULL); + } + + /* Wait for the signal watchers to close. */ + r = uv_run(loop); + ASSERT(r == 0); + + uv_loop_delete(loop); +} + + +static void signal_unexpected_cb(uv_signal_t* handle, int signum) { + ASSERT(0 && "signal_unexpected_cb should never be called"); +} + + +static void loop_creating_worker(void* context) { + (void) context; + + do { + uv_loop_t* loop; + uv_signal_t signal; + int r; + + loop = uv_loop_new(); + ASSERT(loop != NULL); + + r = uv_signal_init(loop, &signal); + ASSERT(r == 0); + + r = uv_signal_start(&signal, signal_unexpected_cb, SIGTERM); + ASSERT(r == 0); + + uv_close((uv_handle_t*) &signal, NULL); + + r = uv_run(loop); + ASSERT(r == 0); + + uv_loop_delete(loop); + + increment_counter(&loop_creation_counter); + } while (!stop); +} + + +TEST_IMPL(signal_multiple_loops) { + int i, r; + uv_thread_t loop_creating_threads[NUM_LOOP_CREATING_THREADS]; + uv_thread_t signal_handling_threads[NUM_SIGNAL_HANDLING_THREADS]; + sigset_t sigset; + + r = uv_sem_init(&sem, 0); + ASSERT(r == 0); + + r = uv_mutex_init(&counter_lock); + ASSERT(r == 0); + + /* Create a couple of threads that create a destroy loops continuously. */ + for (i = 0; i < NUM_LOOP_CREATING_THREADS; i++) { + r = uv_thread_create(&loop_creating_threads[i], + loop_creating_worker, + NULL); + ASSERT(r == 0); + } + + /* Create a couple of threads that actually handle signals. */ + for (i = 0; i < NUM_SIGNAL_HANDLING_THREADS; i++) { + uintptr_t mask; + + switch (i % 3) { + case 0: mask = SIGUSR1; break; + case 1: mask = SIGUSR2; break; + case 2: mask = SIGUSR1 | SIGUSR2; break; + } + + r = uv_thread_create(&signal_handling_threads[i], + signal_handling_worker, + (void*) mask); + ASSERT(r == 0); + } + + /* Wait until all threads have started and set up their signal watchers. */ + for (i = 0; i < NUM_SIGNAL_HANDLING_THREADS; i++) + uv_sem_wait(&sem); + + r = kill(getpid(), SIGUSR1); + ASSERT(r == 0); + r = kill(getpid(), SIGUSR2); + ASSERT(r == 0); + + /* Wait for all threads to handle these signals. */ + for (i = 0; i < NUM_SIGNAL_HANDLING_THREADS; i++) + uv_sem_wait(&sem); + + /* Block all signals to this thread, so we are sure that from here the signal + * handler runs in another thread. This is is more likely to catch thread and + * signal safety issues if there are any. + */ + sigfillset(&sigset); + pthread_sigmask(SIG_SETMASK, &sigset, NULL); + + r = kill(getpid(), SIGUSR1); + ASSERT(r == 0); + r = kill(getpid(), SIGUSR2); + ASSERT(r == 0); + + /* Wait for all signal handling threads to exit. */ + for (i = 0; i < NUM_SIGNAL_HANDLING_THREADS; i++) { + r = uv_thread_join(&signal_handling_threads[i]); + ASSERT(r == 0); + } + + /* Tell all loop creating threads to stop. */ + stop = 1; + + /* Wait for all loop creating threads to exit. */ + for (i = 0; i < NUM_LOOP_CREATING_THREADS; i++) { + r = uv_thread_join(&loop_creating_threads[i]); + ASSERT(r == 0); + } + + printf("signal1_cb calls: %d\n", signal1_cb_counter); + printf("signal2_cb calls: %d\n", signal2_cb_counter); + printf("loops created and destroyed: %d\n", loop_creation_counter); + + ASSERT(signal1_cb_counter == 4 * NUM_SIGNAL_HANDLING_THREADS); + ASSERT(signal2_cb_counter == 2 * NUM_SIGNAL_HANDLING_THREADS); + /* We don't know exactly how much loops will be created and destroyed, but at + * least there should be 1 for every loop creating thread. + */ + ASSERT(loop_creation_counter >= NUM_LOOP_CREATING_THREADS); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#endif /* !_WIN32 */ diff --git a/deps/uv/test/test-signal.c b/deps/uv/test/test-signal.c index b39bc24460..bf38068646 100644 --- a/deps/uv/test/test-signal.c +++ b/deps/uv/test/test-signal.c @@ -19,31 +19,19 @@ * IN THE SOFTWARE. */ -#include "uv.h" -#include "task.h" - -#ifdef _WIN32 -TEST_IMPL(we_get_signal) { - return 0; -} - - -TEST_IMPL(we_get_signals) { - return 0; -} +/* This test does not pretend to be cross-platform. */ +#ifndef _WIN32 -#else /* !_WIN32 */ +#include "uv.h" +#include "task.h" +#include +#include +#include #include #include -#include #include -#include - -/* This test does not pretend to be cross-platform. */ -#include -#include #include #define NSIGNALS 10 @@ -131,6 +119,7 @@ TEST_IMPL(we_get_signal) { ASSERT(tc.ncalls == NSIGNALS); ASSERT(sc.ncalls == NSIGNALS); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -156,6 +145,7 @@ TEST_IMPL(we_get_signals) { for (i = 0; i < ARRAY_SIZE(tc); i++) ASSERT(tc[i].ncalls == NSIGNALS); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-spawn.c b/deps/uv/test/test-spawn.c index 666d00f7f4..cb03efdf6a 100644 --- a/deps/uv/test/test-spawn.c +++ b/deps/uv/test/test-spawn.c @@ -152,6 +152,8 @@ TEST_IMPL(spawn_fails) { ASSERT(0 != uv_is_active((uv_handle_t*)&process)); ASSERT(0 == uv_run(uv_default_loop())); ASSERT(uv_last_error(uv_default_loop()).code == UV_ENOENT); + + MAKE_VALGRIND_HAPPY(); return 0; } @@ -170,6 +172,7 @@ TEST_IMPL(spawn_exit_code) { ASSERT(exit_cb_called == 1); ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -202,6 +205,7 @@ TEST_IMPL(spawn_stdout) { printf("output is: %s", output); ASSERT(strcmp("hello world\n", output) == 0); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -254,6 +258,7 @@ TEST_IMPL(spawn_stdout_to_file) { /* Cleanup. */ unlink("stdout_file"); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -296,6 +301,7 @@ TEST_IMPL(spawn_stdin) { ASSERT(close_cb_called == 3); /* Once for process twice for the pipe. */ ASSERT(strcmp(buffer, output) == 0); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -330,6 +336,7 @@ TEST_IMPL(spawn_stdio_greater_than_3) { printf("output from stdio[3] is: %s", output); ASSERT(strcmp("fourth stdio!\n", output) == 0); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -351,6 +358,7 @@ TEST_IMPL(spawn_ignored_stdio) { ASSERT(exit_cb_called == 1); ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -375,6 +383,7 @@ TEST_IMPL(spawn_and_kill) { ASSERT(exit_cb_called == 1); ASSERT(close_cb_called == 2); /* Once for process and once for timer. */ + MAKE_VALGRIND_HAPPY(); return 0; } @@ -402,6 +411,7 @@ TEST_IMPL(spawn_detached) { err = uv_kill(process.pid, 15); ASSERT(err.code == 0); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -459,6 +469,7 @@ TEST_IMPL(spawn_and_kill_with_std) { ASSERT(exit_cb_called == 1); ASSERT(close_cb_called == 5); /* process x 1, timer x 1, stdio x 3. */ + MAKE_VALGRIND_HAPPY(); return 0; } @@ -505,6 +516,7 @@ TEST_IMPL(spawn_and_ping) { ASSERT(exit_cb_called == 1); ASSERT(strcmp(output, "TEST") == 0); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -538,6 +550,7 @@ TEST_IMPL(kill) { ASSERT(exit_cb_called == 1); ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -585,6 +598,7 @@ TEST_IMPL(spawn_detect_pipe_name_collisions_on_windows) { printf("output is: %s", output); ASSERT(strcmp("hello world\n", output) == 0); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -744,6 +758,7 @@ TEST_IMPL(spawn_setuid_setgid) { ASSERT(exit_cb_called == 1); ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } #endif @@ -777,6 +792,7 @@ TEST_IMPL(spawn_setuid_fails) { ASSERT(exit_cb_called == 1); ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -808,6 +824,7 @@ TEST_IMPL(spawn_setgid_fails) { ASSERT(exit_cb_called == 1); ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } #endif @@ -839,6 +856,7 @@ TEST_IMPL(spawn_setuid_fails) { ASSERT(close_cb_called == 0); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -860,6 +878,7 @@ TEST_IMPL(spawn_setgid_fails) { ASSERT(close_cb_called == 0); + MAKE_VALGRIND_HAPPY(); return 0; } #endif diff --git a/deps/uv/test/test-stdio-over-pipes.c b/deps/uv/test/test-stdio-over-pipes.c index 7603027fb8..03e71071b6 100644 --- a/deps/uv/test/test-stdio-over-pipes.c +++ b/deps/uv/test/test-stdio-over-pipes.c @@ -147,6 +147,7 @@ TEST_IMPL(stdio_over_pipes) { ASSERT(memcmp("hello world\n", output, 12) == 0); ASSERT(output_used == 12); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -242,5 +243,6 @@ int stdio_over_pipes_helper() { ASSERT(on_pipe_read_called == 1); ASSERT(close_cb_called == 2); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-tcp-bind-error.c b/deps/uv/test/test-tcp-bind-error.c index 9512519ac0..5c3be70a7c 100644 --- a/deps/uv/test/test-tcp-bind-error.c +++ b/deps/uv/test/test-tcp-bind-error.c @@ -63,6 +63,7 @@ TEST_IMPL(tcp_bind_error_addrinuse) { ASSERT(close_cb_called == 2); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -87,6 +88,7 @@ TEST_IMPL(tcp_bind_error_addrnotavail_1) { ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -108,6 +110,7 @@ TEST_IMPL(tcp_bind_error_addrnotavail_2) { ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -133,6 +136,7 @@ TEST_IMPL(tcp_bind_error_fault) { ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -159,6 +163,7 @@ TEST_IMPL(tcp_bind_error_inval) { ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -174,6 +179,7 @@ TEST_IMPL(tcp_bind_localhost_ok) { r = uv_tcp_bind(&server, addr); ASSERT(r == 0); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -187,5 +193,6 @@ TEST_IMPL(tcp_listen_without_bind) { r = uv_listen((uv_stream_t*)&server, 128, NULL); ASSERT(r == 0); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-tcp-bind6-error.c b/deps/uv/test/test-tcp-bind6-error.c index 5a8b76363a..f281b94e31 100644 --- a/deps/uv/test/test-tcp-bind6-error.c +++ b/deps/uv/test/test-tcp-bind6-error.c @@ -63,6 +63,7 @@ TEST_IMPL(tcp_bind6_error_addrinuse) { ASSERT(close_cb_called == 2); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -84,6 +85,7 @@ TEST_IMPL(tcp_bind6_error_addrnotavail) { ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -109,6 +111,7 @@ TEST_IMPL(tcp_bind6_error_fault) { ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -135,6 +138,7 @@ TEST_IMPL(tcp_bind6_error_inval) { ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -150,5 +154,6 @@ TEST_IMPL(tcp_bind6_localhost_ok) { r = uv_tcp_bind6(&server, addr); ASSERT(r == 0); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-tcp-close-while-connecting.c b/deps/uv/test/test-tcp-close-while-connecting.c index 90471ecacd..c8a8bda92b 100644 --- a/deps/uv/test/test-tcp-close-while-connecting.c +++ b/deps/uv/test/test-tcp-close-while-connecting.c @@ -76,5 +76,6 @@ TEST_IMPL(tcp_close_while_connecting) { ASSERT(timer1_cb_called == 1); ASSERT(close_cb_called == 2); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-tcp-close.c b/deps/uv/test/test-tcp-close.c index 33f79974b4..321a0e4683 100644 --- a/deps/uv/test/test-tcp-close.c +++ b/deps/uv/test/test-tcp-close.c @@ -125,5 +125,6 @@ TEST_IMPL(tcp_close) { ASSERT(write_cb_called == NUM_WRITE_REQS); ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-tcp-connect-error-after-write.c b/deps/uv/test/test-tcp-connect-error-after-write.c index a9c020378c..7fbbf7cb31 100644 --- a/deps/uv/test/test-tcp-connect-error-after-write.c +++ b/deps/uv/test/test-tcp-connect-error-after-write.c @@ -91,5 +91,6 @@ TEST_IMPL(tcp_connect_error_after_write) { ASSERT(write_cb_called == 1); ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-tcp-connect-error.c b/deps/uv/test/test-tcp-connect-error.c index 5cdacab632..20a5a40317 100644 --- a/deps/uv/test/test-tcp-connect-error.c +++ b/deps/uv/test/test-tcp-connect-error.c @@ -66,5 +66,6 @@ TEST_IMPL(tcp_connect_error_fault) { ASSERT(connect_cb_called == 0); ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-tcp-connect-timeout.c b/deps/uv/test/test-tcp-connect-timeout.c index 32b0dffd85..8eb959b6fb 100644 --- a/deps/uv/test/test-tcp-connect-timeout.c +++ b/deps/uv/test/test-tcp-connect-timeout.c @@ -81,5 +81,6 @@ TEST_IMPL(tcp_connect_timeout) { r = uv_run(uv_default_loop()); ASSERT(r == 0); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-tcp-connect6-error.c b/deps/uv/test/test-tcp-connect6-error.c index 5c158ff876..2eb55ca99c 100644 --- a/deps/uv/test/test-tcp-connect6-error.c +++ b/deps/uv/test/test-tcp-connect6-error.c @@ -64,5 +64,6 @@ TEST_IMPL(tcp_connect6_error_fault) { ASSERT(connect_cb_called == 0); ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-tcp-flags.c b/deps/uv/test/test-tcp-flags.c index c441b563f4..33c2002ca7 100644 --- a/deps/uv/test/test-tcp-flags.c +++ b/deps/uv/test/test-tcp-flags.c @@ -47,5 +47,6 @@ TEST_IMPL(tcp_flags) { r = uv_run(loop); ASSERT(r == 0); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-tcp-open.c b/deps/uv/test/test-tcp-open.c index 48188d2458..7546993112 100644 --- a/deps/uv/test/test-tcp-open.c +++ b/deps/uv/test/test-tcp-open.c @@ -50,7 +50,6 @@ static void startup(void) { static uv_os_sock_t create_tcp_socket(void) { uv_os_sock_t sock; - int r; sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); #ifdef _WIN32 @@ -63,7 +62,7 @@ static uv_os_sock_t create_tcp_socket(void) { { /* Allow reuse of the port. */ int yes = 1; - r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes); + int r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes); ASSERT(r == 0); } #endif @@ -171,5 +170,6 @@ TEST_IMPL(tcp_open) { ASSERT(write_cb_called == 1); ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-tcp-shutdown-after-write.c b/deps/uv/test/test-tcp-shutdown-after-write.c index 219a3b4054..b3e06f5f72 100644 --- a/deps/uv/test/test-tcp-shutdown-after-write.c +++ b/deps/uv/test/test-tcp-shutdown-after-write.c @@ -127,5 +127,6 @@ TEST_IMPL(tcp_shutdown_after_write) { ASSERT(conn_close_cb_called == 1); ASSERT(timer_close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-tcp-unexpected-read.c b/deps/uv/test/test-tcp-unexpected-read.c index 709d7dd50e..772746bc9c 100644 --- a/deps/uv/test/test-tcp-unexpected-read.c +++ b/deps/uv/test/test-tcp-unexpected-read.c @@ -109,5 +109,6 @@ TEST_IMPL(tcp_unexpected_read) { */ ASSERT(ticks <= 20); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-tcp-write-error.c b/deps/uv/test/test-tcp-write-error.c index 32207dd239..a0fbeca608 100644 --- a/deps/uv/test/test-tcp-write-error.c +++ b/deps/uv/test/test-tcp-write-error.c @@ -164,5 +164,6 @@ TEST_IMPL(tcp_write_error) { ASSERT(write_cb_error_called >= 1); ASSERT(tcp_client.write_queue_size == 0); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-tcp-write-to-half-open-connection.c b/deps/uv/test/test-tcp-write-to-half-open-connection.c index 26f914b995..8c3389539c 100644 --- a/deps/uv/test/test-tcp-write-to-half-open-connection.c +++ b/deps/uv/test/test-tcp-write-to-half-open-connection.c @@ -131,5 +131,6 @@ TEST_IMPL(tcp_write_to_half_open_connection) { ASSERT(write_cb_called > 0); ASSERT(read_cb_called > 0); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-tcp-writealot.c b/deps/uv/test/test-tcp-writealot.c index 16d141ad32..05f18058c2 100644 --- a/deps/uv/test/test-tcp-writealot.c +++ b/deps/uv/test/test-tcp-writealot.c @@ -166,5 +166,6 @@ TEST_IMPL(tcp_writealot) { free(send_buffer); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-threadpool.c b/deps/uv/test/test-threadpool.c index 92130b506c..12777b6e43 100644 --- a/deps/uv/test/test-threadpool.c +++ b/deps/uv/test/test-threadpool.c @@ -53,5 +53,6 @@ TEST_IMPL(threadpool_queue_work_simple) { ASSERT(work_cb_count == 1); ASSERT(after_work_cb_count == 1); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-timer-again.c b/deps/uv/test/test-timer-again.c index e492c364e4..73bc5303d7 100644 --- a/deps/uv/test/test-timer-again.c +++ b/deps/uv/test/test-timer-again.c @@ -137,5 +137,6 @@ TEST_IMPL(timer_again) { (long int)(uv_now(uv_default_loop()) - start_time)); ASSERT(700 <= uv_now(uv_default_loop()) - start_time); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-timer.c b/deps/uv/test/test-timer.c index c1b629b2fb..5f63449554 100644 --- a/deps/uv/test/test-timer.c +++ b/deps/uv/test/test-timer.c @@ -129,6 +129,7 @@ TEST_IMPL(timer) { ASSERT(500 <= uv_now(uv_default_loop()) - start_time); + MAKE_VALGRIND_HAPPY(); return 0; } @@ -148,5 +149,6 @@ TEST_IMPL(timer_start_twice) { ASSERT(once_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-tty.c b/deps/uv/test/test-tty.c index ded59c9f77..3bf37883a3 100644 --- a/deps/uv/test/test-tty.c +++ b/deps/uv/test/test-tty.c @@ -106,5 +106,6 @@ TEST_IMPL(tty) { uv_run(loop); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-udp-dgram-too-big.c b/deps/uv/test/test-udp-dgram-too-big.c index 2d172c0640..ebf82de9e3 100644 --- a/deps/uv/test/test-udp-dgram-too-big.c +++ b/deps/uv/test/test-udp-dgram-too-big.c @@ -82,5 +82,6 @@ TEST_IMPL(udp_dgram_too_big) { ASSERT(send_cb_called == 1); ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-udp-ipv6.c b/deps/uv/test/test-udp-ipv6.c index 6ff36b32b0..883772adaf 100644 --- a/deps/uv/test/test-udp-ipv6.c +++ b/deps/uv/test/test-udp-ipv6.c @@ -133,6 +133,8 @@ static void do_test(uv_udp_recv_cb recv_cb, int bind_flags) { uv_run(uv_default_loop()); ASSERT(close_cb_called == 3); + + MAKE_VALGRIND_HAPPY(); } diff --git a/deps/uv/test/test-udp-multicast-join.c b/deps/uv/test/test-udp-multicast-join.c index b32ef0737a..e995012e4f 100644 --- a/deps/uv/test/test-udp-multicast-join.c +++ b/deps/uv/test/test-udp-multicast-join.c @@ -135,5 +135,6 @@ TEST_IMPL(udp_multicast_join) { ASSERT(sv_send_cb_called == 1); ASSERT(close_cb_called == 2); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-udp-multicast-ttl.c b/deps/uv/test/test-udp-multicast-ttl.c index b2f1125142..3fd4be8dc2 100644 --- a/deps/uv/test/test-udp-multicast-ttl.c +++ b/deps/uv/test/test-udp-multicast-ttl.c @@ -82,5 +82,6 @@ TEST_IMPL(udp_multicast_ttl) { ASSERT(sv_send_cb_called == 1); ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-udp-open.c b/deps/uv/test/test-udp-open.c index 9168549e66..bb6d28a22a 100644 --- a/deps/uv/test/test-udp-open.c +++ b/deps/uv/test/test-udp-open.c @@ -46,7 +46,6 @@ static void startup(void) { static uv_os_sock_t create_udp_socket(void) { uv_os_sock_t sock; - int r; sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); #ifdef _WIN32 @@ -59,7 +58,7 @@ static uv_os_sock_t create_udp_socket(void) { { /* Allow reuse of the port. */ int yes = 1; - r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes); + int r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes); ASSERT(r == 0); } #endif @@ -150,5 +149,6 @@ TEST_IMPL(udp_open) { ASSERT(send_cb_called == 1); ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-udp-options.c b/deps/uv/test/test-udp-options.c index 4ff650dc06..e7b21678ba 100644 --- a/deps/uv/test/test-udp-options.c +++ b/deps/uv/test/test-udp-options.c @@ -82,5 +82,6 @@ TEST_IMPL(udp_options) { r = uv_run(loop); ASSERT(r == 0); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-udp-send-and-recv.c b/deps/uv/test/test-udp-send-and-recv.c index ab47e91c21..7f57c32dff 100644 --- a/deps/uv/test/test-udp-send-and-recv.c +++ b/deps/uv/test/test-udp-send-and-recv.c @@ -204,5 +204,6 @@ TEST_IMPL(udp_send_and_recv) { ASSERT(sv_recv_cb_called == 1); ASSERT(close_cb_called == 2); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/test/test-walk-handles.c b/deps/uv/test/test-walk-handles.c index a72c095bc0..298f98f552 100644 --- a/deps/uv/test/test-walk-handles.c +++ b/deps/uv/test/test-walk-handles.c @@ -73,5 +73,6 @@ TEST_IMPL(walk_handles) { uv_walk(loop, walk_cb, magic_cookie); ASSERT(seen_timer_handle == 0); + MAKE_VALGRIND_HAPPY(); return 0; } diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index 0a7f832c51..14930cfabd 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -283,6 +283,7 @@ 'test/test-shutdown-close.c', 'test/test-shutdown-eof.c', 'test/test-signal.c', + 'test/test-signal-multiple-loops.c', 'test/test-spawn.c', 'test/test-fs-poll.c', 'test/test-stdio-over-pipes.c', @@ -303,7 +304,6 @@ 'test/test-tcp-unexpected-read.c', 'test/test-threadpool.c', 'test/test-mutexes.c', - 'test/test-signal.c', 'test/test-thread.c', 'test/test-barrier.c', 'test/test-condvar.c',