unix: allow uv_getnameinfo to be cancelled

This commit is contained in:
Saúl Ibarra Corretgé 2014-06-18 02:00:07 +02:00
parent 6ffb82ef08
commit 133b9d1cc1
3 changed files with 56 additions and 6 deletions

View File

@ -59,13 +59,14 @@ static void uv__getnameinfo_done(struct uv__work* w, int status) {
req = container_of(w, uv_getnameinfo_t, work_req);
uv__req_unregister(req->loop, req);
host = service = NULL;
if (req->retcode == 0) {
if (status == -ECANCELED) {
assert(req->retcode == 0);
req->retcode = UV_EAI_CANCELED;
} else if (req->retcode == 0) {
host = req->host;
service = req->service;
} else {
host = NULL;
service = NULL;
}
req->getnameinfo_cb(req, req->retcode, host, service);
@ -102,6 +103,7 @@ int uv_getnameinfo(uv_loop_t* loop,
req->flags = flags;
req->type = UV_GETNAMEINFO;
req->loop = loop;
req->retcode = 0;
uv__work_submit(loop,
&req->work_req,

View File

@ -229,6 +229,7 @@ TEST_DECLARE (threadpool_queue_work_simple)
TEST_DECLARE (threadpool_queue_work_einval)
TEST_DECLARE (threadpool_multiple_event_loops)
TEST_DECLARE (threadpool_cancel_getaddrinfo)
TEST_DECLARE (threadpool_cancel_getnameinfo)
TEST_DECLARE (threadpool_cancel_work)
TEST_DECLARE (threadpool_cancel_fs)
TEST_DECLARE (threadpool_cancel_single)
@ -573,6 +574,7 @@ TASK_LIST_START
TEST_ENTRY (threadpool_queue_work_einval)
TEST_ENTRY (threadpool_multiple_event_loops)
TEST_ENTRY (threadpool_cancel_getaddrinfo)
TEST_ENTRY (threadpool_cancel_getnameinfo)
TEST_ENTRY (threadpool_cancel_work)
TEST_ENTRY (threadpool_cancel_fs)
TEST_ENTRY (threadpool_cancel_single)

View File

@ -46,7 +46,6 @@ static unsigned work_cb_called;
static unsigned done_cb_called;
static unsigned done2_cb_called;
static unsigned timer_cb_called;
static unsigned getaddrinfo_cb_called;
static void work_cb(uv_work_t* req) {
@ -125,7 +124,16 @@ static void getaddrinfo_cb(uv_getaddrinfo_t* req,
ASSERT(status == UV_EAI_CANCELED);
ASSERT(res == NULL);
uv_freeaddrinfo(res); /* Should not crash. */
getaddrinfo_cb_called++;
}
static void getnameinfo_cb(uv_getnameinfo_t* handle,
int status,
char* hostname,
char* service) {
ASSERT(status == UV_EAI_CANCELED);
ASSERT(hostname == NULL);
ASSERT(service == NULL);
}
@ -202,6 +210,44 @@ TEST_IMPL(threadpool_cancel_getaddrinfo) {
}
TEST_IMPL(threadpool_cancel_getnameinfo) {
uv_getnameinfo_t reqs[4];
struct sockaddr_in addr4;
struct cancel_info ci;
uv_loop_t* loop;
int r;
r = uv_ip4_addr("127.0.0.1", 80, &addr4);
ASSERT(r == 0);
INIT_CANCEL_INFO(&ci, reqs);
loop = uv_default_loop();
saturate_threadpool();
r = uv_getnameinfo(loop, reqs + 0, getnameinfo_cb, (const struct sockaddr*)&addr4, 0);
ASSERT(r == 0);
r = uv_getnameinfo(loop, reqs + 1, getnameinfo_cb, (const struct sockaddr*)&addr4, 0);
ASSERT(r == 0);
r = uv_getnameinfo(loop, reqs + 2, getnameinfo_cb, (const struct sockaddr*)&addr4, 0);
ASSERT(r == 0);
r = uv_getnameinfo(loop, reqs + 3, getnameinfo_cb, (const struct sockaddr*)&addr4, 0);
ASSERT(r == 0);
ASSERT(0 == uv_timer_init(loop, &ci.timer_handle));
ASSERT(0 == uv_timer_start(&ci.timer_handle, timer_cb, 10, 0));
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
ASSERT(1 == timer_cb_called);
cleanup_threadpool();
MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(threadpool_cancel_work) {
struct cancel_info ci;
uv_work_t reqs[16];