This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: data in socketpair() channel lost if writer closes or exits without shutting down


>  Date: Fri, 13 Jul 2001 20:21:46 -0400
>  From: Christopher Faylor <cgf@redhat.com>
>  
>  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/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]