[evolution-data-server/gnome-3-24] Bug 779749 - [NNTP] Add exclusive usage locking for underlying stream



commit 191c2add752e4fa75be816300b62fe3933a90947
Author: Milan Crha <mcrha redhat com>
Date:   Wed May 3 09:27:36 2017 +0200

    Bug 779749 - [NNTP] Add exclusive usage locking for underlying stream

 src/camel/providers/nntp/camel-nntp-folder.c |   22 +++++++-------
 src/camel/providers/nntp/camel-nntp-store.c  |   40 +++++++++++++++++--------
 src/camel/providers/nntp/camel-nntp-store.h  |    1 +
 src/camel/providers/nntp/camel-nntp-stream.c |   16 ++++++++++
 src/camel/providers/nntp/camel-nntp-stream.h |    2 +
 5 files changed, 57 insertions(+), 24 deletions(-)
---
diff --git a/src/camel/providers/nntp/camel-nntp-folder.c b/src/camel/providers/nntp/camel-nntp-folder.c
index 51efa8c..f75d82c 100644
--- a/src/camel/providers/nntp/camel-nntp-folder.c
+++ b/src/camel/providers/nntp/camel-nntp-folder.c
@@ -252,13 +252,11 @@ nntp_folder_download_message (CamelNNTPFolder *nntp_folder,
 
        ret = camel_nntp_command (
                nntp_store, cancellable, error,
-               nntp_folder, &line, "article %s", id);
+               nntp_folder, &nntp_stream, &line, "article %s", id);
 
        if (ret == 220) {
                GIOStream *base_stream;
 
-               nntp_stream = camel_nntp_store_ref_stream (nntp_store);
-
                base_stream = camel_data_cache_add (
                        nntp_cache, "cache", msgid, NULL);
                if (base_stream != NULL) {
@@ -296,13 +294,16 @@ nntp_folder_download_message (CamelNNTPFolder *nntp_folder,
 
        goto exit;
 
-fail:
+ fail:
        camel_data_cache_remove (nntp_cache, "cache", msgid, NULL);
        g_prefix_error (error, _("Cannot get message %s: "), msgid);
 
        g_clear_object (&stream);
 
-exit:
+ exit:
+       if (nntp_stream)
+               camel_nntp_stream_unlock (nntp_stream);
+
        g_clear_object (&nntp_cache);
        g_clear_object (&nntp_stream);
 
@@ -418,8 +419,7 @@ nntp_folder_append_message_sync (CamelFolder *folder,
        nntp_store = CAMEL_NNTP_STORE (parent_store);
 
        /* send 'POST' command */
-       ret = camel_nntp_command (
-               nntp_store, cancellable, error, NULL, &line, "post");
+       ret = camel_nntp_command (nntp_store, cancellable, error, NULL, &nntp_stream, &line, "post");
        if (ret != 340) {
                if (ret == 440) {
                        g_set_error (
@@ -446,8 +446,6 @@ nntp_folder_append_message_sync (CamelFolder *folder,
        camel_medium_remove_header (CAMEL_MEDIUM (message), "Cc");
        camel_medium_remove_header (CAMEL_MEDIUM (message), "Bcc");
 
-       nntp_stream = camel_nntp_store_ref_stream (nntp_store);
-
        /* setup stream filtering */
        filtered_stream = camel_stream_filter_new (CAMEL_STREAM (nntp_stream));
        crlffilter = camel_mime_filter_crlf_new (
@@ -502,7 +500,9 @@ nntp_folder_append_message_sync (CamelFolder *folder,
 
        camel_name_value_array_free (previous_headers);
 
-exit:
+ exit:
+       if (nntp_stream)
+               camel_nntp_stream_unlock (nntp_stream);
        g_clear_object (&nntp_stream);
 
        return success;
@@ -709,7 +709,7 @@ nntp_folder_refresh_info_sync (CamelFolder *folder,
        /* When invoked with no fmt, camel_nntp_command() just selects the folder
         * and should return zero. */
        success = !camel_nntp_command (
-               nntp_store, cancellable, error, nntp_folder, &line, NULL);
+               nntp_store, cancellable, error, nntp_folder, NULL, &line, NULL);
 
        if (camel_folder_change_info_changed (nntp_folder->changes)) {
                changes = nntp_folder->changes;
diff --git a/src/camel/providers/nntp/camel-nntp-store.c b/src/camel/providers/nntp/camel-nntp-store.c
index b2e1677..6e99d89 100644
--- a/src/camel/providers/nntp/camel-nntp-store.c
+++ b/src/camel/providers/nntp/camel-nntp-store.c
@@ -858,7 +858,7 @@ nntp_store_get_subscribed_folder_info (CamelNNTPStore *nntp_store,
                        if (folder) {
                                CamelFolderChangeInfo *changes = NULL;
 
-                               if (camel_nntp_command (nntp_store, cancellable, NULL, folder, &line, NULL) 
!= -1) {
+                               if (camel_nntp_command (nntp_store, cancellable, NULL, folder, NULL, &line, 
NULL) != -1) {
                                        if (camel_folder_change_info_changed (folder->changes)) {
                                                changes = folder->changes;
                                                folder->changes = camel_folder_change_info_new ();
@@ -1158,7 +1158,7 @@ nntp_get_date (CamelNNTPStore *nntp_store,
        gboolean success = FALSE;
 
        ret = camel_nntp_command (
-               nntp_store, cancellable, error, NULL,
+               nntp_store, cancellable, error, NULL, NULL,
                (gchar **) &line, "date");
 
        nntp_store_summary = camel_nntp_store_ref_summary (nntp_store);
@@ -1215,7 +1215,7 @@ nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store,
                        if (!nntp_get_date (nntp_store, cancellable, NULL))
                                goto do_complete_list_nodate;
 
-                       ret = camel_nntp_command (nntp_store, cancellable, error, NULL, (gchar **) &line, 
"newgroups %s", date);
+                       ret = camel_nntp_command (nntp_store, cancellable, error, NULL, &nntp_stream, (gchar 
**) &line, "newgroups %s", date);
                        if (ret == -1)
                                goto error;
                        else if (ret != 231) {
@@ -1224,8 +1224,6 @@ nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store,
                                goto do_complete_list;
                        }
 
-                       nntp_stream = camel_nntp_store_ref_stream (nntp_store);
-
                        while ((ret = camel_nntp_stream_line (nntp_stream, &line, &len, cancellable, error)) 
0)
                                nntp_store_info_update (nntp_store, (gchar *) line, is_folder_list);
                } else {
@@ -1240,7 +1238,7 @@ nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store,
                        /* at first, we do a DATE to find out the last load occasion */
                        nntp_get_date (nntp_store, cancellable, NULL);
                do_complete_list_nodate:
-                       ret = camel_nntp_command (nntp_store, cancellable, error, NULL, (gchar **) &line, 
"list");
+                       ret = camel_nntp_command (nntp_store, cancellable, error, NULL, &nntp_stream, (gchar 
**) &line, "list");
                        if (ret == -1)
                                goto error;
                        else if (ret != 215) {
@@ -1264,8 +1262,6 @@ nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store,
 
                        camel_store_summary_array_free (store_summary, array);
 
-                       nntp_stream = camel_nntp_store_ref_stream (nntp_store);
-
                        while ((ret = camel_nntp_stream_line (nntp_stream, &line, &len, cancellable, error)) 
0) {
                                si = nntp_store_info_update (nntp_store, (gchar *) line, is_folder_list);
                                g_hash_table_remove (all, si->path);
@@ -1288,7 +1284,9 @@ nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store,
 
        fi = nntp_store_get_cached_folder_info (nntp_store, top, flags, error);
 
-error:
+ error:
+       if (nntp_stream)
+               camel_nntp_stream_unlock (nntp_stream);
        g_clear_object (&nntp_stream);
        g_clear_object (&nntp_store_summary);
 
@@ -2190,6 +2188,7 @@ camel_nntp_command (CamelNNTPStore *nntp_store,
                     GCancellable *cancellable,
                     GError **error,
                     CamelNNTPFolder *folder,
+                   CamelNNTPStream **out_nntp_stream,
                     gchar **line,
                     const gchar *fmt,
                     ...)
@@ -2247,6 +2246,8 @@ camel_nntp_command (CamelNNTPStore *nntp_store,
                        g_return_val_if_fail (nntp_stream != NULL, -1);
                }
 
+               camel_nntp_stream_lock (nntp_stream);
+
                /* Check for unprocessed data, !*/
                if (nntp_stream->mode == CAMEL_NNTP_STREAM_DATA) {
                        g_warning ("Unprocessed data left in stream, flushing");
@@ -2267,13 +2268,14 @@ camel_nntp_command (CamelNNTPStore *nntp_store,
                                nntp_store, cancellable, &local_error,
                                line, "group %s", full_name);
                        if (ret == 211) {
-                               camel_nntp_store_set_current_group (
-                                       nntp_store, full_name);
                                if (camel_nntp_folder_selected (folder, *line, cancellable, &local_error) < 
0) {
+                                       camel_nntp_store_set_current_group (nntp_store, NULL);
                                        ret = -1;
                                        goto error;
                                }
+                               camel_nntp_store_set_current_group (nntp_store, full_name);
                        } else {
+                               camel_nntp_store_set_current_group (nntp_store, NULL);
                                goto error;
                        }
                }
@@ -2349,11 +2351,23 @@ camel_nntp_command (CamelNNTPStore *nntp_store,
                        break;
                }
 
-               g_clear_object (&nntp_stream);
+               if (ret == -1) {
+                       if (nntp_stream)
+                               camel_nntp_stream_unlock (nntp_stream);
+
+                       g_clear_object (&nntp_stream);
+               }
 
        } while (ret == -1 && retry < 3);
 
-exit:
+ exit:
+       if (nntp_stream) {
+               if (ret != -1 && out_nntp_stream)
+                       *out_nntp_stream = g_object_ref (nntp_stream);
+               else
+                       camel_nntp_stream_unlock (nntp_stream);
+       }
+
        g_clear_object (&nntp_stream);
 
        return ret;
diff --git a/src/camel/providers/nntp/camel-nntp-store.h b/src/camel/providers/nntp/camel-nntp-store.h
index 69f1832..3ef8625 100644
--- a/src/camel/providers/nntp/camel-nntp-store.h
+++ b/src/camel/providers/nntp/camel-nntp-store.h
@@ -131,6 +131,7 @@ gint                camel_nntp_command              (CamelNNTPStore *nntp_store,
                                                 GCancellable *cancellable,
                                                 GError **error,
                                                 struct _CamelNNTPFolder *folder,
+                                                CamelNNTPStream **out_nntp_stream,
                                                 gchar **line,
                                                 const gchar *fmt,
                                                 ...);
diff --git a/src/camel/providers/nntp/camel-nntp-stream.c b/src/camel/providers/nntp/camel-nntp-stream.c
index 5861fe9..369a0ed 100644
--- a/src/camel/providers/nntp/camel-nntp-stream.c
+++ b/src/camel/providers/nntp/camel-nntp-stream.c
@@ -529,3 +529,19 @@ camel_nntp_stream_getd (CamelNNTPStream *is,
 
        return 1;
 }
+
+void
+camel_nntp_stream_lock (CamelNNTPStream *nntp_stream)
+{
+       g_return_if_fail (CAMEL_IS_NNTP_STREAM (nntp_stream));
+
+       g_rec_mutex_lock (&nntp_stream->lock);
+}
+
+void
+camel_nntp_stream_unlock (CamelNNTPStream *nntp_stream)
+{
+       g_return_if_fail (CAMEL_IS_NNTP_STREAM (nntp_stream));
+
+       g_rec_mutex_unlock (&nntp_stream->lock);
+}
diff --git a/src/camel/providers/nntp/camel-nntp-stream.h b/src/camel/providers/nntp/camel-nntp-stream.h
index 8e26559..8d1a36b 100644
--- a/src/camel/providers/nntp/camel-nntp-stream.h
+++ b/src/camel/providers/nntp/camel-nntp-stream.h
@@ -92,6 +92,8 @@ gint          camel_nntp_stream_getd          (CamelNNTPStream *is,
                                                 guint *len,
                                                 GCancellable *cancellable,
                                                 GError **error);
+void           camel_nntp_stream_lock          (CamelNNTPStream *nntp_stream);
+void           camel_nntp_stream_unlock        (CamelNNTPStream *nntp_stream);
 
 G_END_DECLS
 


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