From ee73a723f9fb3d51927b60f6bc38b277adcf58e9 Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Wed, 05 Jun 2013 04:56:26 -0400
Subject: [PATCH] Improvements in garbage collector: created gc() method to run all gc-related cleanups in one place, added posibility to run gc in environments without session

---
 program/lib/Roundcube/rcube.php |   56 ++++++++++++++++++++++-----
 program/include/bc.php          |    2 
 bin/gc.sh                       |    3 -
 3 files changed, 47 insertions(+), 14 deletions(-)

diff --git a/bin/gc.sh b/bin/gc.sh
index d099615..1ee6107 100755
--- a/bin/gc.sh
+++ b/bin/gc.sh
@@ -24,5 +24,4 @@
 require INSTALL_PATH.'program/include/clisetup.php';
 
 $rcmail = rcube::get_instance();
-$rcmail->temp_gc();
-$rcmail->cache_gc();
+$rcmail->gc();
diff --git a/program/include/bc.php b/program/include/bc.php
index 447876d..a7d7b5a 100644
--- a/program/include/bc.php
+++ b/program/include/bc.php
@@ -62,7 +62,7 @@
 
 function rcmail_temp_gc()
 {
-  rcmail::get_instance()->temp_gc();
+  rcmail::get_instance()->gc_temp();
 }
 
 function rcube_charset_convert($str, $from, $to=NULL)
diff --git a/program/lib/Roundcube/rcube.php b/program/lib/Roundcube/rcube.php
index 4e3f8fc..ebfa4f8 100644
--- a/program/lib/Roundcube/rcube.php
+++ b/program/lib/Roundcube/rcube.php
@@ -462,9 +462,7 @@
         // use database for storing session data
         $this->session = new rcube_session($this->get_dbh(), $this->config);
 
-        $this->session->register_gc_handler(array($this, 'temp_gc'));
-        $this->session->register_gc_handler(array($this, 'cache_gc'));
-
+        $this->session->register_gc_handler(array($this, 'gc_handler'));
         $this->session->set_secret($this->config->get('des_key') . dirname($_SERVER['SCRIPT_NAME']));
         $this->session->set_ip_check($this->config->get('ip_check'));
 
@@ -476,10 +474,29 @@
 
 
     /**
+     * Garbage collector - cache/temp cleaner
+     */
+    public function gc()
+    {
+        foreach ($this->caches as $cache) {
+            if (is_object($cache)) {
+                $cache->expunge();
+            }
+        }
+
+        if (is_object($this->storage)) {
+            $this->storage->expunge_cache();
+        }
+
+        $this->gc_temp();
+    }
+
+
+    /**
      * Garbage collector function for temp files.
      * Remove temp files older than two days
      */
-    public function temp_gc()
+    public function gc_temp()
     {
         $tmp = unslashify($this->config->get('temp_dir'));
         $expire = time() - 172800;  // expire in 48 hours
@@ -504,11 +521,30 @@
      * Garbage collector for cache entries.
      * Set flag to expunge caches on shutdown
      */
-    public function cache_gc()
+    public function gc_handler()
     {
         // because this gc function is called before storage is initialized,
         // we just set a flag to expunge storage cache on shutdown.
         $this->expunge_cache = true;
+    }
+
+
+    /**
+     * Runs garbage collector with probability based on
+     * session settings. This is intended for environments
+     * without a session.
+     */
+    public function gc_run()
+    {
+        $probability = (int) ini_get('session.gc_probability');
+        $divisor     = (int) ini_get('session.gc_divisor');
+
+        if ($divisor > 0 && $probability > 0) {
+            $random = mt_rand(1, $divisor);
+            if ($random <= $probability) {
+                $this->gc();
+            }
+        }
     }
 
 
@@ -896,19 +932,17 @@
             $this->smtp->disconnect();
         }
 
+        if ($this->expunge_cache) {
+            $this->gc();
+        }
+
         foreach ($this->caches as $cache) {
             if (is_object($cache)) {
-                if ($this->expunge_cache) {
-                    $cache->expunge();
-                }
                 $cache->close();
             }
         }
 
         if (is_object($this->storage)) {
-            if ($this->expunge_cache) {
-                $this->storage->expunge_cache();
-            }
             $this->storage->close();
         }
     }

--
Gitblit v1.9.1