* VM and non-blocking writes @ 2007-12-13 17:31 Wayne Christopher 2007-12-13 17:45 ` Dave Korn 2007-12-13 17:59 ` Corinna Vinschen 0 siblings, 2 replies; 20+ messages in thread From: Wayne Christopher @ 2007-12-13 17:31 UTC (permalink / raw) To: cygwin I have a server application that runs on XP under the latest cygwin, that opens up a socket connection to a client on another system, makes that socket non-blocking using fcntl(.... O_NDELAY), and then feeds the client a large file (100's of MBs) by doing the following: 1. call write() with the entire size of the data not yet written 2. the return value of write is the number of bytes actually written (should be limited by the socket buffer size - it is on linux) 3. select() for writable status on the socket (and do other things in the mean time) 4. when the socket becomes writable, goto 1 What I see is that no matter how large the size is that I give to write(), the return value is always the full size. Also, I see the virtual memory used by my process go way up - in fact it goes up by much more than the amount of data I've written. I tried putting in a limit of 10KB in the size given to the write() call. I still see the VM size grow - more slowly this time, but it eventually reaches 1.5GB and then I'm out of memory. Has anybody seen this behavior? Should I not be using O_NDELAY? Any other workarounds? I don't have a simple example program but I can make one if that will help. Thanks, Wayne -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* RE: VM and non-blocking writes 2007-12-13 17:31 VM and non-blocking writes Wayne Christopher @ 2007-12-13 17:45 ` Dave Korn 2007-12-13 17:59 ` Corinna Vinschen 1 sibling, 0 replies; 20+ messages in thread From: Dave Korn @ 2007-12-13 17:45 UTC (permalink / raw) To: cygwin On 13 December 2007 17:35, Wayne Christopher wrote: > What I see is that no matter how large the size is that I give to > write(), the return value is always the full size. Also, I see the > virtual memory used by my process go way up - in fact it goes up by much > more than the amount of data I've written. > > I tried putting in a limit of 10KB in the size given to the write() > call. I still see the VM size grow - more slowly this time, but it > eventually reaches 1.5GB and then I'm out of memory. > > Has anybody seen this behavior? Dunno about anyone else, but I haven't. > Should I not be using O_NDELAY? It's supposed to work; it's always possible you've hit on a bug. > Any other workarounds? > > I don't have a simple example program but I can make one if that will help. Yes, it would be a good idea; let's see if anyone can reproduce the problem. What firewall/antispyware/other net-related security software do you have installed? cheers, DaveK -- Can't think of a witty .sigline today.... -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: VM and non-blocking writes 2007-12-13 17:31 VM and non-blocking writes Wayne Christopher 2007-12-13 17:45 ` Dave Korn @ 2007-12-13 17:59 ` Corinna Vinschen 2007-12-13 19:16 ` Wayne Christopher 1 sibling, 1 reply; 20+ messages in thread From: Corinna Vinschen @ 2007-12-13 17:59 UTC (permalink / raw) To: cygwin On Dec 13 09:34, Wayne Christopher wrote: > I have a server application that runs on XP under the latest cygwin, that > opens up a socket connection to a client on another system, makes that > socket non-blocking using fcntl(.... O_NDELAY), and then feeds the client a > large file (100's of MBs) by doing the following: > > 1. call write() with the entire size of the data not yet written > > 2. the return value of write is the number of bytes actually written > (should be limited by the socket buffer size - it is on linux) > > 3. select() for writable status on the socket (and do other things in the > mean time) > > 4. when the socket becomes writable, goto 1 > > What I see is that no matter how large the size is that I give to write(), > the return value is always the full size. Also, I see the virtual memory > used by my process go way up - in fact it goes up by much more than the > amount of data I've written. > > I tried putting in a limit of 10KB in the size given to the write() call. > I still see the VM size grow - more slowly this time, but it eventually > reaches 1.5GB and then I'm out of memory. > > Has anybody seen this behavior? Should I not be using O_NDELAY? Any other > workarounds? I never saw this behaviour. Nonblocking sockets are no problem, usually. ssh is using them, too. A quick scan through the call chain (write -> writev -> sendmsg -> WSASendTo) doesn't show up any memory allocation which wouldn't be free'd again. Practically everything is done on the stack. The return code of write is an error code or the number of bytes written as returned by the WSASendTo function. If it really behaves as you describe, there would be nothing Cygwin could do about that. However, I'd expect that WSASendTo frequently returns SOCKET_ERROR with the error code set to WSAEWOULDBLOCK, which translates to a return code -1 from write with errno set to EAGAIN. Are you absolutely sure you're not wasting the memory yourself, somehow? Or, is it possible that there's a strange interaction with some piece of firewall or virus scanner? > I don't have a simple example program but I can make one if that will help. Yes, please. If it's actually a problem in Cygwin, it's occuring only in some border cases. Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Project Co-Leader cygwin AT cygwin DOT com Red Hat -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: VM and non-blocking writes 2007-12-13 17:59 ` Corinna Vinschen @ 2007-12-13 19:16 ` Wayne Christopher 2007-12-14 11:15 ` Corinna Vinschen 0 siblings, 1 reply; 20+ messages in thread From: Wayne Christopher @ 2007-12-13 19:16 UTC (permalink / raw) To: cygwin [-- Attachment #1: Type: text/plain, Size: 919 bytes --] 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: python 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. 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 space. 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. Thanks, Wayne [-- Attachment #2: nbcheck.c --] [-- Type: text/x-c++src, Size: 1785 bytes --] #include <stdio.h> #include <ctype.h> #include <unistd.h> #include <netdb.h> #include <sys/socket.h> #include <netinet/in.h> #include <fcntl.h> #include <assert.h> main() { int i, fd, fd2, len; struct hostent *hp; struct protoent *pp; char hostname[64]; struct sockaddr_in lAddr, rAddr; char* data; int datalen, datapos; gethostname(hostname, 64); pp = getprotobyname("tcp"); hp = gethostbyname(hostname); assert(pp && hp); fd = socket(AF_INET, SOCK_STREAM, pp->p_proto); assert(fd >= 0); lAddr.sin_family = hp->h_addrtype; memcpy((char *)&lAddr.sin_addr.s_addr, (char *)hp->h_addr, sizeof(lAddr.sin_addr.s_addr)); lAddr.sin_port = htons(12345); i = bind(fd, (struct sockaddr *)&lAddr, sizeof(lAddr)); assert(i >= 0); printf("listening to port %d host %s (%s)\n", ntohs(lAddr.sin_port), hostname, inet_ntoa(lAddr.sin_addr)); i = listen(fd, 5); assert(i >= 0); len = sizeof(rAddr); memset(&rAddr, 0, sizeof(rAddr)); fd2 = accept(fd, (struct sockaddr *)&rAddr, &len); assert(fd2 >= 0); printf("got connection from %s\n", inet_ntoa(rAddr.sin_addr)); i = fcntl(fd2, F_SETFL, O_NDELAY); assert(i >= 0); datalen = (int) 1e8; data = (char *) malloc(datalen); datapos = 0; while (datapos < datalen) { fd_set wfds; FD_ZERO(&wfds); FD_SET(fd2, &wfds); i = select(fd2 + 1, NULL, &wfds, NULL, NULL); assert(i == 1); printf("trying to write %d bytes\n", datalen - datapos); i = write(fd2, data + datapos, datalen - datapos); printf("%d bytes written\n", i); assert(i > 0); datapos += i; assert(datapos <= datalen); } printf("hit return to exit "); getchar(); exit(0); } [-- Attachment #3: Type: text/plain, Size: 218 bytes --] -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: VM and non-blocking writes 2007-12-13 19:16 ` Wayne Christopher @ 2007-12-14 11:15 ` Corinna Vinschen 2007-12-14 13:41 ` Corinna Vinschen 2007-12-14 14:33 ` VM and non-blocking writes Corinna Vinschen 0 siblings, 2 replies; 20+ messages in thread From: Corinna Vinschen @ 2007-12-14 11:15 UTC (permalink / raw) To: cygwin 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: > > python > 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 > space. > > 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 available." 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 -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Project Co-Leader cygwin AT cygwin DOT com Red Hat -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: VM and non-blocking writes 2007-12-14 11:15 ` Corinna Vinschen @ 2007-12-14 13:41 ` Corinna Vinschen 2007-12-14 13:52 ` Corinna Vinschen 2007-12-14 14:33 ` VM and non-blocking writes Corinna Vinschen 1 sibling, 1 reply; 20+ messages in thread From: Corinna Vinschen @ 2007-12-14 13:41 UTC (permalink / raw) To: cygwin On Dec 14 12:15, Corinna Vinschen wrote: > On Dec 13 11:19, Wayne Christopher wrote: > > Okay, here's my test program. > > [...] > 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 > available." > > 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. I can reproduce this behaviour with a native Windows application. It does not depend on using WSASendTo vs. using send, and in case of using WSASendTo it happens independently of using one big WSABUF element or multiple smaller elements. I can reproduce the behaviour on Windows 2000 SP4, XP SP2 and Vista SP1 RC1, so it's not even OS dependent. On the other hand, as soon as I call send (or WSASendTo) multiple times with smaller sizes (I tried with 10k), select starts to block at one point. But even then strange things happen. After some time (after 5 seconds, then after 14 seconds, then about every 60 seconds) select() just signals the socket ready for write and the next send adds another 10K to the internal buffer. A tcpdump on the interface shows that no package goes over the line... which would be a surprise anyway, given that the peer does not even once call read(). Given that, I don't see what we can do about this misbehaviour. I guess I'll report this as a bug and see what the reaction will be. Especially if there's a useful workaround. Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Project Co-Leader cygwin AT cygwin DOT com Red Hat -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: VM and non-blocking writes 2007-12-14 13:41 ` Corinna Vinschen @ 2007-12-14 13:52 ` Corinna Vinschen 2007-12-14 14:35 ` Lev Bishop 0 siblings, 1 reply; 20+ messages in thread From: Corinna Vinschen @ 2007-12-14 13:52 UTC (permalink / raw) To: cygwin On Dec 14 14:41, Corinna Vinschen wrote: > On the other hand, as soon as I call send (or WSASendTo) multiple > times with smaller sizes (I tried with 10k), select starts to > block at one point. But even then strange things happen. After > some time (after 5 seconds, then after 14 seconds, then about every > 60 seconds) select() just signals the socket ready for write and > the next send adds another 10K to the internal buffer. A tcpdump > on the interface shows that no package goes over the line... which > would be a surprise anyway, given that the peer does not even once > call read(). Hmm, a few minutes ago select() mysteriously blocked fully after send has written 19 blocks of 10K each.... Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Project Co-Leader cygwin AT cygwin DOT com Red Hat -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: VM and non-blocking writes 2007-12-14 13:52 ` Corinna Vinschen @ 2007-12-14 14:35 ` Lev Bishop 2007-12-14 17:25 ` Corinna Vinschen 0 siblings, 1 reply; 20+ messages in thread From: Lev Bishop @ 2007-12-14 14:35 UTC (permalink / raw) To: cygwin On Dec 14, 2007 8:52 AM, Corinna Vinschen wrote: > On Dec 14 14:41, Corinna Vinschen wrote: > > On the other hand, as soon as I call send (or WSASendTo) multiple > > times with smaller sizes (I tried with 10k), select starts to > > block at one point. But even then strange things happen. After > > some time (after 5 seconds, then after 14 seconds, then about every > > 60 seconds) select() just signals the socket ready for write and > > the next send adds another 10K to the internal buffer. A tcpdump > > on the interface shows that no package goes over the line... which > > would be a surprise anyway, given that the peer does not even once > > call read(). > > Hmm, a few minutes ago select() mysteriously blocked fully after send > has written 19 blocks of 10K each.... Good luck with figuring this stuff out. The way winsock deals with all of this stuff is rather mysterious and quite hackish, basically because it's all implemented in an emulation layer afd.sys and msafd.dll which tries to give bsd socket syntax (or something sorta close anyway) on top of the native overlapped io. The afd layer does some mighty weird things. See, for example, my reverse engineering of one aspect of it's send buffer management here: http://www.cygwin.com/ml/cygwin-patches/2006-q2/msg00031.html There's a whole bunch of tuning parameters that deal with when afd should make a copy of an application-supplied buffer (incurring the copy costs) or just lock the application buffer in ram (incurring VM manipulation costs) and so on. Look at registry configuration parameters: DefaultReceiveWindow, DefaultSendWindow, FastCopyReceiveThreshold, FastSendDatagramThreshold, LargeBufferSize, LargeBufferListDepth, MaxFastTransmit, MaxFastCopyTransmit, MediumBufferSize, MediumBufferListDepth, OverheadChargeGranularity, PriorityBoost, SmallBufferListDepth, SmallBufferSize, TransmitIoLength, FFPControlFlags, FFPFastForwardingCacheSize, GlobalMaxTcpWindowSize and probably others. You can probably do something about this particular issue by tweaking those parameters, or making sure you make the sends fall on the right side of some boundary defined by those parameters. But in general.... I'm not confident. Lev Lev -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: VM and non-blocking writes 2007-12-14 14:35 ` Lev Bishop @ 2007-12-14 17:25 ` Corinna Vinschen 2007-12-14 21:56 ` mmap failing Wayne Christopher 0 siblings, 1 reply; 20+ messages in thread From: Corinna Vinschen @ 2007-12-14 17:25 UTC (permalink / raw) To: cygwin On Dec 14 09:34, Lev Bishop wrote: > http://www.cygwin.com/ml/cygwin-patches/2006-q2/msg00031.html Gosh, I didn't even remember this discussion anymore, sorry. > There's a whole bunch of tuning parameters that deal with when afd > should make a copy of an application-supplied buffer [...] > You can probably do something about this particular issue by tweaking > those parameters, or making sure you make the sends fall on the right > side of some boundary defined by those parameters. But in general.... > I'm not confident. Same here. Tweaking registry parameters is nothing the Cygwin DLL should resort to. Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Project Co-Leader cygwin AT cygwin DOT com Red Hat -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* mmap failing 2007-12-14 17:25 ` Corinna Vinschen @ 2007-12-14 21:56 ` Wayne Christopher 2007-12-16 11:04 ` Corinna Vinschen 2008-01-07 16:03 ` Linda Walsh 0 siblings, 2 replies; 20+ messages in thread From: Wayne Christopher @ 2007-12-14 21:56 UTC (permalink / raw) To: cygwin I have a 268MB file open for writing. I close it and then immediately try to mmap() it, and a get ENOMEM. However I do have the VM space available and can malloc() the size of the file right after the failure. Also, I have mmap()'ed other similar files in the same program before this, but these had not just been closed. My initial guess was that it was timing related, but if I wait for 5 seconds and try again I still get the failure. I wasn't able to duplicate it in a small example since my app has a bunch of threads and is doing other stuff at the same time. Any suggestions for solutions or workarounds? Maybe strategic use of fsync() ? Thanks, Wayne -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: mmap failing 2007-12-14 21:56 ` mmap failing Wayne Christopher @ 2007-12-16 11:04 ` Corinna Vinschen 2007-12-17 18:47 ` Wayne Christopher 2008-01-07 16:03 ` Linda Walsh 1 sibling, 1 reply; 20+ messages in thread From: Corinna Vinschen @ 2007-12-16 11:04 UTC (permalink / raw) To: cygwin On Dec 14 13:59, Wayne Christopher wrote: > I have a 268MB file open for writing. I close it and then > immediately try to mmap() it, and a get ENOMEM. However I do have the > VM space available and can malloc() the size of the file right after the > failure. Also, I have mmap()'ed other similar files in the same program > before this, but these had not just been closed. > > My initial guess was that it was timing related, but if I wait for 5 > seconds and try again I still get the failure. > > I wasn't able to duplicate it in a small example since my app has a bunch > of threads and is doing other stuff at the same time. > > Any suggestions for solutions or workarounds? Not without testcase and version information. Is that under 1.5.24-2 or 1.5.25-x? Could you test if the result differs between these two versions? If so, how? Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Project Co-Leader cygwin AT cygwin DOT com Red Hat -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: mmap failing 2007-12-16 11:04 ` Corinna Vinschen @ 2007-12-17 18:47 ` Wayne Christopher 0 siblings, 0 replies; 20+ messages in thread From: Wayne Christopher @ 2007-12-17 18:47 UTC (permalink / raw) To: cygwin [-- Attachment #1: Type: text/plain, Size: 1210 bytes --] My test program is attached. This example works but in my real program the same write+close+mmap sequence did not. It appears that calling fsync before the close sometimes avoids the error but not always. This is Cygwin 1.5.24(0.156/4/2). Any thoughts? Thanks, Wayne Corinna Vinschen wrote: > On Dec 14 13:59, Wayne Christopher wrote: > >> I have a 268MB file open for writing. I close it and then >> immediately try to mmap() it, and a get ENOMEM. However I do have the >> VM space available and can malloc() the size of the file right after the >> failure. Also, I have mmap()'ed other similar files in the same program >> before this, but these had not just been closed. >> >> My initial guess was that it was timing related, but if I wait for 5 >> seconds and try again I still get the failure. >> >> I wasn't able to duplicate it in a small example since my app has a bunch >> of threads and is doing other stuff at the same time. >> >> Any suggestions for solutions or workarounds? >> > > Not without testcase and version information. Is that under 1.5.24-2 > or 1.5.25-x? Could you test if the result differs between these two > versions? If so, how? > > > Corinna > > [-- Attachment #2: mmcheck.c --] [-- Type: text/x-c++src, Size: 795 bytes --] #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <assert.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/mman.h> #include <sys/unistd.h> #define SIZE 268000000 main() { char* fname = "test_file"; char* data; int fd, i; struct stat sb; caddr_t base; data = malloc(SIZE); fd = open(fname, O_RDWR|O_CREAT, 0666); assert(fd >= 0); i = write(fd, data, SIZE); assert(i == SIZE); close(fd); i = stat(fname, &sb); assert(i >= 0); assert(SIZE == sb.st_size); fd = open(fname, O_RDONLY, 0); assert(fd >= 0); base = (caddr_t) mmap(NULL, SIZE, PROT_READ, MAP_SHARED, fd, 0); printf("base = %ld\n", (long) base); if (MAP_FAILED == base) perror("mmap"); exit(0); } [-- Attachment #3: Type: text/plain, Size: 218 bytes --] -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: mmap failing 2007-12-14 21:56 ` mmap failing Wayne Christopher 2007-12-16 11:04 ` Corinna Vinschen @ 2008-01-07 16:03 ` Linda Walsh 1 sibling, 0 replies; 20+ messages in thread From: Linda Walsh @ 2008-01-07 16:03 UTC (permalink / raw) To: cygwin; +Cc: wayne Wayne Christopher wrote: > I have a 268MB file open for writing. I close it and then > immediately try to mmap() it, and a get ENOMEM. However I do have the > VM space available and can malloc() the size of the file right after the > failure. Also, I have mmap()'ed other similar files in the same program > before this, but these had not just been closed. > > Any suggestions for solutions or workarounds? Maybe strategic use of > fsync() ? ---- Don't know if this problem was 'solved' or not, but I'm guessing that mmap attempts to allocate a large chunk of virtual memory to map the file to (e.g. 268MB in your example). The problem has to do with finding 268MB of contiguous address space -- and I believe that was the 'rub'. Over time, the "free memory areas"(1) get fragmented and when large blocks of memory are desired, you may get back a failure if Win cannot find a block large enough to fit your request -- i.e. it may not be able to find a single memory block large enough to satisfy your request. So you get back an error. I'm not sure what you can use to solve this at the cygwin-application level, but at the windows-application level Microsoft offers a something called a 'low fragmentation heap' (LFH), that tries to lower fragmentation for many applications. According to http://support.microsoft.com/kb/929136, it can be turned off 'accidentally' in some situations which can cause more heap-fragmentation problems. It's unlikely most users would encounter this problem. Windows has more than one memory allocation pool that it uses (main heap, for example instead of low-frag heap) and I would guess more than one of them could get overly fragmented. I'd think the system would 'cleanup' at some point. I've only encountered the 'out-of-mem' (when I had enough, but alloc size was too large) once that I remember. But I when I immediately retried the program, the error had 'gone away'... Linda -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: VM and non-blocking writes 2007-12-14 11:15 ` Corinna Vinschen 2007-12-14 13:41 ` Corinna Vinschen @ 2007-12-14 14:33 ` Corinna Vinschen 2007-12-15 17:39 ` Robert Pendell 1 sibling, 1 reply; 20+ messages in thread From: Corinna Vinschen @ 2007-12-14 14:33 UTC (permalink / raw) To: cygwin On Dec 14 12:15, Corinna Vinschen wrote: > I searched the net > for this problem but I didn't find any other report which would describe > such a weird behaviour. Obviously I searched wrong. There a reports about this behaviour since at least 1998 and it has never been fixed. These two links might be interesting: http://support.microsoft.com/kb/q201213/ http://tinyurl.com/2brokp Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Project Co-Leader cygwin AT cygwin DOT com Red Hat -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: VM and non-blocking writes 2007-12-14 14:33 ` VM and non-blocking writes Corinna Vinschen @ 2007-12-15 17:39 ` Robert Pendell 2007-12-16 13:42 ` Corinna Vinschen 0 siblings, 1 reply; 20+ messages in thread From: Robert Pendell @ 2007-12-15 17:39 UTC (permalink / raw) To: cygwin -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Corinna Vinschen wrote: > On Dec 14 12:15, Corinna Vinschen wrote: >> I searched the net >> for this problem but I didn't find any other report which would describe >> such a weird behaviour. > > Obviously I searched wrong. There a reports about this behaviour > since at least 1998 and it has never been fixed. These two links > might be interesting: > > http://support.microsoft.com/kb/q201213/ > http://tinyurl.com/2brokp > > > Corinna > Do you have the test case you used for the pure win32 mode? If you do then maybe I can try and push to get this fixed for the next service pack release for both XP and Vista as well as Server 2008. This will especially be the case if it can be easily reproduced. A source and binary version will be useful for this. I am in the tech beta group for Vista SP1, XP SP3, and Server 2008 so I can at least remind them of this bug and show them a test case. No guarantees that it will be fixed. - -- Robert Pendell -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFHZA73s1pR2j1qW+sRAqgIAJ44S32pjI8k2EzVNQeqV29uRarLigCghExr L4nnayAMFPFWrrCOQlUpnfs= =iltL -----END PGP SIGNATURE----- -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: VM and non-blocking writes 2007-12-15 17:39 ` Robert Pendell @ 2007-12-16 13:42 ` Corinna Vinschen 2007-12-16 14:07 ` Corinna Vinschen 0 siblings, 1 reply; 20+ messages in thread From: Corinna Vinschen @ 2007-12-16 13:42 UTC (permalink / raw) To: cygwin [-- Attachment #1: Type: text/plain, Size: 5989 bytes --] On Dec 15 12:29, Robert Pendell wrote: > Corinna Vinschen wrote: > > Obviously I searched wrong. There a reports about this behaviour > > since at least 1998 and it has never been fixed. These two links > > might be interesting: > > > > http://support.microsoft.com/kb/q201213/ > > http://tinyurl.com/2brokp > > Do you have the test case you used for the pure win32 mode? Sure, but before we start with this, a note: I'm contemplating the idea to workaround this problem in Cygwin (not for 1.5.25, but in the main trunk) by caping the number of bytes in a single send call, according to the patch Lev sent in http://www.cygwin.com/ml/cygwin-patches/2006-q2/msg00031.html. Lev, are you interested in reworking your patch (minus the pipe stuff) to match current CVS? Is there any gain in raising SO_SNDBUF/SO_RCVBUF to a value > 8K, especially in the light of my experiences commented on in net.cc, function fdsock()? Back to the testcase. Source attached. I created it so that it can be built as Cygwin or Linux executable $ gcc -g -o nbcheck nbcheck.c as well as native Windows application using mingw: $ gcc -g -mno-cygwin -o nbcheck-nat nbcheck.c -lws2_32 It takes the size of the user data buffer as optional argument, defaulting to 100,000,000 bytes. > If you do > then maybe I can try and push to get this fixed for the next service > pack release for both XP and Vista as well as Server 2008. This will > especially be the case if it can be easily reproduced. Reproducing the issue is as easy as Wayne described. Just start a client application which connects but never reads, for instance by using the python sequence Wayne used in his mail: $ python import socket s = socket.socket() s.connect(("name-of-windows-box", 12345)) If you add a second arbitrary argument, the testcase tries to write always in 10,000 bytes chunks. This shows how select starts to block at one point, in my case on XP SP2 after writing 190,000 bytes. Result on Linux: $ ./nbcheck 500000000 listening to port 12345 host linux-box (10.0.0.1) got connection from 10.0.0.3 accepted socket is nonblocking now buffer size is 100000000 bytes trying to write 100000000 bytes 65536 bytes written trying to write 99934464 bytes 147456 bytes written [HANG in select] $ ./nbcheck 100000000 listening to port 12345 host linux-box (10.0.0.1) got connection from 10.0.0.3 accepted socket is nonblocking now buffer size is 100000000 bytes trying to write 100000000 bytes 65536 bytes written trying to write 99934464 bytes 147456 bytes written [HANG in select] $ ./nbcheck 100000000 x listening to port 12345 host linux-box (10.0.0.1) got connection from 10.0.0.3 accepted socket is nonblocking now buffer size is 100000000 bytes trying to write 10000 bytes 10000 bytes written trying to write 10000 bytes 10000 bytes written trying to write 10000 bytes 10000 bytes written trying to write 10000 bytes 10000 bytes written trying to write 10000 bytes 10000 bytes written trying to write 10000 bytes 10000 bytes written trying to write 10000 bytes 10000 bytes written trying to write 10000 bytes 10000 bytes written trying to write 10000 bytes 10000 bytes written trying to write 10000 bytes 10000 bytes written trying to write 10000 bytes 10000 bytes written trying to write 10000 bytes 10000 bytes written trying to write 10000 bytes 10000 bytes written trying to write 10000 bytes 10000 bytes written trying to write 10000 bytes 10000 bytes written trying to write 10000 bytes 10000 bytes written trying to write 10000 bytes 10000 bytes written [HANG in select] Result on Windows; $ ./nbcheck-nat 500000000 listening to port 12345 host windows-box (10.0.0.2) got connection from 10.0.0.3 accepted socket is nonblocking now buffer size is 500000000 bytes trying to write 500000000 bytes Err: 10055 hit return to exit $ ./nbcheck-nat 100000000 listening to port 12345 host windows-box (10.0.0.2) got connection from 10.0.0.3 accepted socket is nonblocking now buffer size is 100000000 bytes trying to write 100000000 bytes 100000000 bytes written hit return to exit $ ./nbcheck-nat 100000000 x listening to port 12345 host windows-box (10.0.0.2) got connection from 10.0.0.3 accepted socket is nonblocking now buffer size is 100000000 bytes trying to write 10000 bytes 10000 bytes written trying to write 10000 bytes 10000 bytes written trying to write 10000 bytes 10000 bytes written trying to write 10000 bytes 10000 bytes written trying to write 10000 bytes 10000 bytes written trying to write 10000 bytes 10000 bytes written trying to write 10000 bytes 10000 bytes written [WAIT in select for 5 seconds] trying to write 10000 bytes 10000 bytes written [WAIT in select for 14 seconds] trying to write 10000 bytes 10000 bytes written [WAIT in select for about 60 seconds] trying to write 10000 bytes 10000 bytes written [WAIT in select for about 60 seconds] [a couple of times, but not always the same] trying to write 10000 bytes 10000 bytes written [HANG in select] The hang occured in one testruns after 160,000 bytes, in another after 190,000 bytes. I have no idea if there's some sort of rule behind that. > A source and > binary version will be useful for this. Creating a binary is most easy, see above. > I am in the tech beta group for > Vista SP1, XP SP3, and Server 2008 so I can at least remind them of this > bug and show them a test case. No guarantees that it will be fixed. Actually, given that this behaviour is known since at least 10 years, I doubt that it will even be accepted as a bug. But you never should give up hope, right? :) Thanks for your offer, Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Project Co-Leader cygwin AT cygwin DOT com Red Hat [-- Attachment #2: nbcheck.c --] [-- Type: text/x-c++src, Size: 3154 bytes --] #include <stdio.h> #include <assert.h> #ifdef _WIN32 #include <windows.h> #include <winsock2.h> WSADATA wsadata; #define SOCKLEN_T int #else // Assume Unix-like system #include <unistd.h> #include <stdlib.h> #include <netdb.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <fcntl.h> #include <assert.h> #include <stdlib.h> #include <string.h> #include <errno.h> #define SOCKET int #define WSADATA int #define WSAStartup(a,b) #define SOCKET_ERROR -1 #define SOCKLEN_T socklen_t #define WSAGetLastError() (errno) #define SD_BOTH SHUT_RDWR #define closesocket close #define WSACleanup() #endif int main(int argc, char **argv) { int i; SOCKET fd, fd2; struct hostent *hp; struct protoent *pp; char hostname[64]; struct sockaddr_in lAddr, rAddr; char* data; size_t datalen, datapos; WSAStartup (MAKEWORD(2,2), &wsadata); gethostname(hostname, 64); pp = getprotobyname("tcp"); hp = gethostbyname(hostname); setbuf (stdout, NULL); assert(pp && hp); fd = socket(AF_INET, SOCK_STREAM, pp->p_proto); assert(fd != SOCKET_ERROR); lAddr.sin_family = hp->h_addrtype; memcpy(&lAddr.sin_addr.s_addr, hp->h_addr, sizeof(lAddr.sin_addr.s_addr)); lAddr.sin_port = htons(12345); i = bind(fd, (struct sockaddr *)&lAddr, sizeof(lAddr)); assert(i != SOCKET_ERROR); printf("listening to port %d host %s (%s)\n", ntohs(lAddr.sin_port), hostname, inet_ntoa(lAddr.sin_addr)); i = listen(fd, 5); assert(i != SOCKET_ERROR); i = sizeof(rAddr); memset(&rAddr, 0, sizeof(rAddr)); fd2 = accept(fd, (struct sockaddr *)&rAddr, (SOCKLEN_T *) &i); assert(fd2 != SOCKET_ERROR); printf("got connection from %s\n", inet_ntoa(rAddr.sin_addr)); #ifdef _WIN32 { u_long on = 1; i = ioctlsocket (fd2, FIONBIO, &on); } #else i = fcntl(fd2, F_SETFL, O_NONBLOCK); #endif assert(i != SOCKET_ERROR); printf("accepted socket is nonblocking now\n"); datalen = argc > 1 ? strtol (argv[1], NULL, 0) : 100000000; data = (char *) malloc(datalen); assert(data); printf("buffer size is %lu bytes\n", (unsigned long) datalen); datapos = 0; while (datapos < datalen) { fd_set wfds; FD_ZERO(&wfds); FD_SET(fd2, &wfds); i = select(fd2 + 1, NULL, &wfds, NULL, NULL); assert(i == 1); printf("trying to write %d bytes\n", (int) (argc > 2 ? 10000 : datalen - datapos)); #if 0 // Same effect as send() on Windows, not available on Unix { DWORD ret; WSABUF iov[1]; iov[0].buf = data + datapos; iov[0].len = argc > 2 ? 10000 : datalen - datapos; i = WSASendTo (fd2, iov, 1, &ret, 0, NULL, 0, NULL, NULL); if (i != SOCKET_ERROR) i = ret; } #else i = send (fd2, data + datapos, argc > 2 ? 10000 : datalen - datapos, 0); #endif if (i == SOCKET_ERROR) { printf ("Err: %d\n", WSAGetLastError ()); break; } else printf("%d bytes written\n", i); datapos += i; assert(datapos <= datalen); } shutdown (fd2, SD_BOTH); closesocket (fd2); printf("hit return to exit "); getchar(); WSACleanup (); return 0; } [-- Attachment #3: Type: text/plain, Size: 218 bytes --] -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: VM and non-blocking writes 2007-12-16 13:42 ` Corinna Vinschen @ 2007-12-16 14:07 ` Corinna Vinschen 2007-12-17 18:24 ` Lev Bishop 0 siblings, 1 reply; 20+ messages in thread From: Corinna Vinschen @ 2007-12-16 14:07 UTC (permalink / raw) To: cygwin On Dec 16 14:42, Corinna Vinschen wrote: > I'm contemplating the idea to workaround this problem in Cygwin (not > for 1.5.25, but in the main trunk) by caping the number of bytes in a > single send call, according to the patch Lev sent in > http://www.cygwin.com/ml/cygwin-patches/2006-q2/msg00031.html. > > Lev, are you interested in reworking your patch (minus the pipe stuff) > to match current CVS? Is there any gain in raising SO_SNDBUF/SO_RCVBUF > to a value > 8K, especially in the light of my experiences commented > on in net.cc, function fdsock()? Lev, do you have a copyright assignment in place? I don't find you on my list of signers. Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Project Co-Leader cygwin AT cygwin DOT com Red Hat -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: VM and non-blocking writes 2007-12-16 14:07 ` Corinna Vinschen @ 2007-12-17 18:24 ` Lev Bishop 2007-12-17 20:22 ` Corinna Vinschen 0 siblings, 1 reply; 20+ messages in thread From: Lev Bishop @ 2007-12-17 18:24 UTC (permalink / raw) To: cygwin On Dec 16, 2007 9:07 AM, Corinna Vinschen wrote: > On Dec 16 14:42, Corinna Vinschen wrote: > > I'm contemplating the idea to workaround this problem in Cygwin (not > > for 1.5.25, but in the main trunk) by caping the number of bytes in a > > single send call, according to the patch Lev sent in > > http://www.cygwin.com/ml/cygwin-patches/2006-q2/msg00031.html. > > > > Lev, are you interested in reworking your patch (minus the pipe stuff) > > to match current CVS? Is there any gain in raising SO_SNDBUF/SO_RCVBUF > > to a value > 8K, especially in the light of my experiences commented > > on in net.cc, function fdsock()? > > Lev, do you have a copyright assignment in place? I don't find you on > my list of signers. No I don't have a copyright assignment in place yet. I will see what I can do about that -- don't think it will be a problem. I'd be interested in reworking the patch against current CVS (though I haven't looked to see how far current CVS has moved so I don't know how much that will involve). But I have to warn you in advance that I haven't had much time to work on this stuff, and I don't see that situation changing any time soon, so it may take multiple weeks before I get a chance. (I'll have some time over christmas, but I'll be away from all my network hardware and the openbsd box I originally used at the other end of the wire for testing the patches, so testing would be a problem). If you were hoping to get something into CVS on a more rigorous timescale, better to push on without me -- I'll still try to get a copyright assignment submitted, in case you wish to derive from my original patches. As far as changing SO_SNDBUF/SO_RCVBUF a few comments, which I originally wrote in response to your patch in fdsock() but you had already #ifdef'd out the patch by the time I wrote this, so I never bothered to send it: <quote> Your intention with the patch was to make cygwin's default buffer sizes be more like on linux, but.... 1) On windows/cygwin (without my patch), the interpretation of so_sndbuf is very different from linux. The afd layer will accept *any* size of send, so long as the current buffer position is less than so_sndbuf. Whereas on linux, so_sndbuf limits the total size of the send buffer. This works nicely for transaction-oriented apps. For an app which does it's side of a transaction in one large writev() and then waits for the next request from the client (which will piggyback the ack the server needs in order to empty it's send buffer), the send buffer on windows is effectively infinite, for all values of so_sndbuf except 0. So so_sndbuf cannot really be compared between windows and linux, because the interpretation is totally different. 2) Linux includes all the overheads of it's skb structures, the part of the buffer that's given to the application, etc, etc when it accounts for the memory used by the send buffer, the result of which is that you can only put about half as much data into the buffer as there is memory allocated (linux internally doubles the number from setsockopt(SO_SNDBUF) to hide this from applications expecting BSD semantics, but it doesn't halve the number from getsockopt() a longstanding point of controversy). The upshot of this is that the cygwin default sendbuffer should better be *half* of the linux tcp_wmem default, if you are going to go that way. 3) Linux does dynamic autotuning on the buffers, so the middle value in tcp_wmem is more like a hint on what's a convenient chunk of memory to allocate in one go, rather than a hint on what's actually the best size for the buffer. 4) Your implementation ignored that some users may have actually calculated optimal values for their situation and put them in the relevant registry parameters. It seems it would be best either to: only set so_{snd,rcv}buf in the case that the registry parameters are absent; or don't touch so_{snd,rcv}buf at all and just advise users experiencing problems that the registry parameters have the desired effect. I'm inclined to go with the latter. </quote> Having said all that, the winsock default 8kb really is far too small for many situations. I find that in my tests (this may be network hardware/driver dependent) I need 32kb for the stack to start coalescing packets reliably. Based on this, and on the problems described in your comments of net.cc fdsock() where the issue was with 64kb buffer size, it seems that 32kb would be a good size to use (again, it's possibly better to recommend the user to alter his registry setting to 32kb, rather than have cygwin force it through setsockopt()). Before getting too set on the plan of having cygwin break applications' send()s into chunks, maybe it's worth reconsidering the overall strategy. We're basically at this point implementing our best attempt at BSD semantics on top of microsoft's half-assed attempt at BSD semantics on top of the native not-BSD-like-at-all but powerful and quite self-consistent NT semantics. If we keep having to work around more issues like this, perhaps we'd be better off bypassing the afd layer entirely, by setting SO_SNDBUF to 0, using overlapped IO, and managing buffers ourselves. I'm sure this would bring it's own set of complications, but at least we'd be in a better position to deal with them, not having to go through the afd layer. What do you think? -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: VM and non-blocking writes 2007-12-17 18:24 ` Lev Bishop @ 2007-12-17 20:22 ` Corinna Vinschen 2007-12-17 20:29 ` Corinna Vinschen 0 siblings, 1 reply; 20+ messages in thread From: Corinna Vinschen @ 2007-12-17 20:22 UTC (permalink / raw) To: cygwin On Dec 17 12:28, Lev Bishop wrote: > On Dec 16, 2007 9:07 AM, Corinna Vinschen wrote: > > On Dec 16 14:42, Corinna Vinschen wrote: > > > Lev, are you interested in reworking your patch (minus the pipe stuff) > > > to match current CVS? Is there any gain in raising SO_SNDBUF/SO_RCVBUF > > > to a value > 8K, especially in the light of my experiences commented > > > on in net.cc, function fdsock()? > > > > Lev, do you have a copyright assignment in place? I don't find you on > > my list of signers. > > No I don't have a copyright assignment in place yet. I will see what I > can do about that -- don't think it will be a problem. I'd be > interested in reworking the patch against current CVS (though I > haven't looked to see how far current CVS has moved so I don't know > how much that will involve). But I have to warn you in advance that I > haven't had much time to work on this stuff, and I don't see that > situation changing any time soon, so it may take multiple weeks before > I get a chance [...] It's not time critical. The next major release will take some more time anyway. If you just could send the copyright assignment, it wou;d be a good start. > Having said all that, the winsock default 8kb really is far too small > for many situations. I find that in my tests (this may be network > hardware/driver dependent) I need 32kb for the stack to start > coalescing packets reliably. Based on this, and on the problems > described in your comments of net.cc fdsock() where the issue was with > 64kb buffer size, it seems that 32kb would be a good size to use > (again, it's possibly better to recommend the user to alter his > registry setting to 32kb, rather than have cygwin force it through > setsockopt()). We could just check if the parameter is still set to 8K and only change it to 32K if so. Since that already happens at socket creation time, it doesn't affect later settings in the application anyway, isn't it? > Before getting too set on the plan of having cygwin break > applications' send()s into chunks, maybe it's worth reconsidering the > overall strategy. We're basically at this point implementing our best > attempt at BSD semantics on top of microsoft's half-assed attempt at > BSD semantics on top of the native not-BSD-like-at-all but powerful > and quite self-consistent NT semantics. If we keep having to work > around more issues like this, perhaps we'd be better off bypassing the > afd layer entirely, by setting SO_SNDBUF to 0, using overlapped IO, > and managing buffers ourselves. I'm sure this would bring it's own set > of complications, but at least we'd be in a better position to deal > with them, not having to go through the afd layer. What do you think? Sorry, I'm unfamiliar with the native NT socket interface :} Is there somewhere a (good) tutorial for the native NT socket stuff? Even without using the native API, we could also just set the Winsock SO_RCVBUF/SO_SNDBUF settings to 0 and intercept the setsockopt/getsockopt calls to maintain our own buffers, right? Having said that, for a start I would prefer a simple "upgrade" along the lines of your previous patch. Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Project Co-Leader cygwin AT cygwin DOT com Red Hat -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: VM and non-blocking writes 2007-12-17 20:22 ` Corinna Vinschen @ 2007-12-17 20:29 ` Corinna Vinschen 0 siblings, 0 replies; 20+ messages in thread From: Corinna Vinschen @ 2007-12-17 20:29 UTC (permalink / raw) To: cygwin On Dec 17 19:24, Corinna Vinschen wrote: > On Dec 17 12:28, Lev Bishop wrote: > > If we keep having to work > > around more issues like this, perhaps we'd be better off bypassing the > > afd layer entirely, by setting SO_SNDBUF to 0, using overlapped IO, > > and managing buffers ourselves. I'm sure this would bring it's own set > > of complications, [...] > > Sorry, I'm unfamiliar with the native NT socket interface :} Is there > somewhere a (good) tutorial for the native NT socket stuff? Even > without using the native API, we could also just set the Winsock > SO_RCVBUF/SO_SNDBUF settings to 0 and intercept the setsockopt/getsockopt > calls to maintain our own buffers, right? On re-reading, my reply seems a bit off-track. You're suggesting to use SO_SNDBUF==0 with overlapped I/O. I'm asking to keep the standard nonblocking semantics when maintaining our own per-socket buffer. At one point the socket stuff was implemented using overlapped I/O, but I had serious trouble with that. What happened was that the overlapped code waited for the socket operation to complete in a WaitForMultipleEvents call. When a signal arrived, I canceled the I/O operation using CancelIO. The problem was that the send operation is not atomic, and there is no way to find out how much bytes from the current send buffer have been actually sent. So it was not possible to return the correct number of sent bytes to the application. Instead the code always returned with EINTR. This in turn could result in data corruption or lost connections. If there is some way to accomplish that, for instance in the native API, then we could revert to overlapped I/O. If not, well... Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Project Co-Leader cygwin AT cygwin DOT com Red Hat -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ ^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2008-01-07 2:45 UTC | newest] Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2007-12-13 17:31 VM and non-blocking writes Wayne Christopher 2007-12-13 17:45 ` Dave Korn 2007-12-13 17:59 ` Corinna Vinschen 2007-12-13 19:16 ` Wayne Christopher 2007-12-14 11:15 ` Corinna Vinschen 2007-12-14 13:41 ` Corinna Vinschen 2007-12-14 13:52 ` Corinna Vinschen 2007-12-14 14:35 ` Lev Bishop 2007-12-14 17:25 ` Corinna Vinschen 2007-12-14 21:56 ` mmap failing Wayne Christopher 2007-12-16 11:04 ` Corinna Vinschen 2007-12-17 18:47 ` Wayne Christopher 2008-01-07 16:03 ` Linda Walsh 2007-12-14 14:33 ` VM and non-blocking writes Corinna Vinschen 2007-12-15 17:39 ` Robert Pendell 2007-12-16 13:42 ` Corinna Vinschen 2007-12-16 14:07 ` Corinna Vinschen 2007-12-17 18:24 ` Lev Bishop 2007-12-17 20:22 ` Corinna Vinschen 2007-12-17 20:29 ` Corinna Vinschen
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).