diff --git a/lib/isc/include/isc/netmgr.h b/lib/isc/include/isc/netmgr.h index c6f2a74a22..206655814a 100644 --- a/lib/isc/include/isc/netmgr.h +++ b/lib/isc/include/isc/netmgr.h @@ -195,6 +195,17 @@ isc_nm_pauseread(isc_nmsocket_t *sock); * Pause reading on this socket, while still remembering the callback. */ +void +isc_nm_cancelread(isc_nmhandle_t *handle); +/*%< + * Cancel reading on a connected socket. Calls the read/recv callback on + * active handles with a result code of ISC_R_CANCELED. + * + * Requires: + * \li 'sock' is a valid netmgr socket + * \li ...for which a read/recv callback has been defined. + */ + isc_result_t isc_nm_resumeread(isc_nmsocket_t *sock); /*%< diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h index 5325c8cfbf..b0b4833e4b 100644 --- a/lib/isc/netmgr/netmgr-int.h +++ b/lib/isc/netmgr/netmgr-int.h @@ -715,7 +715,14 @@ isc__nm_tcp_resumeread(isc_nmsocket_t *sock); void isc__nm_tcp_shutdown(isc_nmsocket_t *sock); /*%< - * Called on shutdown to close and clean up a listening TCP socket. + * Called during the shutdown process to close and clean up connected + * sockets. + */ + +void +isc__nm_tcp_cancelread(isc_nmsocket_t *sock); +/*%< + * Stop reading on a connected socket. */ void diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index b84229a5ff..ef281430fb 100644 --- a/lib/isc/netmgr/netmgr.c +++ b/lib/isc/netmgr/netmgr.c @@ -1346,9 +1346,24 @@ isc_nm_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) { } } +void +isc_nm_cancelread(isc_nmhandle_t *handle) { + REQUIRE(VALID_NMHANDLE(handle)); + + switch (handle->sock->type) { + case isc_nm_tcpsocket: + isc__nm_tcp_cancelread(handle->sock); + break; + default: + INSIST(0); + ISC_UNREACHABLE(); + } +} + isc_result_t isc_nm_pauseread(isc_nmsocket_t *sock) { REQUIRE(VALID_NMSOCK(sock)); + switch (sock->type) { case isc_nm_tcpsocket: return (isc__nm_tcp_pauseread(sock)); @@ -1361,6 +1376,7 @@ isc_nm_pauseread(isc_nmsocket_t *sock) { isc_result_t isc_nm_resumeread(isc_nmsocket_t *sock) { REQUIRE(VALID_NMSOCK(sock)); + switch (sock->type) { case isc_nm_tcpsocket: return (isc__nm_tcp_resumeread(sock)); @@ -1373,6 +1389,7 @@ isc_nm_resumeread(isc_nmsocket_t *sock) { void isc_nm_stoplistening(isc_nmsocket_t *sock) { REQUIRE(VALID_NMSOCK(sock)); + switch (sock->type) { case isc_nm_udplistener: isc__nm_udp_stoplistening(sock); diff --git a/lib/isc/netmgr/tcp.c b/lib/isc/netmgr/tcp.c index 3e210bd43c..d60797b766 100644 --- a/lib/isc/netmgr/tcp.c +++ b/lib/isc/netmgr/tcp.c @@ -1080,3 +1080,15 @@ isc__nm_tcp_shutdown(isc_nmsocket_t *sock) { sock->rcbarg); } } + +void +isc__nm_tcp_cancelread(isc_nmsocket_t *sock) { + REQUIRE(VALID_NMSOCK(sock)); + + if (sock->type == isc_nm_tcpsocket && sock->tcphandle != NULL && + sock->rcb.recv != NULL) + { + sock->rcb.recv(sock->tcphandle, ISC_R_CANCELED, NULL, + sock->rcbarg); + } +} diff --git a/lib/isc/win32/libisc.def.in b/lib/isc/win32/libisc.def.in index 11abd15a10..6ffcaf83a4 100644 --- a/lib/isc/win32/libisc.def.in +++ b/lib/isc/win32/libisc.def.in @@ -449,6 +449,7 @@ isc_nmhandle_peeraddr isc_nmhandle_ref isc_nmhandle_setdata isc_nmhandle_unref +isc_nm_cancelread isc_nm_closedown isc_nm_destroy isc_nm_detach