Index: uipc_usrreq.c =================================================================== RCS file: /home/ncvs/src/sys/kern/uipc_usrreq.c,v retrieving revision 1.167 diff -u -r1.167 uipc_usrreq.c --- uipc_usrreq.c 24 Apr 2006 19:09:33 -0000 1.167 +++ uipc_usrreq.c 7 Jun 2006 22:01:53 -0000 @@ -350,6 +350,7 @@ struct unpcb *unp; struct socket *so2; u_long newhiwat; + u_int mbcnt, sbcc; unp = sotounpcb(so); KASSERT(unp != NULL, ("uipc_send: unp == NULL")); @@ -419,9 +420,8 @@ } } - SOCKBUF_LOCK(&so->so_snd); + /* Lockless read. */ if (so->so_snd.sb_state & SBS_CANTSENDMORE) { - SOCKBUF_UNLOCK(&so->so_snd); error = EPIPE; break; } @@ -448,16 +448,20 @@ } else { sbappend_locked(&so2->so_rcv, m); } - so->so_snd.sb_mbmax -= - so2->so_rcv.sb_mbcnt - unp->unp_conn->unp_mbcnt; + mbcnt = so2->so_rcv.sb_mbcnt - unp->unp_conn->unp_mbcnt; unp->unp_conn->unp_mbcnt = so2->so_rcv.sb_mbcnt; + sbcc = so2->so_rcv.sb_cc; + sorwakeup_locked(so2); + + SOCKBUF_LOCK(&so->so_snd); newhiwat = so->so_snd.sb_hiwat - - (so2->so_rcv.sb_cc - unp->unp_conn->unp_cc); + (sbcc - unp->unp_conn->unp_cc); (void)chgsbsize(so->so_cred->cr_uidinfo, &so->so_snd.sb_hiwat, newhiwat, RLIM_INFINITY); + so->so_snd.sb_mbmax -= mbcnt; SOCKBUF_UNLOCK(&so->so_snd); - unp->unp_conn->unp_cc = so2->so_rcv.sb_cc; - sorwakeup_locked(so2); + + unp->unp_conn->unp_cc = sbcc; m = NULL; break;