aboutsummaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2013-05-08 21:10:58 +0800
committerMatthew Barnes <mbarnes@redhat.com>2013-05-08 21:10:58 +0800
commite403abb2e4eaace12e23749e4d8cf6ddf07950fe (patch)
treecb1d820554b02a5b07413b3c2a2fcca0c8ce654f /modules
parent58ef54715147561c2b8d458dd75c44223c46ac10 (diff)
downloadgsoc2013-evolution-e403abb2e4eaace12e23749e4d8cf6ddf07950fe.tar
gsoc2013-evolution-e403abb2e4eaace12e23749e4d8cf6ddf07950fe.tar.gz
gsoc2013-evolution-e403abb2e4eaace12e23749e4d8cf6ddf07950fe.tar.bz2
gsoc2013-evolution-e403abb2e4eaace12e23749e4d8cf6ddf07950fe.tar.lz
gsoc2013-evolution-e403abb2e4eaace12e23749e4d8cf6ddf07950fe.tar.xz
gsoc2013-evolution-e403abb2e4eaace12e23749e4d8cf6ddf07950fe.tar.zst
gsoc2013-evolution-e403abb2e4eaace12e23749e4d8cf6ddf07950fe.zip
contact-photos: Obtain an EClient asynchronously.
Obtain an EClient for contact photo lookup asynchronously. If an instance needs to be created, it's more likely created in a thread with a main loop so signal emissions can work.
Diffstat (limited to 'modules')
-rw-r--r--modules/contact-photos/e-contact-photo-source.c115
1 files changed, 76 insertions, 39 deletions
diff --git a/modules/contact-photos/e-contact-photo-source.c b/modules/contact-photos/e-contact-photo-source.c
index b290a2168f..e124046cee 100644
--- a/modules/contact-photos/e-contact-photo-source.c
+++ b/modules/contact-photos/e-contact-photo-source.c
@@ -30,8 +30,10 @@ struct _EContactPhotoSourcePrivate {
};
struct _AsyncContext {
+ EBookClient *client;
gchar *query_string;
GInputStream *stream;
+ GCancellable *cancellable;
gint priority;
};
@@ -57,8 +59,10 @@ G_DEFINE_DYNAMIC_TYPE_EXTENDED (
static void
async_context_free (AsyncContext *async_context)
{
+ g_clear_object (&async_context->client);
g_free (async_context->query_string);
g_clear_object (&async_context->stream);
+ g_clear_object (&async_context->cancellable);
g_slice_free (AsyncContext, async_context);
}
@@ -85,51 +89,22 @@ contact_photo_source_get_photo_thread (GSimpleAsyncResult *simple,
GObject *source_object,
GCancellable *cancellable)
{
- EContactPhotoSource *photo_source;
AsyncContext *async_context;
- EClientCache *client_cache;
- ESourceRegistry *registry;
- EClient *client = NULL;
- ESource *source;
GSList *slist = NULL;
GSList *slink;
GError *error = NULL;
- photo_source = E_CONTACT_PHOTO_SOURCE (source_object);
async_context = g_simple_async_result_get_op_res_gpointer (simple);
- client_cache = e_contact_photo_source_ref_client_cache (photo_source);
- source = e_contact_photo_source_ref_source (photo_source);
- registry = e_client_cache_ref_registry (client_cache);
-
- /* Return no result if the source is disabled. */
- if (!e_source_registry_check_enabled (registry, source))
- goto exit;
-
- client = e_client_cache_get_client_sync (
- client_cache, source,
- E_SOURCE_EXTENSION_ADDRESS_BOOK,
- cancellable, &error);
-
- /* Sanity check. */
- g_return_if_fail (
- ((client != NULL) && (error == NULL)) ||
- ((client == NULL) && (error != NULL)));
-
- if (error != NULL) {
- g_simple_async_result_take_error (simple, error);
- goto exit;
- }
-
e_book_client_get_contacts_sync (
- E_BOOK_CLIENT (client),
+ async_context->client,
async_context->query_string,
&slist, cancellable, &error);
if (error != NULL) {
g_warn_if_fail (slist == NULL);
g_simple_async_result_take_error (simple, error);
- goto exit;
+ return;
}
/* See if any of the contacts have a photo. */
@@ -181,12 +156,46 @@ contact_photo_source_get_photo_thread (GSimpleAsyncResult *simple,
}
g_slist_free_full (slist, (GDestroyNotify) g_object_unref);
+}
+
+static void
+contact_photo_source_get_client_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncContext *async_context;
+ EClient *client;
+ GError *error = NULL;
+
+ simple = G_SIMPLE_ASYNC_RESULT (user_data);
+ async_context = g_simple_async_result_get_op_res_gpointer (simple);
+
+ client = e_client_cache_get_client_finish (
+ E_CLIENT_CACHE (source_object), result, &error);
+
+ /* Sanity check. */
+ g_return_if_fail (
+ ((client != NULL) && (error == NULL)) ||
+ ((client == NULL) && (error != NULL)));
+
+ if (client != NULL) {
+ async_context->client = g_object_ref (client);
+
+ /* The rest of the operation we can run from a
+ * worker thread to keep the logic flow simple. */
+ g_simple_async_result_run_in_thread (
+ simple, contact_photo_source_get_photo_thread,
+ G_PRIORITY_DEFAULT, async_context->cancellable);
+
+ g_object_unref (client);
+
+ } else {
+ g_simple_async_result_take_error (simple, error);
+ g_simple_async_result_complete_in_idle (simple);
+ }
-exit:
- g_clear_object (&client_cache);
- g_clear_object (&registry);
- g_clear_object (&client);
- g_clear_object (&source);
+ g_object_unref (simple);
}
static void
@@ -280,7 +289,10 @@ contact_photo_source_get_photo (EPhotoSource *photo_source,
{
GSimpleAsyncResult *simple;
AsyncContext *async_context;
+ EClientCache *client_cache;
+ ESourceRegistry *registry;
EBookQuery *book_query;
+ ESource *source;
book_query = e_book_query_field_test (
E_CONTACT_EMAIL, E_BOOK_QUERY_IS, email_address);
@@ -288,6 +300,9 @@ contact_photo_source_get_photo (EPhotoSource *photo_source,
async_context = g_slice_new0 (AsyncContext);
async_context->query_string = e_book_query_to_string (book_query);
+ if (G_IS_CANCELLABLE (cancellable))
+ async_context->cancellable = g_object_ref (cancellable);
+
e_book_query_unref (book_query);
simple = g_simple_async_result_new (
@@ -299,9 +314,31 @@ contact_photo_source_get_photo (EPhotoSource *photo_source,
g_simple_async_result_set_op_res_gpointer (
simple, async_context, (GDestroyNotify) async_context_free);
- g_simple_async_result_run_in_thread (
- simple, contact_photo_source_get_photo_thread,
- G_PRIORITY_DEFAULT, cancellable);
+ client_cache = e_contact_photo_source_ref_client_cache (
+ E_CONTACT_PHOTO_SOURCE (photo_source));
+ registry = e_client_cache_ref_registry (client_cache);
+
+ source = e_contact_photo_source_ref_source (
+ E_CONTACT_PHOTO_SOURCE (photo_source));
+
+ if (e_source_registry_check_enabled (registry, source)) {
+ /* Obtain the EClient asynchronously. If an instance needs
+ * to be created, it's more likely created in a thread with
+ * a main loop so signal emissions can work. */
+ e_client_cache_get_client (
+ client_cache, source,
+ E_SOURCE_EXTENSION_ADDRESS_BOOK,
+ cancellable,
+ contact_photo_source_get_client_cb,
+ g_object_ref (simple));
+ } else {
+ /* Return no result if the source is disabled. */
+ g_simple_async_result_complete_in_idle (simple);
+ }
+
+ g_object_unref (client_cache);
+ g_object_unref (registry);
+ g_object_unref (source);
g_object_unref (simple);
}