# HG changeset patch # User Evan Schoenberg # Date 1168289827 0 # Node ID b6f192c01225069d16a8d2dde3bfdf7e2dd0252e # Parent a2a0c0a13a754272c6bc8fd09029c5a13819238d [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 diff -r a2a0c0a13a75 -r b6f192c01225 libgaim/protocols/jabber/buddy.c --- 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); } diff -r a2a0c0a13a75 -r b6f192c01225 libgaim/protocols/jabber/buddy.h --- 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_ */ diff -r a2a0c0a13a75 -r b6f192c01225 libgaim/protocols/jabber/jabber.c --- 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) diff -r a2a0c0a13a75 -r b6f192c01225 libgaim/protocols/jabber/jabber.h --- 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;