This is the mail archive of the
mailing list for the Cygwin project.
Re: VM and non-blocking writes
On Dec 13 11:19, Wayne Christopher wrote:
> Okay, here's my test program. Compile and run with no arguments, then
> connect to it from another machine - on a linux box I just did:
> import socket
> s = socket.socket()
> s.connect(("name-of-windows-box", 12345))
> At this point, nbcheck printed:
> listening to port 12345 on host xp1 (10.1.2.40)
> got connection from 10.1.2.14
> trying to write 100000000
> 100000000 bytes written
> When I hit return to exit from nbcheck, it does not actually exit until
> the remote socket is closed.
This is due to trying to work around a problem in WinSock. If you
want to make sure that your application has shutdown gracefully,
call shutdown and close. Otherwise Cygwin has to linger. Not doing
so resulted in data loss in some scenarios.
> The VM usage is 100M, which is all the data array that I allocated, so
> it doesn't look like the write() call allocated anything in my process
> This behavior makes some sense to me, but it's not how I expect it to
> work (based on the write(2) man page and how it works on linux). It's
> more like asynchronous write than non-blocking write. Using O_NONBLOCK
> instead of O_NDELAY doesn't change the behavior.
I can reproduce this behaviour. Stepping through the code shows that
the socket has been successfully switched to non-blocking (the WinSock
ioctlsocket function returns with success). But the WinSock function
WSASendTo hangs for a while and returns with SOCKET_SUCCESS and the
number of bytes written is 100000000.
Since the peer doesn't read these bytes, it appears that WSASendTo
creates a temporary buffer in kernel space and copies the full user
buffer into this temporary buffer. When I raised the memory buffer to
512K, the WSASendTo function failed with WSAENOBUFS, "No buffer space
This is really surprising. The socket write buffer size on Windows is
usually 8K, afaik, if you don't change it with setsockopt(SO_SNDBUF).
Why it tries to buffer more than this 8K beats me. I searched the net
for this problem but I didn't find any other report which would describe
such a weird behaviour.
However, I have to make some more tests, especially in a pure Win32
application to be sure that it's not a Cygwin problem only.
For the time being, I can only suggest to use smaller user buffer sizes
in calls to send()/write().
Thanks for the testcase,
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Project Co-Leader cygwin AT cygwin DOT com
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html