From bfcad7858e75c99a2cb6fa51a5fc47c473df23dc Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Mon, 21 Mar 2011 09:27:00 +0000 Subject: Fix some races in the chatroom joining code The auto-reconnection logic for chatrooms was a bit odd. It would for every chatroom that existed when the account manager was prepared connect once to status-changed for each account for each chatroom... Change this such that whenever an account connects, we simply get the then current list of chatrooms and auto-connect those as needed. This fixes issues when a chatroom gets removed from the manager and when the auto-connect options on a chatrooms change. Conflicts: src/empathy.c --- src/empathy.c | 69 ++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 38 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/empathy.c b/src/empathy.c index 325c4d742..96a509d7b 100644 --- a/src/empathy.c +++ b/src/empathy.c @@ -291,6 +291,37 @@ account_manager_ready_cb (GObject *source_object, g_object_unref (gsettings); } +static void +account_join_chatrooms (TpAccount *account, + EmpathyChatroomManager *chatroom_manager) +{ + TpConnection *conn; + GList *chatrooms, *p; + + if (tp_account_get_connection_status (account, NULL) != + TP_CONNECTION_STATUS_CONNECTED) + return; + + /* If we're connected we should have a connection */ + conn = tp_account_get_connection (account); + g_return_if_fail (conn != NULL); + + chatrooms = empathy_chatroom_manager_get_chatrooms ( + chatroom_manager, account); + + for (p = chatrooms; p != NULL; p = p->next) + { + EmpathyChatroom *room = EMPATHY_CHATROOM (p->data); + + if (!empathy_chatroom_get_auto_connect (room)) + continue; + + empathy_dispatcher_join_muc (account, + empathy_chatroom_get_room (room), TP_USER_ACTION_TIME_NOT_USER_ACTION); + } + g_list_free (chatrooms); +} + static void account_status_changed_cb (TpAccount *account, guint old_status, @@ -298,13 +329,12 @@ account_status_changed_cb (TpAccount *account, guint reason, gchar *dbus_error_name, GHashTable *details, - EmpathyChatroom *room) + EmpathyChatroomManager *manager) { if (new_status != TP_CONNECTION_STATUS_CONNECTED) return; - empathy_dispatcher_join_muc (account, - empathy_chatroom_get_room (room), TP_USER_ACTION_TIME_NOT_USER_ACTION); + account_join_chatrooms (account, manager); } static void @@ -329,37 +359,14 @@ account_manager_chatroom_ready_cb (GObject *source_object, for (l = accounts; l != NULL; l = g_list_next (l)) { TpAccount *account = TP_ACCOUNT (l->data); - TpConnection *conn; - GList *chatrooms, *p; - - conn = tp_account_get_connection (account); - chatrooms = empathy_chatroom_manager_get_chatrooms ( - chatroom_manager, account); + /* Try to join all rooms if we're connected */ + account_join_chatrooms (account, chatroom_manager); - for (p = chatrooms; p != NULL; p = p->next) - { - EmpathyChatroom *room = EMPATHY_CHATROOM (p->data); - - if (!empathy_chatroom_get_auto_connect (room)) - continue; - - if (conn == NULL) - { - g_signal_connect (G_OBJECT (account), "status-changed", - G_CALLBACK (account_status_changed_cb), room); - } - else - { - empathy_dispatcher_join_muc (account, - empathy_chatroom_get_room (room), - TP_USER_ACTION_TIME_NOT_USER_ACTION); - } - } - - g_list_free (chatrooms); + /* And/or join them on (re)connection */ + tp_g_signal_connect_object (account, "status-changed", + G_CALLBACK (account_status_changed_cb), chatroom_manager, 0); } - g_list_free (accounts); } -- cgit v1.2.3