adium: 56178695: My patch #325 to pidgin-facebookchat whi...

evands at pidgin.im evands at pidgin.im
Mon Jan 26 09:40:28 EST 2009


-----------------------------------------------------------------
Revision: 561786951e7feff87a934b352a0b4a04fba4eaf3
Ancestor: 3ba017bd8b355f5076c570db7ade6c288e522514
Author: evands at pidgin.im
Date: 2009-01-26T14:32:53
Branch: im.pidgin.adium
URL: http://d.pidgin.im/viewmtn/revision/info/561786951e7feff87a934b352a0b4a04fba4eaf3

Modified files:
        libpurple/protocols/facebook/fb_messages.c
        libpurple/protocols/facebook/fb_messages.h
        libpurple/protocols/facebook/libfacebook.c
        libpurple/protocols/facebook/libfacebook.h

ChangeLog: 

My patch #325 to pidgin-facebookchat which fixes various safety issues related to callback timers firing after a disconnection

-------------- next part --------------
============================================================
--- libpurple/protocols/facebook/fb_messages.c	d18a9659bb3e848ef696e465875a0e13b110b4e5
+++ libpurple/protocols/facebook/fb_messages.c	63dd1c9053fb8cae9d8edd3f1f17d3292b8a47d2
@@ -30,11 +30,42 @@ struct _FacebookOutgoingMessage {
 	gchar *message;
 	gint msg_id;
 	guint retry_count;
+	guint resend_timer;
 };
 
 static gboolean fb_send_im_fom(FacebookOutgoingMessage *msg);
+static gboolean fb_resend_im_fom(FacebookOutgoingMessage *msg);
 static gboolean fb_get_new_messages(FacebookAccount *fba);
 
+static FacebookOutgoingMessage *fb_msg_create(FacebookAccount *fba)
+{
+	FacebookOutgoingMessage *msg;
+	
+	msg = g_new0(FacebookOutgoingMessage, 1);
+	msg->fba = fba;
+	
+	return msg;
+}
+
+static void fb_msg_destroy(FacebookOutgoingMessage *msg)
+{
+	if (msg->resend_timer) {
+		purple_timeout_remove(msg->resend_timer);
+	}
+	g_free(msg->who);
+	g_free(msg->message);
+	g_free(msg);	
+}
+
+void fb_cancel_resending_messages(FacebookAccount *fba)
+{
+	while (fba->resending_messages != NULL) {
+		FacebookOutgoingMessage *msg = fba->resending_messages->data;
+		fba->resending_messages = g_slist_remove(fba->resending_messages, msg);
+		fb_msg_destroy(msg);
+	}	
+}
+								  
 static void got_new_messages(FacebookAccount *fba, gchar *data,
 		gsize data_len, gpointer userdata)
 {
@@ -113,7 +144,8 @@ static void got_new_messages(FacebookAcc
 	/* refresh means that the session or post_form_id is invalid */
 	if (g_str_equal(data, "for (;;);{\"t\":\"refresh\"}"))
 	{
-		purple_timeout_add_seconds(1, (GSourceFunc)fb_get_post_form_id, fba);
+		if (fba->post_form_id_refresh_timer == 0)
+			fba->post_form_id_refresh_timer = purple_timeout_add_seconds(1, (GSourceFunc)fb_get_post_form_id, fba);
 		return;
 	}
 
@@ -401,7 +433,8 @@ static void fb_send_im_cb(FacebookAccoun
 				/* there was an error, either report it or retry */
 				if (msg->retry_count++ < FB_MAX_MSG_RETRY)
 				{
-					purple_timeout_add_seconds(1, (GSourceFunc)fb_send_im_fom, msg);
+					msg->resend_timer = purple_timeout_add_seconds(1, (GSourceFunc)fb_resend_im_fom, msg);
+					fba->resending_messages = g_slist_prepend(fba->resending_messages, msg);
 					g_free(error_summary);
 					return;
 				}
@@ -418,9 +451,7 @@ static void fb_send_im_cb(FacebookAccoun
 	}
 
 	g_free(error_summary);
-	g_free(msg->who);
-	g_free(msg->message);
-	g_free(msg);
+	fb_msg_destroy(msg);
 }
 
 static gboolean fb_send_im_fom(FacebookOutgoingMessage *msg)
@@ -441,19 +472,24 @@ static gboolean fb_send_im_fom(FacebookO
 	return FALSE;
 }
 
+static gboolean fb_resend_im_fom(FacebookOutgoingMessage *msg)
+{
+	msg->fba->resending_messages = g_slist_remove(msg->fba->resending_messages, msg);
+
+	return fb_send_im_fom(msg);
+}
+
 int fb_send_im(PurpleConnection *pc, const gchar *who, const gchar *message, PurpleMessageFlags flags)
 {
 	FacebookOutgoingMessage *msg;
 
-	msg = g_new0(FacebookOutgoingMessage, 1);
-	msg->fba = pc->proto_data;
+	msg = fb_msg_create(pc->proto_data);
 
 	/* convert html to plaintext, removing trailing spaces */
 	msg->message = purple_markup_strip_html(message);
 	if (strlen(msg->message) > 999)
 	{
-		g_free(msg->message);
-		g_free(msg);
+		fb_msg_destroy(msg);
 		return -E2BIG;
 	}
 
@@ -547,6 +583,7 @@ gboolean fb_get_post_form_id(FacebookAcc
 
 gboolean fb_get_post_form_id(FacebookAccount *fba)
 {
+	fba->post_form_id_refresh_timer = 0;
 	fb_post_or_get(fba, FB_METHOD_GET, NULL, "/home.php", NULL, got_form_id_page, NULL, FALSE);
 	return FALSE;
 }
============================================================
--- libpurple/protocols/facebook/fb_messages.h	44345656bb5ce15bc8a1a50d66aaa6ed88426dff
+++ libpurple/protocols/facebook/fb_messages.h	79be7f4f904b524f43c1c45564065564b4cc1e96
@@ -27,4 +27,6 @@ int fb_send_im(PurpleConnection *pc, con
 int fb_send_im(PurpleConnection *pc, const gchar *who, const gchar *message,
 		PurpleMessageFlags flags);
 
+void fb_cancel_resending_messages(FacebookAccount *fba);
+
 #endif /* FACEBOOK_MESSAGES_H */
============================================================
--- libpurple/protocols/facebook/libfacebook.c	6c9a0c0fd5e58fbcac93a6517a68d720bd5a9c83
+++ libpurple/protocols/facebook/libfacebook.c	f92cb984ed2d987621f48d5753f224ec7411097e
@@ -360,6 +360,9 @@ static void fb_close(PurpleConnection *p
 	if (fba->perpetual_messages_timer) {
 		purple_timeout_remove(fba->perpetual_messages_timer);
 	}
+	if (fba->post_form_id_refresh_timer) {
+		purple_timeout_remove(fba->post_form_id_refresh_timer);
+	}
 
 	purple_debug_info("facebook", "destroying %d incomplete connections\n",
 			g_slist_length(fba->conns));
@@ -374,6 +377,10 @@ static void fb_close(PurpleConnection *p
 		fba->dns_queries = g_slist_remove(fba->dns_queries, dns_query);
 		purple_dnsquery_destroy(dns_query);
 	}
+	
+	if (fba->resending_messages != NULL) {
+		fb_cancel_resending_messages(fba);
+	}
 
 	g_hash_table_destroy(fba->cookie_table);
 	g_hash_table_destroy(fba->hostname_ip_cache);
============================================================
--- libpurple/protocols/facebook/libfacebook.h	b1496fabcd8c5b8af7cc0f4405daaad3301657fb
+++ libpurple/protocols/facebook/libfacebook.h	e3cc22c0e4235b0ccd35bd750d5023af6a0ce0ef
@@ -90,6 +90,7 @@ struct _FacebookAccount {
 	GSList *dns_queries;
 	GHashTable *cookie_table;
 	gchar *post_form_id;
+	guint post_form_id_refresh_timer;
 	gint32 uid;
 	guint buddy_list_timer;
 	guint friend_request_timer;
@@ -97,6 +98,7 @@ struct _FacebookAccount {
 	guint message_fetch_sequence;
 	gint64 last_messages[FB_LAST_MESSAGE_MAX];
 	guint16 next_message_pointer;
+	GSList *resending_messages;
 	GSList *auth_buddies;
 	GHashTable *hostname_ip_cache;
 	guint notifications_timer;


More information about the Commits mailing list