1
0
mirror of https://github.com/libuv/libuv synced 2025-03-28 21:13:16 +00:00

Merge remote-tracking branch 'origin/v0.10'

Conflicts:
	ChangeLog
	src/version.c
This commit is contained in:
Ben Noordhuis 2013-05-02 09:22:39 +02:00
commit ebdeaed2e3
9 changed files with 225 additions and 187 deletions

View File

@ -84,3 +84,4 @@ Ben Kelly <ben@wanderview.com>
Kristian Evensen <kristian.evensen@gmail.com>
Nils Maier <maierman@web.de>
Nicholas Vavilov <vvnicholas@gmail.com>
Miroslav Bajtoš <miro.bajtos@gmail.com>

View File

@ -1,39 +1,16 @@
2013.04.11, Version 0.11.1 (Unstable), 5c10e82ae0bc99eff86d4b9baff1f1aa0bf84c0a
2013.04.24, Version 0.10.5 (Stable), 6595a7732c52eb4f8e57c88655f72997a8567a67
This is the first versioned release from the current unstable libuv branch.
Changes since version 0.10.4:
Changes since Node.js v0.11.0:
* unix: silence STATIC_ASSERT compiler warnings (Ben Noordhuis)
* all platforms: nanosecond resolution support for uv_fs_[fl]stat (Timothy J.
Fontaine)
* windows: make timers handle large timeouts (Miroslav Bajtoš)
* all platforms: add netmask to uv_interface_address (Ben Kelly)
* windows: remove superfluous assert statement (Bert Belder)
* unix: make sure the `status` parameter passed to the `uv_getaddrinfo` is 0 or
-1 (Ben Noordhuis)
* unix: silence STATIC_ASSERT compiler warnings (Ben Noordhuis)
* unix: limit the number of iovecs written in a single `writev` syscall to
IOV_MAX (Fedor Indutny)
* unix: add dtrace probes for tick-start and tick-stop (Timothy J. Fontaine)
* mingw-w64: don't call _set_invalid_parameter_handler (Nils Maier)
* windows: fix memory leak in fs__sendfile (Shannen Saez)
* windows: fix edge case bugs in uv_cpu_info (Bert Belder)
* include: no longer ship with / include ngx-queue.h (Ben Noordhuis)
* include: remove UV_VERSION_* macros from uv.h (Ben Noordhuis)
* documentation updates (Kristian Evensen, Ben Kelly, Ben Noordhuis)
* build: fix dtrace-enabled builds (Ben Noordhuis, Timothy J. Fontaine)
* build: gyp disable thin archives (Timothy J. Fontaine)
* build: add support for Visual Studio 2012 (Nicholas Vavilov)
* linux: don't use fopen() in uv_resident_set_memory() (Ben Noordhuis)
2013.04.12, Version 0.10.4 (Stable), 85827e26403ac6dfa331af8ec9916ea7e27bd833
@ -71,6 +48,42 @@ Changes since version 0.10.3:
* build: -Wno-dollar-in-identifier-extension is clang only (Ben Noordhuis)
2013.04.11, Version 0.11.1 (Unstable), 5c10e82ae0bc99eff86d4b9baff1f1aa0bf84c0a
This is the first versioned release from the current unstable libuv branch.
Changes since Node.js v0.11.0:
* all platforms: nanosecond resolution support for uv_fs_[fl]stat (Timothy J.
Fontaine)
* all platforms: add netmask to uv_interface_address (Ben Kelly)
* unix: make sure the `status` parameter passed to the `uv_getaddrinfo` is 0 or
-1 (Ben Noordhuis)
* unix: limit the number of iovecs written in a single `writev` syscall to
IOV_MAX (Fedor Indutny)
* unix: add dtrace probes for tick-start and tick-stop (Timothy J. Fontaine)
* mingw-w64: don't call _set_invalid_parameter_handler (Nils Maier)
* windows: fix memory leak in fs__sendfile (Shannen Saez)
* windows: fix edge case bugs in uv_cpu_info (Bert Belder)
* include: no longer ship with / include ngx-queue.h (Ben Noordhuis)
* include: remove UV_VERSION_* macros from uv.h (Ben Noordhuis)
* documentation updates (Kristian Evensen, Ben Kelly, Ben Noordhuis)
* build: fix dtrace-enabled builds (Ben Noordhuis, Timothy J. Fontaine)
* build: gyp disable thin archives (Timothy J. Fontaine)
* build: add support for Visual Studio 2012 (Nicholas Vavilov)
2013.02.04, Version 0.10.3 (Stable), 31ebe23973dd98fd8a24c042b606f37a794e99d0
Changes since version 0.10.2:

View File

@ -88,6 +88,7 @@ TESTS= \
test/test-loop-stop.o \
test/test-multiple-listen.o \
test/test-mutexes.o \
test/test-osx-select.o \
test/test-pass-always.o \
test/test-ping-pong.o \
test/test-pipe-bind-error.o \

View File

@ -71,10 +71,8 @@ STATIC_ASSERT(sizeof(&((uv_buf_t*) 0)->base) ==
sizeof(((struct iovec*) 0)->iov_base));
STATIC_ASSERT(sizeof(&((uv_buf_t*) 0)->len) ==
sizeof(((struct iovec*) 0)->iov_len));
STATIC_ASSERT((uintptr_t) &((uv_buf_t*) 0)->base ==
(uintptr_t) &((struct iovec*) 0)->iov_base);
STATIC_ASSERT((uintptr_t) &((uv_buf_t*) 0)->len ==
(uintptr_t) &((struct iovec*) 0)->iov_len);
STATIC_ASSERT(offsetof(uv_buf_t, base) == offsetof(struct iovec, iov_base));
STATIC_ASSERT(offsetof(uv_buf_t, len) == offsetof(struct iovec, iov_len));
uint64_t uv_hrtime(void) {

View File

@ -284,98 +284,59 @@ uint64_t uv_get_total_memory(void) {
uv_err_t uv_resident_set_memory(size_t* rss) {
FILE* f;
int itmp;
char ctmp;
unsigned int utmp;
size_t page_size = getpagesize();
char *cbuf;
int foundExeEnd;
char buf[PATH_MAX + 1];
char buf[1024];
const char* s;
ssize_t n;
long val;
int fd;
int i;
f = fopen("/proc/self/stat", "r");
if (!f) return uv__new_sys_error(errno);
do
fd = open("/proc/self/stat", O_RDONLY);
while (fd == -1 && errno == EINTR);
/* PID */
if (fscanf(f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
/* Exec file */
cbuf = buf;
foundExeEnd = 0;
if (fscanf (f, "%c", cbuf++) == 0) goto error;
while (1) {
if (fscanf(f, "%c", cbuf) == 0) goto error;
if (*cbuf == ')') {
foundExeEnd = 1;
} else if (foundExeEnd && *cbuf == ' ') {
*cbuf = 0;
break;
}
if (fd == -1)
return uv__new_sys_error(errno);
cbuf++;
do
n = read(fd, buf, sizeof(buf) - 1);
while (n == -1 && errno == EINTR);
SAVE_ERRNO(close(fd));
if (n == -1)
return uv__new_sys_error(errno);
buf[n] = '\0';
s = strchr(buf, ' ');
if (s == NULL)
goto err;
s += 1;
if (*s != '(')
goto err;
s = strchr(s, ')');
if (s == NULL)
goto err;
for (i = 1; i <= 22; i++) {
s = strchr(s + 1, ' ');
if (s == NULL)
goto err;
}
/* State */
if (fscanf (f, "%c ", &ctmp) == 0) goto error; /* coverity[secure_coding] */
/* Parent process */
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
/* Process group */
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
/* Session id */
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
/* TTY */
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
/* TTY owner process group */
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
/* Flags */
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
/* Minor faults (no memory page) */
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
/* Minor faults, children */
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
/* Major faults (memory page faults) */
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
/* Major faults, children */
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
/* utime */
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
/* stime */
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
/* utime, children */
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
/* stime, children */
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
/* jiffies remaining in current time slice */
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
/* 'nice' value */
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
/* jiffies until next timeout */
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
/* jiffies until next SIGALRM */
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
/* start time (jiffies since system boot) */
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */
/* Virtual memory size */
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
errno = 0;
val = strtol(s, NULL, 10);
if (errno != 0)
goto err;
if (val < 0)
goto err;
/* Resident set size */
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
*rss = (size_t) utmp * page_size;
/* rlim */
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
/* Start of text */
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
/* End of text */
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
/* Start of stack */
if (fscanf (f, "%u ", &utmp) == 0) goto error; /* coverity[secure_coding] */
fclose (f);
*rss = val * getpagesize();
return uv_ok_;
error:
fclose (f);
return uv__new_sys_error(errno);
err:
return uv__new_artificial_error(UV_EINVAL);
}

View File

@ -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));
if (fd == -1) {
switch (errno) {
#if EWOULDBLOCK != EAGAIN
case EWOULDBLOCK:
#endif
case EAGAIN:
return; /* Not an error. */
if (errno == EAGAIN || errno == EWOULDBLOCK)
return; /* Not an error. */
case ECONNABORTED:
UV_DEC_BACKLOG(w)
continue; /* Ignore. */
if (errno == ECONNABORTED)
continue; /* Ignore. Nothing we can do about that. */
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;
}
}
/* Fall through. */
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);

View File

@ -222,6 +222,9 @@ TEST_DECLARE (we_get_signal)
TEST_DECLARE (we_get_signals)
TEST_DECLARE (signal_multiple_loops)
#endif
#ifdef __APPLE__
TEST_DECLARE (osx_select)
#endif
HELPER_DECLARE (tcp4_echo_server)
HELPER_DECLARE (tcp6_echo_server)
HELPER_DECLARE (udp4_echo_server)
@ -444,6 +447,10 @@ TASK_LIST_START
TEST_ENTRY (signal_multiple_loops)
#endif
#ifdef __APPLE__
TEST_ENTRY (osx_select)
#endif
TEST_ENTRY (fs_file_noent)
TEST_ENTRY (fs_file_nametoolong)
TEST_ENTRY (fs_file_loop)

82
test/test-osx-select.c Normal file
View File

@ -0,0 +1,82 @@
/* 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"
#ifdef __APPLE__
#include <sys/ioctl.h>
#include <string.h>
static int read_count;
static uv_buf_t alloc_cb(uv_handle_t* handle, size_t size) {
static char buf[1024];
return uv_buf_init(buf, ARRAY_SIZE(buf));
}
static void read_cb(uv_stream_t* stream, ssize_t nread, uv_buf_t buf) {
fprintf(stdout, "got data %d\n", ++read_count);
if (read_count == 3)
uv_close((uv_handle_t*) stream, NULL);
}
TEST_IMPL(osx_select) {
int r;
int fd;
size_t i;
size_t len;
const char* str;
uv_tty_t tty;
fd = open("/dev/tty", O_RDONLY);
ASSERT(fd >= 0);
r = uv_tty_init(uv_default_loop(), &tty, fd, 1);
ASSERT(r == 0);
uv_read_start((uv_stream_t*) &tty, alloc_cb, read_cb);
// Emulate user-input
str = "got some input\n"
"with a couple of lines\n"
"feel pretty happy\n";
for (i = 0, len = strlen(str); i < len; i++) {
r = ioctl(fd, TIOCSTI, str + i);
ASSERT(r == 0);
}
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(read_count == 3);
MAKE_VALGRIND_HAPPY();
return 0;
}
#endif /* __APPLE__ */

12
uv.gyp
View File

@ -236,21 +236,16 @@
}],
[ 'OS=="freebsd" or OS=="dragonflybsd"', {
'sources': [ 'src/unix/freebsd.c' ],
'link_settings': {
'libraries': [
'-lkvm',
],
},
}],
[ 'OS=="openbsd"', {
'sources': [ 'src/unix/openbsd.c' ],
}],
[ 'OS=="netbsd"', {
'sources': [ 'src/unix/netbsd.c' ],
}],
[ 'OS in "freebsd dragonflybsd openbsd netbsd".split()', {
'link_settings': {
'libraries': [
'-lkvm',
],
'libraries': [ '-lkvm' ],
},
}],
[ 'OS in "mac freebsd dragonflybsd openbsd netbsd".split()', {
@ -310,6 +305,7 @@
'test/test-loop-stop.c',
'test/test-walk-handles.c',
'test/test-multiple-listen.c',
'test/test-osx-select.c',
'test/test-pass-always.c',
'test/test-ping-pong.c',
'test/test-pipe-bind-error.c',