#include <sys/protosw.h>
#include <sys/domain.h>
#include <sys/mbuf.h>
+#include <sys/mcache.h>
#include <sys/fcntl.h>
#include <sys/filio.h>
#include <sys/uio_internal.h>
socket_unlock(sock, 1);
return (ENOTSUP);
}
+check_again:
if (((flags & MSG_DONTWAIT) != 0 || (sock->so_state & SS_NBIO) != 0) &&
sock->so_comp.tqh_first == NULL) {
socket_unlock(sock, 1);
return (error);
}
+ so_acquire_accept_list(sock, NULL);
+ if (TAILQ_EMPTY(&sock->so_comp)) {
+ so_release_accept_list(sock);
+ goto check_again;
+ }
new_so = TAILQ_FIRST(&sock->so_comp);
TAILQ_REMOVE(&sock->so_comp, new_so, so_list);
+ new_so->so_state &= ~SS_COMP;
+ new_so->so_head = NULL;
sock->so_qlen--;
+ so_release_accept_list(sock);
+
/*
* Pass the pre-accepted socket to any interested socket filter(s).
* Upon failure, the socket would have been closed by the callee.
* again once we're done with the filter(s).
*/
socket_unlock(sock, 0);
- if ((error = soacceptfilter(new_so)) != 0) {
+ if ((error = soacceptfilter(new_so, sock)) != 0) {
/* Drop reference on listening socket */
sodereference(sock);
return (error);
socket_lock(new_so, 1);
}
- new_so->so_state &= ~SS_COMP;
- new_so->so_head = NULL;
(void) soacceptlock(new_so, &sa, 0);
socket_unlock(sock, 1); /* release the head */
soclose_locked(sock);
} else {
/* remove extra reference holding the socket */
+ VERIFY(sock->so_usecount > 1);
sock->so_usecount--;
}
socket_unlock(sock, 1);