* is data to process.
*/
-isc_result_t
+void
isc_nm_pauseread(isc_nmhandle_t *handle);
/*%<
* Pause reading on this handle's socket, but remember the callback.
* or, for child sockets, 'sock->parent->active'.
*/
+bool
+isc__nmsocket_deactivate(isc_nmsocket_t *sock);
+/*%<
+ * @brief Deactivate active socket
+ *
+ * Atomically deactive the socket by setting @p sock->active or, for child
+ * sockets, @p sock->parent->active to @c false
+ *
+ * @param[in] sock - valid nmsocket
+ * @return @c false if the socket was already inactive, @c true otherwise
+ */
+
void
isc__nmsocket_clearcb(isc_nmsocket_t *sock);
/*%<
/*%<
* Close a TCP socket.
*/
-isc_result_t
+void
isc__nm_tcp_pauseread(isc_nmsocket_t *sock);
/*%<
* Pause reading on this socket, while still remembering the callback.
return (atomic_load(&sock->active));
}
+bool
+isc__nmsocket_deactivate(isc_nmsocket_t *sock) {
+ REQUIRE(VALID_NMSOCK(sock));
+
+ if (sock->parent != NULL) {
+ return (atomic_compare_exchange_strong(&sock->parent->active,
+ &(bool){ true }, false));
+ }
+
+ return (atomic_compare_exchange_strong(&sock->active, &(bool){ true },
+ false));
+}
+
void
isc__nmsocket_attach(isc_nmsocket_t *sock, isc_nmsocket_t **target) {
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(VALID_NM(mgr));
REQUIRE(VALID_NMSOCK(sock));
- if (sock != NULL && atomic_load(&sock->active)) {
+ if (sock != NULL && isc__nmsocket_active(sock)) {
/* Try to reuse one */
req = isc_astack_pop(sock->inactivereqs);
}
handle = req->handle;
req->handle = NULL;
- if (!atomic_load(&sock->active) ||
+ if (!isc__nmsocket_active(sock) ||
!isc_astack_trypush(sock->inactivereqs, req)) {
isc_mempool_put(sock->mgr->reqpool, req);
}
}
}
-isc_result_t
+void
isc_nm_pauseread(isc_nmhandle_t *handle) {
REQUIRE(VALID_NMHANDLE(handle));
switch (sock->type) {
case isc_nm_tcpsocket:
- return (isc__nm_tcp_pauseread(sock));
+ isc__nm_tcp_pauseread(sock);
+ break;
default:
INSIST(0);
ISC_UNREACHABLE();
}
}
-isc_result_t
+void
isc__nm_tcp_pauseread(isc_nmsocket_t *sock) {
isc__netievent_pauseread_t *ievent = NULL;
REQUIRE(VALID_NMSOCK(sock));
- if (atomic_load(&sock->readpaused)) {
- return (ISC_R_SUCCESS);
+ if (!atomic_compare_exchange_strong(&sock->readpaused, &(bool){ false },
+ true)) {
+ return;
}
- atomic_store(&sock->readpaused, true);
ievent = isc__nm_get_ievent(sock->mgr, netievent_tcppauseread);
ievent->sock = sock;
(isc__netievent_t *)ievent);
}
- return (ISC_R_SUCCESS);
+ return;
}
void
return;
}
- if (!atomic_load(&sock->readpaused)) {
+ if (!atomic_compare_exchange_strong(&sock->readpaused, &(bool){ true },
+ false)) {
return;
}
- atomic_store(&sock->readpaused, false);
-
ievent = isc__nm_get_ievent(sock->mgr, netievent_tcpstartread);
ievent->sock = sock;
REQUIRE(VALID_NMSOCK(ssock));
- if (!atomic_load_relaxed(&ssock->active) ||
- atomic_load_relaxed(&ssock->mgr->closing))
- {
+ if (!isc__nmsocket_active(ssock) || atomic_load(&ssock->mgr->closing)) {
/* We're closing, bail */
if (quota != NULL) {
isc_quota_detach("a);
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_nm_tid());
- if (!isc__nmsocket_active(sock)) {
+ /*
+ * If the socket is active, mark it inactive and
+ * continue. If it isn't active, stop now.
+ */
+ if (!isc__nmsocket_deactivate(sock)) {
return;
}
- atomic_store(&sock->active, false);
-
if (sock->type == isc_nm_tcpsocket && sock->statichandle != NULL) {
failed_read_cb(sock, ISC_R_CANCELED);
}
REQUIRE(worker->id == sock->tid);
REQUIRE(sock->tid == isc_nm_tid());
- if (atomic_load(&sock->active) && sock->outerhandle != NULL) {
+ if (isc__nmsocket_active(sock) && sock->outerhandle != NULL) {
isc_nmhandle_t *sendhandle = NULL;
isc_region_t r;
REQUIRE(sock->type == isc_nm_udplistener);
/*
- * Socket is already closing; there's nothing to do.
+ * If the socket is active, mark it inactive and
+ * continue. If it isn't active, stop now.
*/
- if (!isc__nmsocket_active(sock)) {
+ if (!isc__nmsocket_deactivate(sock)) {
return;
}
- /*
- * Mark it inactive now so that all sends will be ignored
- * and we won't try to stop listening again.
- */
- atomic_store(&sock->active, false);
/*
* If the manager is interlocked, re-enqueue this as an asynchronous