Exemplo n.º 1
0
int
sblock(struct sockbuf *sb, int flags)
{

	KASSERT((flags & SBL_VALID) == flags,
	    ("sblock: flags invalid (0x%x)", flags));

	if (flags & SBL_WAIT) {
		rw_rlock(&sb->sb_rwlock);
		return (0);
	} else {
		if (rw_try_rlock(&sb->sb_rwlock) == 0)
			return (EWOULDBLOCK);
		return (0);
	}
}
Exemplo n.º 2
0
/*
 * Caveat:  Called from interrupt context
 */
static void
ps_ether_input(struct ifnet *ifp, struct mbuf **mp) {
    struct pspcb *psp = NULL, *psp_next;
    struct ether_header *eh;
    struct sockaddr esa;
    struct socket *so = NULL;
    u_short etype;

    eh = mtod(*mp, struct ether_header *);
    etype = ntohs(eh->ether_type);

    if (PS_ETHER_TYPE != etype)
	return;

    /*
     * We currently place the mbuf to a bound socket's rcv.
     *
     * However,this is not the long term plan.  Instead, in the 
     * longer term we should fill in a page, place the page at
     * the local cache, and then wake up the network receiver.
     * through the bound socket.
     */

    PS_PRINTF(PS_DEBUG_SOCKET, "m = %p\n", *mp);
    LIST_FOREACH_SAFE(psp, pspcbhead, psp_list, psp_next) {
#if __FreeBSD_version >= 701000
	if (!rw_try_rlock(&psp->psp_lock)) {
            PS_PRINTF(PS_DEBUG_SOCKET | PS_DEBUG_WARNING,
                      "psp is w-locked, discard data\n");
	    /* Simply discard data if the psp happens to be w-locked */
	    continue;
	}
#endif
	if (ifp == psp->psp_ifp) {
	    so = psp->psp_socket;
#if __FreeBSD_version >= 701000
	    rw_runlock(&psp->psp_lock);
#endif
	    break;
	}
#if __FreeBSD_version >= 701000
	rw_runlock(&psp->psp_lock);
#endif
    }

    if (so) {
	/*
	 * XXX: We don't understand why simple sbappend
	 *      doesn't work.  But spappendaddr does.  So be it.
	 */
	esa.sa_family = AF_LINK;
	esa.sa_len = 0;
	m_adj(*mp, sizeof(*eh)); /* Remove ethernet header */
	if (!sbappendaddr(&so->so_rcv, &esa, *mp, NULL)) {
            PS_PRINTF(PS_DEBUG_SOCKET | PS_DEBUG_WARNING,
                      "sbappendaddr() failed. "
                      "Probably not enough buffer space. "
                      "Packet lost.\n");
        }
	sorwakeup(so);
    	*mp = NULL;
	return;
    }


#ifdef NOTYET
    /* We could free *mp here, but we don't.  It gets discarded anyway */
    m_freem(*mp);
    *mp = NULL;
#endif
    return;
}