fix bug leading to never freeing images cache on x86_64 because of strange glibc...
authorGuillaume Cottenceau <gcottenc@gmail.com>
Sun, 8 Nov 2009 14:56:51 +0000 (15:56 +0100)
committerGuillaume Cottenceau <gcottenc@gmail.com>
Sun, 8 Nov 2009 14:56:51 +0000 (15:56 +0100)
bin/booh-classifier

index d2f9d3f..1edbc4a 100644 (file)
@@ -255,6 +255,14 @@ class InterruptedLoading < Exception
     #- not a StandardError, not catched by a simple rescue
 end
 
+def show_pixbufs_present
+    out = 'Full pixbufs ['
+    for entry in $allentries
+        out += entry.pixbuf_full_present? ? 'F' : '.'
+    end
+    msg 3, out + ']'
+end
+
 class Entry
     @@max_width = nil
     def Entry.thumbnails_height
@@ -272,6 +280,9 @@ class Entry
         end
     end
 
+    def pixbuf_full_present?
+        return ! @pixbuf_full.nil?
+    end
     def free_pixbuf_full
         if @pixbuf_full.nil?
             return false
@@ -281,6 +292,7 @@ class Entry
             return true
         end
     end
+
     def pixbuf_main
         Gtk.main_iteration while Gtk.events_pending?
         width, height = $mainview.window.size 
@@ -311,6 +323,9 @@ class Entry
         end
         return @pixbuf_main
     end
+    def pixbuf_main_present?
+        return ! @pixbuf_main.nil?
+    end
     def free_pixbuf_main
         if @pixbuf_main.nil?
             return false
@@ -320,6 +335,7 @@ class Entry
             return true
         end
     end
+
     def pixbuf_thumbnail
         Gtk.main_iteration while Gtk.events_pending?
         if @pixbuf_thumbnail.nil?
@@ -417,6 +433,7 @@ class Entry
                     end
                 end
             }
+            show_pixbufs_present
         end
     end
 
@@ -494,39 +511,52 @@ def gc
     msg 3, "GC in #{Time.now - start} s"
 end
 
-def free_cache(avoid)
+def free_cache_if_needed
     i = $allentries.index($mainview.get_shown_entry)
     return if i.nil?
+    if get_mem > $config['cache-memory-use-figure']
+        msg 3, "too much RSS, triggering GC"
+        gc
+    end
+    if get_mem < $config['cache-memory-use-figure']
+        return
+    end
+    msg 3, "too much RSS, freeing some cache"
     start = Time.now
+    freed = 0
     ($allentries.size - 1).downto($config['preload-distance'].to_i + 1) { |j|
         index = i + j
-        if i + j < $allentries.size && ! avoid.include?(i + j)
+        if i + j < $allentries.size
             $allentries[i + j].free_pixbuf_full
-            $allentries[i + j].free_pixbuf_main
+            if $allentries[i + j].free_pixbuf_main
+                freed += 1
+            end
         end
-        if i - j >= 0 && ! avoid.include?(i - j)
+        if i - j >= 0
             $allentries[i - j].free_pixbuf_full
-            $allentries[i - j].free_pixbuf_main
+            if $allentries[i - j].free_pixbuf_main
+                freed += 1
+            end
+        end
+        if freed >= 10
+            gc
+            if get_mem < $config['cache-memory-use-figure'] * 3 / 4
+                msg 3, "RSS down enough - freeing done in #{Time.now - start} s"
+                show_pixbufs_present
+                return
+            end
+            freed = 0
         end
     }
     msg 3, "freeing done in #{Time.now - start} s"
-    if get_mem > $config['cache-memory-use-figure'] * 3 / 4
-        gc
-        get_mem
-    end
+    show_pixbufs_present
 end
 
 def run_preloader_real
     msg 3, "*** >> main preloading triggered..."
     if $mainview.get_shown_entry
-        if get_mem > $config['cache-memory-use-figure']
-            msg 3, "too much RSS, stopping preloading, triggering GC"
-            gc
-            get_mem
-            return true
-        end
+        free_cache_if_needed
         if $config['preload-distance'].to_i == 0
-            free_cache([])
             return true
         end
         index = $allentries.index($mainview.get_shown_entry)
@@ -546,12 +576,14 @@ def run_preloader_real
                 if index_right == $allentries.size
                     right_done = true
                 else
-                    msg 3, "preloading #{$allentries[index_right].path}"
-                    begin
-                        $allentries[index_right].pixbuf_main
-                    rescue InterruptedLoading
-                        msg 3, "*** >>>> interrupted, rerun"
-                        return false
+                    if ! $allentries[index_right].pixbuf_main_present?
+                        msg 3, "preloading #{$allentries[index_right].path}"
+                        begin
+                            $allentries[index_right].pixbuf_main
+                        rescue InterruptedLoading
+                            msg 3, "*** >>>> interrupted, rerun"
+                            return false
+                        end
                     end
                     loaded << index_right
                     loaded_right += 1
@@ -569,12 +601,14 @@ def run_preloader_real
                 if index_left == -1
                     left_done = true
                 else
-                    msg 3, "preloading #{$allentries[index_left].path}"
-                    begin
-                        $allentries[index_left].pixbuf_main
-                    rescue InterruptedLoading
-                        msg 3, "*** >>>> interrupted, rerun"
-                        return false
+                    if ! $allentries[index_left].pixbuf_main_present?
+                        msg 3, "preloading #{$allentries[index_left].path}"
+                        begin
+                            $allentries[index_left].pixbuf_main
+                        rescue InterruptedLoading
+                            msg 3, "*** >>>> interrupted, rerun"
+                            return false
+                        end
                     end
                     loaded << index_left
                     loaded_left += 1
@@ -595,7 +629,6 @@ def run_preloader_real
                 return false
             end
         end
-        free_cache(loaded)
     end
     msg 3, "*** << main preloading finished"
     return true
@@ -920,6 +953,7 @@ def thumbnail_keypressed(entry, event)
             entry.free_pixbuf_full
             entry.free_pixbuf_main
             entry.free_pixbuf_thumbnail
+            show_pixbufs_present
             $mainview.redraw
             entry.image.pixbuf = entry.pixbuf_thumbnail
             if $config['rotate-set-exif'] == 'true' && entry.type == 'image'
@@ -1195,10 +1229,13 @@ def show_entries(allentries)
         if $quit
             return
         end
+        if i % 25 == 0
+            gc
+        end
     end
+    $preloader_allowed = true
     if i <= $config['preload-distance'].to_i * 2
         #- not yet preloaded correctly
-        $preloader_allowed = true
         run_preloader
     end
     sb_msg(_("%d images of total %s kB loaded in %3.2f seconds.") % [ total_loaded_files, commify(total_loaded_size / 1024), Time.now - t1 ])