changeset 15302:b6f192c01225

[gaim-migrate @ 18092] When a Jabber account disconnects, remove the timeouts associated with buddy info requests which are still pending. This fixes sf.net bug 1570738, a crash with a stack trace like: Thread 0 Crashed: 0 Libgaim 0x0651ee20 g_hash_table_remove 64 (http.c:525) 1 Libgaim 0x06437598 jabber_buddy_get_info_timeout 52 (buddy.c:1075) 2 com.adiumX.AdiumLibgaim 0x03593b0c callTimerFunc 48 (icplusplus.c:28) committer: Tailor Script <tailor@pidgin.im>
author Evan Schoenberg <evan.s@dreskin.net>
date Mon, 08 Jan 2007 20:57:07 +0000
parents a2a0c0a13a75
children 70ffa34b4143
files libgaim/protocols/jabber/buddy.c libgaim/protocols/jabber/buddy.h libgaim/protocols/jabber/jabber.c libgaim/protocols/jabber/jabber.h
diffstat 4 files changed, 44 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/libgaim/protocols/jabber/buddy.c	Mon Jan 08 20:54:54 2007 +0000
+++ b/libgaim/protocols/jabber/buddy.c	Mon Jan 08 20:57:07 2007 +0000
@@ -597,6 +597,18 @@
  * end of that ancient crap that needs to die
  ******/
 
+static void jabber_buddy_info_destroy(JabberBuddyInfo *jbi)
+{
+	/* Remove the timeout, which would otherwise trigger jabber_buddy_get_info_timeout() */
+	if (jbi->timeout_handle > 0)
+		gaim_timeout_remove(jbi->timeout_handle);
+	
+	g_free(jbi->jid);
+	g_hash_table_destroy(jbi->resources);
+	g_free(jbi->vcard_text);
+	g_free(jbi);	
+}
+
 static void jabber_buddy_info_show_if_ready(JabberBuddyInfo *jbi)
 {
 	char *resource_name, *tmp;
@@ -702,13 +714,9 @@
 		jbi->vcard_imgids = g_slist_delete_link(jbi->vcard_imgids, jbi->vcard_imgids);
 	}
 
-	if (jbi->timeout_handle > 0)
-		gaim_timeout_remove(jbi->timeout_handle);
+	jbi->js->pending_buddy_info_requests = g_slist_remove(jbi->js->pending_buddy_info_requests, jbi);
 
-	g_free(jbi->jid);
-	g_hash_table_destroy(jbi->resources);
-	g_free(jbi->vcard_text);
-	g_free(jbi);
+	jabber_buddy_info_destroy(jbi);
 }
 
 static void jabber_buddy_info_remove_id(JabberBuddyInfo *jbi, const char *id)
@@ -1068,6 +1076,26 @@
 	jabber_buddy_info_show_if_ready(jbi);
 }
 
+void jabber_buddy_remove_all_pending_buddy_info_requests(JabberStream *js)
+{
+	if (js->pending_buddy_info_requests)
+	{
+		JabberBuddyInfo *jbi;
+		GSList *l = js->pending_buddy_info_requests;
+		while (l) {
+			jbi = l->data;
+
+			g_slist_free(jbi->ids);
+			jabber_buddy_info_destroy(jbi);
+
+			l = l->next;			
+		}
+
+		g_slist_free(js->pending_buddy_info_requests);
+		js->pending_buddy_info_requests = NULL;
+	}
+}
+
 static gboolean jabber_buddy_get_info_timeout(gpointer data)
 {
 	JabberBuddyInfo *jbi = data;
@@ -1076,10 +1104,11 @@
 	while(jbi->ids) {
 		char *id = jbi->ids->data;
 		jabber_iq_remove_callback_by_id(jbi->js, id);
+		jbi->ids = g_slist_remove(jbi->ids, id);
 		g_free(id);
-		jbi->ids = g_slist_remove(jbi->ids, id);
 	}
 
+	jbi->js->pending_buddy_info_requests = g_slist_remove(jbi->js->pending_buddy_info_requests, jbi);
 	jbi->timeout_handle = 0;
 
 	jabber_buddy_info_show_if_ready(jbi);
@@ -1153,6 +1182,7 @@
 		g_free(full_jid);
 	}
 
+	js->pending_buddy_info_requests = g_slist_prepend(js->pending_buddy_info_requests, jbi);
 	jbi->timeout_handle = gaim_timeout_add(30000, jabber_buddy_get_info_timeout, jbi);
 }
 
--- a/libgaim/protocols/jabber/buddy.h	Mon Jan 08 20:54:54 2007 +0000
+++ b/libgaim/protocols/jabber/buddy.h	Mon Jan 08 20:57:07 2007 +0000
@@ -101,4 +101,6 @@
 
 void jabber_user_search_begin(GaimPluginAction *);
 
+void jabber_buddy_remove_all_pending_buddy_info_requests(JabberStream *js);
+
 #endif /* _GAIM_JABBER_BUDDY_H_ */
--- a/libgaim/protocols/jabber/jabber.c	Mon Jan 08 20:54:54 2007 +0000
+++ b/libgaim/protocols/jabber/jabber.c	Mon Jan 08 20:57:07 2007 +0000
@@ -965,6 +965,9 @@
 			gaim_input_remove(js->gc->inpa);
 		close(js->fd);
 	}
+
+	jabber_buddy_remove_all_pending_buddy_info_requests(js);
+
 	if(js->iq_callbacks)
 		g_hash_table_destroy(js->iq_callbacks);
 	if(js->disco_callbacks)
--- a/libgaim/protocols/jabber/jabber.h	Mon Jan 08 20:54:54 2007 +0000
+++ b/libgaim/protocols/jabber/jabber.h	Mon Jan 08 20:57:07 2007 +0000
@@ -122,6 +122,8 @@
 	char *avatar_hash;
 	GSList *pending_avatar_requests;
 
+	GSList *pending_buddy_info_requests;
+		
 	GaimCircBuffer *write_buffer;
 	guint writeh;