aboutsummaryrefslogtreecommitdiffstats
path: root/camel
diff options
context:
space:
mode:
authorNot Zed <NotZed@Ximian.com>2004-09-28 12:53:28 +0800
committerMichael Zucci <zucchi@src.gnome.org>2004-09-28 12:53:28 +0800
commit665df59a88360115e410d46f50ebe61dead6b151 (patch)
treeecf68dc67404f06d4de946371b6e0f36ce23016b /camel
parentf3c3a422abf537dcfc24030433e9556d34d71492 (diff)
downloadgsoc2013-evolution-665df59a88360115e410d46f50ebe61dead6b151.tar
gsoc2013-evolution-665df59a88360115e410d46f50ebe61dead6b151.tar.gz
gsoc2013-evolution-665df59a88360115e410d46f50ebe61dead6b151.tar.bz2
gsoc2013-evolution-665df59a88360115e410d46f50ebe61dead6b151.tar.lz
gsoc2013-evolution-665df59a88360115e410d46f50ebe61dead6b151.tar.xz
gsoc2013-evolution-665df59a88360115e410d46f50ebe61dead6b151.tar.zst
gsoc2013-evolution-665df59a88360115e410d46f50ebe61dead6b151.zip
free the unmatched uid values as well.
2004-09-24 Not Zed <NotZed@Ximian.com> * camel-vee-store.c (camel_vee_store_finalise): free the unmatched uid values as well. * camel-vee-folder.c (vee_folder_remove_folder): lock main folder summary lock before doing the unmatched stuff, so the order is right. 2004-08-25 Ed Catmur <ed@catmur.co.uk> ** See bug #63881. * camel-vee-store.c: * camel-vee-folder.c: move the unmatched folder onto the camel-vee-store object. Removede the global unmatched folder and associated locks/etc, fixed all the code up to work with the new unmatched folder, if present. svn path=/trunk/; revision=27408
Diffstat (limited to 'camel')
-rw-r--r--camel/ChangeLog19
-rw-r--r--camel/camel-vee-folder.c334
-rw-r--r--camel/camel-vee-folder.h4
-rw-r--r--camel/camel-vee-store.c17
-rw-r--r--camel/camel-vee-store.h3
5 files changed, 211 insertions, 166 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 9d1c574e72..3aadea280d 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,22 @@
+2004-09-24 Not Zed <NotZed@Ximian.com>
+
+ * camel-vee-store.c (camel_vee_store_finalise): free the unmatched
+ uid values as well.
+
+ * camel-vee-folder.c (vee_folder_remove_folder): lock main folder
+ summary lock before doing the unmatched stuff, so the order is
+ right.
+
+2004-08-25 Ed Catmur <ed@catmur.co.uk>
+
+ ** See bug #63881.
+
+ * camel-vee-store.c:
+ * camel-vee-folder.c: move the unmatched
+ folder onto the camel-vee-store object. Removede the global
+ unmatched folder and associated locks/etc, fixed all the code up
+ to work with the new unmatched folder, if present.
+
2004-09-27 Not Zed <NotZed@Ximian.com>
* providers/local/camel-spool-folder.c (camel_spool_folder_new):
diff --git a/camel/camel-vee-folder.c b/camel/camel-vee-folder.c
index 1475c1da25..34211a48aa 100644
--- a/camel/camel-vee-folder.c
+++ b/camel/camel-vee-folder.c
@@ -86,16 +86,6 @@ static void folder_changed_remove_uid(CamelFolder *sub, const char *uid, const c
static CamelFolderClass *camel_vee_folder_parent;
-/* a vfolder for unmatched messages */
-/* use folder_unmatched->summary_lock for access to unmatched_uids or appropriate internals, for consistency */
-static CamelVeeFolder *folder_unmatched;
-static GHashTable *unmatched_uids; /* a refcount of uid's that are matched by any rules */
-static pthread_mutex_t unmatched_lock = PTHREAD_MUTEX_INITIALIZER;
-/* only used to initialise folder_unmatched */
-#define UNMATCHED_LOCK() pthread_mutex_lock(&unmatched_lock)
-#define UNMATCHED_UNLOCK() pthread_mutex_unlock(&unmatched_lock)
-
-
CamelType
camel_vee_folder_get_type (void)
{
@@ -174,6 +164,7 @@ camel_vee_folder_finalise (CamelObject *obj)
CamelVeeFolder *vf = (CamelVeeFolder *)obj;
struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
GList *node;
+ CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
/* FIXME: check leaks */
node = p->folders;
@@ -209,8 +200,8 @@ camel_vee_folder_finalise (CamelObject *obj)
g_free(p);
}
-static void
-vee_folder_construct (CamelVeeFolder *vf, CamelStore *parent_store, const char *name, guint32 flags)
+void
+camel_vee_folder_construct (CamelVeeFolder *vf, CamelStore *parent_store, const char *name, guint32 flags)
{
CamelFolder *folder = (CamelFolder *)vf;
char *tmp;
@@ -227,25 +218,9 @@ vee_folder_construct (CamelVeeFolder *vf, CamelStore *parent_store, const char *
/* should CamelVeeMessageInfo be subclassable ..? */
folder->summary = camel_folder_summary_new();
folder->summary->message_info_size = sizeof(CamelVeeMessageInfo);
-}
-void
-camel_vee_folder_construct(CamelVeeFolder *vf, CamelStore *parent_store, const char *name, guint32 flags)
-{
- UNMATCHED_LOCK();
-
- /* setup unmatched folder if we haven't yet */
- if (folder_unmatched == NULL) {
- unmatched_uids = g_hash_table_new (g_str_hash, g_str_equal);
- folder_unmatched = (CamelVeeFolder *)camel_object_new (camel_vee_folder_get_type ());
- d(printf("created foldeer unmatched %p\n", folder_unmatched));
-
- vee_folder_construct (folder_unmatched, parent_store, CAMEL_UNMATCHED_NAME, CAMEL_STORE_FOLDER_PRIVATE);
- }
-
- UNMATCHED_UNLOCK();
-
- vee_folder_construct (vf, parent_store, name, flags);
+ if (CAMEL_IS_VEE_STORE(parent_store))
+ vf->parent_vee_store = (CamelVeeStore *)parent_store;
}
/**
@@ -263,25 +238,13 @@ camel_vee_folder_new(CamelStore *parent_store, const char *name, guint32 flags)
{
CamelVeeFolder *vf;
char *tmp;
-
- UNMATCHED_LOCK();
-
- /* setup unmatched folder if we haven't yet */
- if (folder_unmatched == NULL) {
- unmatched_uids = g_hash_table_new(g_str_hash, g_str_equal);
- folder_unmatched = vf = (CamelVeeFolder *)camel_object_new(camel_vee_folder_get_type());
- d(printf("created foldeer unmatched %p\n", folder_unmatched));
- vee_folder_construct (vf, parent_store, CAMEL_UNMATCHED_NAME, CAMEL_STORE_FOLDER_PRIVATE);
- }
-
- UNMATCHED_UNLOCK();
-
- if (strcmp(name, CAMEL_UNMATCHED_NAME) == 0) {
- vf = folder_unmatched;
+
+ if (CAMEL_IS_VEE_STORE(parent_store) && strcmp(name, CAMEL_UNMATCHED_NAME) == 0) {
+ vf = ((CamelVeeStore *)parent_store)->folder_unmatched;
camel_object_ref(vf);
} else {
vf = (CamelVeeFolder *)camel_object_new(camel_vee_folder_get_type());
- vee_folder_construct(vf, parent_store, name, flags);
+ camel_vee_folder_construct(vf, parent_store, name, flags);
}
d(printf("returning folder %s %p, count = %d\n", name, vf, camel_folder_get_message_count((CamelFolder *)vf)));
@@ -343,8 +306,9 @@ camel_vee_folder_set_expression(CamelVeeFolder *vf, const char *query)
void
camel_vee_folder_add_folder(CamelVeeFolder *vf, CamelFolder *sub)
{
- struct _CamelVeeFolderPrivate *p = _PRIVATE(vf), *up = _PRIVATE(folder_unmatched);
+ struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
int i;
+ CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
if (vf == (CamelVeeFolder *)sub) {
g_warning("Adding a virtual folder to itself as source, ignored");
@@ -366,7 +330,8 @@ camel_vee_folder_add_folder(CamelVeeFolder *vf, CamelFolder *sub)
CAMEL_FOLDER_UNLOCK(vf, change_lock);
}
- if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub)) {
+ if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub) && folder_unmatched != NULL) {
+ struct _CamelVeeFolderPrivate *up = _PRIVATE(folder_unmatched);
camel_object_ref((CamelObject *)sub);
up->folders = g_list_append(up->folders, sub);
@@ -400,9 +365,10 @@ camel_vee_folder_add_folder(CamelVeeFolder *vf, CamelFolder *sub)
void
camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub)
{
- struct _CamelVeeFolderPrivate *p = _PRIVATE(vf), *up = _PRIVATE(folder_unmatched);
+ struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
int killun = FALSE;
int i;
+ CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock);
@@ -429,36 +395,40 @@ camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub)
CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock);
- CAMEL_VEE_FOLDER_LOCK(folder_unmatched, subfolder_lock);
- /* if folder deleted, then blow it away from unmatched always, and remove all refs to it */
- if (sub->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED) {
- while (g_list_find(up->folders, sub)) {
- killun = TRUE;
- up->folders = g_list_remove(up->folders, sub);
- camel_object_unref((CamelObject *)sub);
-
- /* undo the freeze state that Unmatched has imposed on this source folder */
- CAMEL_FOLDER_LOCK(folder_unmatched, change_lock);
- for (i = 0; i < ((CamelFolder *)folder_unmatched)->priv->frozen; i++)
- camel_folder_thaw(sub);
- CAMEL_FOLDER_UNLOCK(folder_unmatched, change_lock);
- }
- } else if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) {
- if (g_list_find(up->folders, sub) != NULL) {
- up->folders = g_list_remove(up->folders, sub);
- camel_object_unref((CamelObject *)sub);
-
- /* undo the freeze state that Unmatched has imposed on this source folder */
- CAMEL_FOLDER_LOCK(folder_unmatched, change_lock);
- for (i = 0; i < ((CamelFolder *)folder_unmatched)->priv->frozen; i++)
- camel_folder_thaw(sub);
- CAMEL_FOLDER_UNLOCK(folder_unmatched, change_lock);
- }
- if (g_list_find(up->folders, sub) == NULL) {
- killun = TRUE;
+ if (folder_unmatched != NULL) {
+ struct _CamelVeeFolderPrivate *up = _PRIVATE(folder_unmatched);
+
+ CAMEL_VEE_FOLDER_LOCK(folder_unmatched, subfolder_lock);
+ /* if folder deleted, then blow it away from unmatched always, and remove all refs to it */
+ if (sub->folder_flags & CAMEL_FOLDER_HAS_BEEN_DELETED) {
+ while (g_list_find(up->folders, sub)) {
+ killun = TRUE;
+ up->folders = g_list_remove(up->folders, sub);
+ camel_object_unref((CamelObject *)sub);
+
+ /* undo the freeze state that Unmatched has imposed on this source folder */
+ CAMEL_FOLDER_LOCK(folder_unmatched, change_lock);
+ for (i = 0; i < ((CamelFolder *)folder_unmatched)->priv->frozen; i++)
+ camel_folder_thaw(sub);
+ CAMEL_FOLDER_UNLOCK(folder_unmatched, change_lock);
+ }
+ } else if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) {
+ if (g_list_find(up->folders, sub) != NULL) {
+ up->folders = g_list_remove(up->folders, sub);
+ camel_object_unref((CamelObject *)sub);
+
+ /* undo the freeze state that Unmatched has imposed on this source folder */
+ CAMEL_FOLDER_LOCK(folder_unmatched, change_lock);
+ for (i = 0; i < ((CamelFolder *)folder_unmatched)->priv->frozen; i++)
+ camel_folder_thaw(sub);
+ CAMEL_FOLDER_UNLOCK(folder_unmatched, change_lock);
+ }
+ if (g_list_find(up->folders, sub) == NULL) {
+ killun = TRUE;
+ }
}
+ CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, subfolder_lock);
}
- CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, subfolder_lock);
vee_folder_remove_folder(vf, sub, killun);
@@ -689,6 +659,7 @@ vee_search_by_expression(CamelFolder *folder, const char *expression, CamelExcep
CamelVeeFolder *vf = (CamelVeeFolder *)folder;
struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);
GHashTable *searched = g_hash_table_new(NULL, NULL);
+ CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock);
@@ -919,56 +890,59 @@ vee_folder_add_uid(CamelVeeFolder *vf, CamelFolder *f, const char *inuid, const
static void
vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun)
{
- int i, count, n, still, start, last;
+ int i, count, n, still = FALSE, start, last;
char *oldkey;
CamelFolder *folder = (CamelFolder *)vf;
char hash[8];
/*struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);*/
CamelFolderChangeInfo *vf_changes = NULL, *unmatched_changes = NULL;
void *oldval;
+ CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
+ GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
if (vf == folder_unmatched)
return;
- /* check if this folder is still to be part of unmatched */
- if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !killun) {
- CAMEL_VEE_FOLDER_LOCK(folder_unmatched, subfolder_lock);
- still = g_list_find(_PRIVATE(folder_unmatched)->folders, source) != NULL;
- CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, subfolder_lock);
- camel_vee_folder_hash_folder(source, hash);
- } else {
- still = FALSE;
- }
-
CAMEL_VEE_FOLDER_LOCK(vf, summary_lock);
- CAMEL_VEE_FOLDER_LOCK(folder_unmatched, summary_lock);
- /* See if we just blow all uid's from this folder away from unmatched, regardless */
- if (killun) {
- start = -1;
- last = -1;
- count = camel_folder_summary_count(((CamelFolder *)folder_unmatched)->summary);
- for (i=0;i<count;i++) {
- CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(((CamelFolder *)folder_unmatched)->summary, i);
-
- if (mi) {
- if (mi->folder == source) {
- camel_folder_change_info_remove_uid(folder_unmatched->changes, camel_message_info_uid(mi));
- if (last == -1) {
- last = start = i;
- } else if (last+1 == i) {
- last = i;
- } else {
- camel_folder_summary_remove_range(((CamelFolder *)folder_unmatched)->summary, start, last);
- i -= (last-start)+1;
- start = last = i;
+ if (folder_unmatched != NULL) {
+ /* check if this folder is still to be part of unmatched */
+ if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !killun) {
+ CAMEL_VEE_FOLDER_LOCK(folder_unmatched, subfolder_lock);
+ still = g_list_find(_PRIVATE(folder_unmatched)->folders, source) != NULL;
+ CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, subfolder_lock);
+ camel_vee_folder_hash_folder(source, hash);
+ }
+
+ CAMEL_VEE_FOLDER_LOCK(folder_unmatched, summary_lock);
+
+ /* See if we just blow all uid's from this folder away from unmatched, regardless */
+ if (killun) {
+ start = -1;
+ last = -1;
+ count = camel_folder_summary_count(((CamelFolder *)folder_unmatched)->summary);
+ for (i=0;i<count;i++) {
+ CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(((CamelFolder *)folder_unmatched)->summary, i);
+
+ if (mi) {
+ if (mi->folder == source) {
+ camel_folder_change_info_remove_uid(folder_unmatched->changes, camel_message_info_uid(mi));
+ if (last == -1) {
+ last = start = i;
+ } else if (last+1 == i) {
+ last = i;
+ } else {
+ camel_folder_summary_remove_range(((CamelFolder *)folder_unmatched)->summary, start, last);
+ i -= (last-start)+1;
+ start = last = i;
+ }
}
+ camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)mi);
}
- camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)mi);
}
+ if (last != -1)
+ camel_folder_summary_remove_range(((CamelFolder *)folder_unmatched)->summary, start, last);
}
- if (last != -1)
- camel_folder_summary_remove_range(((CamelFolder *)folder_unmatched)->summary, start, last);
}
start = -1;
@@ -991,7 +965,7 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun)
i -= (last-start)+1;
start = last = i;
}
- if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) {
+ if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && folder_unmatched != NULL) {
if (still) {
if (g_hash_table_lookup_extended(unmatched_uids, uid, (void **)&oldkey, &oldval)) {
n = GPOINTER_TO_INT (oldval);
@@ -1019,9 +993,13 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun)
if (last != -1)
camel_folder_summary_remove_range(folder->summary, start, last);
- if (camel_folder_change_info_changed(folder_unmatched->changes)) {
- unmatched_changes = folder_unmatched->changes;
- folder_unmatched->changes = camel_folder_change_info_new();
+ if (folder_unmatched) {
+ if (camel_folder_change_info_changed(folder_unmatched->changes)) {
+ unmatched_changes = folder_unmatched->changes;
+ folder_unmatched->changes = camel_folder_change_info_new();
+ }
+
+ CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, summary_lock);
}
if (camel_folder_change_info_changed(vf->changes)) {
@@ -1029,7 +1007,6 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun)
vf->changes = camel_folder_change_info_new();
}
- CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, summary_lock);
CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock);
if (unmatched_changes) {
@@ -1047,6 +1024,8 @@ struct _update_data {
CamelFolder *source;
CamelVeeFolder *vf;
char hash[8];
+ CamelVeeFolder *folder_unmatched;
+ GHashTable *unmatched_uids;
};
static void
@@ -1058,16 +1037,16 @@ unmatched_check_uid(char *uidin, void *value, struct _update_data *u)
uid = alloca(strlen(uidin)+9);
memcpy(uid, u->hash, 8);
strcpy(uid+8, uidin);
- n = GPOINTER_TO_INT(g_hash_table_lookup(unmatched_uids, uid));
+ n = GPOINTER_TO_INT(g_hash_table_lookup(u->unmatched_uids, uid));
if (n == 0) {
- if (vee_folder_add_uid(folder_unmatched, u->source, uidin, u->hash))
- camel_folder_change_info_add_uid(folder_unmatched->changes, uid);
+ if (vee_folder_add_uid(u->folder_unmatched, u->source, uidin, u->hash))
+ camel_folder_change_info_add_uid(u->folder_unmatched->changes, uid);
} else {
- CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(((CamelFolder *)folder_unmatched)->summary, uid);
+ CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(((CamelFolder *)u->folder_unmatched)->summary, uid);
if (mi) {
- camel_folder_summary_remove(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)mi);
- camel_folder_change_info_remove_uid(folder_unmatched->changes, uid);
- camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)mi);
+ camel_folder_summary_remove(((CamelFolder *)u->folder_unmatched)->summary, (CamelMessageInfo *)mi);
+ camel_folder_change_info_remove_uid(u->folder_unmatched->changes, uid);
+ camel_folder_summary_info_free(((CamelFolder *)u->folder_unmatched)->summary, (CamelMessageInfo *)mi);
}
}
}
@@ -1083,12 +1062,12 @@ folder_added_uid(char *uidin, void *value, struct _update_data *u)
if ( (mi = vee_folder_add_uid(u->vf, u->source, uidin, u->hash)) ) {
camel_folder_change_info_add_uid(u->vf->changes, camel_message_info_uid(mi));
- if (!CAMEL_IS_VEE_FOLDER(u->source)) {
- if (g_hash_table_lookup_extended(unmatched_uids, camel_message_info_uid(mi), (void **)&oldkey, &oldval)) {
+ if (!CAMEL_IS_VEE_FOLDER(u->source) && u->unmatched_uids != NULL) {
+ if (g_hash_table_lookup_extended(u->unmatched_uids, camel_message_info_uid(mi), (void **)&oldkey, &oldval)) {
n = GPOINTER_TO_INT (oldval);
- g_hash_table_insert(unmatched_uids, oldkey, GINT_TO_POINTER(n+1));
+ g_hash_table_insert(u->unmatched_uids, oldkey, GINT_TO_POINTER(n+1));
} else {
- g_hash_table_insert(unmatched_uids, g_strdup(camel_message_info_uid(mi)), GINT_TO_POINTER(1));
+ g_hash_table_insert(u->unmatched_uids, g_strdup(camel_message_info_uid(mi)), GINT_TO_POINTER(1));
}
}
}
@@ -1105,6 +1084,8 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException
int i, n, count, start, last;
struct _update_data u;
CamelFolderChangeInfo *vf_changes = NULL, *unmatched_changes = NULL;
+ CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
+ GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
if (vf == folder_unmatched)
return 0;
@@ -1120,6 +1101,8 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException
u.source = source;
u.vf = vf;
+ u.folder_unmatched = folder_unmatched;
+ u.unmatched_uids = unmatched_uids;
camel_vee_folder_hash_folder(source, u.hash);
CAMEL_VEE_FOLDER_LOCK(vf, summary_lock);
@@ -1136,7 +1119,8 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException
if (g_hash_table_lookup(matchhash, all->pdata[i]) == NULL)
g_hash_table_insert(allhash, all->pdata[i], GINT_TO_POINTER (1));
- CAMEL_VEE_FOLDER_LOCK(folder_unmatched, summary_lock);
+ if (folder_unmatched != NULL)
+ CAMEL_VEE_FOLDER_LOCK(folder_unmatched, summary_lock);
/* scan, looking for "old" uid's to be removed */
start = -1;
@@ -1162,6 +1146,7 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException
}
camel_folder_change_info_remove_uid(vf->changes, camel_message_info_uid(mi));
if (!CAMEL_IS_VEE_FOLDER(source)
+ && unmatched_uids != NULL
&& g_hash_table_lookup_extended(unmatched_uids, uid, (void **)&oldkey, &oldval)) {
n = GPOINTER_TO_INT (oldval);
if (n == 1) {
@@ -1184,36 +1169,40 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException
/* now matchhash contains any new uid's, add them, etc */
g_hash_table_foreach(matchhash, (GHFunc)folder_added_uid, &u);
- /* scan unmatched, remove any that have vanished, etc */
- count = camel_folder_summary_count(((CamelFolder *)folder_unmatched)->summary);
- for (i=0;i<count;i++) {
- CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(((CamelFolder *)folder_unmatched)->summary, i);
+ if (folder_unmatched != NULL) {
+ /* scan unmatched, remove any that have vanished, etc */
+ count = camel_folder_summary_count(((CamelFolder *)folder_unmatched)->summary);
+ for (i=0;i<count;i++) {
+ CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(((CamelFolder *)folder_unmatched)->summary, i);
- if (mi) {
- if (mi->folder == source) {
- char *uid = (char *)camel_message_info_uid(mi);
+ if (mi) {
+ if (mi->folder == source) {
+ char *uid = (char *)camel_message_info_uid(mi);
- if (g_hash_table_lookup(allhash, uid+8) == NULL) {
- /* no longer exists at all, just remove it entirely */
- camel_folder_summary_remove_index(((CamelFolder *)folder_unmatched)->summary, i);
- camel_folder_change_info_remove_uid(folder_unmatched->changes, camel_message_info_uid(mi));
- i--;
- } else {
- g_hash_table_remove(allhash, uid+8);
+ if (g_hash_table_lookup(allhash, uid+8) == NULL) {
+ /* no longer exists at all, just remove it entirely */
+ camel_folder_summary_remove_index(((CamelFolder *)folder_unmatched)->summary, i);
+ camel_folder_change_info_remove_uid(folder_unmatched->changes, camel_message_info_uid(mi));
+ i--;
+ } else {
+ g_hash_table_remove(allhash, uid+8);
+ }
}
+ camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)mi);
}
- camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)mi);
}
- }
- /* now allhash contains all potentially new uid's for the unmatched folder, process */
- if (!CAMEL_IS_VEE_FOLDER(source))
- g_hash_table_foreach(allhash, (GHFunc)unmatched_check_uid, &u);
+ /* now allhash contains all potentially new uid's for the unmatched folder, process */
+ if (!CAMEL_IS_VEE_FOLDER(source))
+ g_hash_table_foreach(allhash, (GHFunc)unmatched_check_uid, &u);
- /* copy any changes so we can raise them outside the lock */
- if (camel_folder_change_info_changed(folder_unmatched->changes)) {
- unmatched_changes = folder_unmatched->changes;
- folder_unmatched->changes = camel_folder_change_info_new();
+ /* copy any changes so we can raise them outside the lock */
+ if (camel_folder_change_info_changed(folder_unmatched->changes)) {
+ unmatched_changes = folder_unmatched->changes;
+ folder_unmatched->changes = camel_folder_change_info_new();
+ }
+
+ CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, summary_lock);
}
if (camel_folder_change_info_changed(vf->changes)) {
@@ -1221,7 +1210,6 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException
vf->changes = camel_folder_change_info_new();
}
- CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, summary_lock);
CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock);
g_hash_table_destroy(matchhash);
@@ -1262,6 +1250,8 @@ folder_changed_add_uid(CamelFolder *sub, const char *uid, const char hash[8], Ca
char *oldkey;
void *oldval;
int n;
+ CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
+ GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
vinfo = vee_folder_add_uid(vf, sub, uid, hash);
if (vinfo == NULL)
@@ -1270,7 +1260,7 @@ folder_changed_add_uid(CamelFolder *sub, const char *uid, const char hash[8], Ca
vuid = camel_message_info_uid(vinfo);
camel_folder_change_info_add_uid(vf->changes, vuid);
- if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub)) {
+ if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub) && folder_unmatched != NULL) {
if (g_hash_table_lookup_extended(unmatched_uids, vuid, (void **)&oldkey, &oldval)) {
n = GPOINTER_TO_INT (oldval);
g_hash_table_insert(unmatched_uids, oldkey, GINT_TO_POINTER(n+1));
@@ -1294,6 +1284,8 @@ folder_changed_remove_uid(CamelFolder *sub, const char *uid, const char hash[8],
void *oldval;
int n;
CamelVeeMessageInfo *vinfo;
+ CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
+ GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
vuid = alloca(strlen(uid)+9);
memcpy(vuid, hash, 8);
@@ -1306,7 +1298,7 @@ folder_changed_remove_uid(CamelFolder *sub, const char *uid, const char hash[8],
camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo);
}
- if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub)) {
+ if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER(sub) && folder_unmatched != NULL) {
if (keep) {
if (g_hash_table_lookup_extended(unmatched_uids, vuid, (void **)&oldkey, &oldval)) {
n = GPOINTER_TO_INT (oldval);
@@ -1342,16 +1334,18 @@ static void
folder_changed_change_uid(CamelFolder *sub, const char *uid, const char hash[8], CamelVeeFolder *vf)
{
char *vuid;
- CamelVeeMessageInfo *vinfo, *uinfo;
+ CamelVeeMessageInfo *vinfo, *uinfo = NULL;
CamelMessageInfo *info;
CamelFolder *folder = (CamelFolder *)vf;
+ CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
vuid = alloca(strlen(uid)+9);
memcpy(vuid, hash, 8);
strcpy(vuid+8, uid);
vinfo = (CamelVeeMessageInfo *)camel_folder_summary_uid(folder->summary, vuid);
- uinfo = (CamelVeeMessageInfo *)camel_folder_summary_uid(((CamelFolder *)folder_unmatched)->summary, vuid);
+ if (folder_unmatched != NULL)
+ uinfo = (CamelVeeMessageInfo *)camel_folder_summary_uid(((CamelFolder *)folder_unmatched)->summary, vuid);
if (vinfo || uinfo) {
info = camel_folder_get_message_info(sub, uid);
if (info) {
@@ -1425,6 +1419,8 @@ folder_changed_change(CamelSession *session, CamelSessionThreadMsg *msg)
*changed;
GPtrArray *always_changed = NULL;
GHashTable *matches_hash;
+ CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
+ GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
/* Check the folder hasn't beem removed while we weren't watching */
CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock);
@@ -1479,7 +1475,8 @@ folder_changed_change(CamelSession *session, CamelSessionThreadMsg *msg)
}
CAMEL_VEE_FOLDER_LOCK(vf, summary_lock);
- CAMEL_VEE_FOLDER_LOCK(folder_unmatched, summary_lock);
+ if (folder_unmatched != NULL)
+ CAMEL_VEE_FOLDER_LOCK(folder_unmatched, summary_lock);
dd(printf("Vfolder '%s' subfolder changed '%s'\n", folder->full_name, sub->full_name));
dd(printf(" changed %d added %d removed %d\n", changes->uid_changed->len, changes->uid_added->len, changes->uid_removed->len));
@@ -1510,7 +1507,7 @@ folder_changed_change(CamelSession *session, CamelSessionThreadMsg *msg)
memcpy(vuid, hash, 8);
strcpy(vuid+8, uid);
- if (!CAMEL_IS_VEE_FOLDER(sub) && g_hash_table_lookup(unmatched_uids, vuid) == NULL) {
+ if (!CAMEL_IS_VEE_FOLDER(sub) && folder_unmatched != NULL && g_hash_table_lookup(unmatched_uids, vuid) == NULL) {
dd(printf(" adding uid '%s' to Unmatched [newly unmatched]\n", (char *)uid));
vinfo = (CamelVeeMessageInfo *)camel_folder_get_message_info((CamelFolder *)folder_unmatched, vuid);
if (vinfo == NULL) {
@@ -1581,17 +1578,20 @@ folder_changed_change(CamelSession *session, CamelSessionThreadMsg *msg)
folder_changed_change_uid(sub, changed->pdata[i], hash, vf);
}
- if (camel_folder_change_info_changed(folder_unmatched->changes)) {
- unmatched_changes = folder_unmatched->changes;
- folder_unmatched->changes = camel_folder_change_info_new();
- }
+ if (folder_unmatched != NULL) {
+ if (camel_folder_change_info_changed(folder_unmatched->changes)) {
+ unmatched_changes = folder_unmatched->changes;
+ folder_unmatched->changes = camel_folder_change_info_new();
+ }
+ CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, summary_lock);
+ }
+
if (camel_folder_change_info_changed(vf->changes)) {
vf_changes = vf->changes;
vf->changes = camel_folder_change_info_new();
}
- CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, summary_lock);
CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock);
/* Cleanup stuff on our folder */
@@ -1608,7 +1608,7 @@ folder_changed_change(CamelSession *session, CamelSessionThreadMsg *msg)
g_ptr_array_free(newchanged, TRUE);
g_free(vuid);
-
+
if (unmatched_changes) {
camel_object_trigger_event((CamelObject *)folder_unmatched, "folder_changed", unmatched_changes);
camel_folder_change_info_free(unmatched_changes);
@@ -1671,6 +1671,8 @@ subfolder_renamed_update(CamelVeeFolder *vf, CamelFolder *sub, char hash[8])
{
int count, i;
CamelFolderChangeInfo *changes = NULL;
+ CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
+ GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
CAMEL_VEE_FOLDER_LOCK(vf, summary_lock);
@@ -1727,6 +1729,7 @@ static void
subfolder_renamed(CamelFolder *f, void *event_data, CamelVeeFolder *vf)
{
char hash[8];
+ CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
/* TODO: This could probably be done in another thread, tho it is pretty quick/memory bound */
@@ -1736,7 +1739,8 @@ subfolder_renamed(CamelFolder *f, void *event_data, CamelVeeFolder *vf)
camel_vee_folder_hash_folder(f, hash);
subfolder_renamed_update(vf, f, hash);
- subfolder_renamed_update(folder_unmatched, f, hash);
+ if (folder_unmatched != NULL)
+ subfolder_renamed_update(folder_unmatched, f, hash);
}
static void
diff --git a/camel/camel-vee-folder.h b/camel/camel-vee-folder.h
index 3339b3a1d9..79f13a7280 100644
--- a/camel/camel-vee-folder.h
+++ b/camel/camel-vee-folder.h
@@ -56,6 +56,10 @@ struct _CamelVeeFolder {
CamelFolderChangeInfo *changes;
CamelFolderSearch *search;
+
+ /* only set-up if our parent is a vee-store, used also as a flag to
+ * say that this folder is part of the unmatched folder */
+ struct _CamelVeeStore *parent_vee_store;
};
struct _CamelVeeFolderClass {
diff --git a/camel/camel-vee-store.c b/camel/camel-vee-store.c
index 770a0239c1..90c6ee1f95 100644
--- a/camel/camel-vee-store.c
+++ b/camel/camel-vee-store.c
@@ -93,12 +93,27 @@ camel_vee_store_init (CamelVeeStore *obj)
/* we dont want a vtrash/vjunk on this one */
store->flags &= ~(CAMEL_STORE_VTRASH | CAMEL_STORE_VJUNK);
+
+ /* Set up unmatched folder */
+ obj->unmatched_uids = g_hash_table_new (g_str_hash, g_str_equal);
+ obj->folder_unmatched = (CamelVeeFolder *)camel_object_new (camel_vee_folder_get_type ());
+ camel_vee_folder_construct (obj->folder_unmatched, store, CAMEL_UNMATCHED_NAME, CAMEL_STORE_FOLDER_PRIVATE);
+}
+
+static void
+cvs_free_unmatched(void *key, void *value, void *data)
+{
+ g_free(key);
}
static void
camel_vee_store_finalise (CamelObject *obj)
{
- ;
+ CamelVeeStore *vstore = (CamelVeeStore *)obj;
+
+ g_hash_table_foreach(vstore->unmatched_uids, cvs_free_unmatched, NULL);
+ g_hash_table_destroy(vstore->unmatched_uids);
+ camel_object_unref(vstore->folder_unmatched);
}
/**
diff --git a/camel/camel-vee-store.h b/camel/camel-vee-store.h
index d0352046be..a5a9864a56 100644
--- a/camel/camel-vee-store.h
+++ b/camel/camel-vee-store.h
@@ -44,6 +44,9 @@ typedef struct _CamelVeeStoreClass CamelVeeStoreClass;
struct _CamelVeeStore {
CamelStore parent;
+ /* Unmatched folder, set up in camel_vee_store_init */
+ struct _CamelVeeFolder *folder_unmatched;
+ GHashTable *unmatched_uids;
};
struct _CamelVeeStoreClass {