[evolution-data-server] Bug #580198 - IMAP offline mode improvement
- From: Milan Crha <mcrha src gnome org>
- To: svn-commits-list gnome org
- Subject: [evolution-data-server] Bug #580198 - IMAP offline mode improvement
- Date: Tue, 9 Jun 2009 06:57:49 -0400 (EDT)
commit 7aaf3c8b7f66c7221c2d18cab4911a3a2c6e63d7
Author: Milan Crha <mcrha redhat com>
Date: Tue Jun 9 12:56:12 2009 +0200
Bug #580198 - IMAP offline mode improvement
---
camel/camel-folder.c | 2 +
camel/providers/imap/camel-imap-folder.c | 81 ++++++++++++++++++++-------
camel/providers/imap/camel-imap-journal.c | 4 ++
camel/providers/imap/camel-imap-journal.h | 2 +-
camel/providers/local/camel-local-folder.c | 9 ---
5 files changed, 67 insertions(+), 31 deletions(-)
diff --git a/camel/camel-folder.c b/camel/camel-folder.c
index 84d0537..2575084 100644
--- a/camel/camel-folder.c
+++ b/camel/camel-folder.c
@@ -346,7 +346,9 @@ camel_folder_refresh_info (CamelFolder *folder, CamelException *ex)
{
g_return_if_fail (CAMEL_IS_FOLDER (folder));
+ CAMEL_FOLDER_REC_LOCK (folder, lock);
CF_CLASS (folder)->refresh_info (folder, ex);
+ CAMEL_FOLDER_REC_UNLOCK (folder, lock);
}
static gint
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
index b2395d2..1a3ac21 100644
--- a/camel/providers/imap/camel-imap-folder.c
+++ b/camel/providers/imap/camel-imap-folder.c
@@ -233,6 +233,35 @@ camel_imap_folder_get_type (void)
return camel_imap_folder_type;
}
+static void
+replay_offline_journal (CamelImapStore *imap_store, CamelImapFolder *imap_folder, CamelException *ex)
+{
+ CamelIMAPJournal *imap_journal;
+
+ g_return_if_fail (imap_store != NULL);
+ g_return_if_fail (imap_folder != NULL);
+ g_return_if_fail (imap_folder->journal != NULL);
+
+ imap_journal = CAMEL_IMAP_JOURNAL (imap_folder->journal);
+ g_return_if_fail (imap_journal != NULL);
+
+ /* do not replay when still in offline */
+ if (CAMEL_OFFLINE_STORE (imap_store)->state != CAMEL_OFFLINE_STORE_NETWORK_AVAIL || !camel_imap_store_connected (imap_store, ex))
+ return;
+
+ /* Check if the replay is already in progress as imap_sync would be called while expunge resync */
+ if (!imap_journal->rp_in_progress) {
+ imap_journal->rp_in_progress++;
+
+ camel_offline_journal_replay (imap_folder->journal, ex);
+ camel_imap_journal_close_folders (imap_journal);
+ camel_offline_journal_write (imap_folder->journal, ex);
+
+ imap_journal->rp_in_progress--;
+ g_return_if_fail (imap_journal->rp_in_progress >= 0);
+ }
+}
+
CamelFolder *
camel_imap_folder_new (CamelStore *parent, const gchar *folder_name,
const gchar *folder_dir, CamelException *ex)
@@ -298,9 +327,8 @@ camel_imap_folder_new (CamelStore *parent, const gchar *folder_name,
imap_folder->search = camel_imap_search_new(folder_dir);
- camel_offline_journal_replay (imap_folder->journal, ex);
- camel_imap_journal_close_folders ((CamelIMAPJournal *)imap_folder->journal);
- camel_offline_journal_write (CAMEL_IMAP_FOLDER (folder)->journal, ex);
+ /* do not do that here, as other folders for 'transfer' might not be opened yet
+ replay_offline_journal (imap_store, imap_folder, ex);*/
return folder;
}
@@ -706,6 +734,9 @@ imap_refresh_info (CamelFolder *folder, CamelException *ex)
if (camel_application_is_exiting || !camel_imap_store_connected(imap_store, ex))
goto done;
+ /* try to store local changes first, as the summary contains new local messages */
+ replay_offline_journal (imap_store, imap_folder, ex);
+
if (imap_store->current_folder != folder
|| g_ascii_strcasecmp(folder->full_name, "INBOX") == 0) {
response = camel_imap_command (imap_store, folder, ex, NULL);
@@ -770,10 +801,6 @@ imap_refresh_info (CamelFolder *folder, CamelException *ex)
done:
CAMEL_SERVICE_REC_UNLOCK (imap_store, connect_lock);
- camel_offline_journal_replay (CAMEL_IMAP_FOLDER (folder)->journal, ex);
- camel_imap_journal_close_folders ((CamelIMAPJournal *) CAMEL_IMAP_FOLDER (folder)->journal);
- camel_offline_journal_write (CAMEL_IMAP_FOLDER (folder)->journal, ex);
-
camel_folder_summary_save_to_db (folder->summary, ex);
camel_store_summary_save ((CamelStoreSummary *)((CamelImapStore *)folder->parent_store)->summary);
}
@@ -1167,6 +1194,25 @@ imap_rescan (CamelFolder *folder, gint exists, CamelException *ex)
g_array_free (removed, TRUE);
}
+static const gchar *
+get_message_uid (CamelFolder *folder, CamelImapMessageInfo *info)
+{
+ const gchar *uid;
+
+ g_return_val_if_fail (folder != NULL, NULL);
+ g_return_val_if_fail (info != NULL, NULL);
+
+ uid = camel_message_info_uid (info);
+ g_return_val_if_fail (uid != NULL, NULL);
+
+ if (!isdigit ((unsigned char)*uid)) {
+ uid = camel_imap_journal_uidmap_lookup ((CamelIMAPJournal *) CAMEL_IMAP_FOLDER (folder)->journal, uid);
+ g_return_val_if_fail (uid != NULL, NULL);
+ }
+
+ return uid;
+}
+
/* the max number of chars that an unsigned 32-bit gint can be is 10 chars plus 1 for a possible : */
#define UID_SET_FULL(setlen, maxlen) (maxlen > 0 ? setlen + 11 >= maxlen : FALSE)
@@ -1193,7 +1239,7 @@ get_matching (CamelFolder *folder, guint32 flags, guint32 mask, CamelMessageInfo
if (range != i - 1) { \
CamelImapMessageInfo *rinfo = matches->pdata[matches->len - 1]; \
\
- g_string_append_printf (gset, ":%s", camel_message_info_uid (rinfo)); \
+ g_string_append_printf (gset, ":%s", get_message_uid (folder, rinfo)); \
} \
range = -1; \
last_range_uid = -1; \
@@ -1289,12 +1335,12 @@ get_matching (CamelFolder *folder, guint32 flags, guint32 mask, CamelMessageInfo
last_range_uid = uid_num;
if (gset->len)
g_string_append_c (gset, ',');
- g_string_append_printf (gset, "%s", camel_message_info_uid (info));
+ g_string_append_printf (gset, "%s", get_message_uid (folder, info));
}
if (range != -1 && range != max - 1) {
info = matches->pdata[matches->len - 1];
- g_string_append_printf (gset, ":%s", camel_message_info_uid (info));
+ g_string_append_printf (gset, ":%s", get_message_uid (folder, info));
}
if (list1)
@@ -1362,6 +1408,9 @@ imap_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
camel_exception_init (&local_ex);
CAMEL_SERVICE_REC_LOCK (store, connect_lock);
+ /* write local changes first */
+ replay_offline_journal (store, imap_folder, ex);
+
/* Find a message with changed flags, find all of the other
* messages like it, sync them as a group, mark them as
* updated, and continue.
@@ -1484,17 +1533,6 @@ imap_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
if (expunge)
imap_expunge (folder, ex);
- /* Check if the replay is already in progress as imap_sync would be called while expunge resync */
- if (!CAMEL_IMAP_JOURNAL (imap_folder->journal)->rp_in_progress) {
- CAMEL_IMAP_JOURNAL (imap_folder->journal)->rp_in_progress = TRUE;
-
- camel_offline_journal_replay (imap_folder->journal, ex);
- camel_imap_journal_close_folders ((CamelIMAPJournal *)imap_folder->journal);
- camel_offline_journal_write (CAMEL_IMAP_FOLDER (folder)->journal, ex);
-
- CAMEL_IMAP_JOURNAL (imap_folder->journal)->rp_in_progress = FALSE;
- }
-
g_ptr_array_foreach (summary, (GFunc) camel_pstring_free, NULL);
g_ptr_array_free (summary, TRUE);
@@ -2434,6 +2472,7 @@ imap_transfer_resyncing (CamelFolder *source, GPtrArray *uids,
message = camel_folder_get_message (source, uid, NULL);
if (!message) {
/* Message must have been expunged */
+ i++;
continue;
}
info = camel_folder_get_message_info (source, uid);
diff --git a/camel/providers/imap/camel-imap-journal.c b/camel/providers/imap/camel-imap-journal.c
index d82c07f..b8008ed 100644
--- a/camel/providers/imap/camel-imap-journal.c
+++ b/camel/providers/imap/camel-imap-journal.c
@@ -303,8 +303,12 @@ static CamelFolder *
journal_decode_folder (CamelIMAPJournal *journal, const gchar *name)
{
CamelFolder *folder;
+ CamelOfflineJournal *offline = CAMEL_OFFLINE_JOURNAL (journal);
folder = g_hash_table_lookup (journal->folders, name);
+ if (!folder && offline->folder && g_str_equal (offline->folder->full_name, name)) {
+ folder = offline->folder;
+ }
if (!folder) {
CamelException ex;
gchar *msg;
diff --git a/camel/providers/imap/camel-imap-journal.h b/camel/providers/imap/camel-imap-journal.h
index 8419859..ea5e7f0 100644
--- a/camel/providers/imap/camel-imap-journal.h
+++ b/camel/providers/imap/camel-imap-journal.h
@@ -70,7 +70,7 @@ struct _CamelIMAPJournal {
GHashTable *folders;
GHashTable *uidmap;
- gboolean rp_in_progress;
+ gint rp_in_progress;
};
struct _CamelIMAPJournalClass {
diff --git a/camel/providers/local/camel-local-folder.c b/camel/providers/local/camel-local-folder.c
index e05a4f7..1ce89fc 100644
--- a/camel/providers/local/camel-local-folder.c
+++ b/camel/providers/local/camel-local-folder.c
@@ -484,19 +484,10 @@ local_refresh_info(CamelFolder *folder, CamelException *ex)
{
CamelLocalFolder *lf = (CamelLocalFolder *)folder;
- /*
- * Banner: This is a very very ugly hack to get over the summary mismatch. This needs to
- * be done better. Im postponing this post-disk summary.
- * */
-
- CAMEL_FOLDER_REC_LOCK(folder, lock);
-
if (camel_local_summary_check((CamelLocalSummary *)folder->summary, lf->changes, ex) == -1) {
- CAMEL_FOLDER_REC_UNLOCK(folder, lock);
return;
}
- CAMEL_FOLDER_REC_UNLOCK(folder, lock);
if (camel_folder_change_info_changed(lf->changes)) {
camel_object_trigger_event((CamelObject *)folder, "folder_changed", lf->changes);
camel_folder_change_info_clear(lf->changes);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]