Browse Source

* fixed bug in NewHeapBlock, which caused an infinite loop in GetMem, when more
than 2 blocks are needed

git-svn-id: trunk@37642 -

nickysn 7 years ago
parent
commit
b6efaeb8fd
1 changed files with 11 additions and 5 deletions
  1. 11 5
      rtl/win16/glbheap.inc

+ 11 - 5
rtl/win16/glbheap.inc

@@ -40,7 +40,7 @@ circular linked list.
         Size: Word;
         Size: Word;
       end;
       end;
 
 
-    function NewHeapBlock: Boolean;
+    function NewHeapBlock(LastBlock: Word): Boolean;
       var
       var
         hglob: HGLOBAL;
         hglob: HGLOBAL;
         pb: PGlobalHeapBlockHeader;
         pb: PGlobalHeapBlockHeader;
@@ -74,12 +74,14 @@ circular linked list.
               end;
               end;
           end;
           end;
         HeapList:=Seg(pb^);
         HeapList:=Seg(pb^);
+        if LastBlock<>0 then
+          PGlobalHeapBlockHeader(Ptr(LastBlock,0))^.NextBlockSeg:=HeapList;
         result:=true;
         result:=true;
       end;
       end;
 
 
     { tries to suballocate from the existing blocks. Returns nil if not enough
     { tries to suballocate from the existing blocks. Returns nil if not enough
       free space is available. ASize must be aligned by 4. }
       free space is available. ASize must be aligned by 4. }
-    function TryBlockGetMem(ASize: Word): FarPointer;
+    function TryBlockGetMem(ASize: Word; out LastBlock: Word): FarPointer;
       var
       var
         CurBlock: Word;
         CurBlock: Word;
         CurBlockP: PGlobalHeapBlockHeader;
         CurBlockP: PGlobalHeapBlockHeader;
@@ -87,6 +89,7 @@ circular linked list.
       begin
       begin
         CurBlock:=HeapList;
         CurBlock:=HeapList;
         result:=nil;
         result:=nil;
+        LastBlock:=0;
         if CurBlock=0 then
         if CurBlock=0 then
           exit;
           exit;
         repeat
         repeat
@@ -127,23 +130,26 @@ circular linked list.
                   CurSubBlock:=Ptr(CurBlock,CurSubBlock^.Next);
                   CurSubBlock:=Ptr(CurBlock,CurSubBlock^.Next);
                 end;
                 end;
             end;
             end;
+          LastBlock:=CurBlock;
           CurBlock:=CurBlockP^.NextBlockSeg;
           CurBlock:=CurBlockP^.NextBlockSeg;
         until CurBlock=HeapList;
         until CurBlock=HeapList;
       end;
       end;
 
 
     function SysGlobalBlockGetMem(Size: Word): FarPointer;
     function SysGlobalBlockGetMem(Size: Word): FarPointer;
+      var
+        LastBlock: Word;
       begin
       begin
         Size:=(Size+3) and $fffc;
         Size:=(Size+3) and $fffc;
-        result:=TryBlockGetMem(Size);
+        result:=TryBlockGetMem(Size,LastBlock);
         if result<>nil then
         if result<>nil then
           exit;
           exit;
-        if not NewHeapBlock then
+        if not NewHeapBlock(LastBlock) then
           begin
           begin
             { NewHeapBlock can only return false if ReturnNilIfGrowHeapFails=true }
             { NewHeapBlock can only return false if ReturnNilIfGrowHeapFails=true }
             result:=nil;
             result:=nil;
             exit;
             exit;
           end;
           end;
-        result:=TryBlockGetMem(Size);
+        result:=TryBlockGetMem(Size,LastBlock);
       end;
       end;
 
 
     function SysGlobalGetMem(Size: ptruint): FarPointer;
     function SysGlobalGetMem(Size: ptruint): FarPointer;