[svn:parrot] r39181 - trunk/src/io

NotFound at svn.parrot.org NotFound at svn.parrot.org
Tue May 26 20:23:34 UTC 2009


Author: NotFound
Date: Tue May 26 20:23:34 2009
New Revision: 39181
URL: https://trac.parrot.org/parrot/changeset/39181

Log:
[IO] On Win32, retry failed write of big size in smallest chunks on some conditions, TT #710

Modified:
   trunk/src/io/win32.c

Modified: trunk/src/io/win32.c
==============================================================================
--- trunk/src/io/win32.c	Tue May 26 19:29:36 2009	(r39180)
+++ trunk/src/io/win32.c	Tue May 26 20:23:34 2009	(r39181)
@@ -459,8 +459,9 @@
 {
     ASSERT_ARGS(Parrot_io_write_win32)
     DWORD countwrote = 0;
+    DWORD err;
     void * const buffer = s->strstart;
-    size_t len = s->bufused;
+    DWORD len = (DWORD) s->bufused;
     PIOHANDLE os_handle = Parrot_io_get_os_handle(interp, filehandle);
 
     /* do it by hand, Win32 hasn't any specific flag */
@@ -468,7 +469,6 @@
         LARGE_INTEGER p;
         p.LowPart = 0;
         p.HighPart = 0;
-
         p.LowPart = SetFilePointer(os_handle, p.LowPart,
                                    &p.HighPart, FILE_END);
         if (p.LowPart == 0xFFFFFFFF && (GetLastError() != NO_ERROR)) {
@@ -477,8 +477,26 @@
         }
     }
 
-    if (WriteFile(os_handle, (LPCSTR) buffer, (DWORD) len, &countwrote, NULL))
+    if (WriteFile(os_handle, (LPCSTR) buffer, len, &countwrote, NULL))
         return countwrote;
+
+    /* Write may have failed because of small buffers,
+     * see TT #710 for example.
+     * Let's try writing in small chunks */
+    if ((err = GetLastError()) == ERROR_NOT_ENOUGH_MEMORY || err == ERROR_INVALID_USER_BUFFER) {
+        DWORD chunk = 4096; /* Arbitrarily choosen value */
+        if (len < chunk)
+            goto fail;
+        while (len > 0) {
+            if (chunk > len)
+                chunk = len;
+            if (WriteFile(os_handle, (LPCSTR) buffer, chunk, &countwrote, NULL) == 0 || countwrote != chunk)
+                goto fail;
+            len -= chunk;
+        }
+        return len;
+    }
+fail:
     /* FIXME: Set error flag */
     return (size_t)-1;
 }


More information about the parrot-commits mailing list