emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] emacs-25 8badf95: Make 'mmap_realloc' on MS-Windows more r


From: Eli Zaretskii
Subject: [Emacs-diffs] emacs-25 8badf95: Make 'mmap_realloc' on MS-Windows more reliable
Date: Sun, 14 Feb 2016 17:48:09 +0000

branch: emacs-25
commit 8badf953da5e629bc67db113719b72412270dabd
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    Make 'mmap_realloc' on MS-Windows more reliable
    
    * src/w32heap.c (mmap_alloc): If reserving memory succeeds, but
    committing fails, return NULL.  Don't call GetLastError twice for
    the same API error.
    (mmap_realloc): Zero out MEMORY_BASIC_INFORMATION structures
    before calling VirtualQuery, to avoid using garbled values if the
    call fails.  If committing more pages from the same block fails,
    fall back on mmap_alloc + CopyMemory.  Enhance debugging printouts
    if the call to VirtualAlloc to commit more pages fails.
    (Bug#22526)
---
 src/w32heap.c |   51 +++++++++++++++++++++++++++++----------------------
 1 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/src/w32heap.c b/src/w32heap.c
index 00da86a..69706a3 100644
--- a/src/w32heap.c
+++ b/src/w32heap.c
@@ -652,15 +652,19 @@ mmap_alloc (void **var, size_t nbytes)
     {
       /* Now, commit pages for NBYTES.  */
       *var = VirtualAlloc (p, nbytes, MEM_COMMIT, PAGE_READWRITE);
+      if (*var == NULL)
+       p = *var;
     }
 
   if (!p)
     {
-      if (GetLastError () == ERROR_NOT_ENOUGH_MEMORY)
+      DWORD e = GetLastError ();
+
+      if (e == ERROR_NOT_ENOUGH_MEMORY)
        errno = ENOMEM;
       else
        {
-         DebPrint (("mmap_alloc: error %ld\n", GetLastError ()));
+         DebPrint (("mmap_alloc: error %ld\n", e));
          errno = EINVAL;
        }
     }
@@ -683,6 +687,7 @@ void *
 mmap_realloc (void **var, size_t nbytes)
 {
   MEMORY_BASIC_INFORMATION memInfo, m2;
+  void *old_ptr;
 
   if (*var == NULL)
     return mmap_alloc (var, nbytes);
@@ -694,12 +699,14 @@ mmap_realloc (void **var, size_t nbytes)
       return mmap_alloc (var, nbytes);
     }
 
+  memset (&memInfo, 0, sizeof (memInfo));
   if (VirtualQuery (*var, &memInfo, sizeof (memInfo)) == 0)
     DebPrint (("mmap_realloc: VirtualQuery error = %ld\n", GetLastError ()));
 
   /* We need to enlarge the block.  */
   if (memInfo.RegionSize < nbytes)
     {
+      memset (&m2, 0, sizeof (m2));
       if (VirtualQuery (*var + memInfo.RegionSize, &m2, sizeof(m2)) == 0)
         DebPrint (("mmap_realloc: VirtualQuery error = %ld\n",
                   GetLastError ()));
@@ -715,31 +722,31 @@ mmap_realloc (void **var, size_t nbytes)
                            MEM_COMMIT, PAGE_READWRITE);
          if (!p /* && GetLastError() != ERROR_NOT_ENOUGH_MEMORY */)
            {
-             DebPrint (("realloc enlarge: VirtualAlloc error %ld\n",
+             DebPrint (("realloc enlarge: VirtualAlloc (%p + %I64x, %I64x) 
error %ld\n",
+                        *var, (uint64_t)memInfo.RegionSize,
+                        (uint64_t)(nbytes - memInfo.RegionSize),
                         GetLastError ()));
-             errno = ENOMEM;
+             DebPrint (("next region: %p %p %I64x %x\n", m2.BaseAddress,
+                        m2.AllocationBase, m2.RegionSize, 
m2.AllocationProtect));
            }
+         else
+           return *var;
+       }
+      /* Else we must actually enlarge the block by allocating a new
+        one and copying previous contents from the old to the new one.  */
+      old_ptr = *var;
+
+      if (mmap_alloc (var, nbytes))
+       {
+         CopyMemory (*var, old_ptr, memInfo.RegionSize);
+         mmap_free (&old_ptr);
          return *var;
        }
       else
        {
-         /* Else we must actually enlarge the block by allocating a
-            new one and copying previous contents from the old to the
-            new one.  */
-         void *old_ptr = *var;
-
-         if (mmap_alloc (var, nbytes))
-           {
-             CopyMemory (*var, old_ptr, memInfo.RegionSize);
-             mmap_free (&old_ptr);
-             return *var;
-           }
-         else
-           {
-             /* We failed to enlarge the buffer.  */
-             *var = old_ptr;
-             return NULL;
-           }
+         /* We failed to reallocate the buffer.  */
+         *var = old_ptr;
+         return NULL;
        }
     }
 
@@ -751,7 +758,7 @@ mmap_realloc (void **var, size_t nbytes)
         {
           /* Let's give some memory back to the system and release
             some pages.  */
-          void *old_ptr = *var;
+          old_ptr = *var;
 
          if (mmap_alloc (var, nbytes))
             {



reply via email to

[Prev in Thread] Current Thread [Next in Thread]