[evolution-ews/wip/mcrha/soup3] Fix listen for server change notifications blocking follow up requests



commit ce3723c12fbb4eb93f2e46654cb4ea245d56a602
Author: Milan Crha <mcrha redhat com>
Date:   Tue May 31 18:01:11 2022 +0200

    Fix listen for server change notifications blocking follow up requests
    
    But not knowing of changes being done while not listening. This will
    need some more changes.

 src/EWS/common/e-ews-connection.c | 56 ++++++++++++++++++++++++++++++++++-----
 src/EWS/common/e-soap-request.c   | 19 +++++++++++++
 src/EWS/common/e-soap-request.h   |  5 ++++
 3 files changed, 74 insertions(+), 6 deletions(-)
---
diff --git a/src/EWS/common/e-ews-connection.c b/src/EWS/common/e-ews-connection.c
index ea6f9e1d..ab30846b 100644
--- a/src/EWS/common/e-ews-connection.c
+++ b/src/EWS/common/e-ews-connection.c
@@ -169,6 +169,37 @@ e_ews_soup_log_printer (SoupLogger *logger,
        g_debug ("%c %s", direction, e_ews_debug_redact_headers (direction, data));
 }
 
+static gboolean ews_connection_notification_delay_cb (gpointer user_data);
+
+static void
+e_ews_connection_unpause_notifications_locked (EEwsConnection *cnc)
+{
+       if (camel_ews_settings_get_listen_notifications (cnc->priv->settings)) {
+               e_ews_debug_print ("Unpause notifications for cnc:%p\n", cnc);
+
+               if (cnc->priv->notification_delay_id)
+                       g_source_remove (cnc->priv->notification_delay_id);
+
+               cnc->priv->notification_delay_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, 5,
+                       ews_connection_notification_delay_cb, e_weak_ref_new (cnc), (GDestroyNotify) 
e_weak_ref_free);
+       }
+}
+
+static void
+e_ews_connection_pause_notifications_locked (EEwsConnection *cnc)
+{
+       if (cnc->priv->notification_delay_id) {
+               g_source_remove (cnc->priv->notification_delay_id);
+               cnc->priv->notification_delay_id = 0;
+       }
+
+       if (cnc->priv->notification) {
+               e_ews_debug_print ("Pause notifications for cnc:%p\n", cnc);
+               e_ews_notification_stop_listening_sync (cnc->priv->notification);
+               g_clear_object (&cnc->priv->notification);
+       }
+}
+
 static ESoupSession *
 e_ews_connection_create_soup_session (EEwsConnection *cnc)
 {
@@ -430,6 +461,12 @@ e_ews_connection_process_request_sync (EEwsConnection *cnc,
        pd.out_certificate_pem = out_certificate_pem;
        pd.out_certificate_errors = out_certificate_errors;
 
+       if (!e_soap_request_get_is_notification (request)) {
+               NOTIFICATION_LOCK (cnc);
+               e_ews_connection_pause_notifications_locked (cnc);
+               NOTIFICATION_UNLOCK (cnc);
+       }
+
        g_mutex_lock (&pd.mutex);
 
        source = g_idle_source_new ();
@@ -444,6 +481,12 @@ e_ews_connection_process_request_sync (EEwsConnection *cnc,
 
        g_mutex_unlock (&pd.mutex);
 
+       if (!e_soap_request_get_is_notification (request)) {
+               NOTIFICATION_LOCK (cnc);
+               e_ews_connection_unpause_notifications_locked (cnc);
+               NOTIFICATION_UNLOCK (cnc);
+       }
+
        persistent_auth = soup_message_headers_get_one (soup_message_get_response_headers (pd.message), 
"Persistent-Auth");
        if (persistent_auth && g_ascii_strcasecmp (persistent_auth, "false") == 0) {
                SoupSessionFeature *feature;
@@ -8067,11 +8110,7 @@ e_ews_connection_enable_notifications_sync (EEwsConnection *cnc,
 
        g_hash_table_foreach (cnc->priv->subscriptions, ews_connection_build_subscribed_folders_list, cnc);
 
-       if (cnc->priv->notification_delay_id)
-               g_source_remove (cnc->priv->notification_delay_id);
-
-       cnc->priv->notification_delay_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, 5,
-               ews_connection_notification_delay_cb, e_weak_ref_new (cnc), (GDestroyNotify) e_weak_ref_free);
+       e_ews_connection_unpause_notifications_locked (cnc);
 
 exit:
        *subscription_key = notification_key;
@@ -8103,7 +8142,7 @@ e_ews_connection_disable_notifications_sync (EEwsConnection *cnc,
 
        g_hash_table_foreach (cnc->priv->subscriptions, ews_connection_build_subscribed_folders_list, cnc);
        if (cnc->priv->subscribed_folders != NULL && !e_ews_connection_get_disconnected_flag (cnc)) {
-               e_ews_notification_start_listening_sync (cnc->priv->notification, 
cnc->priv->subscribed_folders);
+               e_ews_connection_unpause_notifications_locked (cnc);
        } else {
                g_clear_object (&cnc->priv->notification);
        }
@@ -9543,6 +9582,8 @@ e_ews_connection_subscribe_sync (EEwsConnection *cnc,
 
        e_ews_request_write_footer (request);
 
+       e_soap_request_set_is_notification (request, TRUE);
+
        response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
        if (!response) {
@@ -9590,6 +9631,8 @@ e_ews_connection_unsubscribe_sync (EEwsConnection *cnc,
 
        e_ews_request_write_footer (request);
 
+       e_soap_request_set_is_notification (request, TRUE);
+
        response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
 
        if (!response) {
@@ -9729,6 +9772,7 @@ e_ews_connection_read_streaming_events_sync (EEwsConnection *cnc,
        sed->cb_user_data = cb_user_data;
        sed->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
 
+       e_soap_request_set_is_notification (request, TRUE);
        e_soap_request_set_custom_process_fn (request, e_ews_get_streaming_events_custom_process, sed);
 
        response = e_ews_connection_send_request_sync (cnc, request, cancellable, error);
diff --git a/src/EWS/common/e-soap-request.c b/src/EWS/common/e-soap-request.c
index b6cf7f17..23e3e83a 100644
--- a/src/EWS/common/e-soap-request.c
+++ b/src/EWS/common/e-soap-request.c
@@ -49,6 +49,8 @@ struct _ESoapRequestPrivate {
        xmlChar *env_uri;
        gboolean body_started;
        gchar *action;
+
+       gboolean is_notification;
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE (ESoapRequest, e_soap_request, G_TYPE_OBJECT)
@@ -1037,6 +1039,23 @@ e_soap_request_get_etag (ESoapRequest *req)
        return req->priv->etag;
 }
 
+void
+e_soap_request_set_is_notification (ESoapRequest *req,
+                                   gboolean is_notification)
+{
+       g_return_if_fail (E_IS_SOAP_REQUEST (req));
+
+       req->priv->is_notification = is_notification;
+}
+
+gboolean
+e_soap_request_get_is_notification (ESoapRequest *req)
+{
+       g_return_val_if_fail (E_IS_SOAP_REQUEST (req), FALSE);
+
+       return req->priv->is_notification;
+}
+
 void
 e_soap_request_set_store_node_data (ESoapRequest *req,
                                    const gchar *nodename,
diff --git a/src/EWS/common/e-soap-request.h b/src/EWS/common/e-soap-request.h
index fddff613..f5825fb7 100644
--- a/src/EWS/common/e-soap-request.h
+++ b/src/EWS/common/e-soap-request.h
@@ -176,6 +176,11 @@ gboolean   e_soap_request_get_tls_error_details
 void           e_soap_request_set_etag         (ESoapRequest *req,
                                                 const gchar *etag);
 const gchar *  e_soap_request_get_etag         (ESoapRequest *req);
+void           e_soap_request_set_is_notification
+                                               (ESoapRequest *req,
+                                                gboolean is_notification);
+gboolean       e_soap_request_get_is_notification
+                                               (ESoapRequest *req);
 SoupMessage *  e_soap_request_persist          (ESoapRequest *req,
                                                 ESoupSession *soup_session,
                                                 CamelEwsSettings *settings,


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