[evolution-data-server] I#68 - WebDAV registry backend Refresh can remove existing sources



commit cd03f3f015df0e1306aa40076843846e3dd8140b
Author: Milan Crha <mcrha redhat com>
Date:   Wed Dec 12 11:37:07 2018 +0100

    I#68 - WebDAV registry backend Refresh can remove existing sources
    
    Closes https://gitlab.gnome.org/GNOME/evolution-data-server/issues/68

 src/libebackend/e-backend.c                   | 15 +++++++-
 src/libebackend/e-collection-backend.c        | 50 +++++++++++++++++++++++----
 src/libebackend/e-webdav-collection-backend.c |  5 +--
 src/libedataserver/e-webdav-discover.c        |  9 ++---
 4 files changed, 65 insertions(+), 14 deletions(-)
---
diff --git a/src/libebackend/e-backend.c b/src/libebackend/e-backend.c
index 8e1cc4874..1c09797bd 100644
--- a/src/libebackend/e-backend.c
+++ b/src/libebackend/e-backend.c
@@ -69,6 +69,7 @@ struct _EBackendPrivate {
        GMutex network_monitor_cancellable_lock;
        GCancellable *network_monitor_cancellable;
 
+       GMutex authenticate_lock; /* To not run multiple authenticate requests simultaneously */
        GMutex authenticate_cancellable_lock;
        GCancellable *authenticate_cancellable;
 };
@@ -285,6 +286,7 @@ e_backend_authenticate_sync (EBackend *backend,
                             GError **error)
 {
        EBackendClass *class;
+       ESourceAuthenticationResult res;
 
        g_return_val_if_fail (E_IS_BACKEND (backend), E_SOURCE_AUTHENTICATION_ERROR);
        g_return_val_if_fail (credentials != NULL, E_SOURCE_AUTHENTICATION_ERROR);
@@ -293,7 +295,16 @@ e_backend_authenticate_sync (EBackend *backend,
        g_return_val_if_fail (class != NULL, E_SOURCE_AUTHENTICATION_ERROR);
        g_return_val_if_fail (class->authenticate_sync != NULL, E_SOURCE_AUTHENTICATION_ERROR);
 
-       return class->authenticate_sync (backend, credentials, out_certificate_pem, out_certificate_errors, 
cancellable, error);
+       g_mutex_lock (&backend->priv->authenticate_lock);
+
+       if (g_cancellable_set_error_if_cancelled (cancellable, error))
+               res = E_SOURCE_AUTHENTICATION_ERROR;
+       else
+               res = class->authenticate_sync (backend, credentials, out_certificate_pem, 
out_certificate_errors, cancellable, error);
+
+       g_mutex_unlock (&backend->priv->authenticate_lock);
+
+       return res;
 }
 
 typedef struct _AuthenticateThreadData {
@@ -625,6 +636,7 @@ backend_finalize (GObject *object)
        g_mutex_clear (&priv->property_lock);
        g_mutex_clear (&priv->update_online_state_lock);
        g_mutex_clear (&priv->network_monitor_cancellable_lock);
+       g_mutex_clear (&priv->authenticate_lock);
        g_mutex_clear (&priv->authenticate_cancellable_lock);
 
        /* Chain up to parent's finalize() method. */
@@ -802,6 +814,7 @@ e_backend_init (EBackend *backend)
        g_mutex_init (&backend->priv->property_lock);
        g_mutex_init (&backend->priv->update_online_state_lock);
        g_mutex_init (&backend->priv->network_monitor_cancellable_lock);
+       g_mutex_init (&backend->priv->authenticate_lock);
        g_mutex_init (&backend->priv->authenticate_cancellable_lock);
 
        backend->priv->authenticate_cancellable = NULL;
diff --git a/src/libebackend/e-collection-backend.c b/src/libebackend/e-collection-backend.c
index c92925ea5..5c1f20801 100644
--- a/src/libebackend/e-collection-backend.c
+++ b/src/libebackend/e-collection-backend.c
@@ -142,6 +142,38 @@ collection_backend_children_list (ECollectionBackend *backend)
        return list;
 }
 
+static ESource *
+collection_backend_ref_child_source (ECollectionBackend *backend,
+                                    const gchar *resource_id)
+{
+       ESource *source = NULL;
+       GHashTableIter iter;
+       gpointer key;
+
+       g_mutex_lock (&backend->priv->children_lock);
+
+       g_hash_table_iter_init (&iter, backend->priv->children);
+
+       while (!source && g_hash_table_iter_next (&iter, &key, NULL)) {
+               ESource *candidate = key;
+               gchar *candidate_resource_id;
+
+               if (!candidate)
+                       continue;
+
+               candidate_resource_id = e_collection_backend_dup_resource_id (backend, candidate);
+               if (g_strcmp0 (candidate_resource_id, resource_id) == 0) {
+                       source = g_object_ref (candidate);
+               }
+
+               g_free (candidate_resource_id);
+       }
+
+       g_mutex_unlock (&backend->priv->children_lock);
+
+       return source;
+}
+
 static GFile *
 collection_backend_new_user_file (ECollectionBackend *backend)
 {
@@ -338,15 +370,19 @@ collection_backend_claim_resource (ECollectionBackend *backend,
                g_object_ref (source);
                g_hash_table_remove (unclaimed_resources, resource_id);
        } else {
-               GFile *file = collection_backend_new_user_file (backend);
-               source = collection_backend_new_source (backend, file, error);
-               g_object_unref (file);
+               source = collection_backend_ref_child_source (backend, resource_id);
 
-               if (source) {
-                       if (!backend->priv->new_sources)
-                               backend->priv->new_sources = g_hash_table_new_full (g_str_hash, g_str_equal, 
g_free, NULL);
+               if (!source) {
+                       GFile *file = collection_backend_new_user_file (backend);
+                       source = collection_backend_new_source (backend, file, error);
+                       g_object_unref (file);
 
-                       g_hash_table_insert (backend->priv->new_sources, e_source_dup_uid (source), NULL);
+                       if (source) {
+                               if (!backend->priv->new_sources)
+                                       backend->priv->new_sources = g_hash_table_new_full (g_str_hash, 
g_str_equal, g_free, NULL);
+
+                               g_hash_table_insert (backend->priv->new_sources, e_source_dup_uid (source), 
NULL);
+                       }
                }
        }
 
diff --git a/src/libebackend/e-webdav-collection-backend.c b/src/libebackend/e-webdav-collection-backend.c
index bcf00ec8e..76835cb38 100644
--- a/src/libebackend/e-webdav-collection-backend.c
+++ b/src/libebackend/e-webdav-collection-backend.c
@@ -148,7 +148,6 @@ webdav_collection_add_found_source (ECollectionBackend *collection,
                g_warn_if_fail (source != NULL);
        } else {
                source = e_source_registry_server_ref_source (server, source_uid);
-               g_warn_if_fail (source != NULL);
 
                g_hash_table_remove (known_sources, identity);
        }
@@ -508,6 +507,7 @@ e_webdav_collection_backend_discover_sync (EWebDAVCollectionBackend *webdav_back
        server = e_collection_backend_ref_server (collection);
 
        if (e_source_collection_get_calendar_enabled (collection_extension) && calendar_url &&
+           !g_cancellable_is_cancelled (cancellable) &&
            e_webdav_discover_sources_full_sync (source, calendar_url,
                E_WEBDAV_DISCOVER_SUPPORTS_EVENTS | E_WEBDAV_DISCOVER_SUPPORTS_MEMOS | 
E_WEBDAV_DISCOVER_SUPPORTS_TASKS | E_WEBDAV_DISCOVER_SUPPORTS_CALENDAR_AUTO_SCHEDULE,
                credentials, (EWebDAVDiscoverRefSourceFunc) e_source_registry_server_ref_source, server,
@@ -526,6 +526,7 @@ e_webdav_collection_backend_discover_sync (EWebDAVCollectionBackend *webdav_back
        }
 
        if (!local_error && e_source_collection_get_contacts_enabled (collection_extension) && contacts_url &&
+           !g_cancellable_is_cancelled (cancellable) &&
            e_webdav_discover_sources_full_sync (source, contacts_url, E_WEBDAV_DISCOVER_SUPPORTS_CONTACTS,
                credentials, (EWebDAVDiscoverRefSourceFunc) e_source_registry_server_ref_source, server,
                out_certificate_pem, out_certificate_errors, &discovered_sources, NULL, cancellable, 
&local_error)) {
@@ -540,7 +541,7 @@ e_webdav_collection_backend_discover_sync (EWebDAVCollectionBackend *webdav_back
                any_success = TRUE;
        }
 
-       if (any_success && server) {
+       if (any_success && server && !g_cancellable_is_cancelled (cancellable)) {
                RemoveSourcesData rsd;
 
                rsd.server = server;
diff --git a/src/libedataserver/e-webdav-discover.c b/src/libedataserver/e-webdav-discover.c
index 986cd49c2..a8efac8b5 100644
--- a/src/libedataserver/e-webdav-discover.c
+++ b/src/libedataserver/e-webdav-discover.c
@@ -110,7 +110,7 @@ e_webdav_discover_traverse_propfind_response_cb (EWebDAVSession *webdav,
 
                        length = xmlXPathNodeSetGetLength (xpath_obj->nodesetval);
 
-                       for (ii = 0; ii < length; ii++) {
+                       for (ii = 0; ii < length && !g_cancellable_is_cancelled (wdd->cancellable); ii++) {
                                gchar *home_set_href;
 
                                full_href = NULL;
@@ -145,7 +145,7 @@ e_webdav_discover_traverse_propfind_response_cb (EWebDAVSession *webdav,
 
                        length = xmlXPathNodeSetGetLength (xpath_obj->nodesetval);
 
-                       for (ii = 0; ii < length; ii++) {
+                       for (ii = 0; ii < length && !g_cancellable_is_cancelled (wdd->cancellable); ii++) {
                                gchar *home_set_href, *full_href = NULL;
 
                                home_set_href = e_xml_xpath_eval_as_string (xpath_ctx, 
"%s/C:calendar-home-set/D:href[%d]", xpath_prop_prefix, ii + 1);
@@ -204,7 +204,7 @@ e_webdav_discover_traverse_propfind_response_cb (EWebDAVSession *webdav,
                }
 
                principal_href = e_xml_xpath_eval_as_string (xpath_ctx, "%s/D:current-user-principal/D:href", 
xpath_prop_prefix);
-               if (principal_href && *principal_href) {
+               if (principal_href && *principal_href && !g_cancellable_is_cancelled (wdd->cancellable)) {
                        full_href = e_webdav_session_ensure_full_uri (webdav, request_uri, principal_href);
 
                        if (full_href && *full_href)
@@ -219,7 +219,7 @@ e_webdav_discover_traverse_propfind_response_cb (EWebDAVSession *webdav,
                g_free (principal_href);
 
                principal_href = e_xml_xpath_eval_as_string (xpath_ctx, "%s/D:principal-URL/D:href", 
xpath_prop_prefix);
-               if (principal_href && *principal_href) {
+               if (principal_href && *principal_href && !g_cancellable_is_cancelled (wdd->cancellable)) {
                        full_href = e_webdav_session_ensure_full_uri (webdav, request_uri, principal_href);
 
                        if (full_href && *full_href)
@@ -238,6 +238,7 @@ e_webdav_discover_traverse_propfind_response_cb (EWebDAVSession *webdav,
                        GSList *resources = NULL;
 
                        if (!g_hash_table_contains (wdd->covered_hrefs, href) &&
+                           !g_cancellable_is_cancelled (wdd->cancellable) &&
                            e_webdav_session_list_sync (webdav, href, E_WEBDAV_DEPTH_THIS,
                                E_WEBDAV_LIST_SUPPORTS | E_WEBDAV_LIST_DISPLAY_NAME | 
E_WEBDAV_LIST_DESCRIPTION | E_WEBDAV_LIST_COLOR,
                                &resources, wdd->cancellable, wdd->error)) {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]