changeset 16769:827ebbf9da5f

imapc: Abort pending commands before any deinitialization to avoid crashes.
author Timo Sirainen <tss@iki.fi>
date Thu, 19 Sep 2013 22:20:56 +0300
parents b92118278b06
children ed1f5b4f38be
files src/lib-imap-client/imapc-client.c src/lib-imap-client/imapc-client.h src/lib-storage/index/imapc/imapc-list.c src/lib-storage/index/imapc/imapc-storage.c
diffstat 4 files changed, 27 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-imap-client/imapc-client.c	Wed Sep 18 23:24:30 2013 +0300
+++ b/src/lib-imap-client/imapc-client.c	Thu Sep 19 22:20:56 2013 +0300
@@ -110,17 +110,27 @@
 	pool_unref(&client->pool);
 }
 
+void imapc_client_disconnect(struct imapc_client *client)
+{
+	struct imapc_client_connection *const *conns, *conn;
+	unsigned int i, count;
+
+	conns = array_get(&client->conns, &count);
+	for (i = count; i > 0; i--) {
+		conn = conns[i-1];
+		array_delete(&client->conns, i-1, 1);
+
+		i_assert(imapc_connection_get_mailbox(conn->conn) == NULL);
+		imapc_connection_deinit(&conn->conn);
+		i_free(conn);
+	}
+}
+
 void imapc_client_deinit(struct imapc_client **_client)
 {
 	struct imapc_client *client = *_client;
-	struct imapc_client_connection **connp;
 
-	array_foreach_modifiable(&client->conns, connp) {
-		i_assert(imapc_connection_get_mailbox((*connp)->conn) == NULL);
-		imapc_connection_deinit(&(*connp)->conn);
-		i_free(*connp);
-	}
-	array_clear(&client->conns);
+	imapc_client_disconnect(client);
 	imapc_client_unref(_client);
 }
 
--- a/src/lib-imap-client/imapc-client.h	Wed Sep 18 23:24:30 2013 +0300
+++ b/src/lib-imap-client/imapc-client.h	Thu Sep 19 22:20:56 2013 +0300
@@ -134,6 +134,7 @@
 
 struct imapc_client *
 imapc_client_init(const struct imapc_client_settings *set);
+void imapc_client_disconnect(struct imapc_client *client);
 void imapc_client_deinit(struct imapc_client **client);
 
 /* Explicitly login to server (also done automatically). */
--- a/src/lib-storage/index/imapc/imapc-list.c	Wed Sep 18 23:24:30 2013 +0300
+++ b/src/lib-storage/index/imapc/imapc-list.c	Thu Sep 19 22:20:56 2013 +0300
@@ -98,12 +98,16 @@
 {
 	struct imapc_mailbox_list *list = (struct imapc_mailbox_list *)_list;
 
+	/* make sure all pending commands are aborted before anything is
+	   deinitialized */
+	imapc_client_disconnect(list->client->client);
+
+	imapc_storage_client_unref(&list->client);
 	if (list->index_list != NULL)
 		mailbox_list_destroy(&list->index_list);
 	mailbox_tree_deinit(&list->mailboxes);
 	if (list->tmp_subscriptions != NULL)
 		mailbox_tree_deinit(&list->tmp_subscriptions);
-	imapc_storage_client_unref(&list->client);
 	pool_unref(&list->list.pool);
 }
 
--- a/src/lib-storage/index/imapc/imapc-storage.c	Wed Sep 18 23:24:30 2013 +0300
+++ b/src/lib-storage/index/imapc/imapc-storage.c	Thu Sep 19 22:20:56 2013 +0300
@@ -295,6 +295,10 @@
 {
 	struct imapc_storage *storage = (struct imapc_storage *)_storage;
 
+	/* make sure all pending commands are aborted before anything is
+	   deinitialized */
+	imapc_client_disconnect(storage->client->client);
+
 	imapc_storage_client_unref(&storage->client);
 	index_storage_destroy(_storage);
 }