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: 15 Jul 2001 22:52:20 -0400 Message-ID: <20010716025220.23701.qmail@lizard.curl.com> From: Jonathan Kamens To: cygwin AT cygwin DOT com CC: cygwin AT cygwin DOT com In-reply-to: <20010713202146.B11377@redhat.com> (message from Christopher Faylor on Fri, 13 Jul 2001 20:21:46 -0400) Subject: Re: data in socketpair() channel lost if writer closes or exits without shutting down References: <20010713181435 DOT 3695 DOT qmail AT lizard DOT curl DOT com> <20010713202146 DOT B11377 AT redhat DOT com> > 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. jik -- 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/