From 5e106f5cd6eb01bae5eb617e330a824b74dd3c72 Mon Sep 17 00:00:00 2001 From: Sebastian Dransfeld Date: Thu, 10 Feb 2011 14:25:44 +0000 Subject: [PATCH] Move desktop cache to efreet_cache.c SVN revision: 56912 --- legacy/efreet/ChangeLog | 2 + legacy/efreet/src/lib/efreet_cache.c | 45 ++++++++++--- legacy/efreet/src/lib/efreet_desktop.c | 87 ++++++-------------------- legacy/efreet/src/lib/efreet_desktop.h | 1 - legacy/efreet/src/lib/efreet_private.h | 14 ++++- 5 files changed, 68 insertions(+), 81 deletions(-) diff --git a/legacy/efreet/ChangeLog b/legacy/efreet/ChangeLog index 9246a08fc2..81862e060b 100644 --- a/legacy/efreet/ChangeLog +++ b/legacy/efreet/ChangeLog @@ -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 diff --git a/legacy/efreet/src/lib/efreet_cache.c b/legacy/efreet/src/lib/efreet_cache.c index aaaf12e4c5..7c152f28c4 100644 --- a/legacy/efreet/src/lib/efreet_cache.c +++ b/legacy/efreet/src/lib/efreet_cache.c @@ -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++; diff --git a/legacy/efreet/src/lib/efreet_desktop.c b/legacy/efreet/src/lib/efreet_desktop.c index a21b0c0762..90a69f8950 100644 --- a/legacy/efreet/src/lib/efreet_desktop.c +++ b/legacy/efreet/src/lib/efreet_desktop.c @@ -40,12 +40,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") */ @@ -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); } /** diff --git a/legacy/efreet/src/lib/efreet_desktop.h b/legacy/efreet/src/lib/efreet_desktop.h index beb0f21cec..9d84c19e33 100644 --- a/legacy/efreet/src/lib/efreet_desktop.h +++ b/legacy/efreet/src/lib/efreet_desktop.h @@ -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- */ diff --git a/legacy/efreet/src/lib/efreet_private.h b/legacy/efreet/src/lib/efreet_private.h index ff73e322cf..507fc6c477 100644 --- a/legacy/efreet/src/lib/efreet_private.h +++ b/legacy/efreet/src/lib/efreet_private.h @@ -61,6 +61,17 @@ (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 @@ -92,9 +103,6 @@ #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;