[Bug 38142] proxy factories
bugzilla-daemon at freedesktop.org
bugzilla-daemon at freedesktop.org
Thu Aug 4 17:27:27 CEST 2011
https://bugs.freedesktop.org/show_bug.cgi?id=38142
--- Comment #70 from Will Thompson <will.thompson at collabora.co.uk> 2011-08-04 08:27:26 PDT ---
Here's a review of the first and last outstanding patches.
TpAccountManager: prepare its TpAccounts before exposing them
=============================================================
-tp_account_manager_ensure_account (TpAccountManager *manager,
+tp_account_manager_ensure_account (TpAccountManager *self,
It's *MUCH* more tedious to review code if you will insist on randomly renaming
variables in an already-enormous patch which makes substantial changes to the
inner workings of functions. Please don't do this. I definitely prefer 'self'
being used consistently, but not in the same patch as fundamental changes.
This actively discourages me from reviewing this code, and I don't think I'm
alone in my reaction.
Even disregarding this, the commitdiff is completely illegible. It must have
been possible to make this change in smaller chunks, rather than in a single
400-line patch.
tp_account_manager_get_valid_accounts (TpAccountManager *manager)
{
- TpAccountManagerPrivate *priv;
- GList *ret;
-
g_return_val_if_fail (TP_IS_ACCOUNT_MANAGER (manager), NULL);
- priv = manager->priv;
-
- ret = g_hash_table_get_values (priv->accounts);
-
- return ret;
+ return g_hash_table_get_values (manager->priv->accounts);
}
This is also *completely* unrelated to the rest of the patch, and has *no
functional effect*!
Anyway, on with the review
--------------------------
+ * All #TpAccount<!-- -->s are guaranteed to have all desired features
prepared
+ * (at least %TP_ACCOUNT_FEATURE_CORE).
+ * See tp_simple_client_factory_add_account_features() to define desired
+ * features.
“The returned #TpAccount<!-- -->s are guaranteed to have
%TP_ACCOUNT_FEATURE_CORE prepared, along with all features previously passed to
tp_simple_client_factory_add_account_features().”?
Ditto the other places where you use this wording.
Legacy accounts
---------------
This should have been a separate patch. It's probably a prerequisite for the
other changes, I agree, but it could have been made independently, first.
+tp_account_manager_ensure_account (TpAccountManager *self,
const gchar *path)
{
- TpAccountManagerPrivate *priv;
Why? A bunch of functions seem to randomly lose their 'priv' locals even though
they use the private structure.
+ if (self->priv->legacy_accounts == NULL)
+ self->priv->legacy_accounts = g_hash_table_new_full (
+ g_str_hash, g_str_equal, g_free, g_object_unref);
Why fuss about lazily initializing a hash table?
+static void
+legacy_account_invalidated_cb (TpProxy *account,
+ guint domain,
+ gint code,
+ gchar *message,
+ gpointer user_data)
+{
+ TpAccountManager *self = user_data;
+
+ g_hash_table_remove (self->priv->legacy_accounts,
+ tp_proxy_get_object_path (account));
}
What happens if I do this:
TpAccountManager *am = tp_account_manager_new_with_factory (...);
tp_account_manager_ensure_account (am, "some valid account path");
g_object_unref (am);
I *bet* that when the TpAM eventually gets disposed, it'll crash, because this
code will run:
+ tp_clear_pointer (&priv->legacy_accounts, g_hash_table_unref);
tp_clear_pointer first sets priv->legacy_accounts to NULL, and then unrefs the
hash table, which will unref the account, which will make it emit ::invalidated
(bug 22119), which will call legacy_account_invalidated_cb, which will crash
because self->priv->legacy_account == NULL.
(And no, using tp_g_signal_connect_object() does not save you because weak refs
are notified in GObject's dispose, which runs after
_tp_account_manager_dispose() which is where the hash table is destroyed.)
You might get saved by tp_proxy_prepare_async() keeping the legacy account
alive; so change my above example to unref am only after that's finished.
The corresponding callback for normal accounts does not have this problem
because:
/* We only want to deal with accounts being removed here. */
if (domain != TP_DBUS_ERRORS || code != TP_DBUS_ERROR_OBJECT_REMOVED)
return;
TpSimpleClientFactory: add code example of typical app's main()...
==================================================================
+ * A typical application using its own factory would look like this:
+ * |[
+ * int main()
+ * {
+ * TpSimpleClientFactory *factory;
+ * TpAccountManager *manager;
+ *
+ * factory = my_factory_new ();
A typical application will not use its own factory; it will use
#TpAutomaticClientFactory. If an application does use its own factory class, it
will presumably be a subclass of #TpAutomaticClientFactory.
This example won't compile: main needs arguments.
It also will crash because it doesn't call g_type_init().
--
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.
More information about the telepathy-bugs
mailing list