void
isc__nm_tcpdns_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf);
-void
+isc_result_t
isc__nm_start_reading(isc_nmsocket_t *sock);
void
isc__nm_stop_reading(isc_nmsocket_t *sock);
-void
+isc_result_t
isc__nm_process_sock_buffer(isc_nmsocket_t *sock);
void
isc__nm_resume_processing(void *arg);
worker->recvbuf_inuse = true;
}
-void
+isc_result_t
isc__nm_start_reading(isc_nmsocket_t *sock) {
+ isc_result_t result = ISC_R_SUCCESS;
int r;
if (sock->reading) {
- return;
+ return (ISC_R_SUCCESS);
}
switch (sock->type) {
case isc_nm_udpsocket:
r = uv_udp_recv_start(&sock->uv_handle.udp, isc__nm_alloc_cb,
isc__nm_udp_read_cb);
- UV_RUNTIME_CHECK(uv_udp_recv_start, r);
break;
case isc_nm_tcpsocket:
r = uv_read_start(&sock->uv_handle.stream, isc__nm_alloc_cb,
isc__nm_tcp_read_cb);
- UV_RUNTIME_CHECK(uv_read_start, r);
break;
case isc_nm_tcpdnssocket:
r = uv_read_start(&sock->uv_handle.stream, isc__nm_alloc_cb,
isc__nm_tcpdns_read_cb);
- UV_RUNTIME_CHECK(uv_read_start, r);
break;
default:
UNREACHABLE();
}
- sock->reading = true;
+
+ if (r != 0) {
+ result = isc__nm_uverr2result(r);
+ } else {
+ sock->reading = true;
+ }
+
+ return (result);
}
void
* limit. In this case we'll be called again by resume_processing()
* later.
*/
-void
+isc_result_t
isc__nm_process_sock_buffer(isc_nmsocket_t *sock) {
for (;;) {
int_fast32_t ah = atomic_load(&sock->ah);
* Don't reset the timer until we have a
* full DNS message.
*/
- isc__nm_start_reading(sock);
+ result = isc__nm_start_reading(sock);
+ if (result != ISC_R_SUCCESS) {
+ return (result);
+ }
/*
* Start the timer only if there are no externally used
* active handles, there's always one active handle
if (ah == 1) {
isc__nmsocket_timer_start(sock);
}
- return;
+ goto done;
case ISC_R_CANCELED:
isc__nmsocket_timer_stop(sock);
isc__nm_stop_reading(sock);
- return;
+ goto done;
case ISC_R_SUCCESS:
/*
* Stop the timer on the successful message read, this
ah >= STREAM_CLIENTS_PER_CONN)
{
isc__nm_stop_reading(sock);
- return;
+ goto done;
}
break;
default:
UNREACHABLE();
}
}
+done:
+ return (ISC_R_SUCCESS);
}
void
isc__netievent_tcpstartread_t *ievent =
(isc__netievent_tcpstartread_t *)ev0;
isc_nmsocket_t *sock = ievent->sock;
+ isc_result_t result;
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_nm_tid());
UNUSED(worker);
if (isc__nmsocket_closing(sock)) {
+ result = ISC_R_CANCELED;
+ } else {
+ result = isc__nm_start_reading(sock);
+ }
+
+ if (result != ISC_R_SUCCESS) {
sock->reading = true;
- isc__nm_tcp_failed_read_cb(sock, ISC_R_CANCELED);
+ isc__nm_tcp_failed_read_cb(sock, result);
return;
}
- isc__nm_start_reading(sock);
isc__nmsocket_timer_start(sock);
}
isc__netievent_tcpdnsread_t *ievent =
(isc__netievent_tcpdnsread_t *)ev0;
isc_nmsocket_t *sock = ievent->sock;
+ isc_result_t result;
UNUSED(worker);
REQUIRE(sock->tid == isc_nm_tid());
if (isc__nmsocket_closing(sock)) {
- sock->reading = true;
- isc__nm_failed_read_cb(sock, ISC_R_CANCELED, false);
- return;
+ result = ISC_R_CANCELED;
+ } else {
+ result = isc__nm_process_sock_buffer(sock);
}
- isc__nm_process_sock_buffer(sock);
+ if (result != ISC_R_SUCCESS) {
+ sock->reading = true;
+ isc__nm_failed_read_cb(sock, result, false);
+ }
}
/*
isc_nmsocket_t *sock = uv_handle_get_data((uv_handle_t *)stream);
uint8_t *base = NULL;
size_t len;
+ isc_result_t result;
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_nm_tid());
sock->read_timeout = atomic_load(&sock->mgr->idle);
}
- isc__nm_process_sock_buffer(sock);
+ result = isc__nm_process_sock_buffer(sock);
+ if (result != ISC_R_SUCCESS) {
+ isc__nm_failed_read_cb(sock, result, true);
+ }
free:
if (nread < 0) {
/*
* prep_destroy()->tcpdns_close_direct().
*/
isc_nmhandle_attach(handle, &csock->recv_handle);
- isc__nm_process_sock_buffer(csock);
+ result = isc__nm_process_sock_buffer(csock);
+ if (result != ISC_R_SUCCESS) {
+ isc_nmhandle_detach(&csock->recv_handle);
+ isc_nmhandle_detach(&handle);
+ goto failure;
+ }
/*
* The initial timer has been set, update the read timeout for the next
isc__nm_async_udpread(isc__networker_t *worker, isc__netievent_t *ev0) {
isc__netievent_udpread_t *ievent = (isc__netievent_udpread_t *)ev0;
isc_nmsocket_t *sock = ievent->sock;
+ isc_result_t result;
UNUSED(worker);
REQUIRE(sock->tid == isc_nm_tid());
if (isc__nmsocket_closing(sock)) {
+ result = ISC_R_CANCELED;
+ } else {
+ result = isc__nm_start_reading(sock);
+ }
+
+ if (result != ISC_R_SUCCESS) {
sock->reading = true;
- isc__nm_failed_read_cb(sock, ISC_R_CANCELED, false);
+ isc__nm_failed_read_cb(sock, result, false);
return;
}
- isc__nm_start_reading(sock);
isc__nmsocket_timer_start(sock);
}