diff options
| author | Robert Watson <rwatson@FreeBSD.org> | 2007-03-01 09:00:42 +0000 |
|---|---|---|
| committer | Robert Watson <rwatson@FreeBSD.org> | 2007-03-01 09:00:42 +0000 |
| commit | ede6e136f868d044d00f5935758c675862ef6941 (patch) | |
| tree | e2b2d58775628b38061bef1ca31d50911fe9c24a /sys/kern/uipc_usrreq.c | |
| parent | 6fccc5ecd48f204d60db036d4bfe365c5a9ff216 (diff) | |
Notes
Diffstat (limited to 'sys/kern/uipc_usrreq.c')
| -rw-r--r-- | sys/kern/uipc_usrreq.c | 41 |
1 files changed, 19 insertions, 22 deletions
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 3a30138e6985..17a8fb5c8661 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -774,21 +774,18 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, unp2 = unp->unp_conn; if (nam != NULL) { + UNP_GLOBAL_WLOCK_ASSERT(); if (unp2 != NULL) { error = EISCONN; - UNP_PCB_LOCK(unp); break; } error = unp_connect(so, nam, td); - UNP_PCB_LOCK(unp); if (error) break; unp2 = unp->unp_conn; } else { - UNP_PCB_LOCK(unp); if (unp2 == NULL) { error = ENOTCONN; - UNP_PCB_LOCK(unp); break; } } @@ -799,19 +796,19 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, * return the slightly counter-intuitive but otherwise * correct error that the socket is not connected. */ - UNP_PCB_LOCK_ASSERT(unp); if (unp2 == NULL) { error = ENOTCONN; break; } - UNP_PCB_LOCK(unp2); - so2 = unp2->unp_socket; + /* Lockless read. */ + if (unp2->unp_flags & UNP_WANTCRED) + control = unp_addsockcred(td, control); + UNP_PCB_LOCK(unp); if (unp->unp_addr != NULL) from = (struct sockaddr *)unp->unp_addr; else from = &sun_noname; - if (unp2->unp_flags & UNP_WANTCRED) - control = unp_addsockcred(td, control); + so2 = unp2->unp_socket; SOCKBUF_LOCK(&so2->so_rcv); if (sbappendaddr_locked(&so2->so_rcv, from, m, control)) { sorwakeup_locked(so2); @@ -821,9 +818,13 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, SOCKBUF_UNLOCK(&so2->so_rcv); error = ENOBUFS; } - if (nam != NULL) + if (nam != NULL) { + UNP_GLOBAL_WLOCK_ASSERT(); + UNP_PCB_LOCK(unp2); unp_disconnect(unp, unp2); - UNP_PCB_UNLOCK(unp2); + UNP_PCB_UNLOCK(unp2); + } + UNP_PCB_UNLOCK(unp); break; } @@ -836,18 +837,15 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, */ if ((so->so_state & SS_ISCONNECTED) == 0) { if (nam != NULL) { + UNP_GLOBAL_WLOCK_ASSERT(); error = unp_connect(so, nam, td); - UNP_PCB_LOCK(unp); if (error) break; /* XXX */ } else { error = ENOTCONN; - UNP_PCB_LOCK(unp); break; } - } else - UNP_PCB_LOCK(unp); - UNP_PCB_LOCK_ASSERT(unp); + } /* Lockless read. */ if (so->so_snd.sb_state & SBS_CANTSENDMORE) { @@ -874,13 +872,12 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, error = ENOTCONN; break; } - UNP_PCB_LOCK(unp2); so2 = unp2->unp_socket; + UNP_PCB_LOCK(unp2); SOCKBUF_LOCK(&so2->so_rcv); if (unp2->unp_flags & UNP_WANTCRED) { /* - * Credentials are passed only once on - * SOCK_STREAM. + * Credentials are passed only once on SOCK_STREAM. */ unp2->unp_flags &= ~UNP_WANTCRED; control = unp_addsockcred(td, control); @@ -915,14 +912,14 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, } /* - * SEND_EOF is equivalent to a SEND followed by - * a SHUTDOWN. + * SEND_EOF is equivalent to a SEND followed by a SHUTDOWN. */ if (flags & PRUS_EOF) { + UNP_PCB_LOCK(unp); socantsendmore(so); unp_shutdown(unp); + UNP_PCB_UNLOCK(unp); } - UNP_PCB_UNLOCK(unp); if ((nam != NULL) || (flags & PRUS_EOF)) UNP_GLOBAL_WUNLOCK(); |
