From dcc47cc15f6ff1e1cb866495625006e5481f85a6 Mon Sep 17 00:00:00 2001 From: Peter Williams Date: Tue, 22 Aug 2000 15:40:23 +0000 Subject: Fix an infinite loop in the message threading with empty containers. svn path=/trunk/; revision=4964 --- mail/ChangeLog | 7 +++++++ mail/message-thread.c | 20 +++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/mail/ChangeLog b/mail/ChangeLog index e05e83f780..ff02ff09cd 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,10 @@ +2000-08-22 Peter Williams + + * message-thread.c (free_container): Extra debug print. + (remove_node): Handle the case of empty containers holding the child + that we're interested in. + (thread_messages_free): Extra debug print. + 2000-08-20 Jeremy Wise * folder-browser.c: (fb_resize_cb) Added function to monitor resize of the e_paned in the main view. diff --git a/mail/message-thread.c b/mail/message-thread.c index c8ed152e71..05cd4d43c4 100644 --- a/mail/message-thread.c +++ b/mail/message-thread.c @@ -79,6 +79,7 @@ free_container (struct _container **c) memset ((*c), 0, sizeof (struct _container)); if ((flags = g_hash_table_lookup (allocedht, (*c))) == NULL) printf ("** threading mem debug: freeing unalloced entry %p?\n", (*c)); + d(printf("** Freeing container %p\n", (*c))); g_hash_table_insert (allocedht, (*c), GITP(GPTI(flags)|FREED)); g_free ((*c)); (*c) = NULL; @@ -458,13 +459,29 @@ remove_node(struct _container **list, struct _container *node, struct _container /* this is intentional, even if it looks funny */ c = (struct _container *)list; while (c->next) { + /* we do this to catch cases where the container in the + * subject table is not toplevel. */ + if (c->next->message == NULL) { + /* yeah, this pointer casting trick is evil */ + c = (struct _container *) &(c->next->child); + } + if (c->next == node) { if (clast && *clast == c->next) *clast = c; c->next = c->next->next; break; } - c = c->next; + + /* this could theoretically cause a problem when c = &(head) + * and c->next->next == NULL, because then c->parent wouldn't be + * valid. But that would only happen in a one-message mailbox, + * in which case remove_node() wouldn't be called anyway. + */ + if (c->next->next == NULL && c->parent) + c = c->parent->next; + else + c = c->next; } } @@ -578,6 +595,7 @@ static void thread_messages_free(struct _container *c) { struct _container *n; + d(printf("** thread_messages_free: %p\n", c)); /* FIXME: ok, for some reason this doesn't work .. investigate later ... */ while (c) { -- cgit v1.2.3