diff options
author | isaacs <i@izs.me> | 2013-05-10 15:30:53 -0700 |
---|---|---|
committer | isaacs <i@izs.me> | 2013-05-10 15:30:53 -0700 |
commit | fede68fd68924117a46420c1ecfe42fe681b4ae3 (patch) | |
tree | 6ffe361d1b2896a3fd89ec881f7622893c20f142 /deps/uv/src/unix/stream.c | |
parent | ec576235f1f4d7f5873cf3c0118b28c022740ffe (diff) | |
download | android-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.c | 101 |
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); |