Plug mem leaks.

svn path=/trunk/; revision=4854
This commit is contained in:
Peter Williams
2000-08-16 18:33:20 +00:00
parent f0d329f083
commit aa670b3306
4 changed files with 182 additions and 32 deletions
+1
View File
@@ -126,6 +126,7 @@ camel_type_lock_down (void)
g_warning
("camel_type_lock_down: lock down before a lock up?");
type_system_locklevel = g_private_new (GINT_TO_POINTER (0));
G_UNLOCK (type_system_level);
return;
}
+4 -1
View File
@@ -1,7 +1,10 @@
2000-08-16 Peter Williams <peterw@helixcode.com>
* message-thread.c (walk_containers): More (default disabled)
mem debugging here.
mem debugging here. Fix the big leaks.
* mail-format.c (get_url_for_icon): Copy the url_path so that
it can't get freed under us.
2000-08-15 Peter Williams <peterw@helixcode.com>
+2 -1
View File
@@ -216,7 +216,8 @@ get_url_for_icon (const char *icon_name, MailDisplay *md)
}
close (fd);
g_hash_table_insert (icons, icon_path, ba);
/* FIXME: these aren't freed. */
g_hash_table_insert (icons, g_strdup (icon_path), ba);
}
g_free (icon_path);
+175 -30
View File
@@ -47,12 +47,18 @@ static GHashTable *allocedht = NULL;
#define EXISTS (1 << 0)
#define WALKED (1 << 1)
#define FREED (1 << 2)
#define AL_401 (1 << 3)
#define AL_541 (1 << 4)
#define AL_546 (1 << 5)
#define AL_569 (1 << 6)
#define LINKED (1 << 7)
#define EXCUSED (1 << 8)
#define GITP(x) GINT_TO_POINTER(x)
#define GPTI(x) GPOINTER_TO_INT(x)
static struct _container *
alloc_container (void)
alloc_container (int where)
{
struct _container *c;
@@ -61,17 +67,19 @@ alloc_container (void)
if (!allocedht)
allocedht = g_hash_table_new (g_direct_hash, g_direct_equal);
g_hash_table_insert (allocedht, c, GITP(EXISTS));
g_hash_table_insert (allocedht, c, GITP(EXISTS|where));
return c;
}
static void
free_container (struct _container **c)
{
gpointer flags;
memset ((*c), 0, sizeof (struct _container));
if (g_hash_table_lookup (allocedht, c) == NULL)
if ((flags = g_hash_table_lookup (allocedht, (*c))) == NULL)
printf ("** threading mem debug: freeing unalloced entry %p?\n", (*c));
g_hash_table_insert (allocedht, c, GITP(EXISTS|FREED));
g_hash_table_insert (allocedht, (*c), GITP(GPTI(flags)|FREED));
g_free ((*c));
(*c) = NULL;
}
@@ -80,21 +88,117 @@ static void
cont_print (gpointer key, gpointer value, gpointer user)
{
struct _container *c = (struct _container *) key;
char *line;
printf (" %p: %p %p %p %s %s %d %d : %s %s\n",
if (GPTI(value) & FREED)
return;
if (GPTI(value) & AL_401)
line = "401";
else if (GPTI(value) & AL_541)
line = "541";
else if (GPTI(value) & AL_546)
line = "546";
else if (GPTI(value) & AL_569)
line = "569";
else
line = "???";
printf (" %p : %s %s %s %s %s",
c,
c->next, c->parent, c->child,
c->message ? c->message->subject : "(null message)",
c->root_subject ? c->root_subject : "(null root-subject)",
c->re, c->order,
GPTI(value) & FREED ? "freed" : "unfrd",
GPTI(value) & WALKED ? "walked" : "unwlkd",
GPTI(value) & FREED ? "freed" : "unfrd");
line,
GPTI(value) & LINKED ? "linked" : "unlnkd",
GPTI(value) & EXCUSED ? "excused" : "unexcsd");
if ((GPTI(value) & FREED) == 0) {
gpointer oth_flags;
printf (" : %p %p %p : \"%s\" \"%s\" %d %d",
c->next, c->parent, c->child,
c->message ? c->message->subject : "(null message)",
c->root_subject ? c->root_subject : "(null root-subject)",
c->re, c->order);
if (c->next) {
oth_flags = g_hash_table_lookup (allocedht, c->next);
printf ("\n next : %p : %s %s %s",
c->next,
GPTI(oth_flags) & WALKED ? "walked" : "unwlkd",
GPTI(oth_flags) & LINKED ? "linked" : "unlnkd",
GPTI(oth_flags) & EXCUSED ? "excused" : "unexcsd");
}
if (c->parent) {
oth_flags = g_hash_table_lookup (allocedht, c->parent);
printf ("\n prnt : %p : %s %s %s",
c->parent,
GPTI(oth_flags) & WALKED ? "walked" : "unwlkd",
GPTI(oth_flags) & LINKED ? "linked" : "unlnkd",
GPTI(oth_flags) & EXCUSED ? "excused" : "unexcsd");
}
if (c->child) {
oth_flags = g_hash_table_lookup (allocedht, c->child);
printf ("\n chld : %p : %s %s %s",
c->child,
GPTI(oth_flags) & WALKED ? "walked" : "unwlkd",
GPTI(oth_flags) & LINKED ? "linked" : "unlnkd",
GPTI(oth_flags) & EXCUSED ? "excused" : "unexcsd");
}
}
printf ("\n");
}
static void
make_excuses (gpointer key, gpointer value, gpointer user)
{
struct _container *c;
gpointer chldflags;
gpointer nextflags;
if (GPTI(value) & FREED)
return;
c = (struct _container *) key;
if (c->next) {
nextflags = g_hash_table_lookup (allocedht, c->next);
if ((GPTI(nextflags) & EXCUSED) == 0) {
g_hash_table_insert (allocedht, c->next, GITP(GPTI(nextflags)|EXCUSED));
((gint *)user) = 1;
}
}
if (c->child) {
chldflags = g_hash_table_lookup (allocedht, c->child);
if ((GPTI(chldflags) & EXCUSED) == 0) {
g_hash_table_insert (allocedht, c->child, GITP(GPTI(chldflags)|EXCUSED));
((gint *)user) = 1;
}
}
}
static void
print_containers (void)
{
printf ("Containers currently unfreed:\n");
gint hit;
do {
hit = 0;
g_hash_table_foreach (allocedht, make_excuses, &hit);
} while (hit);
printf ("List of container stats:\n");
g_hash_table_foreach (allocedht, cont_print, NULL);
printf ("End of list.\n");
}
@@ -117,11 +221,22 @@ walk_containers (struct _container *head)
}
}
static void
link_container (struct _container *c)
{
gpointer flags;
if ((flags = g_hash_table_lookup (allocedht, c)) == NULL)
printf ("** threading mem debug: linking unalloced entry %p?\n", c);
g_hash_table_insert (allocedht, c, GITP(GPTI(flags)|LINKED));
}
#else
#define alloc_container() (g_new0 (struct _container, 1))
#define alloc_container(w) (g_new0 (struct _container, 1))
#define free_container(c) g_free (*(c))
#define print_containers()
#define walk_containers(c)
#define link_container(c)
#endif
/* **************************************** */
@@ -174,7 +289,7 @@ container_unparent_child(struct _container *child)
static void
container_parent_child(struct _container *parent, struct _container *child)
{
struct _container *c, *node;
struct _container *c, *node, **prev;
/* are we already the right parent? */
if (child->parent == parent)
@@ -186,19 +301,48 @@ container_parent_child(struct _container *parent, struct _container *child)
return;
}
/* else remove child from its existing parent, and reparent */
node = child->parent;
c = (struct _container *)&node->child;
d(printf("scanning children:\n"));
while (c->next) {
d(printf(" %p\n", c));
if (c->next==child) {
d(printf("found node %p\n", child));
c->next = c->next->next;
child->parent = NULL;
container_add_child(parent, child);
/* check for trying to make my child my parent */
for (c = parent; c; c = c->parent) {
if (c == child) {
d(printf("AIIE: trying to lop off hunk of nodes!\n"));
return;
}
}
/* else remove child from its existing parent, and reparent */
node = child->parent;
/* c = (struct _container *)&node->child;
*d(printf("scanning children:\n"));
*while (c->next) {
* d(printf(" %p\n", c));
* if (c->next==child) {
* d(printf("found node %p\n", child));
* c->next = c->next->next;
* child->parent = NULL;
* container_add_child(parent, child);
* return;
* }
* c = c->next;
*}
*/
d(printf("PKGW deparent child"));
c = node->child;
prev = &(node->child);
while (c) {
d(printf (" %p\n", c));
if (c == child) {
d(printf (" hit child %p\n", child));
(*prev) = c->next;
c->next = NULL;
c->parent = NULL;
container_add_child (parent, child);
return;
}
prev = &(c->next);
c = c->next;
}
@@ -221,6 +365,7 @@ prune_empty(struct _container **cp)
if (c->child == NULL) {
d(printf("removing empty node\n"));
lastc->next = c->next;
free_container (&c);
continue;
}
if (c->parent || c->child->next==0) {
@@ -236,6 +381,7 @@ prune_empty(struct _container **cp)
child = next;
}
free_container (&c);
continue;
}
}
@@ -253,6 +399,7 @@ hashloop(void *key, void *value, void *data)
if (c->parent == NULL) {
c->next = tail->next;
tail->next = c;
link_container(c);
}
}
@@ -386,7 +533,7 @@ group_root_set(struct _container **cp)
remove_node(cp, container, &clast);
remove_node(cp, c, &clast);
scan = alloc_container();
scan = alloc_container(AL_401);
scan->root_subject = c->root_subject;
scan->re = c->re && container->re;
scan->next = c->next;
@@ -431,8 +578,6 @@ static void thread_messages_free(struct _container *c)
{
struct _container *n;
return;
/* FIXME: ok, for some reason this doesn't work .. investigate later ... */
while (c) {
@@ -528,12 +673,12 @@ thread_messages(CamelFolder *folder, GPtrArray *uids)
d(printf("doing : %s\n", mi->message_id));
c = g_hash_table_lookup(id_table, mi->message_id);
if (!c) {
c = alloc_container();
c = alloc_container(AL_541);
g_hash_table_insert(id_table, mi->message_id, c);
}
} else {
d(printf("doing : (no message id)\n"));
c = alloc_container();
c = alloc_container(AL_546);
g_hash_table_insert(no_id_table, (void *)mi, c);
}
@@ -556,7 +701,7 @@ thread_messages(CamelFolder *folder, GPtrArray *uids)
c = g_hash_table_lookup(id_table, ref->id);
if (c == NULL) {
d(printf("not found\n"));
c = alloc_container();
c = alloc_container(AL_569);
g_hash_table_insert(id_table, ref->id, c);
}
if (c!=child)