aboutsummaryrefslogtreecommitdiff
path: root/deps/uv/src/unix
diff options
context:
space:
mode:
authorFedor Indutny <fedor@indutny.com>2014-09-19 21:37:55 +0400
committerTimothy J Fontaine <tjfontaine@gmail.com>2014-09-23 08:18:41 -0700
commitc5f5d4cd11c2aec74fa03985405122d1ecb06f69 (patch)
tree17accc5b501eb89e6810cac8df50b54901b6cfee /deps/uv/src/unix
parent6e08bb94e8b1aaf913cf88106cb59f9d2ae85925 (diff)
downloadandroid-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.c57
-rw-r--r--deps/uv/src/unix/darwin-proctitle.c24
-rw-r--r--deps/uv/src/unix/fs.c41
-rw-r--r--deps/uv/src/unix/fsevents.c2
-rw-r--r--deps/uv/src/unix/getaddrinfo.c67
-rw-r--r--deps/uv/src/unix/internal.h2
-rw-r--r--deps/uv/src/unix/linux-core.c21
-rw-r--r--deps/uv/src/unix/loop.c5
-rw-r--r--deps/uv/src/unix/netbsd.c1
-rw-r--r--deps/uv/src/unix/process.c85
-rw-r--r--deps/uv/src/unix/stream.c153
-rw-r--r--deps/uv/src/unix/timer.c3
-rw-r--r--deps/uv/src/unix/udp.c2
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;