diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2011-12-29 03:18:23 +0400 |
---|---|---|
committer | Ben Noordhuis <info@bnoordhuis.nl> | 2011-12-29 04:56:11 +0400 |
commit | 25ca13ec1a6166c96a77d4d04e4de1a95472521b (patch) | |
tree | ad01448eaeff1949eb89d4f6e97544646f1d450f /deps | |
parent | cdb5864fc329b53a2b28fe404679ae72021757b1 (diff) |
uv: upgrade to 85f6b79
Diffstat (limited to 'deps')
-rw-r--r-- | deps/uv/include/uv-private/uv-unix.h | 2 | ||||
-rw-r--r-- | deps/uv/include/uv.h | 2 | ||||
-rw-r--r-- | deps/uv/src/unix/uv-eio.c | 19 | ||||
-rw-r--r-- | deps/uv/test/test-list.h | 2 | ||||
-rw-r--r-- | deps/uv/test/test-thread.c | 133 |
5 files changed, 150 insertions, 8 deletions
diff --git a/deps/uv/include/uv-private/uv-unix.h b/deps/uv/include/uv-private/uv-unix.h index 99537347f76..24ef37cb9d5 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 9ff318fc675..7e089ef7243 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 7c83f2c1b04..8656ea6f5a0 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 51b847291ed..f5f05412697 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 48b31b172e0..5c0bb75e61f 100644 --- a/deps/uv/test/test-thread.c +++ b/deps/uv/test/test-thread.c @@ -23,12 +23,123 @@ #include "task.h" #include <stdio.h> +#include <stddef.h> #include <stdlib.h> +#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; +} |