dovecot-2.1: imapc: When closing mailbox, don't abort any pendin...

dovecot at dovecot.org dovecot at dovecot.org
Wed Sep 7 17:15:21 EEST 2011


details:   http://hg.dovecot.org/dovecot-2.1/rev/d3335654e9a7
changeset: 13427:d3335654e9a7
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Sep 07 17:15:10 2011 +0300
description:
imapc: When closing mailbox, don't abort any pending non-mailbox commands.

diffstat:

 src/lib-storage/index/imapc/imapc-client.c     |   7 +-
 src/lib-storage/index/imapc/imapc-connection.c |  72 +++++++++++++++----------
 src/lib-storage/index/imapc/imapc-connection.h |  11 ++-
 3 files changed, 52 insertions(+), 38 deletions(-)

diffs (242 lines):

diff -r fdca1c2cce01 -r d3335654e9a7 src/lib-storage/index/imapc/imapc-client.c
--- a/src/lib-storage/index/imapc/imapc-client.c	Wed Sep 07 16:44:14 2011 +0300
+++ b/src/lib-storage/index/imapc/imapc-client.c	Wed Sep 07 17:15:10 2011 +0300
@@ -185,7 +185,7 @@
 	conn = imapc_client_find_connection(client);
 
 	va_start(args, cmd_fmt);
-	imapc_connection_cmdvf(conn, callback, context, cmd_fmt, args);
+	imapc_connection_cmdvf(conn, FALSE, callback, context, cmd_fmt, args);
 	va_end(args);
 }
 
@@ -317,7 +317,8 @@
 	}
 
 	ctx = imapc_client_mailbox_cmd_common(box, callback, context);
-	imapc_connection_cmd(box->conn, cmd, imapc_client_mailbox_cmd_cb, ctx);
+	imapc_connection_cmd(box->conn, TRUE, cmd,
+			     imapc_client_mailbox_cmd_cb, ctx);
 }
 
 void imapc_client_mailbox_cmdf(struct imapc_client_mailbox *box,
@@ -335,7 +336,7 @@
 
 	ctx = imapc_client_mailbox_cmd_common(box, callback, context);
 	va_start(args, cmd_fmt);
-	imapc_connection_cmdvf(box->conn, imapc_client_mailbox_cmd_cb,
+	imapc_connection_cmdvf(box->conn, TRUE, imapc_client_mailbox_cmd_cb,
 			       ctx, cmd_fmt, args);
 	va_end(args);
 }
diff -r fdca1c2cce01 -r d3335654e9a7 src/lib-storage/index/imapc/imapc-connection.c
--- a/src/lib-storage/index/imapc/imapc-connection.c	Wed Sep 07 16:44:14 2011 +0300
+++ b/src/lib-storage/index/imapc/imapc-connection.c	Wed Sep 07 17:15:10 2011 +0300
@@ -50,6 +50,7 @@
 	void *context;
 
 	unsigned int idle:1;
+	unsigned int mailboxcmd:1;
 };
 
 struct imapc_connection_literal {
@@ -613,18 +614,18 @@
 	     need_literal(set->username) && need_literal(set->password)) ||
 	    (conn->capabilities & IMAPC_CAPABILITY_AUTH_PLAIN) == 0) {
 		/* We can use LOGIN command */
-		imapc_connection_cmdf(conn, imapc_connection_login_cb, conn,
-				      "LOGIN %s %s",
+		imapc_connection_cmdf(conn, FALSE, imapc_connection_login_cb,
+				      conn, "LOGIN %s %s",
 				      set->username, set->password);
 	} else if ((conn->capabilities & IMAPC_CAPABILITY_SASL_IR) != 0) {
 		cmd = t_strdup_printf("AUTHENTICATE PLAIN %s",
 			imapc_connection_get_sasl_plain_request(conn));
-		imapc_connection_cmd(conn, cmd,
+		imapc_connection_cmd(conn, FALSE, cmd,
 				     imapc_connection_login_cb, conn);
 	} else {
 		cmd = t_strdup_printf("AUTHENTICATE PLAIN\r\n%s",
 			imapc_connection_get_sasl_plain_request(conn));
-		imapc_connection_cmd(conn, cmd,
+		imapc_connection_cmd(conn, FALSE, cmd,
 				     imapc_connection_login_cb, conn);
 	}
 }
@@ -658,7 +659,7 @@
 			imapc_connection_disconnect(conn);
 			return;
 		}
-		imapc_connection_cmd(conn, "STARTTLS",
+		imapc_connection_cmd(conn, FALSE, "STARTTLS",
 				     imapc_connection_starttls_cb, conn);
 		return;
 	}
@@ -698,7 +699,7 @@
 
 	if (conn->capabilities == 0) {
 		/* capabilities weren't sent in the banner. ask for them. */
-		imapc_connection_cmd(conn, "CAPABILITY",
+		imapc_connection_cmd(conn, FALSE, "CAPABILITY",
 				     imapc_connection_capability_cb, conn);
 	} else {
 		imapc_connection_starttls(conn);
@@ -1293,7 +1294,7 @@
 static void imapc_command_send_more(struct imapc_connection *conn,
 				    struct imapc_command *cmd)
 {
-	const unsigned char *p;
+	const unsigned char *p, *data;
 	unsigned int seek_pos, start_pos, end_pos, size;
 	int ret;
 
@@ -1324,9 +1325,9 @@
 		 p[-1] == '\r' && p[-2] == '}' && p[-3] == '+');
 	end_pos = seek_pos;
 
-	o_stream_send(conn->output,
-		      CONST_PTR_OFFSET(cmd->data->data, cmd->send_pos),
-		      end_pos - cmd->send_pos);
+	data = CONST_PTR_OFFSET(cmd->data->data, cmd->send_pos);
+	size = end_pos - cmd->send_pos;
+	o_stream_send(conn->output, data, size);
 	cmd->send_pos = end_pos;
 
 	if (cmd->send_pos == cmd->data->used) {
@@ -1422,27 +1423,30 @@
 	return cmd;
 }
 
-void imapc_connection_cmd(struct imapc_connection *conn, const char *cmdline,
+void imapc_connection_cmd(struct imapc_connection *conn, bool mailboxcmd,
+			  const char *cmdline,
 			  imapc_command_callback_t *callback, void *context)
 {
 	struct imapc_command *cmd;
 
 	cmd = imapc_connection_cmd_build(cmdline, callback, context);
+	cmd->mailboxcmd = mailboxcmd;
 	imapc_command_send(conn, cmd);
 }
 
-void imapc_connection_cmdf(struct imapc_connection *conn,
+void imapc_connection_cmdf(struct imapc_connection *conn, bool mailboxcmd,
 			   imapc_command_callback_t *callback, void *context,
 			   const char *cmd_fmt, ...)
 {
 	va_list args;
 
 	va_start(args, cmd_fmt);
-	imapc_connection_cmdvf(conn, callback, context, cmd_fmt, args);
+	imapc_connection_cmdvf(conn, mailboxcmd, callback, context,
+			       cmd_fmt, args);
 	va_end(args);
 }
 
-void imapc_connection_cmdvf(struct imapc_connection *conn,
+void imapc_connection_cmdvf(struct imapc_connection *conn, bool mailboxcmd,
 			   imapc_command_callback_t *callback, void *context,
 			   const char *cmd_fmt, va_list args)
 {
@@ -1450,6 +1454,7 @@
 	unsigned int i;
 
 	cmd = imapc_command_begin(callback, context);
+	cmd->mailboxcmd = mailboxcmd;
 	cmd->data = str_new(cmd->pool, 128);
 	str_printfa(cmd->data, "%u ", cmd->tag);
 
@@ -1546,14 +1551,16 @@
 		conn->selected_box = box;
 	}
 
-	imapc_connection_cmdf(conn, callback, context,
+	imapc_connection_cmdf(conn, FALSE, callback, context,
 			      examine ? "EXAMINE %s" : "SELECT %s", name);
 }
 
 void imapc_connection_unselect(struct imapc_client_mailbox *box)
 {
-	struct imapc_command *const *cmdp;
+	struct imapc_connection *conn = box->conn;
+	struct imapc_command *const *cmdp, *cmd;
 	struct imapc_command_reply reply;
+	unsigned int i;
 
 	/* mailbox is being closed. if there are any pending commands, we must
 	   finish them immediately so callbacks don't access any freed
@@ -1562,30 +1569,35 @@
 	reply.state = IMAPC_COMMAND_STATE_DISCONNECTED;
 	reply.text_without_resp = reply.text_full = "Closing mailbox";
 
-	imapc_connection_send_idle_done(box->conn);
+	imapc_connection_send_idle_done(conn);
 
-	array_foreach(&box->conn->cmd_wait_list, cmdp) {
-		if ((*cmdp)->callback != NULL) {
+	array_foreach(&conn->cmd_wait_list, cmdp) {
+		if ((*cmdp)->callback != NULL && (*cmdp)->mailboxcmd) {
 			(*cmdp)->callback(&reply, (*cmdp)->context);
 			(*cmdp)->callback = NULL;
 		}
 	}
-	array_foreach(&box->conn->cmd_send_queue, cmdp) {
-		if ((*cmdp)->callback != NULL) {
-			(*cmdp)->callback(&reply, (*cmdp)->context);
-			(*cmdp)->callback = NULL;
+	for (i = 0; i < array_count(&conn->cmd_send_queue); ) {
+		cmdp = array_idx(&conn->cmd_send_queue, i);
+		cmd = *cmdp;
+		if (!cmd->mailboxcmd)
+			i++;
+		else {
+			array_delete(&conn->cmd_send_queue, i, 1);
+			if (cmd->callback != NULL)
+				cmd->callback(&reply, cmd->context);
+			imapc_command_free(cmd);
 		}
 	}
 
-	if (box->conn->selected_box == NULL &&
-	    box->conn->selecting_box == NULL) {
-		i_assert(box->conn->state == IMAPC_CONNECTION_STATE_DISCONNECTED);
+	if (conn->selected_box == NULL && conn->selecting_box == NULL) {
+		i_assert(conn->state == IMAPC_CONNECTION_STATE_DISCONNECTED);
 	} else {
-		i_assert(box->conn->selected_box == box ||
-			 box->conn->selecting_box == box);
+		i_assert(conn->selected_box == box ||
+			 conn->selecting_box == box);
 
-		box->conn->selected_box = NULL;
-		box->conn->selecting_box = NULL;
+		conn->selected_box = NULL;
+		conn->selecting_box = NULL;
 	}
 }
 
diff -r fdca1c2cce01 -r d3335654e9a7 src/lib-storage/index/imapc/imapc-connection.h
--- a/src/lib-storage/index/imapc/imapc-connection.h	Wed Sep 07 16:44:14 2011 +0300
+++ b/src/lib-storage/index/imapc/imapc-connection.h	Wed Sep 07 17:15:10 2011 +0300
@@ -26,15 +26,16 @@
 void imapc_connection_ioloop_changed(struct imapc_connection *conn);
 void imapc_connection_input_pending(struct imapc_connection *conn);
 
-void imapc_connection_cmd(struct imapc_connection *conn, const char *cmdline,
+void imapc_connection_cmd(struct imapc_connection *conn, bool mailboxcmd,
+			  const char *cmdline,
 			  imapc_command_callback_t *callback, void *context);
-void imapc_connection_cmdf(struct imapc_connection *conn,
+void imapc_connection_cmdf(struct imapc_connection *conn, bool mailboxcmd,
 			   imapc_command_callback_t *callback, void *context,
-			   const char *cmd_fmt, ...) ATTR_FORMAT(4, 5);
-void imapc_connection_cmdvf(struct imapc_connection *conn,
+			   const char *cmd_fmt, ...) ATTR_FORMAT(5, 6);
+void imapc_connection_cmdvf(struct imapc_connection *conn, bool mailboxcmd,
 			    imapc_command_callback_t *callback, void *context,
 			    const char *cmd_fmt, va_list args)
-	ATTR_FORMAT(4, 0);
+	ATTR_FORMAT(5, 0);
 void imapc_connection_select(struct imapc_client_mailbox *box,
 			     const char *name, bool examine,
 			     imapc_command_callback_t *callback, void *context);


More information about the dovecot-cvs mailing list