diff options
author | Fedor Indutny <fedor@indutny.com> | 2014-09-19 21:37:55 +0400 |
---|---|---|
committer | Timothy J Fontaine <tjfontaine@gmail.com> | 2014-09-23 08:18:41 -0700 |
commit | c5f5d4cd11c2aec74fa03985405122d1ecb06f69 (patch) | |
tree | 17accc5b501eb89e6810cac8df50b54901b6cfee /deps/uv/src/unix | |
parent | 6e08bb94e8b1aaf913cf88106cb59f9d2ae85925 (diff) | |
download | android-node-v8-c5f5d4cd11c2aec74fa03985405122d1ecb06f69.tar.gz android-node-v8-c5f5d4cd11c2aec74fa03985405122d1ecb06f69.tar.bz2 android-node-v8-c5f5d4cd11c2aec74fa03985405122d1ecb06f69.zip |
deps: update uv to v1.0.0-rc1
Diffstat (limited to 'deps/uv/src/unix')
-rw-r--r-- | deps/uv/src/unix/core.c | 57 | ||||
-rw-r--r-- | deps/uv/src/unix/darwin-proctitle.c | 24 | ||||
-rw-r--r-- | deps/uv/src/unix/fs.c | 41 | ||||
-rw-r--r-- | deps/uv/src/unix/fsevents.c | 2 | ||||
-rw-r--r-- | deps/uv/src/unix/getaddrinfo.c | 67 | ||||
-rw-r--r-- | deps/uv/src/unix/internal.h | 2 | ||||
-rw-r--r-- | deps/uv/src/unix/linux-core.c | 21 | ||||
-rw-r--r-- | deps/uv/src/unix/loop.c | 5 | ||||
-rw-r--r-- | deps/uv/src/unix/netbsd.c | 1 | ||||
-rw-r--r-- | deps/uv/src/unix/process.c | 85 | ||||
-rw-r--r-- | deps/uv/src/unix/stream.c | 153 | ||||
-rw-r--r-- | deps/uv/src/unix/timer.c | 3 | ||||
-rw-r--r-- | deps/uv/src/unix/udp.c | 2 |
13 files changed, 307 insertions, 156 deletions
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c index 4770d8d8c6..9dcc3935dc 100644 --- a/deps/uv/src/unix/core.c +++ b/deps/uv/src/unix/core.c @@ -163,6 +163,33 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) { uv__make_close_pending(handle); } +int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) { + int r; + int fd; + socklen_t len; + + if (handle == NULL || value == NULL) + return -EINVAL; + + if (handle->type == UV_TCP || handle->type == UV_NAMED_PIPE) + fd = uv__stream_fd((uv_stream_t*) handle); + else if (handle->type == UV_UDP) + fd = ((uv_udp_t *) handle)->io_watcher.fd; + else + return -ENOTSUP; + + len = sizeof(*value); + + if (*value == 0) + r = getsockopt(fd, SOL_SOCKET, optname, value, &len); + else + r = setsockopt(fd, SOL_SOCKET, optname, (const void*) value, len); + + if (r < 0) + return -errno; + + return 0; +} void uv__make_close_pending(uv_handle_t* handle) { assert(handle->flags & UV_CLOSING); @@ -635,6 +662,36 @@ void uv_disable_stdio_inheritance(void) { } +int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) { + int fd_out; + + switch (handle->type) { + case UV_TCP: + case UV_NAMED_PIPE: + case UV_TTY: + fd_out = uv__stream_fd((uv_stream_t*) handle); + break; + + case UV_UDP: + fd_out = ((uv_udp_t *) handle)->io_watcher.fd; + break; + + case UV_POLL: + fd_out = ((uv_poll_t *) handle)->io_watcher.fd; + break; + + default: + return -EINVAL; + } + + if (uv__is_closing(handle) || fd_out == -1) + return -EBADF; + + *fd = fd_out; + return 0; +} + + static void uv__run_pending(uv_loop_t* loop) { QUEUE* q; uv__io_t* w; diff --git a/deps/uv/src/unix/darwin-proctitle.c b/deps/uv/src/unix/darwin-proctitle.c index 8cd358bcf0..b7267caa99 100644 --- a/deps/uv/src/unix/darwin-proctitle.c +++ b/deps/uv/src/unix/darwin-proctitle.c @@ -36,7 +36,7 @@ static int uv__pthread_setname_np(const char* name) { int err; /* pthread_setname_np() first appeared in OS X 10.6 and iOS 3.2. */ - dynamic_pthread_setname_np = dlsym(RTLD_DEFAULT, "pthread_setname_np"); + *(void **)(&dynamic_pthread_setname_np) = dlsym(RTLD_DEFAULT, "pthread_setname_np"); if (dynamic_pthread_setname_np == NULL) return -ENOSYS; @@ -94,13 +94,13 @@ int uv__set_process_title(const char* title) { if (application_services_handle == NULL || core_foundation_handle == NULL) goto out; - pCFStringCreateWithCString = + *(void **)(&pCFStringCreateWithCString) = dlsym(core_foundation_handle, "CFStringCreateWithCString"); - pCFBundleGetBundleWithIdentifier = + *(void **)(&pCFBundleGetBundleWithIdentifier) = dlsym(core_foundation_handle, "CFBundleGetBundleWithIdentifier"); - pCFBundleGetDataPointerForName = + *(void **)(&pCFBundleGetDataPointerForName) = dlsym(core_foundation_handle, "CFBundleGetDataPointerForName"); - pCFBundleGetFunctionPointerForName = + *(void **)(&pCFBundleGetFunctionPointerForName) = dlsym(core_foundation_handle, "CFBundleGetFunctionPointerForName"); if (pCFStringCreateWithCString == NULL || @@ -118,14 +118,14 @@ int uv__set_process_title(const char* title) { if (launch_services_bundle == NULL) goto out; - pLSGetCurrentApplicationASN = + *(void **)(&pLSGetCurrentApplicationASN) = pCFBundleGetFunctionPointerForName(launch_services_bundle, S("_LSGetCurrentApplicationASN")); if (pLSGetCurrentApplicationASN == NULL) goto out; - pLSSetApplicationInformationItem = + *(void **)(&pLSSetApplicationInformationItem) = pCFBundleGetFunctionPointerForName(launch_services_bundle, S("_LSSetApplicationInformationItem")); @@ -138,9 +138,9 @@ int uv__set_process_title(const char* title) { if (display_name_key == NULL || *display_name_key == NULL) goto out; - pCFBundleGetInfoDictionary = dlsym(core_foundation_handle, + *(void **)(&pCFBundleGetInfoDictionary) = dlsym(core_foundation_handle, "CFBundleGetInfoDictionary"); - pCFBundleGetMainBundle = dlsym(core_foundation_handle, + *(void **)(&pCFBundleGetMainBundle) = dlsym(core_foundation_handle, "CFBundleGetMainBundle"); if (pCFBundleGetInfoDictionary == NULL || pCFBundleGetMainBundle == NULL) goto out; @@ -152,13 +152,13 @@ int uv__set_process_title(const char* title) { if (hi_services_bundle == NULL) goto out; - pSetApplicationIsDaemon = pCFBundleGetFunctionPointerForName( + *(void **)(&pSetApplicationIsDaemon) = pCFBundleGetFunctionPointerForName( hi_services_bundle, S("SetApplicationIsDaemon")); - pLSApplicationCheckIn = pCFBundleGetFunctionPointerForName( + *(void **)(&pLSApplicationCheckIn) = pCFBundleGetFunctionPointerForName( launch_services_bundle, S("_LSApplicationCheckIn")); - pLSSetApplicationLaunchServicesServerConnectionStatus = + *(void **)(&pLSSetApplicationLaunchServicesServerConnectionStatus) = pCFBundleGetFunctionPointerForName( launch_services_bundle, S("_LSSetApplicationLaunchServicesServerConnectionStatus")); diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c index 47f667229d..2dd0fe97cc 100644 --- a/deps/uv/src/unix/fs.c +++ b/deps/uv/src/unix/fs.c @@ -38,7 +38,6 @@ #include <sys/stat.h> #include <sys/time.h> #include <pthread.h> -#include <dirent.h> #include <unistd.h> #include <fcntl.h> #include <utime.h> @@ -296,9 +295,9 @@ done: #if defined(__OpenBSD__) || (defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_8)) -static int uv__fs_readdir_filter(struct dirent* dent) { +static int uv__fs_readdir_filter(uv__dirent_t* dent) { #else -static int uv__fs_readdir_filter(const struct dirent* dent) { +static int uv__fs_readdir_filter(const uv__dirent_t* dent) { #endif return strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0; } @@ -306,12 +305,8 @@ static int uv__fs_readdir_filter(const struct dirent* dent) { /* This should have been called uv__fs_scandir(). */ static ssize_t uv__fs_readdir(uv_fs_t* req) { - struct dirent **dents; + uv__dirent_t **dents; int saved_errno; - size_t off; - size_t len; - char *buf; - int i; int n; dents = NULL; @@ -322,32 +317,17 @@ static ssize_t uv__fs_readdir(uv_fs_t* req) { else if (n == -1) return n; - len = 0; - - for (i = 0; i < n; i++) - len += strlen(dents[i]->d_name) + 1; - - buf = malloc(len); - - if (buf == NULL) { - errno = ENOMEM; - n = -1; - goto out; - } - - off = 0; - - for (i = 0; i < n; i++) { - len = strlen(dents[i]->d_name) + 1; - memcpy(buf + off, dents[i]->d_name, len); - off += len; - } + /* NOTE: We will use nbufs as an index field */ + req->ptr = dents; + req->nbufs = 0; - req->ptr = buf; + return n; out: saved_errno = errno; if (dents != NULL) { + int i; + for (i = 0; i < n; i++) free(dents[i]); free(dents); @@ -1184,6 +1164,9 @@ void uv_fs_req_cleanup(uv_fs_t* req) { req->path = NULL; req->new_path = NULL; + if (req->fs_type == UV_FS_READDIR && req->ptr != NULL) + uv__fs_readdir_cleanup(req); + if (req->ptr != &req->statbuf) free(req->ptr); req->ptr = NULL; diff --git a/deps/uv/src/unix/fsevents.c b/deps/uv/src/unix/fsevents.c index 1c7896d8d7..49085306b9 100644 --- a/deps/uv/src/unix/fsevents.c +++ b/deps/uv/src/unix/fsevents.c @@ -525,7 +525,7 @@ static int uv__fsevents_global_init(void) { err = -ENOENT; #define V(handle, symbol) \ do { \ - p ## symbol = dlsym((handle), #symbol); \ + *(void **)(&p ## symbol) = dlsym((handle), #symbol); \ if (p ## symbol == NULL) \ goto out; \ } \ diff --git a/deps/uv/src/unix/getaddrinfo.c b/deps/uv/src/unix/getaddrinfo.c index 1db00680d1..f6c2de9b43 100644 --- a/deps/uv/src/unix/getaddrinfo.c +++ b/deps/uv/src/unix/getaddrinfo.c @@ -18,6 +18,13 @@ * IN THE SOFTWARE. */ +/* Expose glibc-specific EAI_* error codes. Needs to be defined before we + * include any headers. + */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + #include "uv.h" #include "internal.h" @@ -26,6 +33,66 @@ #include <stdlib.h> #include <string.h> +/* EAI_* constants. */ +#include <netdb.h> + + +int uv__getaddrinfo_translate_error(int sys_err) { + switch (sys_err) { + case 0: return 0; +#if defined(EAI_ADDRFAMILY) + case EAI_ADDRFAMILY: return UV_EAI_ADDRFAMILY; +#endif +#if defined(EAI_AGAIN) + case EAI_AGAIN: return UV_EAI_AGAIN; +#endif +#if defined(EAI_BADFLAGS) + case EAI_BADFLAGS: return UV_EAI_BADFLAGS; +#endif +#if defined(EAI_BADHINTS) + case EAI_BADHINTS: return UV_EAI_BADHINTS; +#endif +#if defined(EAI_CANCELED) + case EAI_CANCELED: return UV_EAI_CANCELED; +#endif +#if defined(EAI_FAIL) + case EAI_FAIL: return UV_EAI_FAIL; +#endif +#if defined(EAI_FAMILY) + case EAI_FAMILY: return UV_EAI_FAMILY; +#endif +#if defined(EAI_MEMORY) + case EAI_MEMORY: return UV_EAI_MEMORY; +#endif +#if defined(EAI_NODATA) + case EAI_NODATA: return UV_EAI_NODATA; +#endif +#if defined(EAI_NONAME) +# if !defined(EAI_NODATA) || EAI_NODATA != EAI_NONAME + case EAI_NONAME: return UV_EAI_NONAME; +# endif +#endif +#if defined(EAI_OVERFLOW) + case EAI_OVERFLOW: return UV_EAI_OVERFLOW; +#endif +#if defined(EAI_PROTOCOL) + case EAI_PROTOCOL: return UV_EAI_PROTOCOL; +#endif +#if defined(EAI_SERVICE) + case EAI_SERVICE: return UV_EAI_SERVICE; +#endif +#if defined(EAI_SOCKTYPE) + case EAI_SOCKTYPE: return UV_EAI_SOCKTYPE; +#endif +#if defined(EAI_SYSTEM) + case EAI_SYSTEM: return -errno; +#endif + } + assert(!"unknown EAI_* error code"); + abort(); + return 0; /* Pacify compiler. */ +} + static void uv__getaddrinfo_work(struct uv__work* w) { uv_getaddrinfo_t* req; diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h index 114cb696ee..d5bc3109f0 100644 --- a/deps/uv/src/unix/internal.h +++ b/deps/uv/src/unix/internal.h @@ -143,7 +143,7 @@ enum { UV_TCP_NODELAY = 0x400, /* Disable Nagle. */ UV_TCP_KEEPALIVE = 0x800, /* Turn on keep-alive. */ UV_TCP_SINGLE_ACCEPT = 0x1000, /* Only accept() when idle. */ - UV_HANDLE_IPV6 = 0x2000 /* Handle is bound to a IPv6 socket. */ + UV_HANDLE_IPV6 = 0x10000 /* Handle is bound to a IPv6 socket. */ }; typedef enum { diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c index 5f6215998c..7a43630494 100644 --- a/deps/uv/src/unix/linux-core.c +++ b/deps/uv/src/unix/linux-core.c @@ -149,6 +149,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { int fd; int op; int i; + static int no_epoll_wait; if (loop->nfds == 0) { assert(QUEUE_EMPTY(&loop->watcher_queue)); @@ -195,10 +196,22 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { count = 48; /* Benchmarks suggest this gives the best throughput. */ for (;;) { - nfds = uv__epoll_wait(loop->backend_fd, - events, - ARRAY_SIZE(events), - timeout); + if (!no_epoll_wait) { + nfds = uv__epoll_wait(loop->backend_fd, + events, + ARRAY_SIZE(events), + timeout); + if (nfds == -1 && errno == ENOSYS) { + no_epoll_wait = 1; + continue; + } + } else { + nfds = uv__epoll_pwait(loop->backend_fd, + events, + ARRAY_SIZE(events), + timeout, + NULL); + } /* Update loop->time unconditionally. It's tempting to skip the update when * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the diff --git a/deps/uv/src/unix/loop.c b/deps/uv/src/unix/loop.c index aa74be6455..002224855c 100644 --- a/deps/uv/src/unix/loop.c +++ b/deps/uv/src/unix/loop.c @@ -99,7 +99,6 @@ void uv_loop_delete(uv_loop_t* loop) { static int uv__loop_init(uv_loop_t* loop, int default_loop) { - unsigned int i; int err; uv__signal_global_once_init(); @@ -138,9 +137,7 @@ static int uv__loop_init(uv_loop_t* loop, int default_loop) { uv_signal_init(loop, &loop->child_watcher); uv__handle_unref(&loop->child_watcher); loop->child_watcher.flags |= UV__HANDLE_INTERNAL; - - for (i = 0; i < ARRAY_SIZE(loop->process_handles); i++) - QUEUE_INIT(loop->process_handles + i); + QUEUE_INIT(&loop->process_handles); if (uv_rwlock_init(&loop->cloexec_lock)) abort(); diff --git a/deps/uv/src/unix/netbsd.c b/deps/uv/src/unix/netbsd.c index 7423a71078..5f1182f8b4 100644 --- a/deps/uv/src/unix/netbsd.c +++ b/deps/uv/src/unix/netbsd.c @@ -38,6 +38,7 @@ #include <sys/resource.h> #include <sys/types.h> #include <sys/sysctl.h> +#include <uvm/uvm_extern.h> #include <unistd.h> #include <time.h> diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c index 52e4eb2813..0aff5fd31f 100644 --- a/deps/uv/src/unix/process.c +++ b/deps/uv/src/unix/process.c @@ -45,77 +45,65 @@ extern char **environ; #endif -static QUEUE* uv__process_queue(uv_loop_t* loop, int pid) { - assert(pid > 0); - return loop->process_handles + pid % ARRAY_SIZE(loop->process_handles); -} - - static void uv__chld(uv_signal_t* handle, int signum) { uv_process_t* process; uv_loop_t* loop; int exit_status; int term_signal; - unsigned int i; int status; pid_t pid; QUEUE pending; - QUEUE* h; QUEUE* q; + QUEUE* h; assert(signum == SIGCHLD); QUEUE_INIT(&pending); loop = handle->loop; - for (i = 0; i < ARRAY_SIZE(loop->process_handles); i++) { - h = loop->process_handles + i; - q = QUEUE_HEAD(h); + h = &loop->process_handles; + q = QUEUE_HEAD(h); + while (q != h) { + process = QUEUE_DATA(q, uv_process_t, queue); + q = QUEUE_NEXT(q); - while (q != h) { - process = QUEUE_DATA(q, uv_process_t, queue); - q = QUEUE_NEXT(q); + do + pid = waitpid(process->pid, &status, WNOHANG); + while (pid == -1 && errno == EINTR); - do - pid = waitpid(process->pid, &status, WNOHANG); - while (pid == -1 && errno == EINTR); - - if (pid == 0) - continue; - - if (pid == -1) { - if (errno != ECHILD) - abort(); - continue; - } + if (pid == 0) + continue; - process->status = status; - QUEUE_REMOVE(&process->queue); - QUEUE_INSERT_TAIL(&pending, &process->queue); + if (pid == -1) { + if (errno != ECHILD) + abort(); + continue; } - while (!QUEUE_EMPTY(&pending)) { - q = QUEUE_HEAD(&pending); - QUEUE_REMOVE(q); - QUEUE_INIT(q); + process->status = status; + QUEUE_REMOVE(&process->queue); + QUEUE_INSERT_TAIL(&pending, &process->queue); + } - process = QUEUE_DATA(q, uv_process_t, queue); - uv__handle_stop(process); + QUEUE_FOREACH(q, &pending) { + process = QUEUE_DATA(q, uv_process_t, queue); + QUEUE_REMOVE(q); + uv__handle_stop(process); - if (process->exit_cb == NULL) - continue; + if (process->exit_cb == NULL) + continue; - exit_status = 0; - if (WIFEXITED(process->status)) - exit_status = WEXITSTATUS(process->status); + exit_status = 0; + if (WIFEXITED(process->status)) + exit_status = WEXITSTATUS(process->status); - term_signal = 0; - if (WIFSIGNALED(process->status)) - term_signal = WTERMSIG(process->status); + term_signal = 0; + if (WIFSIGNALED(process->status)) + term_signal = WTERMSIG(process->status); - process->exit_cb(process, exit_status, term_signal); - } + process->exit_cb(process, exit_status, term_signal); } + assert(QUEUE_EMPTY(&pending)); } @@ -369,7 +357,6 @@ int uv_spawn(uv_loop_t* loop, int signal_pipe[2] = { -1, -1 }; int (*pipes)[2]; int stdio_count; - QUEUE* q; ssize_t r; pid_t pid; int err; @@ -483,8 +470,7 @@ int uv_spawn(uv_loop_t* loop, /* Only activate this handle if exec() happened successfully */ if (exec_errorno == 0) { - q = uv__process_queue(loop, pid); - QUEUE_INSERT_TAIL(q, &process->queue); + QUEUE_INSERT_TAIL(&loop->process_handles, &process->queue); uv__handle_start(process); } @@ -526,7 +512,8 @@ int uv_kill(int pid, int signum) { void uv__process_close(uv_process_t* handle) { - /* TODO stop signal watcher when this is the last handle */ QUEUE_REMOVE(&handle->queue); uv__handle_stop(handle); + if (QUEUE_EMPTY(&handle->loop->process_handles)) + uv_signal_stop(&handle->loop->child_watcher); } diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c index ae7880c33f..9c7d28cbf4 100644 --- a/deps/uv/src/unix/stream.c +++ b/deps/uv/src/unix/stream.c @@ -53,6 +53,10 @@ struct uv__stream_select_s { int fake_fd; int int_fd; int fd; + fd_set* sread; + size_t sread_sz; + fd_set* swrite; + size_t swrite_sz; }; #endif /* defined(__APPLE__) */ @@ -127,8 +131,6 @@ static void uv__stream_osx_select(void* arg) { uv_stream_t* stream; uv__stream_select_t* s; char buf[1024]; - fd_set sread; - fd_set swrite; int events; int fd; int r; @@ -149,17 +151,17 @@ static void uv__stream_osx_select(void* arg) { break; /* Watch fd using select(2) */ - FD_ZERO(&sread); - FD_ZERO(&swrite); + memset(s->sread, 0, s->sread_sz); + memset(s->swrite, 0, s->swrite_sz); if (uv__io_active(&stream->io_watcher, UV__POLLIN)) - FD_SET(fd, &sread); + FD_SET(fd, s->sread); if (uv__io_active(&stream->io_watcher, UV__POLLOUT)) - FD_SET(fd, &swrite); - FD_SET(s->int_fd, &sread); + FD_SET(fd, s->swrite); + FD_SET(s->int_fd, s->sread); /* Wait indefinitely for fd events */ - r = select(max_fd + 1, &sread, &swrite, NULL, NULL); + r = select(max_fd + 1, s->sread, s->swrite, NULL, NULL); if (r == -1) { if (errno == EINTR) continue; @@ -173,7 +175,7 @@ static void uv__stream_osx_select(void* arg) { continue; /* Empty socketpair's buffer in case of interruption */ - if (FD_ISSET(s->int_fd, &sread)) + if (FD_ISSET(s->int_fd, s->sread)) while (1) { r = read(s->int_fd, buf, sizeof(buf)); @@ -194,12 +196,12 @@ static void uv__stream_osx_select(void* arg) { /* Handle events */ events = 0; - if (FD_ISSET(fd, &sread)) + if (FD_ISSET(fd, s->sread)) events |= UV__POLLIN; - if (FD_ISSET(fd, &swrite)) + if (FD_ISSET(fd, s->swrite)) events |= UV__POLLOUT; - assert(events != 0 || FD_ISSET(s->int_fd, &sread)); + assert(events != 0 || FD_ISSET(s->int_fd, s->sread)); if (events != 0) { ACCESS_ONCE(int, s->events) = events; @@ -261,6 +263,9 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) { int ret; int kq; int old_fd; + int max_fd; + size_t sread_sz; + size_t swrite_sz; kq = kqueue(); if (kq == -1) { @@ -284,31 +289,48 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) { return 0; /* At this point we definitely know that this fd won't work with kqueue */ - s = malloc(sizeof(*s)); - if (s == NULL) - return -ENOMEM; + + /* + * Create fds for io watcher and to interrupt the select() loop. + * NOTE: do it ahead of malloc below to allocate enough space for fd_sets + */ + if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) + return -errno; + + max_fd = *fd; + if (fds[1] > max_fd) + max_fd = fds[1]; + + sread_sz = (max_fd + NBBY) / NBBY; + swrite_sz = sread_sz; + + s = malloc(sizeof(*s) + sread_sz + swrite_sz); + if (s == NULL) { + err = -ENOMEM; + goto failed_malloc; + } s->events = 0; s->fd = *fd; + s->sread = (fd_set*) ((char*) s + sizeof(*s)); + s->sread_sz = sread_sz; + s->swrite = (fd_set*) ((char*) s->sread + sread_sz); + s->swrite_sz = swrite_sz; err = uv_async_init(stream->loop, &s->async, uv__stream_osx_select_cb); - if (err) { - free(s); - return err; - } + if (err) + goto failed_async_init; s->async.flags |= UV__HANDLE_INTERNAL; uv__handle_unref(&s->async); - if (uv_sem_init(&s->close_sem, 0)) - goto fatal1; - - if (uv_sem_init(&s->async_sem, 0)) - goto fatal2; + err = uv_sem_init(&s->close_sem, 0); + if (err != 0) + goto failed_close_sem_init; - /* Create fds for io watcher and to interrupt the select() loop. */ - if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) - goto fatal3; + err = uv_sem_init(&s->async_sem, 0); + if (err != 0) + goto failed_async_sem_init; s->fake_fd = fds[0]; s->int_fd = fds[1]; @@ -318,26 +340,36 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) { stream->select = s; *fd = s->fake_fd; - if (uv_thread_create(&s->thread, uv__stream_osx_select, stream)) - goto fatal4; + err = uv_thread_create(&s->thread, uv__stream_osx_select, stream); + if (err != 0) + goto failed_thread_create; return 0; -fatal4: +failed_thread_create: s->stream = NULL; stream->select = NULL; *fd = old_fd; - uv__close(s->fake_fd); - uv__close(s->int_fd); - s->fake_fd = -1; - s->int_fd = -1; -fatal3: + uv_sem_destroy(&s->async_sem); -fatal2: + +failed_async_sem_init: uv_sem_destroy(&s->close_sem); -fatal1: + +failed_close_sem_init: + uv__close(fds[0]); + uv__close(fds[1]); uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close); - return -errno; + return err; + +failed_async_init: + free(s); + +failed_malloc: + uv__close(fds[0]); + uv__close(fds[1]); + + return err; } #endif /* defined(__APPLE__) */ @@ -361,10 +393,22 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) { } -void uv__stream_destroy(uv_stream_t* stream) { +void uv__stream_flush_write_queue(uv_stream_t* stream, int error) { uv_write_t* req; QUEUE* q; + while (!QUEUE_EMPTY(&stream->write_queue)) { + q = QUEUE_HEAD(&stream->write_queue); + QUEUE_REMOVE(q); + req = QUEUE_DATA(q, uv_write_t, queue); + req->error = error; + + QUEUE_INSERT_TAIL(&stream->write_completed_queue, &req->queue); + } +} + + +void uv__stream_destroy(uv_stream_t* stream) { assert(!uv__io_active(&stream->io_watcher, UV__POLLIN | UV__POLLOUT)); assert(stream->flags & UV_CLOSED); @@ -374,16 +418,7 @@ void uv__stream_destroy(uv_stream_t* stream) { stream->connect_req = NULL; } - while (!QUEUE_EMPTY(&stream->write_queue)) { - q = QUEUE_HEAD(&stream->write_queue); - QUEUE_REMOVE(q); - - req = QUEUE_DATA(q, uv_write_t, queue); - req->error = -ECANCELED; - - QUEUE_INSERT_TAIL(&stream->write_completed_queue, &req->queue); - } - + uv__stream_flush_write_queue(stream, -ECANCELED); uv__write_callbacks(stream); if (stream->shutdown_req) { @@ -537,7 +572,7 @@ int uv_accept(uv_stream_t* server, uv_stream_t* client) { break; default: - assert(0); + return -EINVAL; } done: @@ -573,7 +608,6 @@ done: int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) { int err; - err = -EINVAL; switch (stream->type) { case UV_TCP: err = uv_tcp_listen((uv_tcp_t*)stream, backlog, cb); @@ -584,7 +618,7 @@ int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) { break; default: - assert(0); + err = -EINVAL; } if (err == 0) @@ -1163,7 +1197,7 @@ static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { assert(uv__stream_fd(stream) >= 0); /* Ignore POLLHUP here. Even it it's set, there may still be data to read. */ - if (events & (UV__POLLIN | UV__POLLERR)) + if (events & (UV__POLLIN | UV__POLLERR | UV__POLLHUP)) uv__read(stream); if (uv__stream_fd(stream) == -1) @@ -1233,10 +1267,21 @@ static void uv__stream_connect(uv_stream_t* stream) { stream->connect_req = NULL; uv__req_unregister(stream->loop, req); - uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT); + + if (error < 0 || QUEUE_EMPTY(&stream->write_queue)) { + uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT); + } if (req->cb) req->cb(req, error); + + if (uv__stream_fd(stream) == -1) + return; + + if (error < 0) { + uv__stream_flush_write_queue(stream, -ECANCELED); + uv__write_callbacks(stream); + } } diff --git a/deps/uv/src/unix/timer.c b/deps/uv/src/unix/timer.c index 9bd0423b5d..ca3ec3db95 100644 --- a/deps/uv/src/unix/timer.c +++ b/deps/uv/src/unix/timer.c @@ -65,6 +65,9 @@ int uv_timer_start(uv_timer_t* handle, uint64_t repeat) { uint64_t clamped_timeout; + if (cb == NULL) + return -EINVAL; + if (uv__is_active(handle)) uv_timer_stop(handle); diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c index bf91cbdf9f..7cafea1d08 100644 --- a/deps/uv/src/unix/udp.c +++ b/deps/uv/src/unix/udp.c @@ -340,8 +340,6 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, unsigned char taddr[sizeof(struct sockaddr_in6)]; socklen_t addrlen; - assert(domain == AF_INET || domain == AF_INET6); - if (handle->io_watcher.fd != -1) return 0; |