all repos — tint2 @ 50e6278327561fb4f3d739ed086d5dbd8db45b7c

fork of the tint2 desktop panel for my custom setup - only minimized windows across all desktops for the taskbar

Move icon cache to a separate file; protect cache with file locks
o9000 mrovi9000@gmail.com
commit

50e6278327561fb4f3d739ed086d5dbd8db45b7c

parent

4dfe411bf423ba333517a850548ba01ecac2d617

M CMakeLists.txtCMakeLists.txt

@@ -85,7 +85,7 @@ src/taskbar

src/launcher src/tooltip src/util - src/execplugin + src/execplugin src/freespace ${X11_INCLUDE_DIRS} ${PANGOCAIRO_INCLUDE_DIRS}

@@ -112,12 +112,13 @@ src/taskbar/task.c

src/taskbar/taskbar.c src/taskbar/taskbarname.c src/tooltip/tooltip.c - src/execplugin/execplugin.c + src/execplugin/execplugin.c src/freespace/freespace.c src/util/area.c src/util/common.c src/util/strnatcmp.c src/util/timer.c + src/util/cache.c src/util/window.c ) if( ENABLE_BATTERY )
M src/launcher/icon-theme-common.csrc/launcher/icon-theme-common.c

@@ -27,6 +27,7 @@ #include <string.h>

#include "apps-common.h" #include "common.h" +#include "cache.h" #define ICON_DIR_TYPE_SCALABLE 0 #define ICON_DIR_TYPE_FIXED 1

@@ -317,7 +318,7 @@ free(theme);

} g_slist_free(wrapper->themes_fallback); g_slist_free_full(wrapper->_queued, free); - g_hash_table_destroy(wrapper->_cache); + free_cache(&wrapper->_cache); free(wrapper); }

@@ -452,72 +453,9 @@ {

return g_build_filename(g_get_user_cache_dir(), "tint2", "icon.cache", NULL); } -void load_cache(GHashTable **cache, gchar *cache_path) -{ - *cache = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); - - FILE *f = fopen(cache_path, "rt"); - if (!f) - return; - - char *line = NULL; - size_t line_size; - - while (getline(&line, &line_size, f) >= 0) { - char *key, *value; - - size_t line_len = strlen(line); - gboolean has_newline = FALSE; - if (line_len >= 1) { - if (line[line_len - 1] == '\n') { - line[line_len - 1] = '\0'; - line_len--; - has_newline = TRUE; - } - } - if (!has_newline) - break; - - if (line_len == 0) - continue; - - if (parse_theme_line(line, &key, &value)) { - g_hash_table_insert(*cache, g_strdup(key), g_strdup(value)); - } - } - free(line); - fclose(f); -} - -void write_cache_line(gpointer key, gpointer value, gpointer user_data) -{ - gchar *k = key; - gchar *v = value; - FILE *f = user_data; - - fprintf(f, "%s=%s\n", k, v); -} - -void save_cache(GHashTable *cache, gchar *cache_path) -{ - FILE *f = fopen(cache_path, "w"); - if (!f) { - gchar *dir_path = g_path_get_dirname(cache_path); - g_mkdir_with_parents(dir_path, 0700); - g_free(dir_path); - f = fopen(cache_path, "w"); - if (!f) { - fprintf(stderr, RED "Could not save icon theme cache!" RESET "\n"); - return; - } - } - g_hash_table_foreach(cache, write_cache_line, f); - fclose(f); -} - void load_icon_cache(IconThemeWrapper *wrapper) { - if (wrapper->_cache) + if (wrapper->_cache.loaded) return; fprintf(stderr, GREEN "Loading icon theme cache..." RESET "\n");

@@ -529,12 +467,12 @@ }

void save_icon_cache(IconThemeWrapper *wrapper) { - if (!wrapper || !wrapper->_cache || !wrapper->_cache_dirty) + if (!wrapper || !wrapper->_cache.dirty) return; fprintf(stderr, GREEN "Saving icon theme cache..." RESET "\n"); gchar *cache_path = get_icon_cache_path(); - save_cache(wrapper->_cache, cache_path); + save_cache(&wrapper->_cache, cache_path); g_free(cache_path); }

@@ -761,8 +699,9 @@

load_icon_cache(wrapper); gchar *key = g_strdup_printf("%s\t%s\t%d", wrapper->icon_theme_name, icon_name, size); - gchar *value = g_hash_table_lookup(wrapper->_cache, key); + const gchar *value = get_from_cache(&wrapper->_cache, key); g_free(key); + if (!value) { fprintf(stderr, YELLOW "Icon path not found in cache: theme = %s, icon = %s, size = %d" RESET "\n",

@@ -787,13 +726,8 @@

load_icon_cache(wrapper); gchar *key = g_strdup_printf("%s\t%s\t%d", wrapper->icon_theme_name, icon_name, size); - gchar *value = g_hash_table_lookup(wrapper->_cache, key); - if (value && g_str_equal(value, path)) { - g_free(key); - return; - } - g_hash_table_insert(wrapper->_cache, key, g_strdup(path)); - wrapper->_cache_dirty = TRUE; + add_to_cache(&wrapper->_cache, key, path); + g_free(key); } char *get_icon_path(IconThemeWrapper *wrapper, const char *icon_name, int size)
M src/launcher/icon-theme-common.hsrc/launcher/icon-theme-common.h

@@ -7,6 +7,7 @@ #ifndef ICON_THEME_COMMON_H

#define ICON_THEME_COMMON_H #include <glib.h> +#include "cache.h" typedef struct IconThemeWrapper { // The icon theme name for which this wrapper was created

@@ -19,8 +20,7 @@ // List of IconTheme*

GSList *themes_fallback; // Fallback themes are loaded lazily when needed. gboolean _fallback_loaded; - GHashTable *_cache; - gboolean _cache_dirty; + Cache _cache; // List of icon theme names that have been queued for loading. // Used to avoid loading the same theme twice, and to avoid cycles. GSList *_queued;
M src/tint2conf/CMakeLists.txtsrc/tint2conf/CMakeLists.txt

@@ -20,8 +20,9 @@ ${GTK2_INCLUDE_DIRS}

${RSVG_INCLUDE_DIRS} ) set(SOURCES ../util/common.c - ../util/strnatcmp.c - ../config.c + ../util/strnatcmp.c + ../util/cache.c + ../config.c ../server.c ../launcher/apps-common.c ../launcher/icon-theme-common.c
A src/util/cache.c

@@ -0,0 +1,156 @@

+/************************************************************************** +* +* Tint2 : cache +* +* Copyright (C) 2016 @o9000 +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License version 2 +* as published by the Free Software Foundation. +* +* This program 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 General Public License for more details. +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +**************************************************************************/ + +#include "cache.h" + +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/file.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +#include "common.h" + +void init_cache(Cache *cache) +{ + if (cache->_table) + free_cache(cache); + cache->_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + cache->dirty = FALSE; + cache->loaded = FALSE; +} + +void free_cache(Cache *cache) +{ + if (cache->_table) + g_hash_table_destroy(cache->_table); + cache->_table = NULL; + cache->dirty = FALSE; + cache->loaded = FALSE; +} + +void load_cache(Cache *cache, const gchar *cache_path) +{ + init_cache(cache); + + int fd = open(cache_path, O_RDONLY); + if (fd == -1) + return; + flock(fd, LOCK_SH); + + FILE *f = fopen(cache_path, "rt"); + if (!f) + goto unlock; + + char *line = NULL; + size_t line_size; + + while (getline(&line, &line_size, f) >= 0) { + char *key, *value; + + size_t line_len = strlen(line); + gboolean has_newline = FALSE; + if (line_len >= 1) { + if (line[line_len - 1] == '\n') { + line[line_len - 1] = '\0'; + line_len--; + has_newline = TRUE; + } + } + if (!has_newline) + break; + + if (line_len == 0) + continue; + + if (parse_line(line, &key, &value)) { + g_hash_table_insert(cache->_table, g_strdup(key), g_strdup(value)); + } + } + free(line); + fclose(f); + + cache->loaded = TRUE; + +unlock: + flock(fd, LOCK_UN); + close(fd); +} + +void write_cache_line(gpointer key, gpointer value, gpointer user_data) +{ + gchar *k = key; + gchar *v = value; + FILE *f = user_data; + + fprintf(f, "%s=%s\n", k, v); +} + +void save_cache(Cache *cache, const gchar *cache_path) +{ + int fd = open(cache_path, O_RDONLY | O_CREAT); + if (fd == -1) + return; + flock(fd, LOCK_EX); + + FILE *f = fopen(cache_path, "w"); + if (!f) { + gchar *dir_path = g_path_get_dirname(cache_path); + g_mkdir_with_parents(dir_path, 0700); + g_free(dir_path); + f = fopen(cache_path, "w"); + if (!f) { + fprintf(stderr, RED "Could not save icon theme cache!" RESET "\n"); + goto unlock; + } + } + g_hash_table_foreach(cache->_table, write_cache_line, f); + fclose(f); + cache->dirty = FALSE; + +unlock: + flock(fd, LOCK_UN); + close(fd); +} + +const gchar *get_from_cache(Cache *cache, const gchar *key) +{ + if (!cache->_table) + return NULL; + return g_hash_table_lookup(cache->_table, key); +} + +void add_to_cache(Cache *cache, const gchar *key, const gchar *value) +{ + if (!cache->_table) + init_cache(cache); + + if (!key || !value) + return; + + gchar *old_value = g_hash_table_lookup(cache->_table, key); + if (old_value && g_str_equal(old_value, value)) + return; + + g_hash_table_insert(cache->_table, g_strdup(key), g_strdup(value)); + cache->dirty = TRUE; +}
A src/util/cache.h

@@ -0,0 +1,39 @@

+#ifndef CACHE_H +#define CACHE_H + +#include <glib.h> + +// A cache with string keys and values, backed by a file. +// The strings must not be NULL and are stripped of any whitespace at start and end. +typedef struct Cache { + gboolean dirty; + gboolean loaded; + GHashTable *_table; +} Cache; + +// Initializes the cache. You can also call load_cache directly if you set the memory contents to zero first. +void init_cache(Cache *cache); + +// Clears the cache contents and releases all memory, but not the object. +// You can use init_cache or load_cache afterwards. +void free_cache(Cache *cache); + +// Clears the cache contents and loads new contents from a file. +// Sets the loaded flag to TRUE. +void load_cache(Cache *cache, const gchar *cache_path); + +// Saves the cache contents to a file. +// Clears the dirty flag. +void save_cache(Cache *cache, const gchar *cache_path); + +// Returns a pointer to the value in the cache, or NULL if not found. +// Do not free the returned value! +const gchar *get_from_cache(Cache *cache, const gchar *key); + +// Adds a key-value pair to the cache. NULL keys or values are not allowed. +// If the key already exists, the old value is and replaced with the new value. +// Does not take ownership of the pointers (neither key, nor value); instead it makes copies. +// Sets the dirty flag to TRUE. +void add_to_cache(Cache *cache, const gchar *key, const gchar *value); + +#endif
M tint2.filestint2.files

@@ -177,3 +177,5 @@ tint2.files

tint2.includes tint2.svg src/tint2conf/po/ru.po +src/util/cache.c +src/util/cache.h