|
|
6159b2 |
diff -up evolution-3.22.6/libemail-engine/mail-folder-cache.c.folder-changed-blocked evolution-3.22.6/libemail-engine/mail-folder-cache.c
|
|
|
6159b2 |
--- evolution-3.22.6/libemail-engine/mail-folder-cache.c.folder-changed-blocked 2016-09-19 10:22:58.000000000 +0200
|
|
|
6159b2 |
+++ evolution-3.22.6/libemail-engine/mail-folder-cache.c 2017-05-29 23:35:00.143560314 +0200
|
|
|
6159b2 |
@@ -93,6 +93,12 @@ enum {
|
|
|
6159b2 |
|
|
|
6159b2 |
static guint signals[LAST_SIGNAL];
|
|
|
6159b2 |
|
|
|
6159b2 |
+typedef enum {
|
|
|
6159b2 |
+ E_FIRST_UPDATE_RUNNING,
|
|
|
6159b2 |
+ E_FIRST_UPDATE_FAILED,
|
|
|
6159b2 |
+ E_FIRST_UPDATE_DONE
|
|
|
6159b2 |
+} EFirstUpdateState;
|
|
|
6159b2 |
+
|
|
|
6159b2 |
struct _StoreInfo {
|
|
|
6159b2 |
volatile gint ref_count;
|
|
|
6159b2 |
|
|
|
6159b2 |
@@ -107,7 +113,7 @@ struct _StoreInfo {
|
|
|
6159b2 |
gulong folder_unsubscribed_handler_id;
|
|
|
6159b2 |
|
|
|
6159b2 |
GHashTable *folder_info_ht; /* by full_name */
|
|
|
6159b2 |
- gboolean first_update; /* TRUE, then FALSE forever */
|
|
|
6159b2 |
+ EFirstUpdateState first_update;
|
|
|
6159b2 |
GSList *pending_folder_notes; /* Gather note_folder calls during first_update period */
|
|
|
6159b2 |
|
|
|
6159b2 |
/* Hold a reference to keep them alive. */
|
|
|
6159b2 |
@@ -261,7 +267,7 @@ store_info_new (CamelStore *store)
|
|
|
6159b2 |
store_info = g_slice_new0 (StoreInfo);
|
|
|
6159b2 |
store_info->ref_count = 1;
|
|
|
6159b2 |
store_info->store = g_object_ref (store);
|
|
|
6159b2 |
- store_info->first_update = TRUE;
|
|
|
6159b2 |
+ store_info->first_update = E_FIRST_UPDATE_RUNNING;
|
|
|
6159b2 |
|
|
|
6159b2 |
store_info->folder_info_ht = g_hash_table_new_full (
|
|
|
6159b2 |
(GHashFunc) g_str_hash,
|
|
|
6159b2 |
@@ -1964,7 +1970,7 @@ mail_folder_cache_first_update (MailFold
|
|
|
6159b2 |
g_object_unref (session);
|
|
|
6159b2 |
|
|
|
6159b2 |
g_mutex_lock (&store_info->lock);
|
|
|
6159b2 |
- store_info->first_update = FALSE;
|
|
|
6159b2 |
+ store_info->first_update = E_FIRST_UPDATE_DONE;
|
|
|
6159b2 |
folders = store_info->pending_folder_notes;
|
|
|
6159b2 |
store_info->pending_folder_notes = NULL;
|
|
|
6159b2 |
g_mutex_unlock (&store_info->lock);
|
|
|
6159b2 |
@@ -1988,6 +1994,7 @@ mail_folder_cache_note_store_thread (GSi
|
|
|
6159b2 |
StoreInfo *store_info;
|
|
|
6159b2 |
GQueue result_queue = G_QUEUE_INIT;
|
|
|
6159b2 |
AsyncContext *async_context;
|
|
|
6159b2 |
+ gboolean success = FALSE;
|
|
|
6159b2 |
GError *local_error = NULL;
|
|
|
6159b2 |
|
|
|
6159b2 |
cache = MAIL_FOLDER_CACHE (source_object);
|
|
|
6159b2 |
@@ -2060,17 +2067,22 @@ mail_folder_cache_note_store_thread (GSi
|
|
|
6159b2 |
|
|
|
6159b2 |
/* Do some extra work for the first update. */
|
|
|
6159b2 |
g_mutex_lock (&store_info->lock);
|
|
|
6159b2 |
- if (store_info->first_update) {
|
|
|
6159b2 |
+ if (store_info->first_update != E_FIRST_UPDATE_DONE) {
|
|
|
6159b2 |
g_mutex_unlock (&store_info->lock);
|
|
|
6159b2 |
mail_folder_cache_first_update (cache, store_info);
|
|
|
6159b2 |
} else {
|
|
|
6159b2 |
g_mutex_unlock (&store_info->lock);
|
|
|
6159b2 |
}
|
|
|
6159b2 |
|
|
|
6159b2 |
+ success = TRUE;
|
|
|
6159b2 |
exit:
|
|
|
6159b2 |
/* We don't want finish() functions being invoked while holding a
|
|
|
6159b2 |
* locked mutex, so flush the StoreInfo's queue to a local queue. */
|
|
|
6159b2 |
g_mutex_lock (&store_info->lock);
|
|
|
6159b2 |
+
|
|
|
6159b2 |
+ if (store_info->first_update != E_FIRST_UPDATE_DONE)
|
|
|
6159b2 |
+ store_info->first_update = success ? E_FIRST_UPDATE_DONE : E_FIRST_UPDATE_FAILED;
|
|
|
6159b2 |
+
|
|
|
6159b2 |
e_queue_transfer (&store_info->folderinfo_updates, &result_queue);
|
|
|
6159b2 |
g_mutex_unlock (&store_info->lock);
|
|
|
6159b2 |
|
|
|
6159b2 |
@@ -2130,6 +2142,9 @@ mail_folder_cache_note_store (MailFolder
|
|
|
6159b2 |
|
|
|
6159b2 |
g_mutex_lock (&store_info->lock);
|
|
|
6159b2 |
|
|
|
6159b2 |
+ if (store_info->first_update != E_FIRST_UPDATE_DONE)
|
|
|
6159b2 |
+ store_info->first_update = E_FIRST_UPDATE_RUNNING;
|
|
|
6159b2 |
+
|
|
|
6159b2 |
g_queue_push_tail (
|
|
|
6159b2 |
&store_info->folderinfo_updates,
|
|
|
6159b2 |
g_object_ref (simple));
|
|
|
6159b2 |
@@ -2211,18 +2226,23 @@ mail_folder_cache_note_folder (MailFolde
|
|
|
6159b2 |
* warnings on startup which might be worth tracking down. */
|
|
|
6159b2 |
if (folder_info == NULL) {
|
|
|
6159b2 |
StoreInfo *store_info;
|
|
|
6159b2 |
- gboolean retry = FALSE;
|
|
|
6159b2 |
+ gboolean retry = FALSE, renote_store = FALSE;
|
|
|
6159b2 |
|
|
|
6159b2 |
store_info = mail_folder_cache_ref_store_info (cache, parent_store);
|
|
|
6159b2 |
if (!store_info)
|
|
|
6159b2 |
return;
|
|
|
6159b2 |
|
|
|
6159b2 |
g_mutex_lock (&store_info->lock);
|
|
|
6159b2 |
- if (store_info->first_update) {
|
|
|
6159b2 |
+ if (store_info->first_update != E_FIRST_UPDATE_DONE) {
|
|
|
6159b2 |
/* The first update did not finish yet, thus add this as a pending
|
|
|
6159b2 |
folder to be noted once the first update finishes */
|
|
|
6159b2 |
store_info->pending_folder_notes = g_slist_prepend (
|
|
|
6159b2 |
store_info->pending_folder_notes, g_object_ref (folder));
|
|
|
6159b2 |
+
|
|
|
6159b2 |
+ if (store_info->first_update == E_FIRST_UPDATE_FAILED) {
|
|
|
6159b2 |
+ store_info->first_update = E_FIRST_UPDATE_RUNNING;
|
|
|
6159b2 |
+ renote_store = TRUE;
|
|
|
6159b2 |
+ }
|
|
|
6159b2 |
} else {
|
|
|
6159b2 |
/* It can be that certain threading interleaving made
|
|
|
6159b2 |
the first store update finished before we reached
|
|
|
6159b2 |
@@ -2233,7 +2253,9 @@ mail_folder_cache_note_folder (MailFolde
|
|
|
6159b2 |
|
|
|
6159b2 |
store_info_unref (store_info);
|
|
|
6159b2 |
|
|
|
6159b2 |
- if (retry)
|
|
|
6159b2 |
+ if (renote_store)
|
|
|
6159b2 |
+ mail_folder_cache_note_store (cache, parent_store, NULL, NULL, NULL);
|
|
|
6159b2 |
+ else if (retry)
|
|
|
6159b2 |
folder_info = mail_folder_cache_ref_folder_info (
|
|
|
6159b2 |
cache, parent_store, full_name);
|
|
|
6159b2 |
|