From a2d1f1da1e386e5b3b194419efb8a18ef8d1ec7d Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 29 Aug 2013 16:28:45 +0100 Subject: [PATCH 11/16] Move "waiting for connectivity" functionality into McdAccount --- src/kludge-transport.c | 61 -------------------------------------------- src/mcd-account-connection.c | 38 +++++++++++++++++++-------- src/mcd-account.c | 40 +++++++++++++++++++++++++++++ src/mcd-account.h | 4 +++ src/mcd-master-priv.h | 4 --- src/mcd-master.c | 53 -------------------------------------- 6 files changed, 71 insertions(+), 129 deletions(-) diff --git a/src/kludge-transport.c b/src/kludge-transport.c index c9beb5b..06c30a2 100644 --- a/src/kludge-transport.c +++ b/src/kludge-transport.c @@ -40,9 +40,6 @@ struct _McdKludgeTransportPrivate { * itself. */ GList *transports; - - /* Hold a set of McdAccounts which would like to go online. */ - GHashTable *pending_accounts; }; static void transport_iface_init ( @@ -77,9 +74,6 @@ mcd_kludge_transport_constructed (GObject *object) /* We just use ourself as the McdTransport pointer... */ priv->transports = g_list_prepend (NULL, self); - - priv->pending_accounts = g_hash_table_new_full (NULL, NULL, - g_object_unref, NULL); } static void @@ -93,8 +87,6 @@ mcd_kludge_transport_dispose (GObject *object) g_list_free (priv->transports); priv->transports = NULL; - g_hash_table_unref (priv->pending_accounts); - if (parent_class->dispose != NULL) parent_class->dispose (object); } @@ -176,58 +168,8 @@ monitor_state_changed_cb ( McdTransportStatus new_status = connected ? MCD_TRANSPORT_STATUS_CONNECTED : MCD_TRANSPORT_STATUS_DISCONNECTED; - GHashTableIter iter; - gpointer key; g_signal_emit_by_name (self, "status-changed", self, new_status); - - g_hash_table_iter_init (&iter, self->priv->pending_accounts); - while (g_hash_table_iter_next (&iter, &key, NULL)) - { - McdAccount *account = MCD_ACCOUNT (key); - - /* If we've gone online, allow the account to actually try to connect; - * if we've fallen offline, say as much. (I don't actually think this - * code will be reached if !connected, but.) - */ - DEBUG ("telling %s to %s", mcd_account_get_unique_name (account), - connected ? "proceed" : "give up"); - mcd_account_connection_proceed_with_reason (account, connected, - connected ? TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED - : TP_CONNECTION_STATUS_REASON_NETWORK_ERROR); - g_hash_table_iter_remove (&iter); - } -} - -/* - * mcd_kludge_transport_account_connection_cb: - * @account: an account which would like to go online - * @parameters: the connection parameters to be used - * @user_data: the McdKludgeTransport. - * - * Called when an account would like to sign in. - */ -static void -mcd_kludge_transport_account_connection_cb ( - McdAccount *account, - GHashTable *parameters, - gpointer user_data) -{ - McdKludgeTransport *self = MCD_KLUDGE_TRANSPORT (user_data); - McdKludgeTransportPrivate *priv = self->priv; - - if (mcd_connectivity_monitor_is_online (priv->minotaur)) - { - mcd_account_connection_proceed (account, TRUE); - } - else if (g_hash_table_lookup (priv->pending_accounts, account) == NULL) - { - DEBUG ("%s wants to connect, but we're offline; queuing it up", - mcd_account_get_unique_name (account)); - g_object_ref (account); - g_hash_table_insert (priv->pending_accounts, account, account); - } - /* ... else we're already waiting, I guess */ } static McdTransportPlugin * @@ -251,7 +193,4 @@ mcd_kludge_transport_install (McdMaster *master, McdTransportPlugin *self = mcd_kludge_transport_new (connectivity_monitor); mcd_master_register_transport (master, self); - mcd_master_register_account_connection (master, - mcd_kludge_transport_account_connection_cb, - MCD_ACCOUNT_CONNECTION_PRIORITY_TRANSPORT, self); } diff --git a/src/mcd-account-connection.c b/src/mcd-account-connection.c index 6d7dbf7..8eca282 100644 --- a/src/mcd-account-connection.c +++ b/src/mcd-account-connection.c @@ -39,7 +39,6 @@ struct _McdAccountConnectionContext { GHashTable *params; - gint i_filter; gboolean user_initiated; }; @@ -69,7 +68,6 @@ _mcd_account_connection_begin (McdAccount *account, /* create dynamic params HT */ /* run the handlers */ ctx = g_malloc (sizeof (McdAccountConnectionContext)); - ctx->i_filter = 0; ctx->user_initiated = user_initiated; /* If we get this far, the account should be valid, so getting the @@ -92,9 +90,7 @@ mcd_account_connection_proceed_with_reason (McdAccount *account, TpConnectionStatusReason reason) { McdAccountConnectionContext *ctx; - McdAccountConnectionFunc func = NULL; - gpointer userdata; - McdMaster *master; + gboolean delayed; /* call next handler, or terminate the chain (emitting proper signal). * if everything is fine, call mcd_manager_create_connection() and @@ -106,15 +102,35 @@ mcd_account_connection_proceed_with_reason (McdAccount *account, if (success) { - master = mcd_master_get_default (); - _mcd_master_get_nth_account_connection (master, ctx->i_filter++, - &func, &userdata); + if (mcd_connectivity_monitor_is_online ( + mcd_account_get_connectivity_monitor (account))) + { + DEBUG ("%s wants to connect and we're online - go for it", + mcd_account_get_unique_name (account)); + delayed = FALSE; + } + else if (!mcd_account_get_waiting_for_connectivity (account)) + { + DEBUG ("%s wants to connect, but we're offline; queuing it up", + mcd_account_get_unique_name (account)); + delayed = TRUE; + mcd_account_set_waiting_for_connectivity (account, TRUE); + } + else + { + DEBUG ("%s wants to connect, but is already waiting for " + "connectivity?", mcd_account_get_unique_name (account)); + delayed = TRUE; + } } - if (func) + else { - func (account, ctx->params, userdata); + DEBUG ("%s failed to connect: reason code %d", + mcd_account_get_unique_name (account), reason); + delayed = FALSE; } - else + + if (!delayed) { /* end of the chain */ g_signal_emit (account, _mcd_account_signal_connection_process, 0, diff --git a/src/mcd-account.c b/src/mcd-account.c index 4b5d25a..863ece6 100644 --- a/src/mcd-account.c +++ b/src/mcd-account.c @@ -173,6 +173,7 @@ struct _McdAccountPrivate gboolean always_on; gboolean changing_presence; gboolean setting_avatar; + gboolean waiting_for_connectivity; gboolean hidden; /* In addition to affecting dispatching, this flag also makes this @@ -3601,6 +3602,29 @@ _mcd_account_constructor (GType type, guint n_params, } static void +monitor_state_changed_cb ( + McdConnectivityMonitor *monitor, + gboolean connected, + gpointer user_data) +{ + McdAccount *self = MCD_ACCOUNT (user_data); + + if (!self->priv->waiting_for_connectivity) + return; + + /* If we've gone online, allow the account to actually try to connect; + * if we've fallen offline, say as much. (I don't actually think this + * code will be reached if !connected, but.) + */ + DEBUG ("telling %s to %s", self->priv->unique_name, + connected ? "proceed" : "give up"); + mcd_account_connection_proceed_with_reason (self, connected, + connected ? TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED + : TP_CONNECTION_STATUS_REASON_NETWORK_ERROR); + self->priv->waiting_for_connectivity = FALSE; +} + +static void _mcd_account_constructed (GObject *object) { GObjectClass *object_class = (GObjectClass *)mcd_account_parent_class; @@ -3613,6 +3637,9 @@ _mcd_account_constructed (GObject *object) mcd_account_migrate_avatar (account); mcd_account_setup (account); + + tp_g_signal_connect_object (account->priv->connectivity, "state-change", + (GCallback) monitor_state_changed_cb, account, 0); } static void @@ -5161,3 +5188,16 @@ mcd_account_get_connectivity_monitor (McdAccount *self) { return self->priv->connectivity; } + +gboolean +mcd_account_get_waiting_for_connectivity (McdAccount *self) +{ + return self->priv->waiting_for_connectivity; +} + +void +mcd_account_set_waiting_for_connectivity (McdAccount *self, + gboolean waiting) +{ + self->priv->waiting_for_connectivity = waiting; +} diff --git a/src/mcd-account.h b/src/mcd-account.h index e88e801..62191d5 100644 --- a/src/mcd-account.h +++ b/src/mcd-account.h @@ -150,6 +150,10 @@ gchar * mcd_account_dup_nickname (McdAccount *self); McdConnectivityMonitor *mcd_account_get_connectivity_monitor ( McdAccount *self); +gboolean mcd_account_get_waiting_for_connectivity (McdAccount *self); +void mcd_account_set_waiting_for_connectivity (McdAccount *self, + gboolean waiting); + G_END_DECLS #endif diff --git a/src/mcd-master-priv.h b/src/mcd-master-priv.h index aaacbb4..ab42c8a 100644 --- a/src/mcd-master-priv.h +++ b/src/mcd-master-priv.h @@ -35,10 +35,6 @@ G_GNUC_INTERNAL gboolean _mcd_master_account_replace_transport (McdMaster *master, McdAccount *account); -void _mcd_master_get_nth_account_connection (McdMaster *master, gint i, - McdAccountConnectionFunc *func, - gpointer *userdata); - McdManager *_mcd_master_lookup_manager (McdMaster *master, const gchar *unique_name); diff --git a/src/mcd-master.c b/src/mcd-master.c index 006a27b..e673335 100644 --- a/src/mcd-master.c +++ b/src/mcd-master.c @@ -95,7 +95,6 @@ struct _McdMasterPrivate TpSimpleClientFactory *client_factory; GPtrArray *transport_plugins; - GList *account_connections; /* Current pending sleep timer */ gint shutdown_timeout_id; @@ -246,17 +245,6 @@ on_transport_status_changed (McdTransportPlugin *plugin, } static void -_mcd_master_finalize (GObject * object) -{ - McdMasterPrivate *priv = MCD_MASTER (object)->priv; - - g_list_foreach (priv->account_connections, (GFunc)g_free, NULL); - g_list_free (priv->account_connections); - - G_OBJECT_CLASS (mcd_master_parent_class)->finalize (object); -} - -static void _mcd_master_get_property (GObject * obj, guint prop_id, GValue * val, GParamSpec * pspec) { @@ -391,7 +379,6 @@ mcd_master_class_init (McdMasterClass * klass) g_type_class_add_private (object_class, sizeof (McdMasterPrivate)); object_class->constructor = mcd_master_constructor; - object_class->finalize = _mcd_master_finalize; object_class->get_property = _mcd_master_get_property; object_class->set_property = _mcd_master_set_property; object_class->dispose = _mcd_master_dispose; @@ -526,46 +513,6 @@ mcd_master_register_transport (McdMaster *master, g_ptr_array_add (master->priv->transport_plugins, transport_plugin); } -void -mcd_master_register_account_connection (McdMaster *master, - McdAccountConnectionFunc func, - gint priority, - gpointer userdata) -{ - McdMasterPrivate *priv = master->priv; - McdAccountConnectionData *acd; - GList *list; - - DEBUG ("called"); - acd = g_malloc (sizeof (McdAccountConnectionData)); - acd->priority = priority; - acd->func = func; - acd->userdata = userdata; - for (list = priv->account_connections; list; list = list->next) - if (((McdAccountConnectionData *)list->data)->priority >= priority) break; - - priv->account_connections = - g_list_insert_before (priv->account_connections, list, acd); -} - -void -_mcd_master_get_nth_account_connection (McdMaster *master, - gint i, - McdAccountConnectionFunc *func, - gpointer *userdata) -{ - McdAccountConnectionData *acd; - - acd = g_list_nth_data (master->priv->account_connections, i); - if (acd) - { - *func = acd->func; - *userdata = acd->userdata; - } - else - *func = NULL; -} - gboolean _mcd_master_account_replace_transport (McdMaster *master, McdAccount *account) -- 1.8.4.rc3