[evolution] Bug 736808 - Fill lists of certificates asynchronously
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] Bug 736808 - Fill lists of certificates asynchronously
- Date: Tue, 22 Mar 2016 16:26:22 +0000 (UTC)
commit 76ad2ab7ff4e99d4a2f1173e6677e443a72fd948
Author: Milan Crha <mcrha redhat com>
Date: Tue Mar 22 17:25:17 2016 +0100
Bug 736808 - Fill lists of certificates asynchronously
smime/gui/certificate-manager.c | 175 ++++++++++++++++++++++++++++++++++-----
1 files changed, 155 insertions(+), 20 deletions(-)
---
diff --git a/smime/gui/certificate-manager.c b/smime/gui/certificate-manager.c
index 793c8c4..daf2870 100644
--- a/smime/gui/certificate-manager.c
+++ b/smime/gui/certificate-manager.c
@@ -167,6 +167,8 @@ struct _ECertManagerConfigPrivate {
GtkTreeModel *mail_model;
GtkTreeView *mail_tree_view; /* not referenced */
+
+ GCancellable *load_all_certs_cancellable;
};
typedef struct {
@@ -1709,6 +1711,153 @@ unload_certs (CertPage *cp)
(GDestroyNotify) gtk_tree_iter_free);
}
+typedef struct _LoadAllCertsAsyncData
+{
+ ECertManagerConfig *ecmc;
+ GCancellable *cancellable;
+ GSList *ecerts;
+ gint tries;
+} LoadAllCertsAsyncData;
+
+static void
+load_all_certs_async_data_free (gpointer ptr)
+{
+ LoadAllCertsAsyncData *data = ptr;
+
+ if (data) {
+ g_clear_object (&data->ecmc);
+ g_clear_object (&data->cancellable);
+ g_slist_free_full (data->ecerts, g_object_unref);
+ g_free (data);
+ }
+}
+
+static gboolean
+load_all_certs_done_idle_cb (gpointer user_data)
+{
+ LoadAllCertsAsyncData *data = user_data;
+
+ g_return_val_if_fail (data != NULL, FALSE);
+ g_return_val_if_fail (E_IS_CERT_MANAGER_CONFIG (data->ecmc), FALSE);
+
+ if (!g_cancellable_is_cancelled (data->cancellable)) {
+ ECertManagerConfig *ecmc = data->ecmc;
+ GSList *link;
+
+ unload_certs (data->ecmc->priv->yourcerts_page);
+ unload_certs (data->ecmc->priv->contactcerts_page);
+ unload_certs (data->ecmc->priv->authoritycerts_page);
+
+ for (link = data->ecerts; link; link = g_slist_next (link)) {
+ ECert *cert = link->data;
+ ECertType ct;
+
+ if (!cert)
+ continue;
+
+ ct = e_cert_get_cert_type (cert);
+ if (ct == data->ecmc->priv->yourcerts_page->cert_type) {
+ add_cert (data->ecmc->priv->yourcerts_page, g_object_ref (cert));
+ } else if (ct == data->ecmc->priv->authoritycerts_page->cert_type) {
+ add_cert (data->ecmc->priv->authoritycerts_page, g_object_ref (cert));
+ } else if (ct == data->ecmc->priv->contactcerts_page->cert_type || (ct != E_CERT_CA
&& ct != E_CERT_USER)) {
+ add_cert (data->ecmc->priv->contactcerts_page, g_object_ref (cert));
+ }
+ }
+
+ /* expand all three trees */
+ gtk_tree_view_expand_all (ECMC_TREE_VIEW (yourcerts_page));
+ gtk_tree_view_expand_all (ECMC_TREE_VIEW (contactcerts_page));
+ gtk_tree_view_expand_all (ECMC_TREE_VIEW (authoritycerts_page));
+
+ /* Now load settings of each treeview */
+ load_treeview_state (ECMC_TREE_VIEW (yourcerts_page));
+ load_treeview_state (ECMC_TREE_VIEW (contactcerts_page));
+ load_treeview_state (ECMC_TREE_VIEW (authoritycerts_page));
+ }
+
+ return FALSE;
+}
+
+static gpointer
+load_all_certs_thread (gpointer user_data)
+{
+ LoadAllCertsAsyncData *data = user_data;
+ CERTCertList *certList;
+ CERTCertListNode *node;
+
+ g_return_val_if_fail (data != NULL, NULL);
+
+ certList = PK11_ListCerts (PK11CertListUnique, NULL);
+
+ for (node = CERT_LIST_HEAD (certList);
+ !CERT_LIST_END (node, certList) && !g_cancellable_is_cancelled (data->cancellable);
+ node = CERT_LIST_NEXT (node)) {
+ ECert *cert = e_cert_new (CERT_DupCertificate ((CERTCertificate *) node->cert));
+
+ data->ecerts = g_slist_prepend (data->ecerts, cert);
+ }
+
+ CERT_DestroyCertList (certList);
+
+ g_idle_add_full (G_PRIORITY_HIGH_IDLE, load_all_certs_done_idle_cb, data,
load_all_certs_async_data_free);
+
+ return NULL;
+}
+
+static gboolean
+load_all_threads_try_create_thread (gpointer user_data)
+{
+ LoadAllCertsAsyncData *data = user_data;
+ GThread *thread;
+ GError *error = NULL;
+
+ g_return_val_if_fail (data != NULL, FALSE);
+
+ if (data->tries > 10 || g_cancellable_is_cancelled (data->cancellable)) {
+ load_all_certs_async_data_free (data);
+ return FALSE;
+ }
+
+ thread = g_thread_try_new (NULL, load_all_certs_thread, data, &error);
+ if (g_error_matches (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN)) {
+ data->tries++;
+
+ g_timeout_add (250, load_all_threads_try_create_thread, data);
+ } else if (!thread) {
+ g_warning ("%s: Failed to create thread: %s", G_STRFUNC, error ? error->message : "Unknown
error");
+ } else {
+ g_thread_unref (thread);
+ }
+
+ g_clear_error (&error);
+
+ return FALSE;
+}
+
+static void
+load_all_certs (ECertManagerConfig *ecmc)
+{
+ LoadAllCertsAsyncData *data;
+
+ g_return_if_fail (E_IS_CERT_MANAGER_CONFIG (ecmc));
+
+ if (ecmc->priv->load_all_certs_cancellable) {
+ g_cancellable_cancel (ecmc->priv->load_all_certs_cancellable);
+ g_clear_object (&ecmc->priv->load_all_certs_cancellable);
+ }
+
+ ecmc->priv->load_all_certs_cancellable = g_cancellable_new ();
+
+ data = g_new0 (LoadAllCertsAsyncData, 1);
+ data->ecmc = g_object_ref (ecmc);
+ data->cancellable = g_object_ref (ecmc->priv->load_all_certs_cancellable);
+ data->ecerts = NULL;
+ data->tries = 0;
+
+ load_all_threads_try_create_thread (data);
+}
+
static void
load_certs (CertPage *cp)
{
@@ -1741,28 +1890,9 @@ populate_ui (ECertManagerConfig *ecmc)
{
/* This is an idle callback. */
- ECertManagerConfigPrivate *priv = ecmc->priv;
-
- unload_certs (priv->yourcerts_page);
- load_certs (priv->yourcerts_page);
-
- unload_certs (priv->contactcerts_page);
- load_certs (priv->contactcerts_page);
-
- unload_certs (priv->authoritycerts_page);
- load_certs (priv->authoritycerts_page);
-
+ load_all_certs (ecmc);
load_mail_certs (ecmc);
- /* expand all three trees */
- gtk_tree_view_expand_all (ECMC_TREE_VIEW (yourcerts_page));
- gtk_tree_view_expand_all (ECMC_TREE_VIEW (contactcerts_page));
- gtk_tree_view_expand_all (ECMC_TREE_VIEW (authoritycerts_page));
-
- /* Now load settings of each treeview */
- load_treeview_state (ECMC_TREE_VIEW (yourcerts_page));
- load_treeview_state (ECMC_TREE_VIEW (contactcerts_page));
- load_treeview_state (ECMC_TREE_VIEW (authoritycerts_page));
load_treeview_state (ecmc->priv->mail_tree_view);
return FALSE;
@@ -1898,6 +2028,11 @@ cert_manager_config_dispose (GObject *object)
ecmc->priv->pref_window = NULL;
}
+ if (ecmc->priv->load_all_certs_cancellable) {
+ g_cancellable_cancel (ecmc->priv->load_all_certs_cancellable);
+ g_clear_object (&ecmc->priv->load_all_certs_cancellable);
+ }
+
G_OBJECT_CLASS (e_cert_manager_config_parent_class)->dispose (object);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]