Mercurial > hg
changeset 2225:dc3b3ac1ba76
Free the buffdata structures when buffers are closed
Free the buffdata strcutures when buffers are closed and there are no
more users (these structures can be shared if the "symlink" shared history
is used).
author | Mikael Berthe <mikael@lilotux.net> |
---|---|
date | Sat, 07 Nov 2015 12:21:12 +0100 |
parents | 736f9323d701 |
children | c1eb68306520 |
files | mcabber/mcabber/screen.c |
diffstat | 1 files changed, 42 insertions(+), 27 deletions(-) [+] |
line wrap: on
line diff
--- a/mcabber/mcabber/screen.c Sat Nov 07 12:16:15 2015 +0100 +++ b/mcabber/mcabber/screen.c Sat Nov 07 12:21:12 2015 +0100 @@ -100,10 +100,12 @@ static GHashTable *winbufhash; typedef struct { - GList *hbuf; - GList *top; // If top is NULL, we'll display the last lines - char cleared; // For ex, user has issued a /clear command... - char lock; + GList *hbuf; + GList *top; // If top is NULL, we'll display the last lines + char cleared; // For ex, user has issued a /clear command... + char lock; + char refcount; // refcount > 0 if there are other users of this struct + // e.g. with symlinked history } buffdata; typedef struct { @@ -1038,6 +1040,7 @@ static winbuf *scr_new_buddy(const char *title, int dont_show) { winbuf *tmp; + char *id; tmp = g_new0(winbuf, 1); @@ -1055,30 +1058,34 @@ update_panels(); // If title is NULL, this is a special buffer - if (title) { - char *id; - id = hlog_get_log_jid(title); - if (id) { - winbuf *wb = scr_search_window(id, FALSE); - if (!wb) - wb = scr_new_buddy(id, TRUE); - tmp->bd=wb->bd; - g_free(id); - } else { // Load buddy history from file (if enabled) - tmp->bd = g_new0(buffdata, 1); - hlog_read_history(title, &tmp->bd->hbuf, - maxX - Roster_Width - scr_getprefixwidth()); - - // Set a readmark to separate new content - hbuf_set_readmark(tmp->bd->hbuf, TRUE); - } - - id = g_strdup(title); - mc_strtolower(id); - g_hash_table_insert(winbufhash, id, tmp); - } else { + if (!title) { tmp->bd = g_new0(buffdata, 1); + return tmp; } + + id = hlog_get_log_jid(title); + if (id) { + // This is a symlinked history log file. + // Let's check if the target JID buffer has already been created. + winbuf *wb = scr_search_window(id, FALSE); + if (!wb) + wb = scr_new_buddy(id, TRUE); + tmp->bd = wb->bd; + tmp->bd->refcount++; + g_free(id); + } else { // Load buddy history from file (if enabled) + tmp->bd = g_new0(buffdata, 1); + hlog_read_history(title, &tmp->bd->hbuf, + maxX - Roster_Width - scr_getprefixwidth()); + + // Set a readmark to separate new content + hbuf_set_readmark(tmp->bd->hbuf, TRUE); + } + + id = g_strdup(title); + mc_strtolower(id); + g_hash_table_insert(winbufhash, id, tmp); + return tmp; } @@ -2867,7 +2874,9 @@ gboolean retval = FALSE; // Delete the current hbuf - hbuf_free(&win_entry->bd->hbuf); + // unless we close the buffer *and* this is a shared bd structure + if (!(*p_closebuf && win_entry->bd->refcount)) + hbuf_free(&win_entry->bd->hbuf); if (*p_closebuf) { GSList *roster_elt; @@ -2876,6 +2885,12 @@ ROSTER_TYPE_USER|ROSTER_TYPE_AGENT); if (roster_elt) buddy_setactiveresource(roster_elt->data, NULL); + if (win_entry->bd->refcount) { + win_entry->bd->refcount--; + } else { + g_free(win_entry->bd); + win_entry->bd = NULL; + } } else { win_entry->bd->cleared = FALSE; win_entry->bd->top = NULL;