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>