2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 14:07:59 +00:00

Change single write timer to per-send timers

Previously, there was a single per-socket write timer that would get
restarted for every new write.  This turned out to be insufficient
because the other side could keep reseting the timer, and never reading
back the responses.

Change the single write timer to per-send timer which would in turn
reset the TCP connection on the first send timeout.
This commit is contained in:
Ondřej Surý 2022-03-10 13:51:08 +01:00
parent 1357d44605
commit a761aa59e3
7 changed files with 71 additions and 186 deletions

View File

@ -384,8 +384,8 @@ struct isc__nm_uvreq {
isc_sockaddr_t peer; /* peer address */
isc__nm_cb_t cb; /* callback */
void *cbarg; /* callback argument */
uv_pipe_t ipc; /* used for sending socket
* uv_handles to other threads */
isc_nm_timer_t *timer; /* TCP write timer */
union {
uv_handle_t handle;
uv_req_t req;
@ -972,9 +972,7 @@ struct isc_nmsocket {
/*%
* TCP write timeout timer.
*/
uv_timer_t write_timer;
uint64_t write_timeout;
int64_t writes;
/*% outer socket is for 'wrapped' sockets - e.g. tcpdns in tcp */
isc_nmsocket_t *outer;
@ -2097,7 +2095,7 @@ isc__nmsocket_connecttimeout_cb(uv_timer_t *timer);
void
isc__nmsocket_readtimeout_cb(uv_timer_t *timer);
void
isc__nmsocket_writetimeout_cb(uv_timer_t *timer);
isc__nmsocket_writetimeout_cb(void *data, isc_result_t eresult);
#define UV_RUNTIME_CHECK(func, ret) \
if (ret != 0) { \

View File

@ -1985,11 +1985,15 @@ isc__nm_accept_connection_log(isc_result_t result, bool can_log_quota) {
}
void
isc__nmsocket_writetimeout_cb(uv_timer_t *timer) {
isc_nmsocket_t *sock = uv_handle_get_data((uv_handle_t *)timer);
isc__nmsocket_writetimeout_cb(void *data, isc_result_t eresult) {
isc__nm_uvreq_t *req = data;
isc_nmsocket_t *sock = NULL;
int r = uv_timer_stop(&sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_stop, r);
REQUIRE(eresult == ISC_R_TIMEDOUT);
REQUIRE(VALID_UVREQ(req));
REQUIRE(VALID_NMSOCK(req->sock));
sock = req->sock;
isc__nmsocket_reset(sock);
}
@ -2802,6 +2806,13 @@ isc__nm_async_detach(isc__networker_t *worker, isc__netievent_t *ev0) {
nmhandle_detach_cb(&ievent->handle FLARG_PASS);
}
static void
reset_shutdown(uv_handle_t *handle) {
isc_nmsocket_t *sock = uv_handle_get_data(handle);
isc__nmsocket_shutdown(sock);
}
void
isc__nmsocket_reset(isc_nmsocket_t *sock) {
REQUIRE(VALID_NMSOCK(sock));
@ -2827,10 +2838,10 @@ isc__nmsocket_reset(isc_nmsocket_t *sock) {
* The real shutdown will be handled in the respective
* close functions.
*/
int r = uv_tcp_close_reset(&sock->uv_handle.tcp, NULL);
int r = uv_tcp_close_reset(&sock->uv_handle.tcp,
reset_shutdown);
UV_RUNTIME_CHECK(uv_tcp_close_reset, r);
}
isc__nmsocket_shutdown(sock);
}
void

View File

@ -78,9 +78,6 @@ quota_accept_cb(isc_quota_t *quota, void *sock0);
static void
failed_accept_cb(isc_nmsocket_t *sock, isc_result_t eresult);
static void
failed_send_cb(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
isc_result_t eresult);
static void
stop_tcp_parent(isc_nmsocket_t *sock);
static void
@ -144,10 +141,6 @@ tcp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
r = uv_timer_init(&worker->loop, &sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
r = uv_tcp_open(&sock->uv_handle.tcp, sock->fd);
if (r != 0) {
isc__nm_closesocket(sock->fd);
@ -542,10 +535,6 @@ isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
r = uv_timer_init(&worker->loop, &sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
LOCK(&sock->parent->lock);
r = uv_tcp_open(&sock->uv_handle.tcp, sock->fd);
@ -718,19 +707,6 @@ destroy:
}
}
static void
failed_send_cb(isc_nmsocket_t *sock, isc__nm_uvreq_t *req,
isc_result_t eresult) {
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(VALID_UVREQ(req));
if (req->cb.send != NULL) {
isc__nm_sendcb(sock, req, eresult, true);
} else {
isc__nm_uvreq_put(&req, sock);
}
}
void
isc__nm_tcp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) {
REQUIRE(VALID_NMHANDLE(handle));
@ -992,10 +968,6 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&csock->read_timer, csock);
r = uv_timer_init(&worker->loop, &csock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&csock->write_timer, csock);
r = uv_accept(&ssock->uv_handle.stream, &csock->uv_handle.stream);
if (r != 0) {
result = isc__nm_uverr2result(r);
@ -1106,20 +1078,20 @@ isc__nm_tcp_send(isc_nmhandle_t *handle, const isc_region_t *region,
static void
tcp_send_cb(uv_write_t *req, int status) {
isc__nm_uvreq_t *uvreq = (isc__nm_uvreq_t *)req->data;
isc_nmsocket_t *sock = NULL;
REQUIRE(VALID_UVREQ(uvreq));
REQUIRE(VALID_NMHANDLE(uvreq->handle));
REQUIRE(VALID_NMSOCK(uvreq->sock));
isc_nmsocket_t *sock = uvreq->sock;
sock = uvreq->sock;
if (--sock->writes == 0) {
int r = uv_timer_stop(&sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_stop, r);
}
isc_nm_timer_stop(uvreq->timer);
isc_nm_timer_detach(&uvreq->timer);
if (status < 0) {
isc__nm_incstats(sock, STATID_SENDFAIL);
failed_send_cb(sock, uvreq, isc__nm_uverr2result(status));
isc__nm_failed_send_cb(sock, uvreq,
isc__nm_uverr2result(status));
return;
}
@ -1143,7 +1115,7 @@ isc__nm_async_tcpsend(isc__networker_t *worker, isc__netievent_t *ev0) {
result = tcp_send_direct(sock, uvreq);
if (result != ISC_R_SUCCESS) {
isc__nm_incstats(sock, STATID_SENDFAIL);
failed_send_cb(sock, uvreq, result);
isc__nm_failed_send_cb(sock, uvreq, result);
}
}
@ -1160,17 +1132,18 @@ tcp_send_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
return (ISC_R_CANCELED);
}
r = uv_timer_start(&sock->write_timer, isc__nmsocket_writetimeout_cb,
sock->write_timeout, 0);
UV_RUNTIME_CHECK(uv_timer_start, r);
RUNTIME_CHECK(sock->writes++ >= 0);
r = uv_write(&req->uv_req.write, &sock->uv_handle.stream, &req->uvbuf,
1, tcp_send_cb);
if (r < 0) {
return (isc__nm_uverr2result(r));
}
isc_nm_timer_create(req->handle, isc__nmsocket_writetimeout_cb, req,
&req->timer);
if (sock->write_timeout > 0) {
isc_nm_timer_start(req->timer, sock->write_timeout);
}
return (ISC_R_SUCCESS);
}
@ -1241,17 +1214,6 @@ read_timer_close_cb(uv_handle_t *handle) {
}
}
static void
write_timer_close_cb(uv_handle_t *timer) {
isc_nmsocket_t *sock = uv_handle_get_data(timer);
uv_handle_set_data(timer, NULL);
REQUIRE(VALID_NMSOCK(sock));
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
uv_close((uv_handle_t *)&sock->read_timer, read_timer_close_cb);
}
static void
stop_tcp_child(isc_nmsocket_t *sock) {
REQUIRE(sock->type == isc_nm_tcpsocket);
@ -1304,8 +1266,6 @@ stop_tcp_parent(isc_nmsocket_t *sock) {
static void
tcp_close_direct(isc_nmsocket_t *sock) {
int r;
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_nm_tid());
REQUIRE(atomic_load(&sock->closing));
@ -1327,10 +1287,8 @@ tcp_close_direct(isc_nmsocket_t *sock) {
isc__nmsocket_timer_stop(sock);
isc__nm_stop_reading(sock);
r = uv_timer_stop(&sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_stop, r);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
uv_close((uv_handle_t *)&sock->write_timer, write_timer_close_cb);
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
uv_close((uv_handle_t *)&sock->read_timer, read_timer_close_cb);
}
void

View File

@ -102,10 +102,6 @@ tcpdns_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
r = uv_timer_init(&worker->loop, &sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
if (isc__nm_closing(sock)) {
result = ISC_R_SHUTTINGDOWN;
goto error;
@ -505,10 +501,6 @@ isc__nm_async_tcpdnslisten(isc__networker_t *worker, isc__netievent_t *ev0) {
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
r = uv_timer_init(&worker->loop, &sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
LOCK(&sock->parent->lock);
r = uv_tcp_open(&sock->uv_handle.tcp, sock->fd);
@ -978,10 +970,6 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&csock->read_timer, csock);
r = uv_timer_init(&worker->loop, &csock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&csock->write_timer, csock);
r = uv_accept(&ssock->uv_handle.stream, &csock->uv_handle.stream);
if (r != 0) {
result = isc__nm_uverr2result(r);
@ -1118,14 +1106,12 @@ tcpdns_send_cb(uv_write_t *req, int status) {
isc_nmsocket_t *sock = NULL;
REQUIRE(VALID_UVREQ(uvreq));
REQUIRE(VALID_NMHANDLE(uvreq->handle));
REQUIRE(VALID_NMSOCK(uvreq->sock));
sock = uvreq->sock;
if (--sock->writes == 0) {
int r = uv_timer_stop(&sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_stop, r);
}
isc_nm_timer_stop(uvreq->timer);
isc_nm_timer_detach(&uvreq->timer);
if (status < 0) {
isc__nm_incstats(sock, STATID_SENDFAIL);
@ -1193,11 +1179,6 @@ isc__nm_async_tcpdnssend(isc__networker_t *worker, isc__netievent_t *ev0) {
goto fail;
}
r = uv_timer_start(&sock->write_timer, isc__nmsocket_writetimeout_cb,
sock->write_timeout, 0);
UV_RUNTIME_CHECK(uv_timer_start, r);
RUNTIME_CHECK(sock->writes++ >= 0);
r = uv_write(&uvreq->uv_req.write, &sock->uv_handle.stream, bufs, nbufs,
tcpdns_send_cb);
if (r < 0) {
@ -1205,6 +1186,12 @@ isc__nm_async_tcpdnssend(isc__networker_t *worker, isc__netievent_t *ev0) {
goto fail;
}
isc_nm_timer_create(uvreq->handle, isc__nmsocket_writetimeout_cb, uvreq,
&uvreq->timer);
if (sock->write_timeout > 0) {
isc_nm_timer_start(uvreq->timer, sock->write_timeout);
}
return;
fail:
isc__nm_incstats(sock, STATID_SENDFAIL);
@ -1282,17 +1269,6 @@ read_timer_close_cb(uv_handle_t *timer) {
}
}
static void
write_timer_close_cb(uv_handle_t *timer) {
isc_nmsocket_t *sock = uv_handle_get_data(timer);
uv_handle_set_data(timer, NULL);
REQUIRE(VALID_NMSOCK(sock));
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
uv_close((uv_handle_t *)&sock->read_timer, read_timer_close_cb);
}
static void
stop_tcpdns_child(isc_nmsocket_t *sock) {
REQUIRE(sock->type == isc_nm_tcpdnssocket);
@ -1345,7 +1321,6 @@ stop_tcpdns_parent(isc_nmsocket_t *sock) {
static void
tcpdns_close_direct(isc_nmsocket_t *sock) {
int r;
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_nm_tid());
REQUIRE(atomic_load(&sock->closing));
@ -1361,10 +1336,8 @@ tcpdns_close_direct(isc_nmsocket_t *sock) {
isc__nmsocket_timer_stop(sock);
isc__nm_stop_reading(sock);
r = uv_timer_stop(&sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_stop, r);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
uv_close((uv_handle_t *)&sock->write_timer, write_timer_close_cb);
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
uv_close((uv_handle_t *)&sock->read_timer, read_timer_close_cb);
}
void

View File

@ -41,6 +41,7 @@ isc_nm_timer_create(isc_nmhandle_t *handle, isc_nm_timer_cb cb, void *cbarg,
sock = handle->sock;
worker = &sock->mgr->workers[isc_nm_tid()];
/* TODO: per-loop object cache */
timer = isc_mem_get(sock->mgr->mctx, sizeof(*timer));
*timer = (isc_nm_timer_t){ .cb = cb, .cbarg = cbarg };
isc_refcount_init(&timer->references, 1);
@ -91,7 +92,8 @@ isc_nm_timer_detach(isc_nm_timer_t **timerp) {
REQUIRE(VALID_NMSOCK(handle->sock));
if (isc_refcount_decrement(&timer->references) == 1) {
uv_timer_stop(&timer->timer);
int r = uv_timer_stop(&timer->timer);
UV_RUNTIME_CHECK(uv_timer_stop, r);
uv_close((uv_handle_t *)&timer->timer, timer_destroy);
}
}

View File

@ -118,10 +118,6 @@ tlsdns_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
r = uv_timer_init(&worker->loop, &sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
if (isc__nm_closing(sock)) {
result = ISC_R_SHUTTINGDOWN;
goto error;
@ -576,10 +572,6 @@ isc__nm_async_tlsdnslisten(isc__networker_t *worker, isc__netievent_t *ev0) {
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
r = uv_timer_init(&worker->loop, &sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
LOCK(&sock->parent->lock);
r = uv_tcp_open(&sock->uv_handle.tcp, sock->fd);
@ -1171,10 +1163,8 @@ tls_write_cb(uv_write_t *req, int status) {
isc__nm_uvreq_t *uvreq = (isc__nm_uvreq_t *)req->data;
isc_nmsocket_t *sock = uvreq->sock;
if (--sock->writes == 0) {
int r = uv_timer_stop(&sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_stop, r);
}
isc_nm_timer_stop(uvreq->timer);
isc_nm_timer_detach(&uvreq->timer);
free_senddata(sock);
@ -1215,7 +1205,8 @@ tls_cycle_output(isc_nmsocket_t *sock) {
sock->tls.senddata.base = isc_mem_get(sock->mgr->mctx, pending);
sock->tls.senddata.length = pending;
req = isc__nm_uvreq_get(sock->mgr, sock);
/* It's a bit misnomer here, but it does the right thing */
req = isc__nm_get_read_req(sock, NULL);
req->uvbuf.base = (char *)sock->tls.senddata.base;
req->uvbuf.len = sock->tls.senddata.length;
@ -1249,12 +1240,6 @@ tls_cycle_output(isc_nmsocket_t *sock) {
break;
}
r = uv_timer_start(&sock->write_timer,
isc__nmsocket_writetimeout_cb,
sock->write_timeout, 0);
UV_RUNTIME_CHECK(uv_timer_start, r);
RUNTIME_CHECK(sock->writes++ >= 0);
r = uv_write(&req->uv_req.write, &sock->uv_handle.stream,
&req->uvbuf, 1, tls_write_cb);
if (r < 0) {
@ -1264,6 +1249,12 @@ tls_cycle_output(isc_nmsocket_t *sock) {
break;
}
isc_nm_timer_create(req->handle, isc__nmsocket_writetimeout_cb,
req, &req->timer);
if (sock->write_timeout > 0) {
isc_nm_timer_start(req->timer, sock->write_timeout);
}
break;
}
@ -1499,10 +1490,6 @@ accept_connection(isc_nmsocket_t *ssock, isc_quota_t *quota) {
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&csock->read_timer, csock);
r = uv_timer_init(&worker->loop, &csock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&csock->write_timer, csock);
r = uv_accept(&ssock->uv_handle.stream, &csock->uv_handle.stream);
if (r != 0) {
result = isc__nm_uverr2result(r);
@ -1849,17 +1836,6 @@ read_timer_close_cb(uv_handle_t *handle) {
}
}
static void
write_timer_close_cb(uv_handle_t *timer) {
isc_nmsocket_t *sock = uv_handle_get_data(timer);
uv_handle_set_data(timer, NULL);
REQUIRE(VALID_NMSOCK(sock));
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
uv_close((uv_handle_t *)&sock->read_timer, read_timer_close_cb);
}
static void
stop_tlsdns_child(isc_nmsocket_t *sock) {
REQUIRE(sock->type == isc_nm_tlsdnssocket);
@ -1913,8 +1889,6 @@ stop_tlsdns_parent(isc_nmsocket_t *sock) {
static void
tlsdns_close_direct(isc_nmsocket_t *sock) {
int r;
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_nm_tid());
REQUIRE(atomic_load(&sock->closing));
@ -1932,10 +1906,8 @@ tlsdns_close_direct(isc_nmsocket_t *sock) {
isc__nmsocket_timer_stop(sock);
isc__nm_stop_reading(sock);
r = uv_timer_stop(&sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_stop, r);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
uv_close((uv_handle_t *)&sock->write_timer, write_timer_close_cb);
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
uv_close((uv_handle_t *)&sock->read_timer, read_timer_close_cb);
}
void

View File

@ -76,9 +76,6 @@ udp_close_cb(uv_handle_t *handle);
static void
read_timer_close_cb(uv_handle_t *handle);
static void
write_timer_close_cb(uv_handle_t *handle);
static void
udp_close_direct(isc_nmsocket_t *sock);
@ -272,10 +269,6 @@ route_connect_direct(isc_nmsocket_t *sock) {
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
r = uv_timer_init(&worker->loop, &sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
if (isc__nm_closing(sock)) {
result = ISC_R_SHUTTINGDOWN;
goto error;
@ -454,10 +447,6 @@ isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
r = uv_timer_init(&worker->loop, &sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
LOCK(&sock->parent->lock);
r = uv_udp_open(&sock->uv_handle.udp, sock->fd);
@ -874,10 +863,6 @@ udp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
r = uv_timer_init(&worker->loop, &sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_init, r);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
if (isc__nm_closing(sock)) {
result = ISC_R_SHUTTINGDOWN;
goto error;
@ -1240,17 +1225,6 @@ read_timer_close_cb(uv_handle_t *handle) {
}
}
static void
write_timer_close_cb(uv_handle_t *timer) {
isc_nmsocket_t *sock = uv_handle_get_data(timer);
uv_handle_set_data(timer, NULL);
REQUIRE(VALID_NMSOCK(sock));
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
uv_close((uv_handle_t *)&sock->read_timer, read_timer_close_cb);
}
static void
stop_udp_child(isc_nmsocket_t *sock) {
REQUIRE(sock->type == isc_nm_udpsocket);
@ -1303,14 +1277,11 @@ stop_udp_parent(isc_nmsocket_t *sock) {
static void
udp_close_direct(isc_nmsocket_t *sock) {
int r;
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_nm_tid());
r = uv_timer_stop(&sock->write_timer);
UV_RUNTIME_CHECK(uv_timer_stop, r);
uv_handle_set_data((uv_handle_t *)&sock->write_timer, sock);
uv_close((uv_handle_t *)&sock->write_timer, write_timer_close_cb);
uv_handle_set_data((uv_handle_t *)&sock->read_timer, sock);
uv_close((uv_handle_t *)&sock->read_timer, read_timer_close_cb);
}
void