Further clean up sorflush:

- Expose sbrelease_internal(), a variant of sbrelease() with no
  expectations about the validity of locks in the socket buffer.
- Use sbrelease_internel() in sorflush(), and as a result avoid intializing
  and destroying a socket buffer lock for the temporary stack copy of the
  actual buffer, asb.
- Add a comment indicating why we do what we do, and remove an XXX since
  things have gotten less ugly in sorflush() lately.

This makes socket close cleaner, and possibly also marginally faster.

MFC after:	3 weeks
This commit is contained in:
Robert Watson 2008-02-04 12:25:13 +00:00
parent 2591e96ce2
commit 3f0bfcccfd
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=175968
3 changed files with 14 additions and 14 deletions

View File

@ -67,7 +67,6 @@ static u_long sb_efficiency = 8; /* parameter for sbreserve() */
static void sbdrop_internal(struct sockbuf *sb, int len);
static void sbflush_internal(struct sockbuf *sb);
static void sbrelease_internal(struct sockbuf *sb, struct socket *so);
/*
* Socantsendmore indicates that no more data will be sent on the socket; it
@ -322,7 +321,7 @@ sbreserve(struct sockbuf *sb, u_long cc, struct socket *so,
/*
* Free mbufs held by a socket, and reserved mbuf space.
*/
static void
void
sbrelease_internal(struct sockbuf *sb, struct socket *so)
{

View File

@ -1877,15 +1877,13 @@ sorflush(struct socket *so)
struct sockbuf asb;
/*
* XXXRW: This is quite ugly. Previously, this code made a copy of
* the socket buffer, then zero'd the original to clear the buffer
* fields. However, with mutexes in the socket buffer, this causes
* problems. We only clear the zeroable bits of the original;
* however, we have to initialize and destroy the mutex in the copy
* so that dom_dispose() and sbrelease() can lock t as needed.
*/
/*
* In order to avoid calling dom_dispose with the socket buffer mutex
* held, and in order to generally avoid holding the lock for a long
* time, we make a copy of the socket buffer and clear the original
* (except locks, state). The new socket buffer copy won't have
* initialized locks so we can only call routines that won't use or
* assert those locks.
*
* Dislodge threads currently blocked in receive and wait to acquire
* a lock against other simultaneous readers before clearing the
* socket buffer. Don't let our acquire be interrupted by a signal
@ -1907,11 +1905,13 @@ sorflush(struct socket *so)
SOCKBUF_UNLOCK(sb);
sbunlock(sb);
SOCKBUF_LOCK_INIT(&asb, "so_rcv");
/*
* Dispose of special rights and flush the socket buffer. Don't call
* any unsafe routines (that rely on locks being initialized) on asb.
*/
if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose != NULL)
(*pr->pr_domain->dom_dispose)(asb.sb_mb);
sbrelease(&asb, so);
SOCKBUF_LOCK_DESTROY(&asb);
sbrelease_internal(&asb, so);
}
/*

View File

@ -483,6 +483,7 @@ void sbdroprecord_locked(struct sockbuf *sb);
void sbflush(struct sockbuf *sb);
void sbflush_locked(struct sockbuf *sb);
void sbrelease(struct sockbuf *sb, struct socket *so);
void sbrelease_internal(struct sockbuf *sb, struct socket *so);
void sbrelease_locked(struct sockbuf *sb, struct socket *so);
int sbreserve(struct sockbuf *sb, u_long cc, struct socket *so,
struct thread *td);