diff --git a/src/unix/getnameinfo.c b/src/unix/getnameinfo.c index b800d9da..c3fb9831 100644 --- a/src/unix/getnameinfo.c +++ b/src/unix/getnameinfo.c @@ -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, diff --git a/test/test-list.h b/test/test-list.h index a138f566..c10c59fe 100644 --- a/test/test-list.h +++ b/test/test-list.h @@ -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) diff --git a/test/test-threadpool-cancel.c b/test/test-threadpool-cancel.c index a349876b..0c8fd146 100644 --- a/test/test-threadpool-cancel.c +++ b/test/test-threadpool-cancel.c @@ -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];