[gegl] buffer: improve handling of dynamically-changing swap dir



commit b61f9015bf19611225df9832db3cfd9ee2558fc9
Author: Ell <ell_se yahoo com>
Date:   Sat Nov 24 09:06:00 2018 -0500

    buffer: improve handling of dynamically-changing swap dir
    
    The current swap-dir management code doesn't cope well with
    programs that modify the swap dir after initialization, which is
    what GIMP is now doing (see issue gimp#2224.)
    
    Move all the swap-dir management code to a new gegl-buffer-swap.c
    file, and have gegl-init.c and gegl-buffer-config.c configure the
    swap through this file.
    
    The new file provides two new public functions:
    gegl_buffer_swap_create_file(), which returns a unique filename for
    a swap file in the current swap dir, and
    gegl_buffer_swap_remove_file(), which removes and deletes a
    previously-created swap file.  All swap files created with
    create_file(), which hasn't been explicitly removed with
    remove_file(), are automatically deleted on shutdown.  This allows
    swap files to be safely deleted, even if the swap dir has been
    changed since their creation.
    
    Deprecate gegl_tile_backend_unlink_swap() in favor of the new
    functions.
    
    Use gegl_buffer_swap_{create,remove}_file() in the swap backend.

 gegl/Makefile.am                       |   1 +
 gegl/buffer/Makefile.am                |   3 +
 gegl/buffer/gegl-buffer-swap-private.h |  31 ++++
 gegl/buffer/gegl-buffer-swap.c         | 283 +++++++++++++++++++++++++++++++++
 gegl/buffer/gegl-buffer-swap.h         |  54 +++++++
 gegl/gegl-config.c                     |  18 +--
 gegl/gegl-init.c                       | 172 +-------------------
 7 files changed, 384 insertions(+), 178 deletions(-)
---
diff --git a/gegl/Makefile.am b/gegl/Makefile.am
index c3dca9f2b..51df572f1 100644
--- a/gegl/Makefile.am
+++ b/gegl/Makefile.am
@@ -63,6 +63,7 @@ GEGL_introspectable_headers = \
        buffer/gegl-buffer-iterator.h   \
        buffer/gegl-buffer-iterator2.h  \
        buffer/gegl-buffer-backend.h    \
+       buffer/gegl-buffer-swap.h       \
        buffer/gegl-rectangle.h         \
        buffer/gegl-tile-backend.h              \
        buffer/gegl-tile-handler.h              \
diff --git a/gegl/buffer/Makefile.am b/gegl/buffer/Makefile.am
index 0c1f79ca4..4256cfa78 100644
--- a/gegl/buffer/Makefile.am
+++ b/gegl/buffer/Makefile.am
@@ -40,6 +40,7 @@ libbuffer_la_SOURCES = \
     gegl-rectangle.c   \
        gegl-buffer-load.c      \
     gegl-buffer-save.c         \
+    gegl-buffer-swap.c         \
     gegl-sampler.c             \
     gegl-sampler-cubic.c       \
     gegl-sampler-linear.c      \
@@ -70,6 +71,8 @@ libbuffer_la_SOURCES = \
     gegl-rectangle.h   \
     gegl-buffer-types.h                \
     gegl-buffer-formats.h      \
+    gegl-buffer-swap.h         \
+    gegl-buffer-swap-private.h \
     gegl-sampler.h             \
     gegl-sampler-cubic.h       \
     gegl-sampler-linear.h      \
diff --git a/gegl/buffer/gegl-buffer-swap-private.h b/gegl/buffer/gegl-buffer-swap-private.h
new file mode 100644
index 000000000..d9b573cfc
--- /dev/null
+++ b/gegl/buffer/gegl-buffer-swap-private.h
@@ -0,0 +1,31 @@
+/* This file is part of GEGL
+ *
+ * GEGL is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * GEGL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GEGL; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GEGL_BUFFER_SWAP_PRIVATE_H__
+#define __GEGL_BUFFER_SWAP_PRIVATE_H__
+
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+void   gegl_buffer_swap_init    (void);
+void   gegl_buffer_swap_cleanup (void);
+
+G_END_DECLS
+
+#endif
diff --git a/gegl/buffer/gegl-buffer-swap.c b/gegl/buffer/gegl-buffer-swap.c
new file mode 100644
index 000000000..205bfe790
--- /dev/null
+++ b/gegl/buffer/gegl-buffer-swap.c
@@ -0,0 +1,283 @@
+/* This file is part of GEGL
+ *
+ * GEGL is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * GEGL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GEGL; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef G_OS_WIN32
+#include <windows.h>
+#include <process.h>
+#define getpid() _getpid()
+#else
+#include <signal.h>
+#endif
+
+#include <glib/gstdio.h>
+
+#include "gegl-buffer-config.h"
+#include "gegl-buffer-swap.h"
+#include "gegl-buffer-swap-private.h"
+
+
+#define SWAP_PREFIX "gegl-swap-"
+
+
+/*  local function prototypes  */
+
+static void       gegl_buffer_swap_notify_swap    (GeglBufferConfig *config);
+
+static void       gegl_buffer_swap_clean_dir      (void);
+static gboolean   gegl_buffer_swap_pid_is_running (gint              pid);
+
+
+/*  local variables  */
+
+static GMutex      swap_mutex;
+static gchar      *swap_dir;
+static GHashTable *swap_files;
+static guint       swap_file_counter;
+
+
+/*  public functions  */
+
+void
+gegl_buffer_swap_init (void)
+{
+  swap_files = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+  g_signal_connect (gegl_buffer_config (), "notify::swap",
+                    G_CALLBACK (gegl_buffer_swap_notify_swap),
+                    NULL);
+
+  gegl_buffer_swap_notify_swap (gegl_buffer_config ());
+}
+
+void
+gegl_buffer_swap_cleanup (void)
+{
+  GHashTableIter  iter;
+  const gchar    *path;
+
+  g_signal_handlers_disconnect_by_func (gegl_buffer_config (),
+                                        gegl_buffer_swap_notify_swap,
+                                        NULL);
+
+  g_mutex_lock (&swap_mutex);
+
+  g_hash_table_iter_init (&iter, swap_files);
+
+  while (g_hash_table_iter_next (&iter, (gpointer) &path, NULL))
+    g_unlink (path);
+
+  g_clear_pointer (&swap_files, g_hash_table_destroy);
+
+  g_clear_pointer (&swap_dir, g_free);
+
+  g_mutex_unlock (&swap_mutex);
+}
+
+gchar *
+gegl_buffer_swap_create_file (const gchar *suffix)
+{
+  gchar    *basename;
+  gchar    *path;
+  gboolean  added;
+
+  if (! swap_dir)
+    return NULL;
+
+  g_mutex_lock (&swap_mutex);
+
+  if (! swap_dir)
+    {
+      g_mutex_unlock (&swap_mutex);
+
+      return NULL;
+    }
+
+  if (suffix)
+    {
+      basename = g_strdup_printf (SWAP_PREFIX "%d-%u-%s",
+                                  (gint) getpid (),
+                                  swap_file_counter++,
+                                  suffix);
+    }
+  else
+    {
+      basename = g_strdup_printf (SWAP_PREFIX "%d-%u",
+                                  (gint) getpid (),
+                                  swap_file_counter++);
+    }
+
+  path = g_build_filename (swap_dir, basename, NULL);
+
+  added = g_hash_table_add (swap_files, path);
+
+  g_mutex_unlock (&swap_mutex);
+
+  g_free (basename);
+
+  if (! added)
+    {
+      g_warning ("swap file collision '%s'", path);
+
+      g_free (path);
+
+      return NULL;
+    }
+
+  return g_strdup (path);
+}
+
+void
+gegl_buffer_swap_remove_file (const gchar *path)
+{
+  gboolean removed;
+
+  g_return_if_fail (path != NULL);
+
+  g_mutex_lock (&swap_mutex);
+
+  removed = g_hash_table_remove (swap_files, path);
+
+  g_mutex_unlock (&swap_mutex);
+
+  if (removed)
+    g_unlink (path);
+  else
+    g_warning ("attempt to remove unregistered swap file '%s'", path);
+}
+
+
+/*  private functions  */
+
+static void
+gegl_buffer_swap_notify_swap (GeglBufferConfig *config)
+{
+  gchar *dir = config->swap;
+
+  if (dir)
+    {
+      dir = g_strstrip (g_strdup (dir));
+
+      /* Remove any trailing separator, unless the path is only made of a
+       * leading separator.
+       */
+      while (strlen (dir) > strlen (G_DIR_SEPARATOR_S) &&
+             g_str_has_suffix (dir, G_DIR_SEPARATOR_S))
+        {
+          dir[strlen (dir) - strlen (G_DIR_SEPARATOR_S)] = '\0';
+        }
+    }
+
+  g_mutex_lock (&swap_mutex);
+
+  if (! g_strcmp0 (dir, swap_dir))
+    {
+      g_mutex_unlock (&swap_mutex);
+
+      g_free (dir);
+
+      return;
+    }
+
+  g_clear_pointer (&swap_dir, g_free);
+
+  if (dir                                     &&
+      ! g_file_test (dir, G_FILE_TEST_IS_DIR) &&
+      g_mkdir_with_parents (dir, S_IRUSR | S_IWUSR | S_IXUSR) != 0)
+    {
+      g_mutex_unlock (&swap_mutex);
+
+      g_free (dir);
+
+      return;
+    }
+
+  swap_dir = dir;
+
+  gegl_buffer_swap_clean_dir ();
+
+  g_mutex_unlock (&swap_mutex);
+
+  return;
+}
+
+static void
+gegl_buffer_swap_clean_dir (void)
+{
+  GDir *dir;
+
+  if (! swap_dir)
+    return;
+
+  dir = g_dir_open (swap_dir, 0, NULL);
+
+  if (dir != NULL)
+    {
+      const gchar *basename;
+
+      while ((basename = g_dir_read_name (dir)) != NULL)
+        {
+          if (g_str_has_prefix (basename, SWAP_PREFIX))
+            {
+              gint pid = atoi (basename + strlen (SWAP_PREFIX));
+
+              if (! gegl_buffer_swap_pid_is_running (pid))
+                {
+                  gchar *path = g_build_filename (swap_dir, basename, NULL);
+
+                  g_unlink (path);
+
+                  g_free (path);
+                }
+            }
+         }
+
+      g_dir_close (dir);
+    }
+}
+
+#ifdef G_OS_WIN32
+
+static gboolean
+gegl_buffer_swap_pid_is_running (gint pid)
+{
+  HANDLE h;
+  DWORD exitcode = 0;
+
+  h = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, pid);
+  GetExitCodeProcess (h, &exitcode);
+  CloseHandle (h);
+
+  return exitcode == STILL_ACTIVE;
+}
+
+#else
+
+static gboolean
+gegl_buffer_swap_pid_is_running (gint pid)
+{
+  return kill (pid, 0) == 0;
+}
+
+#endif
diff --git a/gegl/buffer/gegl-buffer-swap.h b/gegl/buffer/gegl-buffer-swap.h
new file mode 100644
index 000000000..8e6ca074d
--- /dev/null
+++ b/gegl/buffer/gegl-buffer-swap.h
@@ -0,0 +1,54 @@
+/* This file is part of GEGL
+ *
+ * GEGL is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * GEGL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GEGL; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GEGL_BUFFER_SWAP_H__
+#define __GEGL_BUFFER_SWAP_H__
+
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/**
+ * gegl_buffer_swap_create_file:
+ * @suffix: (nullable): a string to suffix the filename with, for
+ *          identification purposes, or %NULL.
+ *
+ * Generates a unique filename in the GEGL swap directory, suitable for
+ * using as swap space.  When the file is no longer needed, it may be
+ * removed with gegl_buffer_swap_remove_file(); otherwise, it will be
+ * removed when gegl_exit() is called.
+ *
+ * Returns: (type filename) (nullable):  a string containing the full
+ * file path, or %NULL is the swap is disabled.  The returned string
+ * should be freed with g_free() when no longer needed.
+ */
+gchar * gegl_buffer_swap_create_file (const gchar *suffix);
+
+/**
+ * gegl_buffer_swap_remove_file:
+ * @path: (type filename): the swap file to remove, as returned by
+ *        gegl_buffer_swap_create_file()
+ *
+ * Removes a swap file, generated using gegl_buffer_swap_create_file(),
+ * unlinking the file, if exists.
+ */
+void    gegl_buffer_swap_remove_file (const gchar *path);
+
+G_END_DECLS
+
+#endif
diff --git a/gegl/gegl-config.c b/gegl/gegl-config.c
index 0a5043690..b24388970 100644
--- a/gegl/gegl-config.c
+++ b/gegl/gegl-config.c
@@ -183,24 +183,21 @@ gegl_config_class_init (GeglConfigClass *klass)
                                                      "Tile width",
                                                      "default tile width for created buffers.",
                                                      0, G_MAXINT, 128,
-                                                     G_PARAM_READWRITE |
-                                                     G_PARAM_CONSTRUCT));
+                                                     G_PARAM_READWRITE));
 
   g_object_class_install_property (gobject_class, PROP_TILE_HEIGHT,
                                    g_param_spec_int ("tile-height",
                                                      "Tile height",
                                                      "default tile height for created buffers.",
                                                      0, G_MAXINT, 128,
-                                                     G_PARAM_READWRITE |
-                                                     G_PARAM_CONSTRUCT));
+                                                     G_PARAM_READWRITE));
 
   g_object_class_install_property (gobject_class, PROP_TILE_CACHE_SIZE,
                                    g_param_spec_uint64 ("tile-cache-size",
                                                         "Tile Cache size",
                                                         "size of tile cache in bytes",
                                                         0, G_MAXUINT64, 512 * 1024 * 1024,
-                                                        G_PARAM_READWRITE |
-                                                        G_PARAM_CONSTRUCT));
+                                                        G_PARAM_READWRITE));
 
   g_object_class_install_property (gobject_class, PROP_CHUNK_SIZE,
                                    g_param_spec_int ("chunk-size",
@@ -223,8 +220,7 @@ gegl_config_class_init (GeglConfigClass *klass)
                                                         "Swap",
                                                         "where gegl stores it's swap files",
                                                         NULL,
-                                                        G_PARAM_READWRITE |
-                                                        G_PARAM_CONSTRUCT));
+                                                        G_PARAM_READWRITE));
 
   _gegl_threads = g_get_num_processors ();
   _gegl_threads = MIN (_gegl_threads, GEGL_MAX_THREADS);
@@ -250,8 +246,7 @@ gegl_config_class_init (GeglConfigClass *klass)
                                                      "Queue size",
                                                      "Maximum size of a file backend's writer thread queue 
(in bytes)",
                                                      2, G_MAXINT, 50 * 1024 *1024,
-                                                     G_PARAM_READWRITE |
-                                                     G_PARAM_CONSTRUCT));
+                                                     G_PARAM_READWRITE));
 
   g_object_class_install_property (gobject_class, PROP_APPLICATION_LICENSE,
                                    g_param_spec_string ("application-license",
@@ -274,7 +269,8 @@ gegl_config_init (GeglConfig *self)
   GeglBufferConfig *bconf = gegl_buffer_config ();
   for (int i = 0; forward_props[i]; i++)
     g_object_bind_property (bconf, forward_props[i],
-                            self, forward_props[i], G_BINDING_BIDIRECTIONAL);
+                            self, forward_props[i],
+                            G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
 }
 
 #undef  gegl_config_threads
diff --git a/gegl/gegl-init.c b/gegl/gegl-init.c
index 414ebeb1f..631f2a517 100644
--- a/gegl/gegl-init.c
+++ b/gegl/gegl-init.c
@@ -56,29 +56,6 @@ DllMain (HINSTANCE hinstDLL,
   return TRUE;
 }
 
-static inline gboolean
-pid_is_running (gint pid)
-{
-  HANDLE h;
-  DWORD exitcode = 0;
-
-  h = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, pid);
-  GetExitCodeProcess (h, &exitcode);
-  CloseHandle (h);
-
-  return exitcode == STILL_ACTIVE;
-}
-
-#else
-
-#include <sys/types.h>
-#include <signal.h>
-
-static inline gboolean
-pid_is_running (gint pid)
-{
-  return (kill (pid, 0) == 0);
-}
 #endif
 
 
@@ -99,6 +76,7 @@ guint gegl_debug_flags = 0;
 #include "operation/gegl-operation-handlers-private.h"
 #include "buffer/gegl-buffer-private.h"
 #include "buffer/gegl-buffer-iterator-private.h"
+#include "buffer/gegl-buffer-swap-private.h"
 #include "buffer/gegl-tile-backend-ram.h"
 #include "buffer/gegl-tile-backend-file.h"
 #include "gegl-config.h"
@@ -121,58 +99,6 @@ static GeglModuleDB *module_db   = NULL;
 
 static glong         global_time = 0;
 
-static gboolean      swap_init_done = FALSE;
-
-static gchar        *swap_dir = NULL;
-
-static void
-gegl_init_swap_dir (void)
-{
-  gchar *swapdir = NULL;
-
-  if (config->swap)
-    {
-      if (g_ascii_strcasecmp (config->swap, "ram") == 0)
-        {
-          swapdir = NULL;
-        }
-      else
-        {
-          swapdir = g_strstrip (g_strdup (config->swap));
-
-          /* Remove any trailing separator, unless the path is only made of a leading separator. */
-          while (strlen (swapdir) > strlen (G_DIR_SEPARATOR_S) && g_str_has_suffix (swapdir, 
G_DIR_SEPARATOR_S))
-            swapdir[strlen (swapdir) - strlen (G_DIR_SEPARATOR_S)] = '\0';
-        }
-    }
-
-  if (swapdir &&
-      ! g_file_test (swapdir, G_FILE_TEST_IS_DIR) &&
-      g_mkdir_with_parents (swapdir, S_IRUSR | S_IWUSR | S_IXUSR) != 0)
-    {
-      g_clear_pointer (&swapdir, g_free);
-    }
-
-  g_object_set (config, "swap", swapdir, NULL);
-
-  swap_dir = swapdir;
-
-  swap_init_done = TRUE;
-}
-
-/* Return the swap directory, or NULL if swapping is disabled */
-const gchar *
-gegl_swap_dir (void)
-{
-  if (!swap_init_done)
-  {
-    g_critical ("swap parsing not done");
-    gegl_init_swap_dir ();
-  }
-
-  return swap_dir;
-}
-
 static void load_module_path(gchar *path, GeglModuleDB *db);
 
 static void
@@ -334,19 +260,6 @@ gegl_get_option_group (void)
   return group;
 }
 
-static void gegl_config_set_defaults (GeglConfig *config)
-{
-  gchar *swapdir = g_build_filename (g_get_user_cache_dir(),
-                                     GEGL_LIBRARY,
-                                     "swap",
-                                     NULL);
-  g_object_set (config,
-                "swap", swapdir,
-                NULL);
-
-  g_free (swapdir);
-}
-
 static void gegl_config_parse_env (GeglConfig *config)
 {
   if (g_getenv ("GEGL_QUALITY"))
@@ -415,10 +328,8 @@ static void gegl_config_parse_env (GeglConfig *config)
 GeglConfig *gegl_config (void)
 {
   if (!config)
-    {
-      config = g_object_new (GEGL_TYPE_CONFIG, NULL);
-      gegl_config_set_defaults (config);
-    }
+    config = g_object_new (GEGL_TYPE_CONFIG, NULL);
+
   return config;
 }
 
@@ -435,43 +346,6 @@ void gegl_reset_stats (void)
   gegl_stats_reset (gegl_stats ());
 }
 
-static void swap_clean (void)
-{
-  const gchar  *swap_dir = gegl_swap_dir ();
-  GDir         *dir;
-
-  if (! swap_dir)
-    return;
-
-  dir = g_dir_open (gegl_swap_dir (), 0, NULL);
-
-  if (dir != NULL)
-    {
-      GPatternSpec *pattern = g_pattern_spec_new ("*");
-      const gchar  *name;
-
-      while ((name = g_dir_read_name (dir)) != NULL)
-        {
-          if (g_pattern_match_string (pattern, name))
-            {
-              gint readpid = atoi (name);
-
-              if (!pid_is_running (readpid))
-                {
-                  gchar *fname = g_build_filename (gegl_swap_dir (),
-                                                   name,
-                                                   NULL);
-                  g_unlink (fname);
-                  g_free (fname);
-                }
-            }
-         }
-
-      g_pattern_spec_free (pattern);
-      g_dir_close (dir);
-    }
-}
-
 void gegl_temp_buffer_free (void);
 
 void
@@ -491,6 +365,7 @@ gegl_exit (void)
   gegl_operation_handlers_cleanup ();
   gegl_random_cleanup ();
   gegl_parallel_cleanup ();
+  gegl_buffer_swap_cleanup ();
   gegl_cl_cleanup ();
 
   gegl_temp_buffer_free ();
@@ -526,44 +401,10 @@ gegl_exit (void)
 #endif
     }
 
-  if (gegl_swap_dir ())
-    {
-      /* remove all files matching <$GEGL_SWAP>/GEGL-<pid>-*.swap */
-
-      guint         pid     = getpid ();
-      GDir         *dir     = g_dir_open (gegl_swap_dir (), 0, NULL);
-
-      gchar        *glob    = g_strdup_printf ("%i-*", pid);
-      GPatternSpec *pattern = g_pattern_spec_new (glob);
-      g_free (glob);
-
-      if (dir != NULL)
-        {
-          const gchar *name;
-
-          while ((name = g_dir_read_name (dir)) != NULL)
-            {
-              if (g_pattern_match_string (pattern, name))
-                {
-                  gchar *fname = g_build_filename (gegl_swap_dir (),
-                                                   name,
-                                                   NULL);
-                  g_unlink (fname);
-                  g_free (fname);
-                }
-            }
-
-          g_dir_close (dir);
-        }
-
-      g_pattern_spec_free (pattern);
-    }
   g_clear_object (&config);
   global_time = 0;
 }
 
-static void swap_clean (void);
-
 void
 gegl_get_version (int *major,
                   int *minor,
@@ -700,10 +541,9 @@ gegl_post_parse_hook (GOptionContext *context,
   if (cmd_gegl_disable_opencl)
     gegl_cl_hard_disable ();
 
-  gegl_init_swap_dir ();
-
   GEGL_INSTRUMENT_START();
 
+  gegl_buffer_swap_init ();
   gegl_parallel_init ();
   gegl_operation_gtype_init ();
   gegl_tile_cache_init ();
@@ -720,8 +560,6 @@ gegl_post_parse_hook (GOptionContext *context,
 
   gegl_instrument ("gegl", "gegl_init", gegl_ticks () - global_time);
 
-  swap_clean ();
-
   g_signal_connect (G_OBJECT (config),
                    "notify::use-opencl",
                    G_CALLBACK (gegl_config_use_opencl_notify),


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