REQUIRE(socketp != NULL);
sock = (isc__socket_t *)*socketp;
REQUIRE(VALID_SOCKET(sock));
-
if (isc_refcount_decrement(&sock->references) == 1) {
destroy(&sock);
}
const char *err = "accept";
INSIST(VALID_SOCKET(sock));
+ REQUIRE(sock->fd >= 0);
- if (sock->fd < 0) {
- /* Socket is gone */
- return;
- }
socket_log(sock, NULL, TRACE, "internal_accept called, locked socket");
manager = sock->manager;
isc_socketevent_t *dev;
INSIST(VALID_SOCKET(sock));
+ REQUIRE(sock->fd >= 0);
- if (sock->fd < 0) {
- /* Socket is gone */
- return;
- }
dev = ISC_LIST_HEAD(sock->recv_list);
if (dev == NULL) {
goto finish;
isc_socketevent_t *dev;
INSIST(VALID_SOCKET(sock));
+ REQUIRE(sock->fd >= 0);
- if (sock->fd < 0) {
- /* Socket is gone */
- return;
- }
dev = ISC_LIST_HEAD(sock->send_list);
if (dev == NULL) {
goto finish;
return;
}
- if (isc_refcount_increment0(&sock->references) == 0) {
+ LOCK(&sock->lock);
+ if (sock->fd < 0) {
/*
- * Sock is being closed, it will be destroyed, bail.
+ * Sock is being closed - the final external reference
+ * is gone but it was not yet removed from event loop
+ * and fdstate[]/fds[] as destroy() is waiting on
+ * thread->fdlock[lockid] or sock->lock that we're holding.
+ * Just release the locks and bail.
*/
- (void)isc_refcount_decrement(&sock->references);
- UNLOCK(&thread->fdlock[lockid]);
- return;
+ goto unlock;
}
- LOCK(&sock->lock);
if (readable) {
if (sock->listener) {
internal_accept(sock);
internal_send(sock);
}
}
- UNLOCK(&sock->lock);
+unlock:
+ UNLOCK(&sock->lock);
UNLOCK(&thread->fdlock[lockid]);
- if (isc_refcount_decrement(&sock->references) == 1) {
- destroy(&sock);
- }
+ /*
+ * Socket destruction might be pending, it will resume
+ * after releasing fdlock and sock->lock.
+ */
}
/*
char peerbuf[ISC_SOCKADDR_FORMATSIZE];
INSIST(VALID_SOCKET(sock));
+ REQUIRE(sock->fd >= 0);
/*
* Get the first item off the connect list.