diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c index a281f2e081..9b471ec7ea 100644 --- a/deps/uv/src/unix/core.c +++ b/deps/uv/src/unix/core.c @@ -65,6 +65,17 @@ static void uv__run_pending(uv_loop_t* loop); static uv_loop_t default_loop_struct; static uv_loop_t* default_loop_ptr; +/* Verify that uv_buf_t is ABI-compatible with struct iovec. */ +STATIC_ASSERT(sizeof(uv_buf_t) == sizeof(struct iovec)); +STATIC_ASSERT(sizeof(&((uv_buf_t*) 0)->base) == + sizeof(((struct iovec*) 0)->iov_base)); +STATIC_ASSERT(sizeof(&((uv_buf_t*) 0)->len) == + sizeof(((struct iovec*) 0)->iov_len)); +STATIC_ASSERT((uintptr_t) &((uv_buf_t*) 0)->base == + (uintptr_t) &((struct iovec*) 0)->iov_base); +STATIC_ASSERT((uintptr_t) &((uv_buf_t*) 0)->len == + (uintptr_t) &((struct iovec*) 0)->iov_len); + uint64_t uv_hrtime(void) { return uv__hrtime(); diff --git a/deps/uv/src/unix/darwin.c b/deps/uv/src/unix/darwin.c index 82a640a840..cfbfed23ff 100644 --- a/deps/uv/src/unix/darwin.c +++ b/deps/uv/src/unix/darwin.c @@ -73,7 +73,7 @@ int uv__platform_loop_init(uv_loop_t* loop, int default_loop) { /* Synchronize threads */ uv_sem_wait(&loop->cf_sem); - assert(((volatile CFRunLoopRef) loop->cf_loop) != NULL); + assert(ACCESS_ONCE(CFRunLoopRef, loop->cf_loop) != NULL); return 0; } @@ -109,7 +109,7 @@ void uv__cf_loop_runner(void* arg) { loop = arg; /* Get thread's loop */ - *((volatile CFRunLoopRef*)&loop->cf_loop) = CFRunLoopGetCurrent(); + ACCESS_ONCE(CFRunLoopRef, loop->cf_loop) = CFRunLoopGetCurrent(); CFRunLoopAddSource(loop->cf_loop, loop->cf_cb, diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h index 7d08c1dac9..35b3b8caa8 100644 --- a/deps/uv/src/unix/internal.h +++ b/deps/uv/src/unix/internal.h @@ -45,6 +45,9 @@ # include #endif +#define STATIC_ASSERT(expr) \ + void uv__static_assert(int static_assert_failed[0 - !(expr)]) + #define ACCESS_ONCE(type, var) \ (*(volatile type*) &(var)) @@ -109,7 +112,6 @@ enum { }; /* core */ -void uv__handle_init(uv_loop_t* loop, uv_handle_t* handle, uv_handle_type type); int uv__nonblock(int fd, int set); int uv__cloexec(int fd, int set); int uv__socket(int domain, int type, int protocol); diff --git a/deps/uv/src/unix/threadpool.c b/deps/uv/src/unix/threadpool.c index b071e4a56d..6e5adc403e 100644 --- a/deps/uv/src/unix/threadpool.c +++ b/deps/uv/src/unix/threadpool.c @@ -22,10 +22,14 @@ #include "internal.h" #include +#define MAX_THREADPOOL_SIZE 128 + static uv_once_t once = UV_ONCE_INIT; static uv_cond_t cond; static uv_mutex_t mutex; -static uv_thread_t threads[4]; +static unsigned int nthreads; +static uv_thread_t* threads; +static uv_thread_t default_threads[4]; static ngx_queue_t exit_message; static ngx_queue_t wq; static volatile int initialized; @@ -89,6 +93,25 @@ static void post(ngx_queue_t* q) { static void init_once(void) { unsigned int i; + const char* val; + + nthreads = ARRAY_SIZE(default_threads); + val = getenv("UV_THREADPOOL_SIZE"); + if (val != NULL) + nthreads = atoi(val); + if (nthreads == 0) + nthreads = 1; + if (nthreads > MAX_THREADPOOL_SIZE) + nthreads = MAX_THREADPOOL_SIZE; + + threads = default_threads; + if (nthreads > ARRAY_SIZE(default_threads)) { + threads = malloc(nthreads * sizeof(threads[0])); + if (threads == NULL) { + nthreads = ARRAY_SIZE(default_threads); + threads = default_threads; + } + } if (uv_cond_init(&cond)) abort(); @@ -98,7 +121,7 @@ static void init_once(void) { ngx_queue_init(&wq); - for (i = 0; i < ARRAY_SIZE(threads); i++) + for (i = 0; i < nthreads; i++) if (uv_thread_create(threads + i, worker, NULL)) abort(); @@ -116,12 +139,18 @@ static void cleanup(void) { post(&exit_message); - for (i = 0; i < ARRAY_SIZE(threads); i++) + for (i = 0; i < nthreads; i++) if (uv_thread_join(threads + i)) abort(); + if (threads != default_threads) + free(threads); + uv_mutex_destroy(&mutex); uv_cond_destroy(&cond); + + threads = NULL; + nthreads = 0; initialized = 0; } #endif diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c index 49028985d6..e1a12f2bc5 100644 --- a/deps/uv/src/unix/udp.c +++ b/deps/uv/src/unix/udp.c @@ -216,7 +216,7 @@ static void uv__udp_recvmsg(uv_loop_t* loop, assert(buf.base != NULL); h.msg_namelen = sizeof(peer); - h.msg_iov = (struct iovec*)&buf; + h.msg_iov = (void*) &buf; h.msg_iovlen = 1; do { diff --git a/deps/uv/src/uv-common.h b/deps/uv/src/uv-common.h index 4ba8516913..80c9c7193f 100644 --- a/deps/uv/src/uv-common.h +++ b/deps/uv/src/uv-common.h @@ -115,96 +115,90 @@ int uv__udp_recv_stop(uv_udp_t* handle); void uv__fs_poll_close(uv_fs_poll_t* handle); -UNUSED static int uv__has_active_reqs(const uv_loop_t* loop) { - return !ngx_queue_empty(&loop->active_reqs); -} - -UNUSED static void uv__req_register(uv_loop_t* loop, uv_req_t* req) { - ngx_queue_insert_tail(&loop->active_reqs, &req->active_queue); -} - -UNUSED static void uv__req_unregister(uv_loop_t* loop, uv_req_t* req) { - assert(uv__has_active_reqs(loop)); - ngx_queue_remove(&req->active_queue); -} - - -UNUSED static int uv__has_active_handles(const uv_loop_t* loop) { - return loop->active_handles > 0; -} - -UNUSED static void uv__active_handle_add(uv_handle_t* h) { - h->loop->active_handles++; -} - -UNUSED static void uv__active_handle_rm(uv_handle_t* h) { - h->loop->active_handles--; -} - - -#define uv__active_handle_add(h) uv__active_handle_add((uv_handle_t*)(h)) -#define uv__active_handle_rm(h) uv__active_handle_rm((uv_handle_t*)(h)) - -#define uv__req_register(loop, req) uv__req_register((loop), (uv_req_t*)(req)) -#define uv__req_unregister(loop, req) uv__req_unregister((loop), (uv_req_t*)(req)) - -UNUSED static int uv__is_active(const uv_handle_t* h) { - return !!(h->flags & UV__HANDLE_ACTIVE); -} -#define uv__is_active(h) uv__is_active((const uv_handle_t*)(h)) - -UNUSED static void uv__handle_start(uv_handle_t* h) { - assert(!(h->flags & UV__HANDLE_CLOSING)); - if (h->flags & UV__HANDLE_ACTIVE) - return; - h->flags |= UV__HANDLE_ACTIVE; - if (h->flags & UV__HANDLE_REF) - uv__active_handle_add(h); -} -#define uv__handle_start(h) uv__handle_start((uv_handle_t*)(h)) - -UNUSED static void uv__handle_stop(uv_handle_t* h) { - assert(!(h->flags & UV__HANDLE_CLOSING)); - if (!(h->flags & UV__HANDLE_ACTIVE)) - return; - h->flags &= ~UV__HANDLE_ACTIVE; - if (h->flags & UV__HANDLE_REF) - uv__active_handle_rm(h); -} -#define uv__handle_stop(h) uv__handle_stop((uv_handle_t*)(h)) - -UNUSED static void uv__handle_ref(uv_handle_t* h) { - if (h->flags & UV__HANDLE_REF) - return; - h->flags |= UV__HANDLE_REF; - if (h->flags & UV__HANDLE_CLOSING) - return; - if (h->flags & UV__HANDLE_ACTIVE) - uv__active_handle_add(h); -} -#define uv__handle_ref(h) uv__handle_ref((uv_handle_t*)(h)) - -UNUSED static void uv__handle_unref(uv_handle_t* h) { - if (!(h->flags & UV__HANDLE_REF)) - return; - h->flags &= ~UV__HANDLE_REF; - if (h->flags & UV__HANDLE_CLOSING) - return; - if (h->flags & UV__HANDLE_ACTIVE) - uv__active_handle_rm(h); -} -#define uv__handle_unref(h) uv__handle_unref((uv_handle_t*)(h)) - -UNUSED static void uv__handle_init(uv_loop_t* loop, - uv_handle_t* handle, - uv_handle_type type) { - handle->loop = loop; - handle->type = type; - handle->flags = UV__HANDLE_REF; /* ref the loop when active */ - ngx_queue_insert_tail(&loop->handle_queue, &handle->handle_queue); -#ifndef _WIN32 - handle->next_closing = NULL; +#define uv__has_active_reqs(loop) \ + (ngx_queue_empty(&(loop)->active_reqs) == 0) + +#define uv__req_register(loop, req) \ + do { \ + ngx_queue_insert_tail(&(loop)->active_reqs, &(req)->active_queue); \ + } \ + while (0) + +#define uv__req_unregister(loop, req) \ + do { \ + assert(uv__has_active_reqs(loop)); \ + ngx_queue_remove(&(req)->active_queue); \ + } \ + while (0) + +#define uv__has_active_handles(loop) \ + ((loop)->active_handles > 0) + +#define uv__active_handle_add(h) \ + do { \ + (h)->loop->active_handles++; \ + } \ + while (0) + +#define uv__active_handle_rm(h) \ + do { \ + (h)->loop->active_handles--; \ + } \ + while (0) + +#define uv__is_active(h) \ + (((h)->flags & UV__HANDLE_ACTIVE) != 0) + +#define uv__handle_start(h) \ + do { \ + assert(((h)->flags & UV__HANDLE_CLOSING) == 0); \ + if (((h)->flags & UV__HANDLE_ACTIVE) != 0) break; \ + (h)->flags |= UV__HANDLE_ACTIVE; \ + if (((h)->flags & UV__HANDLE_REF) != 0) uv__active_handle_add(h); \ + } \ + while (0) + +#define uv__handle_stop(h) \ + do { \ + assert(((h)->flags & UV__HANDLE_CLOSING) == 0); \ + if (((h)->flags & UV__HANDLE_ACTIVE) == 0) break; \ + (h)->flags &= ~UV__HANDLE_ACTIVE; \ + if (((h)->flags & UV__HANDLE_REF) != 0) uv__active_handle_rm(h); \ + } \ + while (0) + +#define uv__handle_ref(h) \ + do { \ + if (((h)->flags & UV__HANDLE_REF) != 0) break; \ + (h)->flags |= UV__HANDLE_REF; \ + if (((h)->flags & UV__HANDLE_CLOSING) != 0) break; \ + if (((h)->flags & UV__HANDLE_ACTIVE) != 0) uv__active_handle_add(h); \ + } \ + while (0) + +#define uv__handle_unref(h) \ + do { \ + if (((h)->flags & UV__HANDLE_REF) == 0) break; \ + (h)->flags &= ~UV__HANDLE_REF; \ + if (((h)->flags & UV__HANDLE_CLOSING) != 0) break; \ + if (((h)->flags & UV__HANDLE_ACTIVE) != 0) uv__active_handle_rm(h); \ + } \ + while (0) + +#if defined(_WIN32) +# define uv__handle_platform_init(h) +#else +# define uv__handle_platform_init(h) ((h)->next_closing = NULL) #endif -} + +#define uv__handle_init(loop_, h, type_) \ + do { \ + (h)->loop = (loop_); \ + (h)->type = (type_); \ + (h)->flags = UV__HANDLE_REF; /* Ref the loop when active. */ \ + ngx_queue_insert_tail(&(loop_)->handle_queue, &(h)->handle_queue); \ + uv__handle_platform_init(h); \ + } \ + while (0) #endif /* UV_COMMON_H_ */ diff --git a/deps/uv/src/win/error.c b/deps/uv/src/win/error.c index 40852cffcb..2a72ff2f6e 100644 --- a/deps/uv/src/win/error.c +++ b/deps/uv/src/win/error.c @@ -157,6 +157,7 @@ uv_err_code uv_translate_sys_error(int sys_errno) { case ERROR_SEM_TIMEOUT: return UV_ETIMEDOUT; case WSAETIMEDOUT: return UV_ETIMEDOUT; case ERROR_NOT_SAME_DEVICE: return UV_EXDEV; + case ERROR_INVALID_FUNCTION: return UV_EISDIR; default: return UV_UNKNOWN; } }