]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix bug #6237.
authorEli Zaretskii <eliz@gnu.org>
Sat, 22 May 2010 19:09:51 +0000 (22:09 +0300)
committerEli Zaretskii <eliz@gnu.org>
Sat, 22 May 2010 19:09:51 +0000 (22:09 +0300)
 w32.c (sys_write): Break writes into chunks smaller than 32MB.

src/ChangeLog
src/w32.c

index 489505f3cf34df40c91edf744dc5a1733d05fbc0..540a85a6b1dc1e8230b17c596e5abe7dc17650f8 100644 (file)
@@ -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.
index 0f2d8b54e6b458fa90029392ced6a7730737c38a..0560ce4a6b869e24c63cbd9cb40e21d2661880c3 100644 (file)
--- a/src/w32.c
+++ b/src/w32.c
@@ -5700,7 +5700,34 @@ sys_write (int fd, const void * buffer, unsigned int count)
     }
   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;
 }