Browse Source

deps: upgrade libuv to a0c1d84

v0.9.11-release
Ben Noordhuis 12 years ago
parent
commit
7bc449c063
  1. 1
      deps/uv/build.mk
  2. 10
      deps/uv/common.gypi
  3. 24
      deps/uv/include/uv-private/uv-unix.h
  4. 10
      deps/uv/include/uv.h
  5. 243
      deps/uv/src/unix/async.c
  6. 28
      deps/uv/src/unix/core.c
  7. 1
      deps/uv/src/unix/fs.c
  8. 10
      deps/uv/src/unix/internal.h
  9. 15
      deps/uv/src/unix/loop.c
  10. 73
      deps/uv/src/unix/proctitle.c
  11. 16
      deps/uv/src/unix/udp.c
  12. 52
      deps/uv/src/uv-common.c
  13. 19
      deps/uv/src/uv-common.h
  14. 33
      deps/uv/src/win/core.c
  15. 14
      deps/uv/src/win/udp.c
  16. 3
      deps/uv/test/runner.c
  17. 2
      deps/uv/test/test-list.h
  18. 73
      deps/uv/test/test-loop-stop.c
  19. 4
      deps/uv/uv.gyp
  20. 2
      deps/uv/vcbuild.bat

1
deps/uv/build.mk

@ -85,6 +85,7 @@ TESTS= \
test/test-ipc.o \ test/test-ipc.o \
test/test-ipc-send-recv.o \ test/test-ipc-send-recv.o \
test/test-loop-handles.o \ test/test-loop-handles.o \
test/test-loop-stop.o \
test/test-multiple-listen.o \ test/test-multiple-listen.o \
test/test-mutexes.o \ test/test-mutexes.o \
test/test-pass-always.o \ test/test-pass-always.o \

10
deps/uv/common.gypi

@ -45,7 +45,13 @@
}, },
'Release': { 'Release': {
'defines': [ 'NDEBUG' ], 'defines': [ 'NDEBUG' ],
'cflags': [ '-O3', '-fomit-frame-pointer', '-fdata-sections', '-ffunction-sections' ], 'cflags': [
'-O3',
'-fstrict-aliasing',
'-fomit-frame-pointer',
'-fdata-sections',
'-ffunction-sections',
],
'msvs_settings': { 'msvs_settings': {
'VCCLCompilerTool': { 'VCCLCompilerTool': {
'target_conditions': [ 'target_conditions': [
@ -163,7 +169,7 @@
'PREBINDING': 'NO', # No -Wl,-prebind 'PREBINDING': 'NO', # No -Wl,-prebind
'USE_HEADERMAP': 'NO', 'USE_HEADERMAP': 'NO',
'OTHER_CFLAGS': [ 'OTHER_CFLAGS': [
'-fno-strict-aliasing', '-fstrict-aliasing',
], ],
'WARNING_CFLAGS': [ 'WARNING_CFLAGS': [
'-Wall', '-Wall',

24
deps/uv/include/uv-private/uv-unix.h

@ -54,9 +54,6 @@
# include "uv-bsd.h" # include "uv-bsd.h"
#endif #endif
struct uv__io_s;
struct uv_loop_s;
#ifndef UV_IO_PRIVATE_PLATFORM_FIELDS #ifndef UV_IO_PRIVATE_PLATFORM_FIELDS
# define UV_IO_PRIVATE_PLATFORM_FIELDS /* empty */ # define UV_IO_PRIVATE_PLATFORM_FIELDS /* empty */
#endif #endif
@ -64,6 +61,10 @@ struct uv_loop_s;
#define UV_IO_PRIVATE_FIELDS \ #define UV_IO_PRIVATE_FIELDS \
UV_IO_PRIVATE_PLATFORM_FIELDS \ UV_IO_PRIVATE_PLATFORM_FIELDS \
struct uv__io_s;
struct uv__async;
struct uv_loop_s;
typedef void (*uv__io_cb)(struct uv_loop_s* loop, typedef void (*uv__io_cb)(struct uv_loop_s* loop,
struct uv__io_s* w, struct uv__io_s* w,
unsigned int events); unsigned int events);
@ -79,6 +80,16 @@ struct uv__io_s {
UV_IO_PRIVATE_FIELDS UV_IO_PRIVATE_FIELDS
}; };
typedef void (*uv__async_cb)(struct uv_loop_s* loop,
struct uv__async* w,
unsigned int nevents);
struct uv__async {
uv__async_cb cb;
uv__io_t io_watcher;
int wfd;
};
struct uv__work { struct uv__work {
void (*work)(struct uv__work *w); void (*work)(struct uv__work *w);
void (*done)(struct uv__work *w, int status); void (*done)(struct uv__work *w, int status);
@ -167,8 +178,7 @@ typedef struct {
ngx_queue_t check_handles; \ ngx_queue_t check_handles; \
ngx_queue_t idle_handles; \ ngx_queue_t idle_handles; \
ngx_queue_t async_handles; \ ngx_queue_t async_handles; \
uv__io_t async_watcher; \ struct uv__async async_watcher; \
int async_pipefd[2]; \
/* RB_HEAD(uv__timers, uv_timer_s) */ \ /* RB_HEAD(uv__timers, uv_timer_s) */ \
struct uv__timers { \ struct uv__timers { \
struct uv_timer_s* rbh_root; \ struct uv_timer_s* rbh_root; \
@ -252,9 +262,9 @@ typedef struct {
ngx_queue_t queue; ngx_queue_t queue;
#define UV_ASYNC_PRIVATE_FIELDS \ #define UV_ASYNC_PRIVATE_FIELDS \
volatile sig_atomic_t pending; \
uv_async_cb async_cb; \ uv_async_cb async_cb; \
ngx_queue_t queue; ngx_queue_t queue; \
int pending; \
#define UV_TIMER_PRIVATE_FIELDS \ #define UV_TIMER_PRIVATE_FIELDS \
/* RB_ENTRY(uv_timer_s) tree_entry; */ \ /* RB_ENTRY(uv_timer_s) tree_entry; */ \

10
deps/uv/include/uv.h

@ -258,6 +258,14 @@ UV_EXTERN uv_loop_t* uv_default_loop(void);
*/ */
UV_EXTERN int uv_run(uv_loop_t*, uv_run_mode mode); UV_EXTERN int uv_run(uv_loop_t*, uv_run_mode mode);
/*
* This function will stop the event loop by forcing uv_run to end
* as soon as possible, but not sooner than the next loop iteration.
* If this function was called before blocking for i/o, the loop won't
* block for i/o on this iteration.
*/
UV_EXTERN void uv_stop(uv_loop_t*);
/* /*
* Manually modify the event loop's reference count. Useful if the user wants * Manually modify the event loop's reference count. Useful if the user wants
* to have a handle or timeout that doesn't keep the loop alive. * to have a handle or timeout that doesn't keep the loop alive.
@ -1934,6 +1942,8 @@ struct uv_loop_s {
unsigned int active_handles; unsigned int active_handles;
ngx_queue_t handle_queue; ngx_queue_t handle_queue;
ngx_queue_t active_reqs; ngx_queue_t active_reqs;
/* Internal flag to signal loop stop */
unsigned int stop_flag;
UV_LOOP_PRIVATE_FIELDS UV_LOOP_PRIVATE_FIELDS
}; };

243
deps/uv/src/unix/async.c

@ -18,21 +18,73 @@
* IN THE SOFTWARE. * IN THE SOFTWARE.
*/ */
/* This file contains both the uv__async internal infrastructure and the
* user-facing uv_async_t functions.
*/
#include "uv.h" #include "uv.h"
#include "internal.h" #include "internal.h"
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
static int uv__async_init(uv_loop_t* loop); static void uv__async_event(uv_loop_t* loop,
static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events); struct uv__async* w,
unsigned int nevents);
static int uv__async_make_pending(int* pending);
static int uv__async_eventfd(void);
int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
if (uv__async_start(loop, &loop->async_watcher, uv__async_event))
return uv__set_sys_error(loop, errno);
uv__handle_init(loop, (uv_handle_t*)handle, UV_ASYNC);
handle->async_cb = async_cb;
handle->pending = 0;
ngx_queue_insert_tail(&loop->async_handles, &handle->queue);
uv__handle_start(handle);
return 0;
}
int uv_async_send(uv_async_t* handle) {
if (uv__async_make_pending(&handle->pending) == 0)
uv__async_send(&handle->loop->async_watcher);
return 0;
}
void uv__async_close(uv_async_t* handle) {
ngx_queue_remove(&handle->queue);
uv__handle_stop(handle);
}
static void uv__async_event(uv_loop_t* loop,
struct uv__async* w,
unsigned int nevents) {
ngx_queue_t* q;
uv_async_t* h;
static int uv__async_make_pending(volatile sig_atomic_t* ptr) { ngx_queue_foreach(q, &loop->async_handles) {
h = ngx_queue_data(q, uv_async_t, queue);
if (!h->pending) continue;
h->pending = 0;
h->async_cb(h, 0);
}
}
static int uv__async_make_pending(int* pending) {
/* Do a cheap read first. */ /* Do a cheap read first. */
if (*ptr) if (ACCESS_ONCE(int, *pending) != 0)
return 1; return 1;
/* Micro-optimization: use atomic memory operations to detect if we've been /* Micro-optimization: use atomic memory operations to detect if we've been
@ -47,100 +99,183 @@ static int uv__async_make_pending(volatile sig_atomic_t* ptr) {
#if defined(__i386__) || defined(__x86_64__) #if defined(__i386__) || defined(__x86_64__)
{ {
unsigned int val = 1; unsigned int val = 1;
__asm__ __volatile__("xchgl %0, %1" : "+r" (val) : "m" (*ptr)); __asm__ __volatile__ ("xchgl %0, %1"
: "+r" (val)
: "m" (*pending));
return val != 0; return val != 0;
} }
#elif defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 0) #elif defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 0)
return __sync_val_compare_and_swap(ptr, 0, 1) != 0; return __sync_val_compare_and_swap(pending, 0, 1) != 0;
#else #else
*ptr = 1; ACCESS_ONCE(int, *pending) = 1;
return 0; return 0;
#endif #endif
} }
int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) { static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
if (uv__async_init(loop)) struct uv__async* wa;
return uv__set_sys_error(loop, errno); char buf[1024];
unsigned n;
ssize_t r;
uv__handle_init(loop, (uv_handle_t*)handle, UV_ASYNC); n = 0;
handle->async_cb = async_cb; for (;;) {
handle->pending = 0; r = read(w->fd, buf, sizeof(buf));
ngx_queue_insert_tail(&loop->async_handles, &handle->queue); if (r > 0)
uv__handle_start(handle); n += r;
return 0; if (r == sizeof(buf))
continue;
if (r != -1)
break;
if (errno == EAGAIN || errno == EWOULDBLOCK)
break;
if (errno == EINTR)
continue;
abort();
}
wa = container_of(w, struct uv__async, io_watcher);
#if defined(__linux__)
if (wa->wfd == -1) {
uint64_t val;
assert(n == sizeof(val));
memcpy(&val, buf, sizeof(val)); /* Avoid alignment issues. */
wa->cb(loop, wa, val);
return;
}
#endif
wa->cb(loop, wa, n);
} }
int uv_async_send(uv_async_t* handle) { void uv__async_send(struct uv__async* wa) {
const void* buf;
ssize_t len;
int fd;
int r; int r;
if (uv__async_make_pending(&handle->pending)) buf = "";
return 0; /* already pending */ len = 1;
fd = wa->wfd;
#if defined(__linux__)
if (fd == -1) {
static const uint64_t val = 1;
buf = &val;
len = sizeof(val);
fd = wa->io_watcher.fd; /* eventfd */
}
#endif
do do
r = write(handle->loop->async_pipefd[1], "x", 1); r = write(fd, buf, len);
while (r == -1 && errno == EINTR); while (r == -1 && errno == EINTR);
assert(r == -1 || r == 1); if (r == len)
return;
if (r == -1 && errno != EAGAIN && errno != EWOULDBLOCK) if (r == -1)
return uv__set_sys_error(handle->loop, errno); if (errno == EAGAIN || errno == EWOULDBLOCK)
return;
return 0; abort();
} }
void uv__async_close(uv_async_t* handle) { void uv__async_init(struct uv__async* wa) {
ngx_queue_remove(&handle->queue); wa->io_watcher.fd = -1;
uv__handle_stop(handle); wa->wfd = -1;
} }
static int uv__async_init(uv_loop_t* loop) { int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb) {
if (loop->async_pipefd[0] != -1) int pipefd[2];
int fd;
if (wa->io_watcher.fd != -1)
return 0; return 0;
if (uv__make_pipe(loop->async_pipefd, UV__F_NONBLOCK)) fd = uv__async_eventfd();
if (fd >= 0) {
pipefd[0] = fd;
pipefd[1] = -1;
}
else if (fd != -ENOSYS)
return -1;
else if (uv__make_pipe(pipefd, UV__F_NONBLOCK))
return -1; return -1;
uv__io_init(&loop->async_watcher, uv__async_io, loop->async_pipefd[0]); uv__io_init(&wa->io_watcher, uv__async_io, pipefd[0]);
uv__io_start(loop, &loop->async_watcher, UV__POLLIN); uv__io_start(loop, &wa->io_watcher, UV__POLLIN);
wa->wfd = pipefd[1];
wa->cb = cb;
return 0; return 0;
} }
static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { void uv__async_stop(uv_loop_t* loop, struct uv__async* wa) {
char buf[1024]; if (wa->io_watcher.fd == -1)
ngx_queue_t* q; return;
uv_async_t* h;
ssize_t r;
while (1) { uv__io_stop(loop, &wa->io_watcher, UV__POLLIN);
r = read(loop->async_pipefd[0], buf, sizeof(buf)); close(wa->io_watcher.fd);
wa->io_watcher.fd = -1;
if (r == sizeof(buf)) if (wa->wfd != -1) {
continue; close(wa->wfd);
wa->wfd = -1;
}
}
if (r != -1)
break;
if (errno == EAGAIN || errno == EWOULDBLOCK) static int uv__async_eventfd() {
break; #if defined(__linux__)
static int no_eventfd2;
static int no_eventfd;
int fd;
if (errno == EINTR) if (no_eventfd2)
continue; goto skip_eventfd2;
abort(); fd = uv__eventfd2(0, UV__EFD_CLOEXEC | UV__EFD_NONBLOCK);
} if (fd != -1)
return fd;
ngx_queue_foreach(q, &loop->async_handles) { if (errno != ENOSYS)
h = ngx_queue_data(q, uv_async_t, queue); return -errno;
if (!h->pending) continue;
h->pending = 0; no_eventfd2 = 1;
h->async_cb(h, 0);
skip_eventfd2:
if (no_eventfd)
goto skip_eventfd;
fd = uv__eventfd(0);
if (fd != -1) {
uv__cloexec(fd, 1);
uv__nonblock(fd, 1);
return fd;
} }
if (errno != ENOSYS)
return -errno;
no_eventfd = 1;
skip_eventfd:
#endif
return -ENOSYS;
} }

28
deps/uv/src/unix/core.c

@ -259,6 +259,9 @@ int uv_backend_fd(const uv_loop_t* loop) {
int uv_backend_timeout(const uv_loop_t* loop) { int uv_backend_timeout(const uv_loop_t* loop) {
if (loop->stop_flag != 0)
return 0;
if (!uv__has_active_handles(loop) && !uv__has_active_reqs(loop)) if (!uv__has_active_handles(loop) && !uv__has_active_reqs(loop))
return 0; return 0;
@ -280,22 +283,35 @@ static int uv__loop_alive(uv_loop_t* loop) {
int uv_run(uv_loop_t* loop, uv_run_mode mode) { int uv_run(uv_loop_t* loop, uv_run_mode mode) {
int timeout;
int r; int r;
if (!uv__loop_alive(loop)) r = uv__loop_alive(loop);
return 0; while (r != 0 && loop->stop_flag == 0) {
do {
uv__update_time(loop); uv__update_time(loop);
uv__run_timers(loop); uv__run_timers(loop);
uv__run_idle(loop); uv__run_idle(loop);
uv__run_prepare(loop); uv__run_prepare(loop);
uv__run_pending(loop); uv__run_pending(loop);
uv__io_poll(loop, (mode & UV_RUN_NOWAIT ? 0 : uv_backend_timeout(loop)));
timeout = 0;
if ((mode & UV_RUN_NOWAIT) == 0)
timeout = uv_backend_timeout(loop);
uv__io_poll(loop, timeout);
uv__run_check(loop); uv__run_check(loop);
uv__run_closing_handles(loop); uv__run_closing_handles(loop);
r = uv__loop_alive(loop); r = uv__loop_alive(loop);
} while (r && !(mode & (UV_RUN_ONCE | UV_RUN_NOWAIT)));
if (mode & (UV_RUN_ONCE | UV_RUN_NOWAIT))
break;
}
/* The if statement lets gcc compile it to a conditional store. Avoids
* dirtying a cache line.
*/
if (loop->stop_flag != 0)
loop->stop_flag = 0;
return r; return r;
} }

1
deps/uv/src/unix/fs.c

@ -374,6 +374,7 @@ static ssize_t uv__fs_sendfile_emul(uv_fs_t* req) {
while (n == -1 && errno == EINTR); while (n == -1 && errno == EINTR);
if (n == -1 || (pfd.revents & ~POLLOUT) != 0) { if (n == -1 || (pfd.revents & ~POLLOUT) != 0) {
errno = EIO;
nsent = -1; nsent = -1;
goto out; goto out;
} }

10
deps/uv/src/unix/internal.h

@ -45,6 +45,9 @@
# include <CoreServices/CoreServices.h> # include <CoreServices/CoreServices.h>
#endif #endif
#define ACCESS_ONCE(type, var) \
(*(volatile type*) &(var))
#define UNREACHABLE() \ #define UNREACHABLE() \
do { \ do { \
assert(0 && "unreachable code"); \ assert(0 && "unreachable code"); \
@ -111,7 +114,6 @@ int uv__nonblock(int fd, int set);
int uv__cloexec(int fd, int set); int uv__cloexec(int fd, int set);
int uv__socket(int domain, int type, int protocol); int uv__socket(int domain, int type, int protocol);
int uv__dup(int fd); int uv__dup(int fd);
int uv_async_stop(uv_async_t* handle);
void uv__make_close_pending(uv_handle_t* handle); void uv__make_close_pending(uv_handle_t* handle);
void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd); void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd);
@ -122,6 +124,12 @@ void uv__io_feed(uv_loop_t* loop, uv__io_t* w);
int uv__io_active(const uv__io_t* w, unsigned int events); int uv__io_active(const uv__io_t* w, unsigned int events);
void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */ void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */
/* async */
void uv__async_send(struct uv__async* wa);
void uv__async_init(struct uv__async* wa);
int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb);
void uv__async_stop(uv_loop_t* loop, struct uv__async* wa);
/* loop */ /* loop */
int uv__loop_init(uv_loop_t* loop, int default_loop); int uv__loop_init(uv_loop_t* loop, int default_loop);
void uv__loop_delete(uv_loop_t* loop); void uv__loop_delete(uv_loop_t* loop);

15
deps/uv/src/unix/loop.c

@ -50,14 +50,14 @@ int uv__loop_init(uv_loop_t* loop, int default_loop) {
loop->closing_handles = NULL; loop->closing_handles = NULL;
loop->time = uv__hrtime() / 1000000; loop->time = uv__hrtime() / 1000000;
loop->async_pipefd[0] = -1; uv__async_init(&loop->async_watcher);
loop->async_pipefd[1] = -1;
loop->signal_pipefd[0] = -1; loop->signal_pipefd[0] = -1;
loop->signal_pipefd[1] = -1; loop->signal_pipefd[1] = -1;
loop->backend_fd = -1; loop->backend_fd = -1;
loop->emfile_fd = -1; loop->emfile_fd = -1;
loop->timer_counter = 0; loop->timer_counter = 0;
loop->stop_flag = 0;
if (uv__platform_loop_init(loop, default_loop)) if (uv__platform_loop_init(loop, default_loop))
return -1; return -1;
@ -85,16 +85,7 @@ int uv__loop_init(uv_loop_t* loop, int default_loop) {
void uv__loop_delete(uv_loop_t* loop) { void uv__loop_delete(uv_loop_t* loop) {
uv__signal_loop_cleanup(loop); uv__signal_loop_cleanup(loop);
uv__platform_loop_delete(loop); uv__platform_loop_delete(loop);
uv__async_stop(loop, &loop->async_watcher);
if (loop->async_pipefd[0] != -1) {
close(loop->async_pipefd[0]);
loop->async_pipefd[0] = -1;
}
if (loop->async_pipefd[1] != -1) {
close(loop->async_pipefd[1]);
loop->async_pipefd[1] = -1;
}
if (loop->emfile_fd != -1) { if (loop->emfile_fd != -1) {
close(loop->emfile_fd); close(loop->emfile_fd);

73
deps/uv/src/unix/proctitle.c

@ -30,68 +30,45 @@ static void* args_mem;
static struct { static struct {
char* str; char* str;
int len; size_t len;
} process_title; } process_title;
char** uv_setup_args(int argc, char** argv) { char** uv_setup_args(int argc, char** argv) {
char** new_argv; char** new_argv;
char** new_env;
size_t size; size_t size;
int envc;
char* s; char* s;
int i; int i;
#if defined(__APPLE__) if (argc <= 0)
char*** _NSGetArgv(void); return argv;
char*** _NSGetEnviron(void);
char** environ = *_NSGetEnviron();
#else
extern char** environ;
#endif
for (envc = 0; environ[envc]; envc++);
if (envc == 0) /* Calculate how much memory we need for the argv strings. */
s = argv[argc - 1]; size = 0;
else for (i = 0; i < argc; i++)
s = environ[envc - 1]; size += strlen(argv[i]) + 1;
process_title.str = argv[0]; process_title.str = argv[0];
process_title.len = s + strlen(s) + 1 - argv[0]; process_title.len = argv[argc - 1] + strlen(argv[argc - 1]) - argv[0];
assert(process_title.len + 1 == size); /* argv memory should be adjacent. */
size = process_title.len; /* Add space for the argv pointers. */
size += (argc + 1) * sizeof(char**); size += (argc + 1) * sizeof(char*);
size += (envc + 1) * sizeof(char**);
s = args_mem = malloc(size);
if (s == NULL) { new_argv = malloc(size);
process_title.str = NULL; if (new_argv == NULL)
process_title.len = 0;
return argv; return argv;
args_mem = new_argv;
/* Copy over the strings and set up the pointer table. */
s = (char*) &new_argv[argc + 1];
for (i = 0; i < argc; i++) {
size = strlen(argv[i]) + 1;
memcpy(s, argv[i], size);
new_argv[i] = s;
s += size;
} }
new_argv[i] = NULL;
new_argv = (char**) s;
new_env = new_argv + argc + 1;
s = (char*) (new_env + envc + 1);
memcpy(s, process_title.str, process_title.len);
for (i = 0; i < argc; i++)
new_argv[i] = s + (argv[i] - argv[0]);
new_argv[argc] = NULL;
s += environ[0] - argv[0];
for (i = 0; i < envc; i++)
new_env[i] = s + (environ[i] - environ[0]);
new_env[envc] = NULL;
#if defined(__APPLE__)
*_NSGetArgv() = new_argv;
*_NSGetEnviron() = new_env;
#else
environ = new_env;
#endif
return new_argv; return new_argv;
} }
@ -101,8 +78,8 @@ uv_err_t uv_set_process_title(const char* title) {
if (process_title.len == 0) if (process_title.len == 0)
return uv_ok_; return uv_ok_;
/* No need to terminate, last char is always '\0'. */ /* No need to terminate, byte after is always '\0'. */
strncpy(process_title.str, title, process_title.len - 1); strncpy(process_title.str, title, process_title.len);
uv__set_process_title(title); uv__set_process_title(title);
return uv_ok_; return uv_ok_;

16
deps/uv/src/unix/udp.c

@ -35,7 +35,7 @@ static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents);
static void uv__udp_recvmsg(uv_loop_t* loop, uv__io_t* w, unsigned int revents); static void uv__udp_recvmsg(uv_loop_t* loop, uv__io_t* w, unsigned int revents);
static void uv__udp_sendmsg(uv_loop_t* loop, uv__io_t* w, unsigned int revents); static void uv__udp_sendmsg(uv_loop_t* loop, uv__io_t* w, unsigned int revents);
static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, int domain); static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, int domain);
static int uv__udp_send(uv_udp_send_t* req, static int uv__send(uv_udp_send_t* req,
uv_udp_t* handle, uv_udp_t* handle,
uv_buf_t bufs[], uv_buf_t bufs[],
int bufcnt, int bufcnt,
@ -413,7 +413,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, int domain) {
} }
static int uv__udp_send(uv_udp_send_t* req, static int uv__send(uv_udp_send_t* req,
uv_udp_t* handle, uv_udp_t* handle,
uv_buf_t bufs[], uv_buf_t bufs[],
int bufcnt, int bufcnt,
@ -645,13 +645,13 @@ out:
} }
int uv_udp_send(uv_udp_send_t* req, int uv__udp_send(uv_udp_send_t* req,
uv_udp_t* handle, uv_udp_t* handle,
uv_buf_t bufs[], uv_buf_t bufs[],
int bufcnt, int bufcnt,
struct sockaddr_in addr, struct sockaddr_in addr,
uv_udp_send_cb send_cb) { uv_udp_send_cb send_cb) {
return uv__udp_send(req, return uv__send(req,
handle, handle,
bufs, bufs,
bufcnt, bufcnt,
@ -661,13 +661,13 @@ int uv_udp_send(uv_udp_send_t* req,
} }
int uv_udp_send6(uv_udp_send_t* req, int uv__udp_send6(uv_udp_send_t* req,
uv_udp_t* handle, uv_udp_t* handle,
uv_buf_t bufs[], uv_buf_t bufs[],
int bufcnt, int bufcnt,
struct sockaddr_in6 addr, struct sockaddr_in6 addr,
uv_udp_send_cb send_cb) { uv_udp_send_cb send_cb) {
return uv__udp_send(req, return uv__send(req,
handle, handle,
bufs, bufs,
bufcnt, bufcnt,
@ -677,7 +677,7 @@ int uv_udp_send6(uv_udp_send_t* req,
} }
int uv_udp_recv_start(uv_udp_t* handle, int uv__udp_recv_start(uv_udp_t* handle,
uv_alloc_cb alloc_cb, uv_alloc_cb alloc_cb,
uv_udp_recv_cb recv_cb) { uv_udp_recv_cb recv_cb) {
if (alloc_cb == NULL || recv_cb == NULL) { if (alloc_cb == NULL || recv_cb == NULL) {
@ -703,7 +703,7 @@ int uv_udp_recv_start(uv_udp_t* handle,
} }
int uv_udp_recv_stop(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, UV__POLLIN);
if (!uv__io_active(&handle->io_watcher, UV__POLLOUT)) if (!uv__io_active(&handle->io_watcher, UV__POLLOUT))

52
deps/uv/src/uv-common.c

@ -254,6 +254,53 @@ int uv_tcp_connect6(uv_connect_t* req,
} }
int uv_udp_send(uv_udp_send_t* req,
uv_udp_t* handle,
uv_buf_t bufs[],
int bufcnt,
struct sockaddr_in addr,
uv_udp_send_cb send_cb) {
if (handle->type != UV_UDP || addr.sin_family != AF_INET) {
return uv__set_artificial_error(handle->loop, UV_EINVAL);
}
return uv__udp_send(req, handle, bufs, bufcnt, addr, send_cb);
}
int uv_udp_send6(uv_udp_send_t* req,
uv_udp_t* handle,
uv_buf_t bufs[],
int bufcnt,
struct sockaddr_in6 addr,
uv_udp_send_cb send_cb) {
if (handle->type != UV_UDP || addr.sin6_family != AF_INET6) {
return uv__set_artificial_error(handle->loop, UV_EINVAL);
}
return uv__udp_send6(req, handle, bufs, bufcnt, addr, send_cb);
}
int uv_udp_recv_start(uv_udp_t* handle,
uv_alloc_cb alloc_cb,
uv_udp_recv_cb recv_cb) {
if (handle->type != UV_UDP || alloc_cb == NULL || recv_cb == NULL) {
return uv__set_artificial_error(handle->loop, UV_EINVAL);
}
return uv__udp_recv_start(handle, alloc_cb, recv_cb);
}
int uv_udp_recv_stop(uv_udp_t* handle) {
if (handle->type != UV_UDP) {
return uv__set_artificial_error(handle->loop, UV_EINVAL);
}
return uv__udp_recv_stop(handle);
}
#ifdef _WIN32 #ifdef _WIN32
static UINT __stdcall uv__thread_start(void *ctx_v) static UINT __stdcall uv__thread_start(void *ctx_v)
#else #else
@ -377,3 +424,8 @@ void uv_ref(uv_handle_t* handle) {
void uv_unref(uv_handle_t* handle) { void uv_unref(uv_handle_t* handle) {
uv__handle_unref(handle); uv__handle_unref(handle);
} }
void uv_stop(uv_loop_t* loop) {
loop->stop_flag = 1;
}

19
deps/uv/src/uv-common.h

@ -93,6 +93,25 @@ int uv__tcp_connect6(uv_connect_t* req,
struct sockaddr_in6 address, struct sockaddr_in6 address,
uv_connect_cb cb); uv_connect_cb cb);
int uv__udp_send(uv_udp_send_t* req,
uv_udp_t* handle,
uv_buf_t bufs[],
int bufcnt,
struct sockaddr_in addr,
uv_udp_send_cb send_cb);
int uv__udp_send6(uv_udp_send_t* req,
uv_udp_t* handle,
uv_buf_t bufs[],
int bufcnt,
struct sockaddr_in6 addr,
uv_udp_send_cb send_cb);
int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloccb,
uv_udp_recv_cb recv_cb);
int uv__udp_recv_stop(uv_udp_t* handle);
void uv__fs_poll_close(uv_fs_poll_t* handle); void uv__fs_poll_close(uv_fs_poll_t* handle);

33
deps/uv/src/win/core.c

@ -116,6 +116,7 @@ static void uv_loop_init(uv_loop_t* loop) {
loop->active_udp_streams = 0; loop->active_udp_streams = 0;
loop->timer_counter = 0; loop->timer_counter = 0;
loop->stop_flag = 0;
loop->last_err = uv_ok_; loop->last_err = uv_ok_;
} }
@ -249,10 +250,13 @@ static void uv_poll_ex(uv_loop_t* loop, int block) {
} }
} }
#define UV_LOOP_ALIVE(loop) \
((loop)->active_handles > 0 || \ static int uv__loop_alive(uv_loop_t* loop) {
!ngx_queue_empty(&(loop)->active_reqs) || \ return loop->active_handles > 0 ||
(loop)->endgame_handles != NULL) !ngx_queue_empty(&loop->active_reqs) ||
loop->endgame_handles != NULL;
}
int uv_run(uv_loop_t *loop, uv_run_mode mode) { int uv_run(uv_loop_t *loop, uv_run_mode mode) {
int r; int r;
@ -263,8 +267,11 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
else else
poll = &uv_poll; poll = &uv_poll;
r = UV_LOOP_ALIVE(loop); if (!uv__loop_alive(loop))
while (r) { return 0;
r = uv__loop_alive(loop);
while (r != 0 && loop->stop_flag == 0) {
uv_update_time(loop); uv_update_time(loop);
uv_process_timers(loop); uv_process_timers(loop);
@ -282,14 +289,22 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
(*poll)(loop, loop->idle_handles == NULL && (*poll)(loop, loop->idle_handles == NULL &&
loop->pending_reqs_tail == NULL && loop->pending_reqs_tail == NULL &&
loop->endgame_handles == NULL && loop->endgame_handles == NULL &&
UV_LOOP_ALIVE(loop) && !loop->stop_flag &&
(loop->active_handles > 0 ||
!ngx_queue_empty(&loop->active_reqs)) &&
!(mode & UV_RUN_NOWAIT)); !(mode & UV_RUN_NOWAIT));
uv_check_invoke(loop); uv_check_invoke(loop);
r = UV_LOOP_ALIVE(loop); r = uv__loop_alive(loop);
if (mode & (UV_RUN_ONCE | UV_RUN_NOWAIT)) if (mode & (UV_RUN_ONCE | UV_RUN_NOWAIT))
break; break;
} }
/* The if statement lets the compiler compile it to a conditional store.
* Avoids dirtying a cache line.
*/
if (loop->stop_flag != 0)
loop->stop_flag = 0;
return r; return r;
} }

14
deps/uv/src/win/udp.c

@ -341,7 +341,7 @@ static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) {
} }
int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb, int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
uv_udp_recv_cb recv_cb) { uv_udp_recv_cb recv_cb) {
uv_loop_t* loop = handle->loop; uv_loop_t* loop = handle->loop;
@ -371,7 +371,7 @@ int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
} }
int uv_udp_recv_stop(uv_udp_t* handle) { int uv__udp_recv_stop(uv_udp_t* handle) {
if (handle->flags & UV_HANDLE_READING) { if (handle->flags & UV_HANDLE_READING) {
handle->flags &= ~UV_HANDLE_READING; handle->flags &= ~UV_HANDLE_READING;
handle->loop->active_udp_streams--; handle->loop->active_udp_streams--;
@ -382,7 +382,7 @@ int uv_udp_recv_stop(uv_udp_t* handle) {
} }
static int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[], static int uv__send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
int bufcnt, struct sockaddr* addr, int addr_len, uv_udp_send_cb cb) { int bufcnt, struct sockaddr* addr, int addr_len, uv_udp_send_cb cb) {
uv_loop_t* loop = handle->loop; uv_loop_t* loop = handle->loop;
DWORD result, bytes; DWORD result, bytes;
@ -424,7 +424,7 @@ static int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
} }
int uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[], int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
int bufcnt, struct sockaddr_in addr, uv_udp_send_cb cb) { int bufcnt, struct sockaddr_in addr, uv_udp_send_cb cb) {
if (!(handle->flags & UV_HANDLE_BOUND) && if (!(handle->flags & UV_HANDLE_BOUND) &&
@ -432,7 +432,7 @@ int uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
return -1; return -1;
} }
return uv__udp_send(req, return uv__send(req,
handle, handle,
bufs, bufs,
bufcnt, bufcnt,
@ -442,7 +442,7 @@ int uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
} }
int uv_udp_send6(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[], int uv__udp_send6(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
int bufcnt, struct sockaddr_in6 addr, uv_udp_send_cb cb) { int bufcnt, struct sockaddr_in6 addr, uv_udp_send_cb cb) {
if (!(handle->flags & UV_HANDLE_BOUND) && if (!(handle->flags & UV_HANDLE_BOUND) &&
@ -450,7 +450,7 @@ int uv_udp_send6(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
return -1; return -1;
} }
return uv__udp_send(req, return uv__send(req,
handle, handle,
bufs, bufs,
bufcnt, bufcnt,

3
deps/uv/test/runner.c

@ -102,7 +102,9 @@ int run_tests(int timeout, int benchmark_output) {
continue; continue;
} }
if (!tap_output)
rewind_cursor(); rewind_cursor();
if (!benchmark_output && !tap_output) { if (!benchmark_output && !tap_output) {
log_progress(total, passed, failed, task->task_name); log_progress(total, passed, failed, task->task_name);
} }
@ -115,6 +117,7 @@ int run_tests(int timeout, int benchmark_output) {
current++; current++;
} }
if (!tap_output)
rewind_cursor(); rewind_cursor();
if (!benchmark_output && !tap_output) { if (!benchmark_output && !tap_output) {

2
deps/uv/test/test-list.h

@ -23,6 +23,7 @@ TEST_DECLARE (platform_output)
TEST_DECLARE (callback_order) TEST_DECLARE (callback_order)
TEST_DECLARE (run_once) TEST_DECLARE (run_once)
TEST_DECLARE (run_nowait) TEST_DECLARE (run_nowait)
TEST_DECLARE (loop_stop)
TEST_DECLARE (barrier_1) TEST_DECLARE (barrier_1)
TEST_DECLARE (barrier_2) TEST_DECLARE (barrier_2)
TEST_DECLARE (barrier_3) TEST_DECLARE (barrier_3)
@ -230,6 +231,7 @@ TASK_LIST_START
#endif #endif
TEST_ENTRY (run_once) TEST_ENTRY (run_once)
TEST_ENTRY (run_nowait) TEST_ENTRY (run_nowait)
TEST_ENTRY (loop_stop)
TEST_ENTRY (barrier_1) TEST_ENTRY (barrier_1)
TEST_ENTRY (barrier_2) TEST_ENTRY (barrier_2)
TEST_ENTRY (barrier_3) TEST_ENTRY (barrier_3)

73
deps/uv/test/test-loop-stop.c

@ -0,0 +1,73 @@
/* 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.
*/
#include "uv.h"
#include "task.h"
static uv_prepare_t prepare_handle;
static uv_timer_t timer_handle;
static int prepare_called = 0;
static int timer_called = 0;
static int num_ticks = 10;
static void prepare_cb(uv_prepare_t* handle, int status) {
ASSERT(handle == &prepare_handle);
ASSERT(status == 0);
prepare_called++;
if (prepare_called == num_ticks)
uv_prepare_stop(handle);
}
static void timer_cb(uv_timer_t* handle, int status) {
ASSERT(handle == &timer_handle);
ASSERT(status == 0);
timer_called++;
if (timer_called == 1)
uv_stop(uv_default_loop());
else if (timer_called == num_ticks)
uv_timer_stop(handle);
}
TEST_IMPL(loop_stop) {
int r;
uv_prepare_init(uv_default_loop(), &prepare_handle);
uv_prepare_start(&prepare_handle, prepare_cb);
uv_timer_init(uv_default_loop(), &timer_handle);
uv_timer_start(&timer_handle, timer_cb, 100, 100);
r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r != 0);
ASSERT(timer_called == 1);
r = uv_run(uv_default_loop(), UV_RUN_NOWAIT);
ASSERT(r != 0);
ASSERT(prepare_called == 3);
r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(timer_called == 10);
ASSERT(prepare_called == 10);
return 0;
}

4
deps/uv/uv.gyp

@ -112,7 +112,8 @@
'-pedantic', '-pedantic',
'-Wall', '-Wall',
'-Wextra', '-Wextra',
'-Wno-unused-parameter' '-Wstrict-aliasing',
'-Wno-unused-parameter',
], ],
'sources': [ 'sources': [
'include/uv-private/uv-unix.h', 'include/uv-private/uv-unix.h',
@ -279,6 +280,7 @@
'test/test-ipc-send-recv.c', 'test/test-ipc-send-recv.c',
'test/test-list.h', 'test/test-list.h',
'test/test-loop-handles.c', 'test/test-loop-handles.c',
'test/test-loop-stop.c',
'test/test-walk-handles.c', 'test/test-walk-handles.c',
'test/test-multiple-listen.c', 'test/test-multiple-listen.c',
'test/test-pass-always.c', 'test/test-pass-always.c',

2
deps/uv/vcbuild.bat

@ -77,7 +77,7 @@ if errorlevel 1 goto gyp_install_failed
goto have_gyp goto have_gyp
:gyp_install_failed :gyp_install_failed
echo Failed to download gyp. Make sure you have subversion installed, or echo Failed to download gyp. Make sure you have git installed, or
echo manually install gyp into %~dp0build\gyp. echo manually install gyp into %~dp0build\gyp.
goto exit goto exit

Loading…
Cancel
Save