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