Example #1
0
int
so_pru_connect_async(struct socket *so, struct sockaddr *nam, struct thread *td)
{
	struct netmsg_pru_connect *msg;
	int error, flags;

	KASSERT(so->so_proto->pr_usrreqs->pru_preconnect != NULL,
	    ("async pru_connect is not supported"));

	/* NOTE: sockaddr immediately follows netmsg */
	msg = kmalloc(sizeof(*msg) + nam->sa_len, M_LWKTMSG,
	    M_WAITOK | M_NULLOK);
	if (msg == NULL) {
		/*
		 * Fail to allocate message; fallback to
		 * synchronized pru_connect.
		 */
		return so_pru_connect(so, nam, td);
	}

	error = so->so_proto->pr_usrreqs->pru_preconnect(so, nam, td);
	if (error) {
		kfree(msg, M_LWKTMSG);
		return error;
	}

	flags = PRUC_ASYNC;
	if (td != NULL && (so->so_proto->pr_flags & PR_ACONN_HOLDTD)) {
		lwkt_hold(td);
		flags |= PRUC_HELDTD;
	}

	netmsg_init(&msg->base, so, &netisr_afree_rport, 0,
	    so->so_proto->pr_usrreqs->pru_connect);
	msg->nm_nam = (struct sockaddr *)(msg + 1);
	memcpy(msg->nm_nam, nam, nam->sa_len);
	msg->nm_td = td;
	msg->nm_m = NULL;
	msg->nm_sndflags = 0;
	msg->nm_flags = flags;
	lwkt_sendmsg(so->so_port, &msg->base.lmsg);
	return 0;
}
Example #2
0
void
so_pru_send_async(struct socket *so, int flags, struct mbuf *m,
    struct sockaddr *addr0, struct mbuf *control, struct thread *td)
{
	struct netmsg_pru_send *msg;
	struct sockaddr *addr = NULL;

	KASSERT(so->so_proto->pr_flags & PR_ASYNC_SEND,
	    ("async pru_send is not supported"));

	if (addr0 != NULL) {
		addr = kmalloc(addr0->sa_len, M_SONAME, M_WAITOK | M_NULLOK);
		if (addr == NULL) {
			/*
			 * Fail to allocate address; fallback to
			 * synchronized pru_send.
			 */
			so_pru_send(so, flags, m, addr0, control, td);
			return;
		}
		memcpy(addr, addr0, addr0->sa_len);
		flags |= PRUS_FREEADDR;
	}
	flags |= PRUS_NOREPLY;

	if (td != NULL && (so->so_proto->pr_flags & PR_ASEND_HOLDTD)) {
		lwkt_hold(td);
		flags |= PRUS_HELDTD;
	}

	msg = &m->m_hdr.mh_sndmsg;
	netmsg_init(&msg->base, so, &netisr_apanic_rport,
		    0, so->so_proto->pr_usrreqs->pru_send);
	msg->nm_flags = flags;
	msg->nm_m = m;
	msg->nm_addr = addr;
	msg->nm_control = control;
	msg->nm_td = td;
	lwkt_sendmsg(so->so_port, &msg->base.lmsg);
}