aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCharles Kerr <charles.kerr@canonical.com>2012-03-17 11:04:31 -0500
committerCharles Kerr <charles.kerr@canonical.com>2012-03-17 11:04:31 -0500
commite80b857298bf76d44824d654901d83a5edc16ddc (patch)
tree4b73d295f8b748be850c8dbbe030f1f7d00c08f9 /src
parent8e26e844c5f42d55257b6f8e52634314d134b4d8 (diff)
downloadayatana-indicator-application-e80b857298bf76d44824d654901d83a5edc16ddc.tar.gz
ayatana-indicator-application-e80b857298bf76d44824d654901d83a5edc16ddc.tar.bz2
ayatana-indicator-application-e80b857298bf76d44824d654901d83a5edc16ddc.zip
Fix two memory bugs with clearing out out directories from our icon search path.
1. indicator_application_dispose() calls g_hash_table_get_keys() N times and leaks them all. 2. indicator_application_dispose() passes each of the hashtable's keys (owned by the hash) to function theme_dir_unref(key), which removes from the hashtable but then continues to use the now-dangling key.
Diffstat (limited to 'src')
-rw-r--r--src/indicator-application.c40
1 files changed, 21 insertions, 19 deletions
diff --git a/src/indicator-application.c b/src/indicator-application.c
index 2c4f232..a1f547e 100644
--- a/src/indicator-application.c
+++ b/src/indicator-application.c
@@ -122,6 +122,7 @@ static void get_applications (GObject * obj, GAsyncResult * res, gpointer user_d
static void get_applications_helper (IndicatorApplication * self, GVariant * variant);
static void theme_dir_unref(IndicatorApplication * ia, const gchar * dir);
static void theme_dir_ref(IndicatorApplication * ia, const gchar * dir);
+static void icon_theme_remove_dir_from_search_path (const char * dir);
static void service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data);
static void receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, GVariant * parameters, gpointer user_data);
@@ -207,9 +208,11 @@ indicator_application_dispose (GObject *object)
}
if (priv->theme_dirs != NULL) {
- while (g_hash_table_size(priv->theme_dirs)) {
- GList * keys = g_hash_table_get_keys(priv->theme_dirs);
- theme_dir_unref(INDICATOR_APPLICATION(object), (gchar *)keys->data);
+ gpointer directory;
+ GHashTableIter iter;
+ g_hash_table_iter_init (&iter, priv->theme_dirs);
+ while (g_hash_table_iter_next (&iter, &directory, NULL)) {
+ icon_theme_remove_dir_from_search_path (directory);
}
g_hash_table_destroy(priv->theme_dirs);
priv->theme_dirs = NULL;
@@ -951,24 +954,23 @@ theme_dir_unref(IndicatorApplication * ia, const gchar * dir)
{
IndicatorApplicationPrivate * priv = INDICATOR_APPLICATION_GET_PRIVATE(ia);
- /* Grab the count for this dir */
- int count = GPOINTER_TO_INT(g_hash_table_lookup(priv->theme_dirs, dir));
-
- /* Is this a simple deprecation, if so, we can just lower the
- number and move on. */
- if (count > 1) {
- count--;
- g_hash_table_insert(priv->theme_dirs, g_strdup(dir), GINT_TO_POINTER(count));
- return;
- }
-
- /* Try to remove it from the hash table, this makes sure
- that it existed */
- if (!g_hash_table_remove(priv->theme_dirs, dir)) {
- g_warning("Unref'd a directory that wasn't in the theme dir hash table.");
- return;
+ if (!g_hash_table_contains (priv->theme_dirs, dir)) {
+ g_warning("Unref'd a directory '%s' that wasn't in the theme dir hash table.", dir);
+ } else {
+ int count = GPOINTER_TO_INT(g_hash_table_lookup(priv->theme_dirs, dir));
+ if (count > 1) {
+ count--;
+ g_hash_table_insert(priv->theme_dirs, g_strdup(dir), GINT_TO_POINTER(count));
+ } else {
+ icon_theme_remove_dir_from_search_path (dir);
+ g_hash_table_remove (priv->theme_dirs, dir);
+ }
}
+}
+static void
+icon_theme_remove_dir_from_search_path (const char * dir)
+{
GtkIconTheme * icon_theme = gtk_icon_theme_get_default();
gchar ** paths;
gint path_count;