Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 22 Mar 2005 12:50:23 -0500
From:      James Juran <James.Juran@baesystems.com>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: kern/79138: close while sending on connected UNIX-domain socket can return ENOTCONN, should return EPIPE or 0
Message-ID:  <1111513822.3629.2.camel@juran.digitalnet.com>
In-Reply-To: <200503221700.j2MH06Ln058240@freefall.freebsd.org>
References:  <200503221700.j2MH06Ln058240@freefall.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
Sorry about the line wrapping on the description.  Here's a properly
wrapped version of the description field:

The test program shown below, when run on a uniproc system compiled with
PREEMPTION and FULL_PREEMPTION, shows that calling send() for more than
2048 bytes on a UNIX-domain connection-oriented socket can return ENOTCONN,
even when the socket is connected.  This happens when the other side of
the connection does a partial recv() and then closes the connection with
data still in the send buffer.  The send() should return either EPIPE, if
the close happens before the send completes, or 0 if the send completes
before the close takes effect.

What happens is that sosend() breaks the send into 2048-byte chunks and
calls uipc_send() for each one.  uipc_send() wakes up a process waiting
in recv().  In the GENERIC kernel on uniproc, this wakeup doesn't actually
take effect until sosend() tries to get the SOCKBUF_LOCK at the bottom of
the main loop.  It then checks SBS_CANTSENDMORE on the next loop iteration,
and returns EPIPE as it should.  However, with option FULL_PREEMPTION, the
process doing the recv() gets run right away, and performs its close before
the second call to uipc_send().  uipc_send() then fails the check for
SS_ISCONNECTED and returns ENOTCONN.

Even though this failure requires FULL_PREEMPTION to reproduce on uniproc,
I would think that on SMP there would be a chance of failure even on a
standard kernel.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1111513822.3629.2.camel>