Browse Source

Upgrade libuv to 1028a9c6a75fde47b848c09c450fc066249fac1b

v0.7.4-release
Bert Belder 14 years ago
parent
commit
4d3a907f73
  1. 1
      deps/uv/msvs/libuv-test.vcxproj
  2. 87
      deps/uv/src/uv-unix.c
  3. 2
      deps/uv/src/win/core.c
  4. 2
      deps/uv/test/test-list.h
  5. 50
      deps/uv/test/test-loop-handles.c
  6. 91
      deps/uv/test/test-ref.c

1
deps/uv/msvs/libuv-test.vcxproj

@ -160,6 +160,7 @@
<ClCompile Include="..\test\runner-win.c" /> <ClCompile Include="..\test\runner-win.c" />
<ClCompile Include="..\test\runner.c" /> <ClCompile Include="..\test\runner.c" />
<ClCompile Include="..\test\test-pipe-bind-error.c" /> <ClCompile Include="..\test\test-pipe-bind-error.c" />
<ClCompile Include="..\test\test-ref.c" />
<ClCompile Include="..\test\test-shutdown-eof.c" /> <ClCompile Include="..\test\test-shutdown-eof.c" />
<ClCompile Include="..\test\test-tcp-bind-error.c" /> <ClCompile Include="..\test\test-tcp-bind-error.c" />
<ClCompile Include="..\test\test-tcp-bind6-error.c" /> <ClCompile Include="..\test\test-tcp-bind6-error.c" />

87
deps/uv/src/uv-unix.c

@ -88,6 +88,7 @@ static int uv__nonblock(int fd, int set) __attribute__((unused));
static int uv__socket(int domain, int type, int protocol); static int uv__socket(int domain, int type, int protocol);
static int uv__accept(int sockfd, struct sockaddr* saddr, socklen_t len); static int uv__accept(int sockfd, struct sockaddr* saddr, socklen_t len);
static int uv__close(int fd);
size_t uv__strlcpy(char* dst, const char* src, size_t size); size_t uv__strlcpy(char* dst, const char* src, size_t size);
@ -329,7 +330,7 @@ int uv__bind(uv_tcp_t* tcp, int domain, struct sockaddr* addr, int addrsize) {
if (uv__stream_open((uv_stream_t*)tcp, fd)) { if (uv__stream_open((uv_stream_t*)tcp, fd)) {
status = -2; status = -2;
close(fd); uv__close(fd);
goto out; goto out;
} }
} }
@ -464,7 +465,7 @@ int uv_accept(uv_handle_t* server, uv_stream_t* client) {
if (uv__stream_open(streamClient, streamServer->accepted_fd)) { if (uv__stream_open(streamClient, streamServer->accepted_fd)) {
/* TODO handle error */ /* TODO handle error */
streamServer->accepted_fd = -1; streamServer->accepted_fd = -1;
close(streamServer->accepted_fd); uv__close(streamServer->accepted_fd);
goto out; goto out;
} }
@ -494,7 +495,7 @@ int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
} }
if (uv__stream_open((uv_stream_t*)tcp, fd)) { if (uv__stream_open((uv_stream_t*)tcp, fd)) {
close(fd); uv__close(fd);
return -1; return -1;
} }
} }
@ -554,11 +555,11 @@ void uv__finish_close(uv_handle_t* handle) {
assert(!ev_is_active(&stream->read_watcher)); assert(!ev_is_active(&stream->read_watcher));
assert(!ev_is_active(&stream->write_watcher)); assert(!ev_is_active(&stream->write_watcher));
close(stream->fd); uv__close(stream->fd);
stream->fd = -1; stream->fd = -1;
if (stream->accepted_fd >= 0) { if (stream->accepted_fd >= 0) {
close(stream->accepted_fd); uv__close(stream->accepted_fd);
stream->accepted_fd = -1; stream->accepted_fd = -1;
} }
break; break;
@ -678,12 +679,14 @@ static uv_write_t* uv__write(uv_stream_t* stream) {
* inside the iov each time we write. So there is no need to offset it. * inside the iov each time we write. So there is no need to offset it.
*/ */
if (iovcnt == 1) { do {
n = write(stream->fd, iov[0].iov_base, iov[0].iov_len); if (iovcnt == 1) {
} n = write(stream->fd, iov[0].iov_base, iov[0].iov_len);
else { } else {
n = writev(stream->fd, iov, iovcnt); n = writev(stream->fd, iov, iovcnt);
}
} }
while (n == -1 && errno == EINTR);
if (n < 0) { if (n < 0) {
if (errno != EAGAIN) { if (errno != EAGAIN) {
@ -799,7 +802,10 @@ static void uv__read(uv_stream_t* stream) {
iov = (struct iovec*) &buf; iov = (struct iovec*) &buf;
nread = read(stream->fd, buf.base, buf.len); do {
nread = read(stream->fd, buf.base, buf.len);
}
while (nread == -1 && errno == EINTR);
if (nread < 0) { if (nread < 0) {
/* Error */ /* Error */
@ -964,7 +970,7 @@ static int uv__connect(uv_connect_t* req,
} }
if (uv__stream_open(stream, sockfd)) { if (uv__stream_open(stream, sockfd)) {
close(sockfd); uv__close(sockfd);
return -2; return -2;
} }
} }
@ -987,7 +993,10 @@ static int uv__connect(uv_connect_t* req,
stream->connect_req = req; stream->connect_req = req;
r = connect(stream->fd, addr, addrlen); do {
r = connect(stream->fd, addr, addrlen);
}
while (r == -1 && errno == EINTR);
stream->delayed_error = 0; stream->delayed_error = 0;
@ -1839,7 +1848,7 @@ out:
/* unlink() before close() to avoid races. */ /* unlink() before close() to avoid races. */
unlink(name); unlink(name);
} }
close(sockfd); uv__close(sockfd);
free((void*)name); free((void*)name);
} }
@ -1875,6 +1884,7 @@ int uv_pipe_connect(uv_connect_t* req,
int saved_errno; int saved_errno;
int sockfd; int sockfd;
int status; int status;
int r;
saved_errno = errno; saved_errno = errno;
sockfd = -1; sockfd = -1;
@ -1892,9 +1902,14 @@ int uv_pipe_connect(uv_connect_t* req,
/* We don't check for EINPROGRESS. Think about it: the socket /* We don't check for EINPROGRESS. Think about it: the socket
* is either there or not. * is either there or not.
*/ */
if (connect(sockfd, (struct sockaddr*)&sun, sizeof sun) == -1) { do {
r = connect(sockfd, (struct sockaddr*)&sun, sizeof sun);
}
while (r == -1 && errno == EINTR);
if (r == -1) {
uv_err_new((uv_handle_t*)handle, errno); uv_err_new((uv_handle_t*)handle, errno);
close(sockfd); uv__close(sockfd);
goto out; goto out;
} }
@ -1971,7 +1986,7 @@ static int uv__socket(int domain, int type, int protocol) {
} }
if (uv__nonblock(sockfd, 1) == -1 || uv__cloexec(sockfd, 1) == -1) { if (uv__nonblock(sockfd, 1) == -1 || uv__cloexec(sockfd, 1) == -1) {
close(sockfd); uv__close(sockfd);
return -1; return -1;
} }
@ -1981,22 +1996,40 @@ static int uv__socket(int domain, int type, int protocol) {
static int uv__accept(int sockfd, struct sockaddr* saddr, socklen_t slen) { static int uv__accept(int sockfd, struct sockaddr* saddr, socklen_t slen) {
#if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
return accept4(sockfd, saddr, &slen, SOCK_NONBLOCK | SOCK_CLOEXEC);
#else
int peerfd; int peerfd;
if ((peerfd = accept(sockfd, saddr, &slen)) == -1) { do {
return -1; #if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
peerfd = accept4(sockfd, saddr, &slen, SOCK_NONBLOCK | SOCK_CLOEXEC);
#else
if ((peerfd = accept(sockfd, saddr, &slen)) != -1) {
if (uv__cloexec(peerfd, 1) == -1 || uv__nonblock(peerfd, 1) == -1) {
uv__close(peerfd);
return -1;
}
}
#endif
} }
while (peerfd == -1 && errno == EINTR);
if (uv__cloexec(peerfd, 1) == -1 || uv__nonblock(peerfd, 1) == -1) { return peerfd;
close(peerfd); }
return -1;
static int uv__close(int fd) {
int status;
/*
* Retry on EINTR. You may think this is academic but on linux
* and probably other Unices too, close(2) is interruptible.
* Failing to handle EINTR is a common source of fd leaks.
*/
do {
status = close(fd);
} }
while (status == -1 && errno == EINTR);
return peerfd; return status;
#endif
} }

2
deps/uv/src/win/core.c

@ -145,7 +145,7 @@ int uv_run() {
uv_prepare_invoke(); uv_prepare_invoke();
uv_poll(LOOP->idle_handles == NULL); uv_poll(LOOP->idle_handles == NULL && LOOP->refs > 0);
uv_check_invoke(); uv_check_invoke();
} }

2
deps/uv/test/test-list.h

@ -53,6 +53,7 @@ TEST_DECLARE (idle_ref)
TEST_DECLARE (async_ref) TEST_DECLARE (async_ref)
TEST_DECLARE (prepare_ref) TEST_DECLARE (prepare_ref)
TEST_DECLARE (check_ref) TEST_DECLARE (check_ref)
TEST_DECLARE (unref_in_prepare_cb)
TEST_DECLARE (async) TEST_DECLARE (async)
TEST_DECLARE (get_currentexe) TEST_DECLARE (get_currentexe)
TEST_DECLARE (hrtime) TEST_DECLARE (hrtime)
@ -121,6 +122,7 @@ TASK_LIST_START
TEST_ENTRY (async_ref) TEST_ENTRY (async_ref)
TEST_ENTRY (prepare_ref) TEST_ENTRY (prepare_ref)
TEST_ENTRY (check_ref) TEST_ENTRY (check_ref)
TEST_ENTRY (unref_in_prepare_cb)
TEST_ENTRY (loop_handles) TEST_ENTRY (loop_handles)

50
deps/uv/test/test-loop-handles.c

@ -359,53 +359,3 @@ TEST_IMPL(loop_handles) {
return 0; return 0;
} }
TEST_IMPL(ref) {
uv_init();
uv_run();
return 0;
}
TEST_IMPL(idle_ref) {
uv_idle_t h;
uv_init();
uv_idle_init(&h);
uv_idle_start(&h, NULL);
uv_unref();
uv_run();
return 0;
}
TEST_IMPL(async_ref) {
uv_async_t h;
uv_init();
uv_async_init(&h, NULL);
uv_unref();
uv_run();
return 0;
}
TEST_IMPL(prepare_ref) {
uv_prepare_t h;
uv_init();
uv_prepare_init(&h);
uv_prepare_start(&h, NULL);
uv_unref();
uv_run();
return 0;
}
TEST_IMPL(check_ref) {
uv_check_t h;
uv_init();
uv_check_init(&h);
uv_check_start(&h, NULL);
uv_unref();
uv_run();
return 0;
}

91
deps/uv/test/test-ref.c

@ -0,0 +1,91 @@
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "uv.h"
#include "task.h"
TEST_IMPL(ref) {
uv_init();
uv_run();
return 0;
}
TEST_IMPL(idle_ref) {
uv_idle_t h;
uv_init();
uv_idle_init(&h);
uv_idle_start(&h, NULL);
uv_unref();
uv_run();
return 0;
}
TEST_IMPL(async_ref) {
uv_async_t h;
uv_init();
uv_async_init(&h, NULL);
uv_unref();
uv_run();
return 0;
}
TEST_IMPL(prepare_ref) {
uv_prepare_t h;
uv_init();
uv_prepare_init(&h);
uv_prepare_start(&h, NULL);
uv_unref();
uv_run();
return 0;
}
TEST_IMPL(check_ref) {
uv_check_t h;
uv_init();
uv_check_init(&h);
uv_check_start(&h, NULL);
uv_unref();
uv_run();
return 0;
}
static void prepare_cb(uv_prepare_t* handle, int status) {
ASSERT(handle != NULL);
ASSERT(status == 0);
uv_unref();
}
TEST_IMPL(unref_in_prepare_cb) {
uv_prepare_t h;
uv_init();
uv_prepare_init(&h);
uv_prepare_start(&h, prepare_cb);
uv_run();
return 0;
}
Loading…
Cancel
Save