summaryrefslogtreecommitdiff
path: root/deps/uv/src/unix/stream.c
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2013-05-10 15:30:53 -0700
committerisaacs <i@izs.me>2013-05-10 15:30:53 -0700
commitfede68fd68924117a46420c1ecfe42fe681b4ae3 (patch)
tree6ffe361d1b2896a3fd89ec881f7622893c20f142 /deps/uv/src/unix/stream.c
parentec576235f1f4d7f5873cf3c0118b28c022740ffe (diff)
downloadandroid-node-v8-fede68fd68924117a46420c1ecfe42fe681b4ae3.tar.gz
android-node-v8-fede68fd68924117a46420c1ecfe42fe681b4ae3.tar.bz2
android-node-v8-fede68fd68924117a46420c1ecfe42fe681b4ae3.zip
uv: Upgrade to 0.11.2
Diffstat (limited to 'deps/uv/src/unix/stream.c')
-rw-r--r--deps/uv/src/unix/stream.c101
1 files changed, 40 insertions, 61 deletions
diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c
index 7a185ab621..0c38231d68 100644
--- a/deps/uv/src/unix/stream.c
+++ b/deps/uv/src/unix/stream.c
@@ -46,8 +46,8 @@ typedef struct uv__stream_select_s uv__stream_select_t;
struct uv__stream_select_s {
uv_stream_t* stream;
uv_thread_t thread;
- uv_sem_t sem;
- uv_mutex_t mutex;
+ uv_sem_t close_sem;
+ uv_sem_t async_sem;
uv_async_t async;
int events;
int fake_fd;
@@ -139,7 +139,7 @@ static void uv__stream_osx_select(void* arg) {
stream = arg;
s = stream->select;
- fd = stream->io_watcher.fd;
+ fd = s->fd;
if (fd > s->int_fd)
max_fd = fd;
@@ -148,7 +148,7 @@ static void uv__stream_osx_select(void* arg) {
while (1) {
/* Terminate on semaphore */
- if (uv_sem_trywait(&s->sem) == 0)
+ if (uv_sem_trywait(&s->close_sem) == 0)
break;
/* Watch fd using select(2) */
@@ -202,12 +202,16 @@ static void uv__stream_osx_select(void* arg) {
if (FD_ISSET(fd, &swrite))
events |= UV__POLLOUT;
- uv_mutex_lock(&s->mutex);
- s->events |= events;
- uv_mutex_unlock(&s->mutex);
+ assert(events != 0 || FD_ISSET(s->int_fd, &sread));
+ if (events != 0) {
+ ACCESS_ONCE(int, s->events) = events;
- if (events != 0)
uv_async_send(&s->async);
+ uv_sem_wait(&s->async_sem);
+
+ /* Should be processed at this stage */
+ assert((s->events == 0) || (stream->flags & UV_CLOSING));
+ }
}
}
@@ -240,10 +244,9 @@ static void uv__stream_osx_select_cb(uv_async_t* handle, int status) {
stream = s->stream;
/* Get and reset stream's events */
- uv_mutex_lock(&s->mutex);
events = s->events;
- s->events = 0;
- uv_mutex_unlock(&s->mutex);
+ ACCESS_ONCE(int, s->events) = 0;
+ uv_sem_post(&s->async_sem);
assert(events != 0);
assert(events == (events & (UV__POLLIN | UV__POLLOUT)));
@@ -305,6 +308,7 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
if (s == NULL)
return uv__set_artificial_error(stream->loop, UV_ENOMEM);
+ s->events = 0;
s->fd = *fd;
if (uv_async_init(stream->loop, &s->async, uv__stream_osx_select_cb)) {
@@ -315,10 +319,10 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
s->async.flags |= UV__HANDLE_INTERNAL;
uv__handle_unref(&s->async);
- if (uv_sem_init(&s->sem, 0))
+ if (uv_sem_init(&s->close_sem, 0))
goto fatal1;
- if (uv_mutex_init(&s->mutex))
+ if (uv_sem_init(&s->async_sem, 0))
goto fatal2;
/* Create fds for io watcher and to interrupt the select() loop. */
@@ -343,9 +347,9 @@ fatal4:
s->fake_fd = -1;
s->int_fd = -1;
fatal3:
- uv_mutex_destroy(&s->mutex);
+ uv_sem_destroy(&s->async_sem);
fatal2:
- uv_sem_destroy(&s->sem);
+ uv_sem_destroy(&s->close_sem);
fatal1:
uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close);
return uv__set_sys_error(stream->loop, errno);
@@ -437,7 +441,6 @@ void uv__stream_destroy(uv_stream_t* stream) {
*/
static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) {
int fd;
- int r;
if (loop->emfile_fd == -1)
return -1;
@@ -455,14 +458,8 @@ static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) {
if (errno == EINTR)
continue;
- if (errno == EAGAIN || errno == EWOULDBLOCK)
- r = 0;
- else
- r = -1;
-
- loop->emfile_fd = uv__open_cloexec("/", O_RDONLY);
-
- return r;
+ SAVE_ERRNO(loop->emfile_fd = uv__open_cloexec("/", O_RDONLY));
+ return errno;
}
}
@@ -475,10 +472,9 @@ static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) {
void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
- static int use_emfile_trick = -1;
uv_stream_t* stream;
+ int err;
int fd;
- int r;
stream = container_of(w, uv_stream_t, io_watcher);
assert(events == UV__POLLIN);
@@ -492,50 +488,32 @@ void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
*/
while (uv__stream_fd(stream) != -1) {
assert(stream->accepted_fd == -1);
+
#if defined(UV_HAVE_KQUEUE)
if (w->rcount <= 0)
return;
#endif /* defined(UV_HAVE_KQUEUE) */
- fd = uv__accept(uv__stream_fd(stream));
+ fd = uv__accept(uv__stream_fd(stream));
if (fd == -1) {
- switch (errno) {
-#if EWOULDBLOCK != EAGAIN
- case EWOULDBLOCK:
-#endif
- case EAGAIN:
- return; /* Not an error. */
-
- case ECONNABORTED:
- UV_DEC_BACKLOG(w)
- continue; /* Ignore. */
-
- case EMFILE:
- case ENFILE:
- if (use_emfile_trick == -1) {
- const char* val = getenv("UV_ACCEPT_EMFILE_TRICK");
- use_emfile_trick = (val == NULL || atoi(val) != 0);
- }
-
- if (use_emfile_trick) {
- SAVE_ERRNO(r = uv__emfile_trick(loop, uv__stream_fd(stream)));
- if (r == 0) {
- UV_DEC_BACKLOG(w)
- continue;
- }
- }
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
+ return; /* Not an error. */
- /* Fall through. */
+ if (errno == ECONNABORTED)
+ continue; /* Ignore. Nothing we can do about that. */
- default:
- uv__set_sys_error(loop, errno);
- stream->connection_cb(stream, -1);
- continue;
+ if (errno == EMFILE || errno == ENFILE) {
+ SAVE_ERRNO(err = uv__emfile_trick(loop, uv__stream_fd(stream)));
+ if (err == EAGAIN || err == EWOULDBLOCK)
+ break;
}
+
+ uv__set_sys_error(loop, errno);
+ stream->connection_cb(stream, -1);
+ continue;
}
UV_DEC_BACKLOG(w)
-
stream->accepted_fd = fd;
stream->connection_cb(stream, 0);
@@ -1356,11 +1334,12 @@ void uv__stream_close(uv_stream_t* handle) {
s = handle->select;
- uv_sem_post(&s->sem);
+ uv_sem_post(&s->close_sem);
+ uv_sem_post(&s->async_sem);
uv__stream_osx_interrupt_select(handle);
uv_thread_join(&s->thread);
- uv_sem_destroy(&s->sem);
- uv_mutex_destroy(&s->mutex);
+ uv_sem_destroy(&s->close_sem);
+ uv_sem_destroy(&s->async_sem);
close(s->fake_fd);
close(s->int_fd);
uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close);