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


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

Re: More Test 15 [CGF please comment]


On Wed, Apr 11, 2001 at 08:47:09PM -0400, Pierre A. Humblet wrote:
>At 04:12 PM 4/11/2001 -0400, Christopher Faylor wrote:
>>On Wed, Apr 11, 2001 at 12:26:42AM -0400, Pierre A. Humblet wrote:
>>>Chris,
>>>
>>>The Xserver code contains the following line
>>> i = Select (MaxClients, &LastSelectMask, NULL, NULL, wt);
>>>wt is set to 10 ms and Select is #defined as select()
>>>By using gdb and netstat, I observe 
>>>1) that the call to select() generates a new connection
>>>2) that, after a while, a large number of connections exist
>>>3) that after about ~ 2000 calls select() doesn't return.
>>>All of that on WinMe. I have no idea why it is so, either.
>>
>>So, you are again mentioning that you are seeing a "connection".
>>
>>A connection, to what?
>
>To itself... While the XServer runs "netstat -a | sort " 
>shows THOUSANDS of lines such as (hpn5170 is the local host)
>  TCP    hpn5170:1103           localhost:1102         TIME_WAIT
>  TCP    hpn5170:1105           localhost:1104         TIME_WAIT
>  TCP    hpn5170:1107           localhost:1106         TIME_WAIT
>  TCP    hpn5170:1111           localhost:1110         TIME_WAIT
>  TCP    hpn5170:1113           localhost:1112         TIME_WAIT
>  TCP    hpn5170:1115           localhost:1114         TIME_WAIT
>  TCP    hpn5170:1117           localhost:1116         TIME_WAIT
>See also
>http://sources.redhat.com/ml/cygwin-xfree/2001-q2/msg00297.html
>http://sources.redhat.com/ml/cygwin-xfree/2001-q2/msg00272.html
>
>>If you think that select is at fault, then look at the socket
>>specific code in select.cc in the Cygwin DLL.
>
>select() is creating sockets on lines 1275 (start_thread_socket),
>which does a listen(), and 1331 (socket_cleanup), which connects()
>to the first socket. 
>This connect() causes winsock_select() to return and the thread_socket 
>to terminate. The connection is immediately shutdown() after the connect().
>This logic seems to be an ingenious trick to force a return from 
>winsock_select() [when select() wants to return for another reason]
>and to cleanup. 
>
>Experience shows that the second socket doesn't disappear immediately and 
>can be seen with netstat on all the platforms. On WinME some timeout
>must be longer, thousands of sockets accumulate, and eventually select()
>does not return 
>(by the way, nice application of Little's law in queueing theory). 
>
>I don't see any bug per se in the code. Using setsockopt() to set 
>SO_LINGER with an interval of 0 (default is NO_LINGER, which does 
>a graceful close) would force a hard close (!). Perhaps this will 
>cause a fast release of the socket, which the method is relying on
>to work when select() is called repeatedly at short intervals.   
>See http://msdn.microsoft.com/library/psdk/winsock/wsapiref_714i.htm

Thank you for the analysis.  This is exactly what I was looking for.
Would you care to submit a patch incorporating your setsockopt idea?

I wonder if this should also be employed for UNIX domain sockets.

>*******
>Now the better news:
>As you wrote in
>
>Re: Chris: message queues and new windows (was select() details)
>
>>Are you saying that X-Windows is not adding windows handle events to its
>>select() call?  It sounds like an obvious win to do this.
>
>this is indeed the obvious (but apparently little known) thing to do
>instead of polling every 10 ms. Thanks for implementing /dev/windows. 

You can thank Sergey Okhapkin.  I had nothing to do with this code.  I
never even really understood the reason for it until recently.

>Harold has put this in Test 17, and  select() is thus called less often.
>With twm, 1 xterm and 1 xclock, the number of sockets visible with
>netstat -a does not exceed about 1100 on my WinME. This is low enough 
>that everything works for now, although I expect eventual freezes
>and messages to this list.

Hopefully the connections that you are seeing will go away within
a few seconds.  I don't see any reason for them to linger for a
long time.

>As I couldn't find much explanations of what /dev/windows does, 
>I was asking you about it. This led to

I see two descriptions of /dev/windows in the Cygwin documentation both
mention that it is an interface for "the windows message queue".

>>If you have specific questions on an implementation detail, I'll try
>>to accomodate you but "What is this used for?" is just too broad a
>>question.
>
>I agree it was a broad question.  I do have an implementation question:
>Why do you use PeekMessage( PM_NOREMOVE) in peek_windows, and not
>GetQueueStatus()?

>PeekMessage() has a side effect: nonqueued messages are sent directly
>to the destination procedure. As the application will normally
>do a PeekMessage( PM_REMOVE) when returning from select(), it gets the 
>message twice. 

I assume that it was used because the person who wrote the original
select code didn't know about the side effect and I just implemented his
idea when I rewrote select().

It's not clear to me from the documentation that PeekMessage could cause
messages to be delivered twice.  Have you actually experienced this?

In any event, it looks like GetMessageStatus is a simpler interface.
Would you like to submit a patch?

cgf


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