changeset 108749:48378bcd6c35

Fix bug #6237. w32.c (sys_write): Break writes into chunks smaller than 32MB.
author Eli Zaretskii <eliz@gnu.org>
date Sat, 22 May 2010 22:09:51 +0300
parents 85d6810f63ed
children 3339da3cfeb3
files src/ChangeLog src/w32.c
diffstat 2 files changed, 33 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Sat May 22 10:39:35 2010 -0700
+++ b/src/ChangeLog	Sat May 22 22:09:51 2010 +0300
@@ -1,3 +1,8 @@
+2010-05-22  Eli Zaretskii  <eliz@gnu.org>
+
+	* w32.c (sys_write): Break writes into chunks smaller than 32MB.
+	(Bug#6237)
+
 2010-05-22  Chong Yidong  <cyd@stupidchicken.com>
 
 	* image.c (Fimage_flush): Rename from image-refresh.
--- a/src/w32.c	Sat May 22 10:39:35 2010 -0700
+++ b/src/w32.c	Sat May 22 22:09:51 2010 +0300
@@ -5700,7 +5700,34 @@
     }
   else
 #endif
-    nchars = _write (fd, buffer, count);
+    {
+      /* Some networked filesystems don't like too large writes, so
+	 break them into smaller chunks.  See the Comments section of
+	 the MSDN documentation of WriteFile for details behind the
+	 choice of the value of CHUNK below.  See also the thread
+	 http://thread.gmane.org/gmane.comp.version-control.git/145294
+	 in the git mailing list.  */
+      const unsigned char *p = buffer;
+      const unsigned chunk = 30 * 1024 * 1024;
+
+      nchars = 0;
+      while (count > 0)
+	{
+	  unsigned this_chunk = count < chunk ? count : chunk;
+	  int n = _write (fd, p, this_chunk);
+
+	  nchars += n;
+	  if (n < 0)
+	    {
+	      nchars = n;
+	      break;
+	    }
+	  else if (n < this_chunk)
+	    break;
+	  count -= n;
+	  p += n;
+	}
+    }
 
   return nchars;
 }