diff options
author | 9 <NotZed@Ximian.com> | 2001-10-19 13:33:21 +0800 |
---|---|---|
committer | Michael Zucci <zucchi@src.gnome.org> | 2001-10-19 13:33:21 +0800 |
commit | 0515ef5e4d5d138f1f7e9956b7a643cc01d7cf19 (patch) | |
tree | 81be21ec9add33d807bd7150887da30db713e5af | |
parent | ec619f7bfaf14ee913f565664459103507adb34f (diff) | |
download | gsoc2013-evolution-0515ef5e4d5d138f1f7e9956b7a643cc01d7cf19.tar.gz gsoc2013-evolution-0515ef5e4d5d138f1f7e9956b7a643cc01d7cf19.tar.zst gsoc2013-evolution-0515ef5e4d5d138f1f7e9956b7a643cc01d7cf19.zip |
Lock the right lock for unmatched subfolder list stuff. If the sub folder
2001-10-19 <NotZed@Ximian.com>
* camel-vee-folder.c (camel_vee_folder_remove_folder): Lock the
right lock for unmatched subfolder list stuff. If the sub folder
is deleted & part of unmatched, or the last ref to the sub folder
is gone from unmatched, blow it away completely from unmatched,
but only do it once.
(vee_folder_remove_folder): Added arg to kill unmatched
unconditionally. Also handle deleted folders, always remove
stuff.
(folder_changed_change): Lock subfolder lock for entirety of
operation, and also check to see if the subfolder is still there
before doing any fancy work (incase it got removed while we were
waiting to execute).
* camel-store.c (camel_store_unsubscribe_folder): If we are
unsubscribing from a folder we have loaded, set the folder
deleted, as with the delete_folder case.
svn path=/trunk/; revision=13786
-rw-r--r-- | camel/ChangeLog | 19 | ||||
-rw-r--r-- | camel/camel-store.c | 34 | ||||
-rw-r--r-- | camel/camel-vee-folder.c | 73 |
3 files changed, 110 insertions, 16 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index acd3428658..840cbe0895 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,18 @@ +2001-10-19 <NotZed@Ximian.com> + + * camel-vee-folder.c (camel_vee_folder_remove_folder): Lock the + right lock for unmatched subfolder list stuff. If the sub folder + is deleted & part of unmatched, or the last ref to the sub folder + is gone from unmatched, blow it away completely from unmatched, + but only do it once. + (vee_folder_remove_folder): Added arg to kill unmatched + unconditionally. Also handle deleted folders, always remove + stuff. + (folder_changed_change): Lock subfolder lock for entirety of + operation, and also check to see if the subfolder is still there + before doing any fancy work (incase it got removed while we were + waiting to execute). + 2001-10-18 Jeffrey Stedfast <fejj@ximian.com> * camel-mime-part-utils.c @@ -9,6 +24,10 @@ 2001-10-18 <NotZed@Ximian.com> + * camel-store.c (camel_store_unsubscribe_folder): If we are + unsubscribing from a folder we have loaded, set the folder + deleted, as with the delete_folder case. + * providers/(imap|local|pop3|sendmail|smtp)/Makefile.am: Added CAMEL_CFLAGS so we get the right iconv stuff, patch from Yanko Kaneti <yaneti@declera.com> diff --git a/camel/camel-store.c b/camel/camel-store.c index 3cd695f1bc..df2f5bebb2 100644 --- a/camel/camel-store.c +++ b/camel/camel-store.c @@ -330,6 +330,8 @@ camel_store_delete_folder (CamelStore *store, const char *folder_name, CamelExce char *key; CAMEL_STORE_LOCK(store, folder_lock); + + /* NB: Note similarity of this code to unsubscribe_folder */ /* if we deleted a folder, force it out of the cache, and also out of the vtrash if setup */ if (store->folders) { @@ -960,13 +962,45 @@ camel_store_unsubscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex) { + CamelFolder *folder = NULL; + char *key; + g_return_if_fail (CAMEL_IS_STORE (store)); g_return_if_fail (store->flags & CAMEL_STORE_SUBSCRIPTIONS); CAMEL_STORE_LOCK(store, folder_lock); + /* NB: Note similarity of this code to delete_folder */ + + /* if we deleted a folder, force it out of the cache, and also out of the vtrash if setup */ + if (store->folders) { + CAMEL_STORE_LOCK(store, cache_lock); + folder = g_hash_table_lookup(store->folders, folder_name); + if (folder) + camel_object_ref((CamelObject *)folder); + CAMEL_STORE_UNLOCK(store, cache_lock); + + if (folder) { + if (store->vtrash) + camel_vee_folder_remove_folder((CamelVeeFolder *)store->vtrash, folder); + camel_folder_delete (folder); + } + } + CS_CLASS (store)->unsubscribe_folder (store, folder_name, ex); + if (folder) + camel_object_unref((CamelObject *)folder); + + if (store->folders) { + CAMEL_STORE_LOCK(store, cache_lock); + if (g_hash_table_lookup_extended(store->folders, folder_name, (void **)&key, (void **)&folder)) { + g_hash_table_remove (store->folders, key); + g_free (key); + } + CAMEL_STORE_UNLOCK(store, cache_lock); + } + CAMEL_STORE_UNLOCK(store, folder_lock); } diff --git a/camel/camel-vee-folder.c b/camel/camel-vee-folder.c index 26f724ab56..2946dffbb2 100644 --- a/camel/camel-vee-folder.c +++ b/camel/camel-vee-folder.c @@ -68,7 +68,7 @@ static void camel_vee_folder_init (CamelVeeFolder *obj); static void camel_vee_folder_finalise (CamelObject *obj); static int vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex); -static void vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source); +static void vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun); static void message_changed(CamelFolder *f, const char *uid, CamelVeeFolder *vf); static void folder_changed(CamelFolder *sub, CamelFolderChangeInfo *changes, CamelVeeFolder *vf); @@ -179,7 +179,7 @@ camel_vee_folder_finalise (CamelObject *obj) camel_object_unhook_event((CamelObject *)f, "deleted", (CamelObjectEventHookFunc) subfolder_deleted, vf); /* this updates the vfolder */ if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) - vee_folder_remove_folder(vf, f); + vee_folder_remove_folder(vf, f, FALSE); } camel_object_unref((CamelObject *)f); @@ -371,6 +371,7 @@ void camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub) { struct _CamelVeeFolderPrivate *p = _PRIVATE(vf), *up = _PRIVATE(folder_unmatched); + int killun = FALSE; CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock); @@ -383,19 +384,34 @@ camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub) return; } + camel_object_unhook_event((CamelObject *)sub, "folder_changed", (CamelObjectEventHookFunc) folder_changed, vf); + camel_object_unhook_event((CamelObject *)sub, "message_changed", (CamelObjectEventHookFunc) message_changed, vf); + camel_object_unhook_event((CamelObject *)sub, "deleted", (CamelObjectEventHookFunc) subfolder_deleted, vf); + p->folders = g_list_remove(p->folders, sub); - if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && g_list_find(p->folders, sub) != NULL) { - up->folders = g_list_remove(up->folders, sub); - camel_object_unref((CamelObject *)sub); - } CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock); - vee_folder_remove_folder(vf, sub); + 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); + } + } 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); + } + if (g_list_find(up->folders, sub) == NULL) { + killun = TRUE; + } + } + CAMEL_VEE_FOLDER_UNLOCK(folder_unmatched, subfolder_lock); - camel_object_unhook_event((CamelObject *)sub, "folder_changed", (CamelObjectEventHookFunc) folder_changed, vf); - camel_object_unhook_event((CamelObject *)sub, "message_changed", (CamelObjectEventHookFunc) message_changed, vf); - camel_object_unhook_event((CamelObject *)sub, "deleted", (CamelObjectEventHookFunc) subfolder_deleted, vf); + vee_folder_remove_folder(vf, sub, killun); camel_object_unref((CamelObject *)sub); } @@ -781,22 +797,22 @@ vee_folder_add_uid(CamelVeeFolder *vf, CamelFolder *f, const char *inuid, const } static void -vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source) +vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun) { int i, count, n, still; char *oldkey; CamelFolder *folder = (CamelFolder *)vf; char hash[8]; - struct _CamelVeeFolderPrivate *p = _PRIVATE(vf); + /*struct _CamelVeeFolderPrivate *p = _PRIVATE(vf);*/ CamelFolderChangeInfo *vf_changes = NULL, *unmatched_changes = 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) { + if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !killun) { CAMEL_VEE_FOLDER_LOCK(folder_unmatched, subfolder_lock); - still = g_list_find(p->folders, source) != NULL; + 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 { @@ -806,6 +822,23 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source) 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) { + 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_summary_remove_index(((CamelFolder *)folder_unmatched)->summary, i); + camel_folder_change_info_remove_uid(folder_unmatched->changes, camel_message_info_uid(mi)); + i--; + } + camel_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)mi); + } + } + } + count = camel_folder_summary_count(folder->summary); for (i=0;i<count;i++) { CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(folder->summary, i); @@ -833,7 +866,6 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source) g_hash_table_remove(unmatched_uids, oldkey); g_free(oldkey); } - camel_folder_summary_remove_uid(((CamelFolder *)folder_unmatched)->summary, uid); } } } @@ -1188,11 +1220,18 @@ folder_changed_change(CamelSession *session, CamelSessionThreadMsg *msg) GPtrArray *matches; GHashTable *matches_hash; - camel_vee_folder_hash_folder(sub, hash); + /* Check the folder hasn't beem removed while we weren't watching */ + CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock); + if (g_list_find(_PRIVATE(vf)->folders, sub) == NULL) { + CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock); + return; + } CAMEL_VEE_FOLDER_LOCK(vf, summary_lock); CAMEL_VEE_FOLDER_LOCK(folder_unmatched, summary_lock); + camel_vee_folder_hash_folder(sub, hash); + 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)); @@ -1283,6 +1322,8 @@ folder_changed_change(CamelSession *session, CamelSessionThreadMsg *msg) camel_object_trigger_event((CamelObject *)vf, "folder_changed", vf_changes); camel_folder_change_info_free(vf_changes); } + + CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock); } static void |