Move desktop cache to efreet_cache.c
authorSebastian Dransfeld <sd@tango.flipp.net>
Thu, 10 Feb 2011 14:25:44 +0000 (14:25 +0000)
committerSebastian Dransfeld <sd@tango.flipp.net>
Thu, 10 Feb 2011 14:25:44 +0000 (14:25 +0000)
SVN revision: 56912

legacy/efreet/ChangeLog
legacy/efreet/src/lib/efreet_cache.c
legacy/efreet/src/lib/efreet_desktop.c
legacy/efreet/src/lib/efreet_desktop.h
legacy/efreet/src/lib/efreet_private.h

index 9246a08..81862e0 100644 (file)
@@ -75,3 +75,5 @@
        * Fix memleak in desktop cache create
        * Pass dirs to desktop cache process as arguments
        * Delay cache recreation with a timer
+       * Move desktop cache to efreet_cache.c, and cache all requests which
+         hit the eet cache
index aaaf12e..7c152f2 100644 (file)
@@ -62,6 +62,7 @@ static Eet_Data_Descriptor *hash_array_string_edd = NULL;
 static Eet_Data_Descriptor *array_string_edd = NULL;
 static Eet_Data_Descriptor *hash_string_edd = NULL;
 
+static Eina_Hash           *desktops = NULL;
 static Efreet_Cache_Array_String *desktop_dirs = NULL;
 static Eet_File            *desktop_cache = NULL;
 static const char          *desktop_cache_file = NULL;
@@ -122,6 +123,7 @@ efreet_cache_init(void)
     themes = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_theme_free));
     icons = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_free));
     fallbacks = eina_hash_string_superfast_new(EINA_FREE_CB(efreet_cache_icon_fallback_free));
+    desktops = eina_hash_string_superfast_new(NULL);
 
     snprintf(buf, sizeof(buf), "%s/efreet", efreet_cache_home_get());
     if (!ecore_file_exists(buf))
@@ -153,6 +155,8 @@ error:
     icons = NULL;
     if (fallbacks) eina_hash_free(fallbacks);
     fallbacks = NULL;
+    if (desktops) eina_hash_free(desktops);
+    desktops = NULL;
 
     if (cache_exe_handler) ecore_event_handler_del(cache_exe_handler);
     cache_exe_handler = NULL;
@@ -176,6 +180,7 @@ efreet_cache_shutdown(void)
     IF_FREE_HASH(icons);
     IF_FREE_HASH(fallbacks);
 
+    IF_FREE_HASH_CB(desktops, EINA_FREE_CB(efreet_cache_desktop_free));
     efreet_cache_array_string_free(desktop_dirs);
     desktop_dirs = NULL;
     desktop_cache = efreet_cache_close(desktop_cache);
@@ -772,18 +777,26 @@ efreet_cache_array_string_free(Efreet_Cache_Array_String *array)
 Efreet_Desktop *
 efreet_cache_desktop_find(const char *file)
 {
-    Efreet_Desktop *desktop;
+    Efreet_Desktop *cache;
     char rp[PATH_MAX];
 
     if (!realpath(file, rp)) return NULL;
 
     if (!efreet_cache_check(&desktop_cache, efreet_desktop_cache_file(), EFREET_DESKTOP_CACHE_MAJOR)) return NULL;
 
-    desktop = eet_data_read(desktop_cache, efreet_desktop_edd(), rp);
-    if (!desktop) return NULL;
-    desktop->ref = 1;
-    desktop->eet = 1;
-    return desktop;
+    cache = eina_hash_find(desktops, rp);
+    if (cache == NON_EXISTING) return NULL;
+    if (cache) return cache;
+
+    cache = eet_data_read(desktop_cache, efreet_desktop_edd(), rp);
+    if (cache)
+    {
+        cache->eet = 1;
+        eina_hash_add(desktops, cache->orig_path, cache);
+    }
+    else
+        eina_hash_add(desktops, rp, NON_EXISTING);
+    return cache;
 }
 
 void
@@ -793,7 +806,13 @@ efreet_cache_desktop_free(Efreet_Desktop *desktop)
     Efreet_Desktop *curr;
     Eina_List *l;
 
-    if (!old_desktop_caches) return;
+    if (!desktop ||
+        desktop == NON_EXISTING ||
+        !desktop->eet) return;
+
+    curr = eina_hash_find(desktops, desktop->orig_path);
+    if (curr == desktop)
+        eina_hash_del_by_key(desktops, desktop->orig_path);
 
     EINA_LIST_FOREACH(old_desktop_caches, l, d)
     {
@@ -809,6 +828,13 @@ efreet_cache_desktop_free(Efreet_Desktop *desktop)
             break;
         }
     }
+
+    eina_list_free(desktop->only_show_in);
+    eina_list_free(desktop->not_show_in);
+    eina_list_free(desktop->categories);
+    eina_list_free(desktop->mime_types);
+    IF_FREE_HASH(desktop->x);
+    free(desktop);
 }
 
 void
@@ -1024,13 +1050,13 @@ cache_update_cb(void *data __UNUSED__, Ecore_File_Monitor *em __UNUSED__,
 
         d = NEW(Efreet_Old_Cache, 1);
         if (!d) goto error;
-        d->hash = efreet_desktop_cache;
+        d->hash = desktops;
         d->ef = desktop_cache;
         old_desktop_caches = eina_list_append(old_desktop_caches, d);
 
         efreet_cache_array_string_free(desktop_dirs);
         desktop_dirs = NULL;
-        efreet_desktop_cache = eina_hash_string_superfast_new(NULL);
+        desktops = eina_hash_string_superfast_new(NULL);
         desktop_cache = NULL;
 
         efreet_cache_array_string_free(util_cache_names);
@@ -1228,6 +1254,7 @@ desktop_cache_update_free(void *data, void *ev)
         it = eina_hash_iterator_tuple_new(d->hash);
         EINA_ITERATOR_FOREACH(it, tuple)
         {
+            if (tuple->data == NON_EXISTING) continue;
             printf("Efreet: %d:%s still in cache on cache close!\n",
                    ((Efreet_Desktop *)tuple->data)->ref, (char *)tuple->key);
             dangling++;
index a21b0c0..90a69f8 100644 (file)
@@ -41,12 +41,6 @@ int _efreet_desktop_log_dom = -1;
 #define DESKTOP_VERSION "1.0"
 
 /**
- * A cache of all loaded desktops, hashed by file name.
- * Values are Efreet_Desktop structures
- */
-Eina_Hash *efreet_desktop_cache = NULL;
-
-/**
  * The current desktop environment (e.g. "Enlightenment" or "Gnome")
  */
 static const char *desktop_environment = NULL;
@@ -132,7 +126,6 @@ efreet_desktop_init(void)
       }
 #endif
 
-    efreet_desktop_cache = eina_hash_string_superfast_new(NULL);
     efreet_desktop_types = NULL;
 
     EFREET_DESKTOP_TYPE_APPLICATION = efreet_desktop_type_add("Application",
@@ -160,7 +153,6 @@ efreet_desktop_shutdown(void)
     Efreet_Desktop_Type_Info *info;
 
     IF_RELEASE(desktop_environment);
-    IF_FREE_HASH(efreet_desktop_cache);
     EINA_LIST_FREE(efreet_desktop_types, info)
         efreet_desktop_type_info_free(info);
     IF_FREE_HASH(change_monitors);
@@ -174,50 +166,25 @@ efreet_desktop_shutdown(void)
 /**
  * @param file The file to get the Efreet_Desktop from
  * @return Returns a reference to a cached Efreet_Desktop on success, NULL
- * on failure. This reference should not be freed.
+ * on failure
  * @brief Gets a reference to an Efreet_Desktop structure representing the
  * contents of @a file or NULL if @a file is not a valid .desktop file.
  *
  * By using efreet_desktop_get the Efreet_Desktop will be saved in an internal
- * cache, and changes will be signalled by events.
- *
- * Efreet will also try to save all files fetched by efreet_desktop_get in a
- * cache to speed up further requests.
+ * cache for quicker loading.
  */
 EAPI Efreet_Desktop *
 efreet_desktop_get(const char *file)
 {
-    /* TODO: Check if we need to differentiate between desktop_new and desktop_get */
     Efreet_Desktop *desktop;
 
-    if (!file) return NULL;
-    if (efreet_desktop_cache)
-    {
-        char rp[PATH_MAX];
-
-        if (!realpath(file, rp)) return NULL;
-        desktop = eina_hash_find(efreet_desktop_cache, rp);
-        if (desktop)
-        {
-            if (efreet_desktop_cache_check(desktop))
-            {
-                desktop->ref++;
-                return desktop;
-            }
-
-            desktop->cached = 0;
-            eina_hash_del_by_key(efreet_desktop_cache, rp);
-        }
-    }
-
     desktop = efreet_desktop_new(file);
     if (!desktop) return NULL;
 
+    /* If we didn't find this file in the eet cache, add path to search path */
     if (!desktop->eet)
         efreet_cache_desktop_add(desktop);
 
-    if (efreet_desktop_cache) eina_hash_direct_add(efreet_desktop_cache, desktop->orig_path, desktop);
-    desktop->cached = 1;
     return desktop;
 }
 
@@ -256,14 +223,11 @@ efreet_desktop_empty_new(const char *file)
 }
 
 /**
- * @param file The file to create the Efreet_Desktop from
- * @return Returns a new Efreet_Desktop on success, NULL on failure
- * @brief Creates a new Efreet_Desktop structure initialized from the
- * contents of @a file or NULL on failure
- *
- * By using efreet_desktop_new the caller will get a unique copy of a
- * Efreet_Desktop. The Efreet_Desktop should immidiatly after use be free'd,
- * as there is no guarantee how long the pointers will be valid.
+ * @param file The file to get the Efreet_Desktop from
+ * @return Returns a reference to a cached Efreet_Desktop on success, NULL
+ * on failure
+ * @brief Gets a reference to an Efreet_Desktop structure representing the
+ * contents of @a file or NULL if @a file is not a valid .desktop file.
  */
 EAPI Efreet_Desktop *
 efreet_desktop_new(const char *file)
@@ -274,7 +238,8 @@ efreet_desktop_new(const char *file)
     desktop = efreet_cache_desktop_find(file);
     if (desktop)
     {
-        if (desktop->load_time == ecore_file_mod_time(desktop->orig_path))
+        desktop->ref++;
+        if (efreet_desktop_cache_check(desktop))
         {
             if (!efreet_desktop_environment_check(desktop))
             {
@@ -385,17 +350,17 @@ efreet_desktop_save(Efreet_Desktop *desktop)
  * @param file The filename to save as
  * @return Returns 1 on success or 0 on failure
  * @brief Saves @a desktop to @a file
+ *
+ * Please use efreet_desktop_uncached_new() on an existing file
+ * before using efreet_desktop_save_as()
  */
 EAPI int
 efreet_desktop_save_as(Efreet_Desktop *desktop, const char *file)
 {
-    if (desktop->cached && efreet_desktop_cache &&
-        desktop == eina_hash_find(efreet_desktop_cache, desktop->orig_path))
-    {
-        desktop->cached = 0;
-        eina_hash_del_by_key(efreet_desktop_cache, desktop->orig_path);
-    }
-    FREE(desktop->orig_path);
+    /* If we save data from eet as new, we will be in trouble */
+    if (desktop->eet) return 0;
+
+    IF_FREE(desktop->orig_path);
     desktop->orig_path = strdup(file);
     return efreet_desktop_save(desktop);
 }
@@ -413,23 +378,9 @@ efreet_desktop_free(Efreet_Desktop *desktop)
     desktop->ref--;
     if (desktop->ref > 0) return;
 
-    if (desktop->cached)
-    {
-       if (efreet_desktop_cache &&
-           desktop == eina_hash_find(efreet_desktop_cache, desktop->orig_path))
-       {
-           eina_hash_del_by_key(efreet_desktop_cache, desktop->orig_path);
-       }
-       efreet_cache_desktop_free(desktop);
-    }
-
     if (desktop->eet)
     {
-        eina_list_free(desktop->only_show_in);
-        eina_list_free(desktop->not_show_in);
-        eina_list_free(desktop->categories);
-        eina_list_free(desktop->mime_types);
-        IF_FREE_HASH(desktop->x);
+        efreet_cache_desktop_free(desktop);
     }
     else
     {
@@ -462,8 +413,8 @@ efreet_desktop_free(Efreet_Desktop *desktop)
             if (info->free_func)
                 info->free_func(desktop->type_data);
         }
+        free(desktop);
     }
-    FREE(desktop);
 }
 
 /**
index beb0f21..9d84c19 100644 (file)
@@ -91,7 +91,6 @@ struct _Efreet_Desktop
     unsigned char hidden;            /**< User delete the item */
     unsigned char terminal;          /**< Does the program run in a terminal */
     unsigned char startup_notify;    /**< The starup notify settings of the app */
-    unsigned char cached:1;          /**< The desktop file is cached by Efreet */
     unsigned char eet:1;             /**< The desktop file is in eet cache */
 
     Eina_Hash *x; /**< Keep track of all user extensions, keys that begin with X- */
index ff73e32..507fc6c 100644 (file)
     (x) = NULL; \
 } while (0)
 
+/**
+ * @def IF_FREE_HASH_CB(x, cb)
+ * If x is a valid pointer destroy x with cb and set to NULL
+ */
+#define IF_FREE_HASH_CB(x, cb) do { \
+    if (x) { \
+        Eina_Hash *__tmp; __tmp = (x); (x) = NULL; efreet_hash_free(__tmp, cb); \
+    } \
+    (x) = NULL; \
+} while (0)
+
 #ifdef EFREET_DEFAULT_LOG_COLOR
 #undef EFREET_DEFAULT_LOG_COLOR
 #endif
 #endif
 #define WRN(...) EINA_LOG_DOM_WARN(EFREET_MODULE_LOG_DOM, __VA_ARGS__)
 
-/* TODO: Move these to cache, make static and add accessor */
-extern Eina_Hash *efreet_desktop_cache;
-
 typedef struct _Efreet_Cache_Icon Efreet_Cache_Icon;
 typedef struct _Efreet_Cache_Icon_Element Efreet_Cache_Icon_Element;
 typedef struct _Efreet_Cache_Fallback_Icon Efreet_Cache_Fallback_Icon;