aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSjoerd Simons <sjoerd.simons@collabora.co.uk>2011-03-20 20:44:51 +0800
committerSjoerd Simons <sjoerd.simons@collabora.co.uk>2011-03-21 17:24:15 +0800
commita8e558e10b1b5170346a75e1322f75d8ebad1662 (patch)
treebf21843a30695d05f9e48c4d91493cdc2368d075
parent79cf371093d1a1b0d9120a4bbcc5d73c7c67842d (diff)
downloadgsoc2013-empathy-a8e558e10b1b5170346a75e1322f75d8ebad1662.tar
gsoc2013-empathy-a8e558e10b1b5170346a75e1322f75d8ebad1662.tar.gz
gsoc2013-empathy-a8e558e10b1b5170346a75e1322f75d8ebad1662.tar.bz2
gsoc2013-empathy-a8e558e10b1b5170346a75e1322f75d8ebad1662.tar.lz
gsoc2013-empathy-a8e558e10b1b5170346a75e1322f75d8ebad1662.tar.xz
gsoc2013-empathy-a8e558e10b1b5170346a75e1322f75d8ebad1662.tar.zst
gsoc2013-empathy-a8e558e10b1b5170346a75e1322f75d8ebad1662.zip
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.
-rw-r--r--src/empathy.c72
1 files changed, 38 insertions, 34 deletions
diff --git a/src/empathy.c b/src/empathy.c
index e18288c35..74d3741a5 100644
--- a/src/empathy.c
+++ b/src/empathy.c
@@ -528,19 +528,46 @@ account_manager_ready_cb (GObject *source_object,
}
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_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,
guint new_status,
guint reason,
gchar *dbus_error_name,
GHashTable *details,
- EmpathyChatroom *room)
+ EmpathyChatroomManager *manager)
{
- if (new_status != TP_CONNECTION_STATUS_CONNECTED)
- return;
-
- empathy_join_muc (account,
- empathy_chatroom_get_room (room), TP_USER_ACTION_TIME_NOT_USER_ACTION);
+ account_join_chatrooms (account, manager);
}
static void
@@ -565,37 +592,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);
+ /* Try to join all rooms if we're connected */
+ account_join_chatrooms (account, chatroom_manager);
- 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;
-
- if (conn == NULL)
- {
- g_signal_connect (G_OBJECT (account), "status-changed",
- G_CALLBACK (account_status_changed_cb), room);
- }
- else
- {
- empathy_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);
}