From: Ben Noordhuis Date: Wed, 28 Dec 2011 23:18:23 +0000 (+0100) Subject: uv: upgrade to 85f6b79 X-Git-Tag: v0.7.0~64^2~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2afd20b5425e62c3019278d6682b62171664f456;p=platform%2Fupstream%2Fnodejs.git uv: upgrade to 85f6b79 --- diff --git a/deps/uv/include/uv-private/uv-unix.h b/deps/uv/include/uv-private/uv-unix.h index 9953734..24ef37c 100644 --- a/deps/uv/include/uv-private/uv-unix.h +++ b/deps/uv/include/uv-private/uv-unix.h @@ -63,6 +63,8 @@ typedef void* uv_lib_t; * definition of ares_timeout(). \ */ \ ev_timer timer; \ + /* Poll result queue */ \ + eio_channel uv_eio_channel; \ struct ev_loop* ev; #define UV_REQ_BUFSML_SIZE (4) diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index 9ff318f..7e089ef 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -1400,8 +1400,6 @@ struct uv_loop_s { uv_async_t uv_eio_want_poll_notifier; uv_async_t uv_eio_done_poll_notifier; uv_idle_t uv_eio_poller; - /* Poll result queue */ - eio_channel uv_eio_channel; /* Diagnostic counters */ uv_counters_t counters; /* The last error */ diff --git a/deps/uv/src/unix/uv-eio.c b/deps/uv/src/unix/uv-eio.c index 7c83f2c..8656ea6 100644 --- a/deps/uv/src/unix/uv-eio.c +++ b/deps/uv/src/unix/uv-eio.c @@ -96,6 +96,18 @@ static void uv_eio_done_poll(eio_channel *channel) { } +static void uv__eio_init(void) { + eio_init(uv_eio_want_poll, uv_eio_done_poll); + /* + * Don't handle more than 10 reqs on each eio_poll(). This is to avoid + * race conditions. See Node's test/simple/test-eio-race.js + */ + eio_set_max_poll_reqs(10); +} + +static uv_once_t uv__eio_init_once_guard = UV_ONCE_INIT; + + void uv_eio_init(uv_loop_t* loop) { if (loop->counters.eio_init == 0) { loop->counters.eio_init++; @@ -112,11 +124,6 @@ void uv_eio_init(uv_loop_t* loop) { uv_eio_done_poll_notifier_cb); uv_unref(loop); - eio_init(uv_eio_want_poll, uv_eio_done_poll); - /* - * Don't handle more than 10 reqs on each eio_poll(). This is to avoid - * race conditions. See Node's test/simple/test-eio-race.js - */ - eio_set_max_poll_reqs(10); + uv_once(&uv__eio_init_once_guard, uv__eio_init); } } diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index 51b8472..f5f0541 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -119,6 +119,7 @@ TEST_DECLARE (fs_readdir_empty_dir) TEST_DECLARE (fs_readdir_file) TEST_DECLARE (fs_open_dir) TEST_DECLARE (threadpool_queue_work_simple) +TEST_DECLARE (threadpool_multiple_event_loops) TEST_DECLARE (thread_mutex) TEST_DECLARE (thread_rwlock) TEST_DECLARE (thread_create) @@ -285,6 +286,7 @@ TASK_LIST_START TEST_ENTRY (fs_readdir_file) TEST_ENTRY (fs_open_dir) TEST_ENTRY (threadpool_queue_work_simple) + TEST_ENTRY (threadpool_multiple_event_loops) TEST_ENTRY (thread_mutex) TEST_ENTRY (thread_rwlock) TEST_ENTRY (thread_create) diff --git a/deps/uv/test/test-thread.c b/deps/uv/test/test-thread.c index 48b31b1..5c0bb75 100644 --- a/deps/uv/test/test-thread.c +++ b/deps/uv/test/test-thread.c @@ -23,12 +23,123 @@ #include "task.h" #include +#include #include +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +#define container_of(ptr, type, member) \ + ((type *) ((char *) (ptr) - offsetof(type, member))) + +struct getaddrinfo_req { + uv_thread_t thread_id; + unsigned int counter; + uv_loop_t* loop; + uv_getaddrinfo_t handle; +}; + + +struct fs_req { + uv_thread_t thread_id; + unsigned int counter; + uv_loop_t* loop; + uv_fs_t handle; +}; + +static void getaddrinfo_do(struct getaddrinfo_req* req); +static void getaddrinfo_cb(uv_getaddrinfo_t* handle, + int status, + struct addrinfo* res); +static void fs_do(struct fs_req* req); +static void fs_cb(uv_fs_t* handle); static volatile int thread_called; +static void getaddrinfo_do(struct getaddrinfo_req* req) { + int r; + + ASSERT(req->thread_id == uv_thread_self()); + + r = uv_getaddrinfo(req->loop, + &req->handle, + getaddrinfo_cb, + "localhost", + NULL, + NULL); + ASSERT(r == 0); +} + + +static void getaddrinfo_cb(uv_getaddrinfo_t* handle, + int status, + struct addrinfo* res) { + struct getaddrinfo_req* req; + + ASSERT(status == 0); + + req = container_of(handle, struct getaddrinfo_req, handle); + uv_freeaddrinfo(res); + + if (--req->counter) + getaddrinfo_do(req); +} + + +static void fs_do(struct fs_req* req) { + int r; + + ASSERT(req->thread_id == uv_thread_self()); + + r = uv_fs_stat(req->loop, &req->handle, ".", fs_cb); + ASSERT(r == 0); +} + + +static void fs_cb(uv_fs_t* handle) { + struct fs_req* req = container_of(handle, struct fs_req, handle); + + if (--req->counter) + fs_do(req); +} + + +static void do_work(void* arg) { + struct getaddrinfo_req getaddrinfo_reqs[16]; + struct fs_req fs_reqs[16]; + uv_thread_t self; + uv_loop_t* loop; + size_t i; + int r; + + self = uv_thread_self(); + + loop = uv_loop_new(); + ASSERT(loop != NULL); + + for (i = 0; i < ARRAY_SIZE(getaddrinfo_reqs); i++) { + struct getaddrinfo_req* req = getaddrinfo_reqs + i; + req->thread_id = self; + req->counter = 16; + req->loop = loop; + getaddrinfo_do(req); + } + + for (i = 0; i < ARRAY_SIZE(fs_reqs); i++) { + struct fs_req* req = fs_reqs + i; + req->thread_id = self; + req->counter = 16; + req->loop = loop; + fs_do(req); + } + + r = uv_run(loop); + ASSERT(r == 0); + + uv_loop_delete(loop); +} + + static void thread_entry(void* arg) { ASSERT(arg == (void *) 42); thread_called++; @@ -56,3 +167,25 @@ TEST_IMPL(thread_self) { tid = uv_thread_self(); return 0; } + + +/* Hilariously bad test name. Run a lot of tasks in the thread pool and verify + * that each "finished" callback is run in its originating thread. + */ +TEST_IMPL(threadpool_multiple_event_loops) { + uv_thread_t threads[8]; + size_t i; + int r; + + for (i = 0; i < ARRAY_SIZE(threads); i++) { + r = uv_thread_create(threads + i, do_work, NULL); + ASSERT(r == 0); + } + + for (i = 0; i < ARRAY_SIZE(threads); i++) { + r = uv_thread_join(threads + i); + ASSERT(r == 0); + } + + return 0; +}