Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin AT sources DOT redhat DOT com Date: Sun, 15 Jul 2001 23:15:52 -0400 From: Christopher Faylor To: cygwin AT cygwin DOT com Subject: Re: data in socketpair() channel lost if writer closes or exits without shutting down Message-ID: <20010715231552.A10472@redhat.com> Reply-To: cygwin AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com References: <20010713181435 DOT 3695 DOT qmail AT lizard DOT curl DOT com> <20010713202146 DOT B11377 AT redhat DOT com> <20010716025220 DOT 23701 DOT qmail AT lizard DOT curl DOT com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <20010716025220.23701.qmail@lizard.curl.com>; from jik@curl.com on Sun, Jul 15, 2001 at 10:52:20PM -0400 On Sun, Jul 15, 2001 at 10:52:20PM -0400, Jonathan Kamens wrote: >> Date: Fri, 13 Jul 2001 20:21:46 -0400 >> From: Christopher Faylor >> >> Thanks for the diagnosis. Would you be willing to look at the >> Cygwin socket code and suggest a fix? > >OK, I looked at this for long enough to understand what's going wrong >and to understand theoretically how to fix it, but I'm hung up on some >of the Cygwin nuts and bolts. Perhaps after I explain the problem, >someone can give me a couple of pointers for how to address it within >the Cygwin framework.... > >In yet another astounding piece of Windows brain-damage, the >*documented* behavior of the Winsock closesocket call is that any data >written to the socket that hasn't been read by the other end is lost, >and thus a client *must* call shutdown on a socket before closing it >to ensure that all data is transmitted to the other end. The >reasoning behind implementing things this way escapes me. > >My first thought after discovering this was that the obvious solution >is to call shutdown on the socket before calling closesocket in >fhandler_socket::close in fhandler_socket.cc. Alas, we can't do this, >because a socket may be shared among multiple processes. Although >each process has a different socket descriptor, the underlying socket >is shared among all of them, which means that as soon as any process >calls shutdown, the socket is unusable by all processes. This is >clearly unacceptable when it's a common idiom, e.g., for a socketpair >to be created in a parent which then forks, and then the parent closes >one end of the socketpair while the child closes the other. > >So, what I think needs to happen is that there needs to be some global >state, shared among all Cygwin processes, keeping track of sockets and >how many processes are using them. Then, fhandler_socket::close can >check to see if all the processes but one have closed a socket, and >*only* then should it call shutdown on the socket before calling >closesocket on it. > >Where I'm hung up is figuring out how to store that kind of global >state. At first I thought it had something to do with "cygheap", but >upon further examination it looks to me like every cygwin process has >its own "cygheap"; perhaps I am confused about that. > >If someone can suggest what I should look at to learn how to keep >global Cygwin state, I may be able to make more progress with this. Each cygwin process inherits a copy of cygheap. The cygheap is not strictly shared between processes. It is just inherited from its parent. We don't have any mechanism for sharing file handle (or actually device) state between processes. Corinna and I have talked about this for some time, though. If we had something like this, I could fix some other problems with the handling pipes, too. cgf -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Bug reporting: http://cygwin.com/bugs.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/