FreeBSD/sys/rpc/svc_vc.c
/*
 * This does all of the accept except the final call to soaccept. The
 * caller will call soaccept after dropping its locks (soaccept may
 * call malloc).
 */
This does all of the accept except the final call to soaccept. The
caller will call soaccept after dropping its locks (soaccept may
call malloc).
This does all of the accept except the final call to soaccept . The caller will call soaccept after dropping its locks ( soaccept may call malloc ) .
int
svc_vc_accept(struct socket *head, struct socket **sop)
{
	int error = 0;
	struct socket *so;
	if ((head->so_options & SO_ACCEPTCONN) == 0) {
		error = EINVAL;
		goto done;
	}
#ifdef MAC
	error = mac_socket_check_accept(curthread->td_ucred, head);
	if (error != 0)
		goto done;
#endif
	ACCEPT_LOCK();
	if (TAILQ_EMPTY(&head->so_comp)) {
		ACCEPT_UNLOCK();
		error = EWOULDBLOCK;
		goto done;
	}
	so = TAILQ_FIRST(&head->so_comp);
	KASSERT(!(so->so_qstate & SQ_INCOMP), ("svc_vc_accept: so SQ_INCOMP"));
	KASSERT(so->so_qstate & SQ_COMP, ("svc_vc_accept: so not SQ_COMP"));
	SOCK_LOCK(so);			
	soref(so);			
	TAILQ_REMOVE(&head->so_comp, so, so_list);
	head->so_qlen--;
	so->so_state |= (head->so_state & SS_NBIO);
	so->so_qstate &= ~SQ_COMP;
	so->so_head = NULL;
	SOCK_UNLOCK(so);
	ACCEPT_UNLOCK();
	*sop = so;
	KNOTE_UNLOCKED(&head->so_rcv.sb_sel.si_note, 0);
done:
	return (error);
}
int svc_vc_accept ( struct socket * head , struct socket * * sop ) { int error = 0 ; struct socket * so ; if ( ( head -> so_options & SO_ACCEPTCONN ) == 0 ) { error = EINVAL ; goto done ; } #ifdef MAC error = mac_socket_check_accept ( curthread -> td_ucred , head ) ; if ( error != 0 ) goto done ; #endif ACCEPT_LOCK ( ) ; if ( TAILQ_EMPTY ( & head -> so_comp ) ) { ACCEPT_UNLOCK ( ) ; error = EWOULDBLOCK ; goto done ; } so = TAILQ_FIRST ( & head -> so_comp ) ; KASSERT ( ! ( so -> so_qstate & SQ_INCOMP ) , ( " " ) ) ; KASSERT ( so -> so_qstate & SQ_COMP , ( " " ) ) ; SOCK_LOCK ( so ) ; soref ( so ) ; TAILQ_REMOVE ( & head -> so_comp , so , so_list ) ; head -> so_qlen -- ; so -> so_state |= ( head -> so_state & SS_NBIO ) ; so -> so_qstate &= ~ SQ_COMP ; so -> so_head = NULL ; SOCK_UNLOCK ( so ) ; ACCEPT_UNLOCK ( ) ; * sop = so ; KNOTE_UNLOCKED ( & head -> so_rcv . sb_sel . si_note , 0 ) ; done : return ( error ) ; }
This does all of the accept except the final call to soaccept.
This does all of the accept except the final call to soaccept .
/*
	 * Before changing the flags on the socket, we have to bump the
	 * reference count.  Otherwise, if the protocol calls sofree(),
	 * the socket will be released due to a zero refcount.
	 * XXX might not need soref() since this is simpler than kern_accept.
	 */ /* soref() and so_state update */ /* file descriptor reference */ /* connection has been removed from the listen queue */