[Telepathy-commits] [telepathy-glib/master] TpContact: on success, don't give the callback a free ref to each contact
Simon McVittie
simon.mcvittie at collabora.co.uk
Fri Oct 24 09:36:37 PDT 2008
It seems saner to require the callback to take a ref itself if it wants
to keep the object (and in fact examples/client/inspect-contact.c failed
to unref it, so it's correct for the new semantics).
Also, on fatal errors, give the callback a bit more information about
what was going on, by telling it the handles or IDs that were requested
in the first place (via the "failed handles/IDs" arguments).
---
telepathy-glib/contact.c | 93 +++++++++++++++++++++++++++------------------
telepathy-glib/contact.h | 4 +-
tests/dbus/contacts.c | 6 +-
3 files changed, 61 insertions(+), 42 deletions(-)
diff --git a/telepathy-glib/contact.c b/telepathy-glib/contact.c
index 4ac4fc8..77360c6 100644
--- a/telepathy-glib/contact.c
+++ b/telepathy-glib/contact.c
@@ -747,19 +747,36 @@ static void
contacts_context_fail (ContactsContext *c,
const GError *error)
{
+ guint i;
+
switch (c->signature)
{
case CB_BY_HANDLE:
- c->callback.by_handle (c->connection, 0, NULL, 0, NULL, error,
- c->user_data, c->weak_object);
+ g_array_append_vals (c->invalid, c->handles->data, c->handles->len);
+
+ c->callback.by_handle (c->connection, 0, NULL,
+ c->invalid->len, (const TpHandle *) c->invalid->data,
+ error, c->user_data, c->weak_object);
return;
case CB_BY_ID:
- c->callback.by_id (c->connection, 0, NULL, NULL, NULL, error,
- c->user_data, c->weak_object);
+ for (i = 0; i < c->request_ids->len; i++)
+ {
+ const gchar *id = g_ptr_array_index (c->request_ids, i);
+
+ if (!g_hash_table_lookup (c->request_errors, id))
+ {
+ g_hash_table_insert (c->request_errors,
+ g_strdup (id), g_error_copy (error));
+ }
+ }
+
+ c->callback.by_id (c->connection, 0, NULL, NULL,
+ c->request_errors, error, c->user_data, c->weak_object);
return;
case CB_UPGRADE:
- c->callback.upgrade (c->connection, 0, NULL, error,
- c->user_data, c->weak_object);
+ c->callback.upgrade (c->connection,
+ c->contacts->len, (TpContact * const *) c->contacts->pdata,
+ error, c->user_data, c->weak_object);
return;
default:
g_assert_not_reached ();
@@ -773,13 +790,14 @@ contacts_context_fail (ContactsContext *c,
* @n_contacts: The number of TpContact objects successfully created
* (one per valid handle), or 0 on unrecoverable errors
* @contacts: An array of @n_contacts TpContact objects (this callback is
- * given one reference to each of these objects, and must unref any that
- * are not needed with g_object_unref()), or %NULL on unrecoverable errors
- * @n_invalid: The number of invalid handles that were passed to
- * tp_connection_get_contacts_by_handle(), or 0 on unrecoverable errors
- * @invalid: An array of @n_invalid handles that were passed to
- * tp_connection_get_contacts_by_handle() but turned out to be invalid,
- * or %NULL on unrecoverable errors
+ * not given a reference to any of these objects, and must call g_object_ref()
+ * on any that it will keep), or %NULL on unrecoverable errors
+ * @n_failed: The number of invalid handles that were passed to
+ * tp_connection_get_contacts_by_handle() (or on unrecoverable errors,
+ * the total number of handles that were given)
+ * @failed: An array of @n_failed handles that were passed to
+ * tp_connection_get_contacts_by_handle() but turned out to be invalid
+ * (or on unrecoverable errors, all the handles that were given)
* @error: %NULL on success, or an unrecoverable error that caused everything
* to fail
* @user_data: the @user_data that was passed to
@@ -808,14 +826,13 @@ contacts_context_fail (ContactsContext *c,
* @n_contacts: The number of TpContact objects successfully created
* (one per valid ID), or 0 on unrecoverable errors
* @contacts: An array of @n_contacts TpContact objects (this callback is
- * given one reference to each of these objects, and must unref any that
- * are not needed with g_object_unref()), or %NULL on unrecoverable errors
+ * not given a reference to any of these objects, and must call
+ * g_object_ref() on any that it will keep), or %NULL on unrecoverable errors
* @requested_ids: An array of @n_contacts valid IDs (JIDs, SIP URIs etc.)
* that were passed to tp_connection_get_contacts_by_id(), in an order
* corresponding to @contacts, or %NULL on unrecoverable errors
- * @invalid_id_errors: A hash table in which the keys are IDs that were
- * passed to tp_connection_get_contacts_by_id() but turned out to be invalid,
- * and the values are the corresponding #GError; %NULL on unrecoverable errors
+ * @failed_id_errors: A hash table in which the keys are IDs
+ * and the values are errors (#GError)
* @error: %NULL on success, or an unrecoverable error that caused everything
* to fail
* @user_data: the @user_data that was passed to
@@ -826,41 +843,47 @@ contacts_context_fail (ContactsContext *c,
* Signature of a callback used to receive the result of
* tp_connection_get_contacts_by_id().
*
- * If an unrecoverable error occurs (for instance, if @connection
- * becomes disconnected) the whole operation fails, and no contacts,
- * requested IDs or invalid IDs are returned.
+ * @requested_ids contains the IDs that were converted to handles successfully.
+ * The normalized form of requested_ids[i] is
+ * tp_contact_get_identifier (contacts[i]).
*
* If some or even all of the @ids passed to
* tp_connection_get_contacts_by_id() were not valid, this is not
- * considered to be a failure. @error will be %NULL in this situation,
+ * considered to be a fatal error. @error will be %NULL in this situation,
* @contacts will contain contact objects for those IDs that were
- * valid (possibly none of them), and @invalid_id_errors will map the IDs
- * that were not valid to a corresponding #GError.
+ * valid (it may be empty), and @failed_id_errors will map the IDs
+ * that were not valid to a corresponding #GError (if the connection manager
+ * complies with the Telepathy spec, it will have domain %TP_ERRORS and code
+ * %TP_ERROR_NOT_AVAILABLE).
*
- * @requested_ids contains the IDs that were requested. The
- * normalized form of requested_ids[i] can be obtained by calling
- * tp_contact_get_identifier (contacts[i]).
+ * If an unrecoverable error occurs (for instance, if @connection
+ * becomes disconnected) the whole operation fails, and no contacts
+ * or requested IDs are returned. @failed_id_errors will contain all the IDs
+ * that were requested, mapped to a corresponding #GError (either one
+ * indicating that the ID was invalid, if that was determined before the
+ * fatal error occurred, or a copy of @error).
*/
/**
* TpConnectionUpgradeContactsCb:
* @connection: The connection
* @n_contacts: The number of TpContact objects for which an upgrade was
- * requested, or 0 on unrecoverable errors
+ * requested
* @contacts: An array of @n_contacts TpContact objects (this callback is
- * given one reference to each of these objects, and must unref any that
- * are not needed with g_object_unref()), or %NULL on unrecoverable errors
+ * not given an extra reference to any of these objects, and must call
+ * g_object_ref() on any that it will keep)
* @error: An unrecoverable error, or %NULL if the connection remains valid
* @user_data: the @user_data that was passed to
- * tp_connection_get_contacts_by_handle()
+ * tp_connection_upgrade_contacts()
* @weak_object: the @weak_object that was passed to
- * tp_connection_get_contacts_by_handle()
+ * tp_connection_upgrade_contacts()
*
* Signature of a callback used to receive the result of
* tp_connection_upgrade_contacts().
*
* If an unrecoverable error occurs (for instance, if @connection becomes
- * disconnected) the whole operation fails, and no contacts are returned.
+ * disconnected) it is indicated by @error, but the contacts in @contacts
+ * are still provided.
*/
@@ -906,10 +929,6 @@ contacts_context_continue (ContactsContext *c)
default:
g_assert_not_reached ();
}
-
- /* we've given the TpContact refs to the callback, so: */
- if (c->contacts->len > 0)
- g_ptr_array_remove_range (c->contacts, 0, c->contacts->len);
}
else
{
diff --git a/telepathy-glib/contact.h b/telepathy-glib/contact.h
index a753105..28c7f49 100644
--- a/telepathy-glib/contact.h
+++ b/telepathy-glib/contact.h
@@ -77,7 +77,7 @@ const gchar *tp_contact_get_presence_message (TpContact *self);
typedef void (*TpConnectionContactsByHandleCb) (TpConnection *connection,
guint n_contacts, TpContact * const *contacts,
- guint n_invalid, const TpHandle *invalid,
+ guint n_failed, const TpHandle *failed,
const GError *error, gpointer user_data, GObject *weak_object);
void tp_connection_get_contacts_by_handle (TpConnection *self,
@@ -98,7 +98,7 @@ void tp_connection_upgrade_contacts (TpConnection *self,
typedef void (*TpConnectionContactsByIdCb) (TpConnection *connection,
guint n_contacts, TpContact * const *contacts,
- const gchar * const *requested_ids, GHashTable *invalid_id_errors,
+ const gchar * const *requested_ids, GHashTable *failed_id_errors,
const GError *error, gpointer user_data, GObject *weak_object);
void tp_connection_get_contacts_by_id (TpConnection *self,
diff --git a/tests/dbus/contacts.c b/tests/dbus/contacts.c
index f0fd625..47da72b 100644
--- a/tests/dbus/contacts.c
+++ b/tests/dbus/contacts.c
@@ -86,7 +86,7 @@ by_handle_cb (TpConnection *connection,
tp_contact_get_presence_status (contact));
DEBUG ("contact #%u presence message: %s", i,
tp_contact_get_presence_message (contact));
- g_ptr_array_add (result->contacts, contact);
+ g_ptr_array_add (result->contacts, g_object_ref (contact));
}
}
else
@@ -354,7 +354,7 @@ upgrade_cb (TpConnection *connection,
tp_contact_get_presence_status (contact));
DEBUG ("contact #%u presence message: %s", i,
tp_contact_get_presence_message (contact));
- g_ptr_array_add (result->contacts, contact);
+ g_ptr_array_add (result->contacts, g_object_ref (contact));
}
}
else
@@ -755,7 +755,7 @@ by_id_cb (TpConnection *connection,
tp_contact_get_presence_status (contact));
DEBUG ("contact #%u presence message: %s", i,
tp_contact_get_presence_message (contact));
- g_ptr_array_add (result->contacts, contact);
+ g_ptr_array_add (result->contacts, g_object_ref (contact));
}
}
else
--
1.5.6.5
More information about the Telepathy-commits
mailing list