Sfoglia il codice sorgente

* fix memory leak introduced in rev 9696, orphaned os chunks are not reused for short-lived threads (fixes issue #13173)

git-svn-id: trunk@12759 -
micha 16 anni fa
parent
commit
82e9d9009d
1 ha cambiato i file con 28 aggiunte e 28 eliminazioni
  1. 28 28
      rtl/inc/heap.inc

+ 28 - 28
rtl/inc/heap.inc

@@ -730,39 +730,39 @@ begin
   else
     maxsize := high(ptruint);
   poc:=nil;
-  if (loc_freelists^.oscount>=MaxKeptOSChunks) then
+  { blocks available in freelist? }
+  { do not reformat fixed size chunks too quickly }
+  if loc_freelists^.oscount >= MaxKeptOSChunks then
+    poc := find_free_oschunk(loc_freelists, minsize, maxsize, size);
+  { if none available, try to recycle orphaned os chunks }
+  if not assigned(poc) and (assigned(orphaned_freelists.waitfixed)
+      or assigned(orphaned_freelists.waitvar) or (orphaned_freelists.oscount > 0)) then
     begin
-      { blocks available in freelist? }
-      poc := find_free_oschunk(loc_freelists, minsize, maxsize, size);
-      if not assigned(poc) and (assigned(orphaned_freelists.waitfixed) 
-          or assigned(orphaned_freelists.waitvar) or (orphaned_freelists.oscount > 0)) then
+      entercriticalsection(heap_lock);
+      finish_waitfixedlist(@orphaned_freelists);
+      finish_waitvarlist(@orphaned_freelists);
+      if orphaned_freelists.oscount > 0 then
         begin
-          entercriticalsection(heap_lock);
-          finish_waitfixedlist(@orphaned_freelists);
-          finish_waitvarlist(@orphaned_freelists);
-          if orphaned_freelists.oscount > 0 then
+          { blocks available in orphaned freelist ? }
+          poc := find_free_oschunk(@orphaned_freelists, minsize, maxsize, size);
+          if assigned(poc) then
             begin
-              { blocks available in orphaned freelist ? }
-              poc := find_free_oschunk(@orphaned_freelists, minsize, maxsize, size);
-              if assigned(poc) then
-                begin
-                  { adopt this os chunk }
-                  poc^.freelists := loc_freelists;
-                  if assigned(poc^.prev_any) then
-                    poc^.prev_any^.next_any := poc^.next_any
-                  else
-                    orphaned_freelists.oslist_all := poc^.next_any;
-                  if assigned(poc^.next_any) then
-                    poc^.next_any^.prev_any := poc^.prev_any;
-                  poc^.next_any := loc_freelists^.oslist_all;
-                  if assigned(loc_freelists^.oslist_all) then
-                    loc_freelists^.oslist_all^.prev_any := poc;
-                  poc^.prev_any := nil;
-                  loc_freelists^.oslist_all := poc;
-                end;
+              { adopt this os chunk }
+              poc^.freelists := loc_freelists;
+              if assigned(poc^.prev_any) then
+                poc^.prev_any^.next_any := poc^.next_any
+              else
+                orphaned_freelists.oslist_all := poc^.next_any;
+              if assigned(poc^.next_any) then
+                poc^.next_any^.prev_any := poc^.prev_any;
+              poc^.next_any := loc_freelists^.oslist_all;
+              if assigned(loc_freelists^.oslist_all) then
+                loc_freelists^.oslist_all^.prev_any := poc;
+              poc^.prev_any := nil;
+              loc_freelists^.oslist_all := poc;
             end;
-          leavecriticalsection(heap_lock);
         end;
+      leavecriticalsection(heap_lock);
     end;
   if poc = nil then
     begin