X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/3903760236c30e3b5ace7a4eefac3a269d68957c..4d15aeb193b2c68f1d38666c317f8d3734f5f083:/bsd/kern/kpi_socket.c diff --git a/bsd/kern/kpi_socket.c b/bsd/kern/kpi_socket.c index 2251c3f6d..2f1b1d96a 100644 --- a/bsd/kern/kpi_socket.c +++ b/bsd/kern/kpi_socket.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -73,6 +74,7 @@ sock_accept(socket_t sock, struct sockaddr *from, int fromlen, int flags, 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); @@ -106,10 +108,19 @@ sock_accept(socket_t sock, struct sockaddr *from, int fromlen, int flags, 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. @@ -122,7 +133,7 @@ sock_accept(socket_t sock, struct sockaddr *from, int fromlen, int flags, * 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); @@ -136,8 +147,6 @@ sock_accept(socket_t sock, struct sockaddr *from, int fromlen, int flags, 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 */ @@ -961,6 +970,7 @@ sock_release(socket_t sock) soclose_locked(sock); } else { /* remove extra reference holding the socket */ + VERIFY(sock->so_usecount > 1); sock->so_usecount--; } socket_unlock(sock, 1);