aboutsummaryrefslogtreecommitdiffstats
path: root/mail/message-thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'mail/message-thread.c')
-rw-r--r--mail/message-thread.c20
1 files changed, 19 insertions, 1 deletions
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) {