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; }
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); }