[evolution-patches] fix for part of problem behind 40989, delete folder doesn't delete fully



I found out which file descriptors you had left open when you deleted a
folder - the index tables, of course ... :-/

Although the reason they're still open is because the folder browser and
message-list still have a single ref each.  I dont know who has that top
ref (i.e. folder browser) though still, might need some more looking
into.  Could be the folder-cache code.

Anyway the attached patch makes 'delete' close the resources/mark the
in-memory object deleted as well, so that it behaves as an atomic
operation, rather than waiting for an unref to close down.

 Z

Index: camel/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/camel/ChangeLog,v
retrieving revision 1.1796
diff -u -3 -r1.1796 ChangeLog
--- camel/ChangeLog	17 Apr 2003 03:09:37 -0000	1.1796
+++ camel/ChangeLog	18 Apr 2003 02:44:48 -0000
@@ -1,5 +1,29 @@
 2003-04-17  Not Zed  <NotZed Ximian com>
 
+	** for #40989
+
+	* camel-text-index.c (text_index_delete): delete the block
+	file/key file directly, not just its files.
+
+	* providers/local/camel-local-folder.c (local_delete): implement,
+	just delete the index file if it exists.
+	camel-store-delete-folder will delete other data (maybe it all
+	should be done here).
+
+	* camel-block-file.c (camel_key_file_finalise): keep lock around
+	decrementing key file use count.
+	(camel_key_file_delete): new function to delete the key file (&
+	close it off).
+	(key_file_use): if we've been deleted, always fail.
+	(camel_block_file_finalise): only close the file if its a valid
+	fd.
+	(block_file_use): if we've been deleted, always fail.
+	(camel_block_file_delete): delete the block file & close.
+	(struct _CamelBlockFilePrivate): fix the !ENABLE_THREADS case to
+	still compile this.
+
+	** for #41163
+
 	* camel-multipart-signed.c (parse_content): Dont assume adding 1
 	to line length will go to the next line.  e.g. for dos lines that
 	end in \r\n.  Fix for #41163.
Index: camel/camel-block-file.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-block-file.c,v
retrieving revision 1.10
diff -u -3 -r1.10 camel-block-file.c
--- camel/camel-block-file.c	24 Sep 2002 01:16:12 -0000	1.10
+++ camel/camel-block-file.c	18 Apr 2003 02:44:50 -0000
@@ -43,8 +43,6 @@
 
 #define d(x) /*(printf("%s(%d):%s: ",  __FILE__, __LINE__, __PRETTY_FUNCTION__),(x))*/
 
-#ifdef ENABLE_THREADS
-
 /* Locks must be obtained in the order defined */
 
 struct _CamelBlockFilePrivate {
@@ -54,11 +52,15 @@
 
 	struct _CamelBlockFile *base;
 
+#ifdef ENABLE_THREADS
 	pthread_mutex_t root_lock; /* for modifying the root block */
 	pthread_mutex_t cache_lock; /* for refcounting, flag manip, cache manip */
 	pthread_mutex_t io_lock; /* for all io ops */
+#endif
+	unsigned int deleted:1;
 };
 
+#ifdef ENABLE_THREADS
 #define CAMEL_BLOCK_FILE_LOCK(kf, lock) (pthread_mutex_lock(&(kf)->priv->lock))
 #define CAMEL_BLOCK_FILE_TRYLOCK(kf, lock) (pthread_mutex_trylock(&(kf)->priv->lock))
 #define CAMEL_BLOCK_FILE_UNLOCK(kf, lock) (pthread_mutex_unlock(&(kf)->priv->lock))
@@ -237,7 +239,8 @@
 	if (bs->root_block)
 		camel_block_file_unref_block(bs, bs->root_block);
 	g_free(bs->path);
-	close(bs->fd);
+	if (bs->fd != -1)
+		close(bs->fd);
 
 #ifdef ENABLE_THREADS
 	pthread_mutex_destroy(&p->io_lock);
@@ -286,7 +289,11 @@
 
 	if (bs->fd != -1)
 		return 0;
-	else
+	else if (p->deleted) {
+		CAMEL_BLOCK_FILE_UNLOCK(bs, io_lock);
+		errno = ENOENT;
+		return -1;
+	} else
 		d(printf("Turning block file online: %s\n", bs->path));
 
 	if ((bs->fd = open(bs->path, bs->flags, 0600)) == -1) {
@@ -438,6 +445,31 @@
 	return ret;
 }
 
+int
+camel_block_file_delete(CamelBlockFile *bs)
+{
+	int ret;
+	struct _CamelBlockFilePrivate *p = bs->priv;
+
+	CAMEL_BLOCK_FILE_LOCK(bs, io_lock);
+
+	if (bs->fd != -1) {
+		LOCK(block_file_lock);
+		block_file_count--;
+		UNLOCK(block_file_lock);
+		close(bs->fd);
+		bs->fd = -1;
+	}
+
+	p->deleted = TRUE;
+	ret = unlink(bs->path);
+
+	CAMEL_BLOCK_FILE_UNLOCK(bs, io_lock);
+
+	return ret;
+	
+}
+
 /**
  * camel_block_file_new_block:
  * @bs: 
@@ -779,10 +811,10 @@
 	struct _CamelKeyFilePrivate *prev;
 
 	struct _CamelKeyFile *base;
-
 #ifdef ENABLE_THREADS
 	pthread_mutex_t lock;
 #endif
+	unsigned int deleted:1;
 };
 
 #ifdef ENABLE_THREADS
@@ -833,12 +865,14 @@
 
 	LOCK(key_file_lock);
 	e_dlist_remove((EDListNode *)p);
-	UNLOCK(key_file_lock);
 
 	if (bs-> fp) {
 		key_file_count--;
 		fclose(bs->fp);
 	}
+
+	UNLOCK(key_file_lock);
+
 	g_free(bs->path);
 
 #ifdef ENABLE_THREADS
@@ -890,7 +924,11 @@
 
 	if (bs->fp != NULL)
 		return 0;
-	else
+	else if (p->deleted) {
+		CAMEL_KEY_FILE_UNLOCK(bs, lock);
+		errno = ENOENT;
+		return -1;
+	} else
 		d(printf("Turning key file online: '%s'\n", bs->path));
 
 	if ((bs->flags & O_ACCMODE) == O_RDONLY)
@@ -1031,6 +1069,31 @@
 	CAMEL_KEY_FILE_UNLOCK(kf, lock);
 
 	return ret;
+}
+
+int
+camel_key_file_delete(CamelKeyFile *kf)
+{
+	int ret;
+	struct _CamelKeyFilePrivate *p = kf->priv;
+
+	CAMEL_KEY_FILE_LOCK(kf, lock);
+
+	if (kf->fp) {
+		LOCK(key_file_lock);
+		key_file_count--;
+		UNLOCK(key_file_lock);
+		fclose(kf->fp);
+		kf->fp = NULL;
+	}
+
+	p->deleted = TRUE;
+	ret = unlink(kf->path);
+
+	CAMEL_KEY_FILE_UNLOCK(kf, lock);
+
+	return ret;
+	
 }
 
 /**
Index: camel/camel-block-file.h
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-block-file.h,v
retrieving revision 1.2
diff -u -3 -r1.2 camel-block-file.h
--- camel/camel-block-file.h	25 Mar 2002 12:11:42 -0000	1.2
+++ camel/camel-block-file.h	18 Apr 2003 02:44:51 -0000
@@ -99,6 +99,7 @@
 
 CamelBlockFile *camel_block_file_new(const char *path, int flags, const char version[8], size_t block_size);
 int camel_block_file_rename(CamelBlockFile *bs, const char *path);
+int camel_block_file_delete(CamelBlockFile *kf);
 
 CamelBlock *camel_block_file_new_block(CamelBlockFile *bs);
 int camel_block_file_free_block(CamelBlockFile *bs, camel_block_t id);
@@ -134,6 +135,7 @@
 
 CamelKeyFile * camel_key_file_new(const char *path, int flags, const char version[8]);
 int	       camel_key_file_rename(CamelKeyFile *kf, const char *path);
+int	       camel_key_file_delete(CamelKeyFile *kf);
 
 int            camel_key_file_write(CamelKeyFile *kf, camel_block_t *parent, size_t len, camel_key_t *records);
 int            camel_key_file_read(CamelKeyFile *kf, camel_block_t *start, size_t *len, camel_key_t **records);
Index: camel/camel-text-index.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-text-index.c,v
retrieving revision 1.13
diff -u -3 -r1.13 camel-text-index.c
--- camel/camel-text-index.c	6 Mar 2003 15:22:56 -0000	1.13
+++ camel/camel-text-index.c	18 Apr 2003 02:44:55 -0000
@@ -531,7 +531,15 @@
 static int
 text_index_delete(CamelIndex *idx)
 {
-	return camel_text_index_remove(idx->path);
+	struct _CamelTextIndexPrivate *p = CTI_PRIVATE(idx);
+	int ret = 0;
+
+	if (camel_block_file_delete(p->blocks) == -1)
+		ret = -1;
+	if (camel_key_file_delete(p->links) == -1)
+		ret = -1;
+
+	return ret;
 }
 
 static int
Index: camel/providers/local/camel-local-folder.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/providers/local/camel-local-folder.c,v
retrieving revision 1.33
diff -u -3 -r1.33 camel-local-folder.c
--- camel/providers/local/camel-local-folder.c	17 Dec 2002 21:46:41 -0000	1.33
+++ camel/providers/local/camel-local-folder.c	18 Apr 2003 02:44:57 -0000
@@ -79,6 +79,7 @@
 static GPtrArray *local_search_by_uids(CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex);
 static void local_search_free(CamelFolder *folder, GPtrArray * result);
 
+static void local_delete(CamelFolder *folder);
 static void local_rename(CamelFolder *folder, const char *newname);
 
 static void local_finalize(CamelObject * object);
@@ -104,6 +105,7 @@
 	camel_folder_class->search_by_uids = local_search_by_uids;
 	camel_folder_class->search_free = local_search_free;
 
+	camel_folder_class->delete = local_delete;
 	camel_folder_class->rename = local_rename;
 
 	camel_local_folder_class->lock = local_lock;
@@ -434,6 +436,16 @@
 	/* Just do a sync with expunge, serves the same purpose */
 	/* call the callback directly, to avoid locking problems */
 	CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(folder))->sync(folder, TRUE, ex);
+}
+
+static void
+local_delete(CamelFolder *folder)
+{
+	CamelLocalFolder *lf = (CamelLocalFolder *)folder;
+
+	camel_index_delete(lf->index);
+
+	parent_class->delete(folder);
 }
 
 static void


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