]> www.infradead.org Git - pidgin-chime.git/commitdiff
Cancel conversation list update properly on connection close
authorDavid Woodhouse <dwmw@amazon.co.uk>
Thu, 5 Apr 2018 11:18:38 +0000 (12:18 +0100)
committerDavid Woodhouse <dwmw@amazon.co.uk>
Thu, 5 Apr 2018 11:18:38 +0000 (12:18 +0100)
There was race condition with close, and if an update was pending there
was a use-after-free of the connection object. Fix that the same way as
we do for the joinable meetings dialog.

chime.c
chime.h
conversations.c

diff --git a/chime.c b/chime.c
index 9d87df7e3c493da3e63f969868ebee4fda99dedc..3f40fa26cc0f8126dcd8ce8967001b6ddb19403e 100644 (file)
--- a/chime.c
+++ b/chime.c
@@ -198,7 +198,7 @@ static void chime_purple_login(PurpleAccount *account)
        struct purple_chime *pc = g_new0(struct purple_chime, 1);
        purple_connection_set_protocol_data(conn, pc);
        purple_chime_init_meetings(conn);
-       purple_chime_init_conversations(pc);
+       purple_chime_init_conversations(conn);
        purple_chime_init_chats(pc);
        purple_chime_init_messages(conn);
 
@@ -242,7 +242,7 @@ static void chime_purple_close(PurpleConnection *conn)
 
        purple_chime_destroy_meetings(conn);
        purple_chime_destroy_messages(conn);
-       purple_chime_destroy_conversations(pc);
+       purple_chime_destroy_conversations(conn);
        purple_chime_destroy_chats(pc);
 
        chime_connection_disconnect(pc->cxn);
diff --git a/chime.h b/chime.h
index e6a4bcc2e7d5da7031bdd646e3274060bf015068..38f9710cceced51155b770372a1a58329b57f8c0 100644 (file)
--- a/chime.h
+++ b/chime.h
@@ -101,8 +101,8 @@ char *chime_purple_get_cb_alias(PurpleConnection *conn, int id, const gchar *who
 
 /* conversations.c */
 void on_chime_new_conversation(ChimeConnection *cxn, ChimeConversation *conv, PurpleConnection *conn);
-void purple_chime_init_conversations(struct purple_chime *pc);
-void purple_chime_destroy_conversations(struct purple_chime *pc);
+void purple_chime_init_conversations(PurpleConnection *conn);
+void purple_chime_destroy_conversations(PurpleConnection *conn);
 int chime_purple_send_im(PurpleConnection *gc, const char *who, const char *message, PurpleMessageFlags flags);
 unsigned int chime_send_typing(PurpleConnection *conn, const char *name, PurpleTypingState state);
 void chime_purple_recent_conversations(PurplePluginAction *action);
index 6c74e2403564dc95b0d29c3b27422f5624f8f143..dcfc64ed9a756a1dda9b8a7c96a1b30a4fcd3e88 100644 (file)
@@ -173,28 +173,6 @@ void on_chime_new_conversation(ChimeConnection *cxn, ChimeConversation *conv, Pu
 
 }
 
-static void im_destroy(gpointer _im)
-{
-       struct chime_im *im = _im;
-
-       g_signal_handlers_disconnect_matched(im->m.obj, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, im);
-       g_object_unref(im->peer);
-       cleanup_msgs(&im->m);
-       g_free(im);
-}
-
-void purple_chime_init_conversations(struct purple_chime *pc)
-{
-       pc->ims_by_email = g_hash_table_new(g_str_hash, g_str_equal);
-       pc->ims_by_profile_id = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, im_destroy);
-}
-
-void purple_chime_destroy_conversations(struct purple_chime *pc)
-{
-       g_clear_pointer(&pc->ims_by_email, g_hash_table_destroy);
-       g_clear_pointer(&pc->ims_by_profile_id, g_hash_table_destroy);
-}
-
 struct im_send_data {
        PurpleConnection *conn;
        struct chime_im *im;
@@ -531,3 +509,32 @@ void chime_purple_recent_conversations(PurplePluginAction *action)
                return;
        }
 }
+
+static void im_destroy(gpointer _im)
+{
+       struct chime_im *im = _im;
+
+       g_signal_handlers_disconnect_matched(im->m.obj, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, im);
+       g_object_unref(im->peer);
+       cleanup_msgs(&im->m);
+       g_free(im);
+}
+
+void purple_chime_init_conversations(PurpleConnection *conn)
+{
+       struct purple_chime *pc = purple_connection_get_protocol_data(conn);
+
+       pc->ims_by_email = g_hash_table_new(g_str_hash, g_str_equal);
+       pc->ims_by_profile_id = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, im_destroy);
+}
+
+void purple_chime_destroy_conversations(PurpleConnection *conn)
+{
+       struct purple_chime *pc = purple_connection_get_protocol_data(conn);
+
+       g_clear_pointer(&pc->ims_by_email, g_hash_table_destroy);
+       g_clear_pointer(&pc->ims_by_profile_id, g_hash_table_destroy);
+
+       if (pc->convlist_handle)
+               convlist_closed_cb(conn);
+}