diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2013-05-08 21:10:58 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@redhat.com> | 2013-05-08 21:10:58 +0800 |
commit | e403abb2e4eaace12e23749e4d8cf6ddf07950fe (patch) | |
tree | cb1d820554b02a5b07413b3c2a2fcca0c8ce654f /modules | |
parent | 58ef54715147561c2b8d458dd75c44223c46ac10 (diff) | |
download | gsoc2013-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.c | 115 |
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 (®istry); - 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); } |