Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Commit

Permalink
Merge branch 'v0.10'
Browse files Browse the repository at this point in the history
Conflicts:
	build.mk
	src/unix/core.c
	src/unix/darwin.c
  • Loading branch information
indutny committed Nov 12, 2013
2 parents 0f5c28b + f50ccd5 commit 6149b66
Show file tree
Hide file tree
Showing 10 changed files with 285 additions and 3 deletions.
1 change: 1 addition & 0 deletions checksparse.sh
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ test/test-stdio-over-pipes.c
test/test-tcp-bind-error.c
test/test-tcp-bind6-error.c
test/test-tcp-close-while-connecting.c
test/test-tcp-close-accept.c
test/test-tcp-close.c
test/test-tcp-connect-error-after-write.c
test/test-tcp-connect-error.c
Expand Down
22 changes: 19 additions & 3 deletions src/unix/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -604,20 +604,33 @@ static unsigned int next_power_of_two(unsigned int val) {

static void maybe_resize(uv_loop_t* loop, unsigned int len) {
uv__io_t** watchers;
void* fake_watcher_list;
void* fake_watcher_count;
unsigned int nwatchers;
unsigned int i;

if (len <= loop->nwatchers)
return;

nwatchers = next_power_of_two(len);
watchers = realloc(loop->watchers, nwatchers * sizeof(loop->watchers[0]));
/* Preserve fake watcher list and count at the end of the watchers */
if (loop->watchers != NULL) {
fake_watcher_list = loop->watchers[loop->nwatchers];
fake_watcher_count = loop->watchers[loop->nwatchers + 1];
} else {
fake_watcher_list = NULL;
fake_watcher_count = NULL;
}

nwatchers = next_power_of_two(len + 2) - 2;
watchers = realloc(loop->watchers,
(nwatchers + 2) * sizeof(loop->watchers[0]));

if (watchers == NULL)
abort();

for (i = loop->nwatchers; i < nwatchers; i++)
watchers[i] = NULL;
watchers[nwatchers] = fake_watcher_list;
watchers[nwatchers + 1] = fake_watcher_count;

loop->watchers = watchers;
loop->nwatchers = nwatchers;
Expand Down Expand Up @@ -709,6 +722,9 @@ void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
void uv__io_close(uv_loop_t* loop, uv__io_t* w) {
uv__io_stop(loop, w, UV__POLLIN | UV__POLLOUT);
QUEUE_REMOVE(&w->pending_queue);

/* Remove stale events for this file descriptor */
uv__platform_invalidate_fd(loop, w->fd);
}


Expand Down
19 changes: 19 additions & 0 deletions src/unix/darwin.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,25 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
}


void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
struct kevent* events;
uintptr_t i;
uintptr_t nfds;

assert(loop->watchers != NULL);

events = (struct kevent*) loop->watchers[loop->nwatchers];
nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
if (events == NULL)
return;

/* Invalidate events with same file descriptor */
for (i = 0; i < nfds; i++)
if ((int) events[i].ident == fd)
events[i].ident = -1;
}


uint64_t uv__hrtime(uv_clocktype_t type) {
mach_timebase_info_data_t info;

Expand Down
1 change: 1 addition & 0 deletions src/unix/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ uint64_t uv__hrtime(uv_clocktype_t type);
int uv__kqueue_init(uv_loop_t* loop);
int uv__platform_loop_init(uv_loop_t* loop, int default_loop);
void uv__platform_loop_delete(uv_loop_t* loop);
void uv__platform_invalidate_fd(uv_loop_t* loop, int fd);

/* various */
void uv__async_close(uv_async_t* handle);
Expand Down
9 changes: 9 additions & 0 deletions src/unix/kqueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,18 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {

nevents = 0;

assert(loop->watchers != NULL);
loop->watchers[loop->nwatchers] = (void*) events;
loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
for (i = 0; i < nfds; i++) {
ev = events + i;
fd = ev->ident;
w = loop->watchers[fd];

/* Skip invalidated events, see uv__platform_invalidate_fd */
if (fd == -1)
continue;

if (w == NULL) {
/* File descriptor that we've stopped watching, disarm it. */
/* TODO batch up */
Expand Down Expand Up @@ -226,6 +233,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
w->cb(loop, w, revents);
nevents++;
}
loop->watchers[loop->nwatchers] = NULL;
loop->watchers[loop->nwatchers + 1] = NULL;

if (nevents != 0) {
if (nfds == ARRAY_SIZE(events) && --count != 0) {
Expand Down
28 changes: 28 additions & 0 deletions src/unix/linux-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,25 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
}


void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
struct uv__epoll_event* events;
uintptr_t i;
uintptr_t nfds;

assert(loop->watchers != NULL);

events = (struct uv__epoll_event*) loop->watchers[loop->nwatchers];
nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
if (events == NULL)
return;

/* Invalidate events with same file descriptor */
for (i = 0; i < nfds; i++)
if ((int) events[i].data == fd)
events[i].data = -1;
}


void uv__io_poll(uv_loop_t* loop, int timeout) {
struct uv__epoll_event events[1024];
struct uv__epoll_event* pe;
Expand Down Expand Up @@ -197,10 +216,17 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {

nevents = 0;

assert(loop->watchers != NULL);
loop->watchers[loop->nwatchers] = (void*) events;
loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
for (i = 0; i < nfds; i++) {
pe = events + i;
fd = pe->data;

/* Skip invalidated events, see uv__platform_invalidate_fd */
if (fd == -1)
continue;

assert(fd >= 0);
assert((unsigned) fd < loop->nwatchers);

Expand Down Expand Up @@ -246,6 +272,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
nevents++;
}
}
loop->watchers[loop->nwatchers] = NULL;
loop->watchers[loop->nwatchers + 1] = NULL;

if (nevents != 0) {
if (nfds == ARRAY_SIZE(events) && --count != 0) {
Expand Down
28 changes: 28 additions & 0 deletions src/unix/sunos.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,25 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
}


void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
struct port_event* events;
uintptr_t i;
uintptr_t nfds;

assert(loop->watchers != NULL);

events = (struct port_event*) loop->watchers[loop->nwatchers];
nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
if (events == NULL)
return;

/* Invalidate events with same file descriptor */
for (i = 0; i < nfds; i++)
if ((int) events[i].portev_object == fd)
events[i].portev_object = -1;
}


void uv__io_poll(uv_loop_t* loop, int timeout) {
struct port_event events[1024];
struct port_event* pe;
Expand Down Expand Up @@ -183,10 +202,17 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {

nevents = 0;

assert(loop->watchers != NULL);
loop->watchers[loop->nwatchers] = (void*) events;
loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
for (i = 0; i < nfds; i++) {
pe = events + i;
fd = pe->portev_object;

/* Skip invalidated events, see uv__platform_invalidate_fd */
if (fd == -1)
continue;

assert(fd >= 0);
assert((unsigned) fd < loop->nwatchers);

Expand All @@ -206,6 +232,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
if (w->pevents != 0 && QUEUE_EMPTY(&w->watcher_queue))
QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue);
}
loop->watchers[loop->nwatchers] = NULL;
loop->watchers[loop->nwatchers + 1] = NULL;

if (nevents != 0) {
if (nfds == ARRAY_SIZE(events) && --count != 0) {
Expand Down
2 changes: 2 additions & 0 deletions test/test-list.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ TEST_DECLARE (tcp_connect_error_fault)
TEST_DECLARE (tcp_connect_timeout)
TEST_DECLARE (tcp_close_while_connecting)
TEST_DECLARE (tcp_close)
TEST_DECLARE (tcp_close_accept)
TEST_DECLARE (tcp_flags)
TEST_DECLARE (tcp_write_to_half_open_connection)
TEST_DECLARE (tcp_unexpected_read)
Expand Down Expand Up @@ -306,6 +307,7 @@ TASK_LIST_START
TEST_ENTRY (tcp_connect_timeout)
TEST_ENTRY (tcp_close_while_connecting)
TEST_ENTRY (tcp_close)
TEST_ENTRY (tcp_close_accept)
TEST_ENTRY (tcp_flags)
TEST_ENTRY (tcp_write_to_half_open_connection)
TEST_ENTRY (tcp_unexpected_read)
Expand Down
Loading

0 comments on commit 6149b66

Please sign in to comment.