From 38ce412a5d4ff25b484f6a92dbfb0711322b6321 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Thu, 22 Aug 2002 20:49:07 +0000 Subject: [PATCH] /RELOADing broken theme file doesn't crash irssi anymore. git-svn-id: http://svn.irssi.org/repos/irssi/trunk@2880 dbcabf3a-b0e7-0310-adc4-f8d773084564 --- src/fe-common/core/themes.c | 42 ++++++++++++++++++++++++++++++------- src/fe-common/core/themes.h | 2 ++ 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/fe-common/core/themes.c b/src/fe-common/core/themes.c index ec4a994a..d9aac5e2 100644 --- a/src/fe-common/core/themes.c +++ b/src/fe-common/core/themes.c @@ -50,6 +50,7 @@ THEME_REC *theme_create(const char *path, const char *name) g_return_val_if_fail(name != NULL, NULL); rec = g_new0(THEME_REC, 1); + rec->refcount = 1; rec->path = g_strdup(path); rec->name = g_strdup(name); rec->abstracts = g_hash_table_new((GHashFunc) g_str_hash, @@ -83,12 +84,8 @@ static void theme_module_destroy(const char *key, MODULE_THEME_REC *rec) g_free(rec); } -void theme_destroy(THEME_REC *rec) +static void theme_real_destroy(THEME_REC *rec) { - themes = g_slist_remove(themes, rec); - - signal_emit("theme destroyed", 1, rec); - g_hash_table_foreach(rec->abstracts, (GHFunc) theme_abstract_destroy, NULL); g_hash_table_destroy(rec->abstracts); g_hash_table_foreach(rec->modules, (GHFunc) theme_module_destroy, NULL); @@ -102,6 +99,20 @@ void theme_destroy(THEME_REC *rec) g_free(rec); } +static void theme_unref(THEME_REC *rec) +{ + if (--rec->refcount == 0) + theme_real_destroy(rec); +} + +void theme_destroy(THEME_REC *rec) +{ + themes = g_slist_remove(themes, rec); + signal_emit("theme destroyed", 1, rec); + + theme_unref(rec); +} + static char *theme_replace_expand(THEME_REC *theme, int index, char default_fg, char default_bg, char *last_fg, char *last_bg, @@ -1207,10 +1218,20 @@ static void read_settings(void) static void themes_read(void) { + GSList *refs; char *fname; - while (themes != NULL) - theme_destroy(themes->data); + /* increase every theme's refcount, and destroy them. this way if + we want to use the theme before it's reloaded we don't crash. */ + refs = NULL; + while (themes != NULL) { + THEME_REC *theme = themes->data; + + refs = g_slist_prepend(refs, theme); + + theme->refcount++; + theme_destroy(theme); + } /* first there's default theme.. */ current_theme = theme_load("default"); @@ -1223,7 +1244,12 @@ static void themes_read(void) } window_themes_update(); - change_theme(settings_get_str("theme"), FALSE); + change_theme(settings_get_str("theme"), FALSE); + + while (refs != NULL) { + theme_unref(refs->data); + refs = g_slist_remove(refs, refs->data); + } } void themes_init(void) diff --git a/src/fe-common/core/themes.h b/src/fe-common/core/themes.h index 3ef7cb92..0a809b95 100644 --- a/src/fe-common/core/themes.h +++ b/src/fe-common/core/themes.h @@ -11,6 +11,8 @@ typedef struct { } MODULE_THEME_REC; typedef struct { + int refcount; + char *path; char *name; time_t last_modify;