dovecot: Added "command state" for running commands. Use it inst...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Jan 12 08:51:21 EET 2008
details: http://hg.dovecot.org/dovecot/rev/5e3188213724
changeset: 7148:5e3188213724
user: Timo Sirainen <tss at iki.fi>
date: Sat Jan 12 06:46:28 2008 +0200
description:
Added "command state" for running commands. Use it instead of some bitfields
to test for the current state.
diffstat:
7 files changed, 40 insertions(+), 31 deletions(-)
src/imap/client.c | 45 +++++++++++++++++++++------------------------
src/imap/client.h | 14 +++++++++++++-
src/imap/cmd-append.c | 2 +-
src/imap/cmd-fetch.c | 2 +-
src/imap/cmd-idle.c | 4 ++--
src/imap/cmd-list.c | 2 +-
src/imap/imap-sync.c | 2 +-
diffs (221 lines):
diff -r 740a17139b67 -r 5e3188213724 src/imap/client.c
--- a/src/imap/client.c Fri Jan 11 07:07:09 2008 +0200
+++ b/src/imap/client.c Sat Jan 12 06:46:28 2008 +0200
@@ -71,7 +71,7 @@ void client_command_cancel(struct client
cmd->cancel = TRUE;
cmd_ret = cmd->func == NULL ? TRUE : cmd->func(cmd);
- if (!cmd_ret && !cmd->param_error) {
+ if (!cmd_ret && cmd->state != CLIENT_COMMAND_STATE_DONE) {
if (cmd->client->output->closed)
i_panic("command didn't cancel itself: %s", cmd->name);
} else {
@@ -258,10 +258,11 @@ void client_send_command_error(struct cl
"Too many invalid IMAP commands.");
}
+ cmd->param_error = TRUE;
/* client_read_args() failures rely on this being set, so that the
command processing is stopped even while command function returns
FALSE. */
- cmd->param_error = TRUE;
+ cmd->state = CLIENT_COMMAND_STATE_DONE;
}
bool client_read_args(struct client_command_context *cmd, unsigned int count,
@@ -282,7 +283,7 @@ bool client_read_args(struct client_comm
/* need more data */
if (cmd->client->input->closed) {
/* disconnected */
- cmd->param_error = TRUE;
+ cmd->state = CLIENT_COMMAND_STATE_DONE;
}
return FALSE;
} else {
@@ -479,6 +480,7 @@ void client_continue_pending_input(struc
if (client_command_check_ambiguity(client->input_lock))
return;
client->input_lock->waiting_unambiguity = FALSE;
+ client->input_lock->state = CLIENT_COMMAND_STATE_WAIT_INPUT;
}
client_add_missing_io(client);
@@ -518,10 +520,8 @@ static void client_idle_output_timeout(s
bool client_handle_unfinished_cmd(struct client_command_context *cmd)
{
- if (!cmd->output_pending) {
- /* need more input */
- return FALSE;
- }
+ if (cmd->state != CLIENT_COMMAND_STATE_WAIT_OUTPUT)
+ return FALSE;
/* output is blocking, we can execute more commands */
o_stream_set_flush_pending(cmd->client->output, TRUE);
@@ -537,10 +537,11 @@ static bool client_command_input(struct
static bool client_command_input(struct client_command_context *cmd)
{
struct client *client = cmd->client;
+ struct command *command;
if (cmd->func != NULL) {
/* command is being executed - continue it */
- if (cmd->func(cmd) || cmd->param_error) {
+ if (cmd->func(cmd) || cmd->state == CLIENT_COMMAND_STATE_DONE) {
/* command execution was finished */
client_command_free(cmd);
client_add_missing_io(client);
@@ -568,20 +569,16 @@ static bool client_command_input(struct
if (cmd->name == '\0') {
/* command not given - cmd_func is already NULL. */
- } else {
- /* find the command function */
- struct command *command = command_find(cmd->name);
-
- if (command != NULL) {
- cmd->func = command->func;
- cmd->cmd_flags = command->flags;
- if (client_command_check_ambiguity(cmd)) {
- /* do nothing until existing commands are
- finished */
- cmd->waiting_unambiguity = TRUE;
- io_remove(&client->io);
- return FALSE;
- }
+ } else if ((command = command_find(cmd->name)) != NULL) {
+ cmd->func = command->func;
+ cmd->cmd_flags = command->flags;
+ if (client_command_check_ambiguity(cmd)) {
+ /* do nothing until existing commands are finished */
+ i_assert(cmd->state == CLIENT_COMMAND_STATE_WAIT_INPUT);
+ cmd->waiting_unambiguity = TRUE;
+ cmd->state = CLIENT_COMMAND_STATE_WAIT;
+ io_remove(&client->io);
+ return FALSE;
}
}
@@ -701,7 +698,7 @@ static void client_output_cmd(struct cli
bool finished;
/* continue processing command */
- finished = cmd->func(cmd) || cmd->param_error;
+ finished = cmd->func(cmd) || cmd->state == CLIENT_COMMAND_STATE_DONE;
if (!finished)
(void)client_handle_unfinished_cmd(cmd);
@@ -735,7 +732,7 @@ int client_output(struct client *client)
cmd = client->command_queue;
for (; cmd != NULL; cmd = next) {
next = cmd->next;
- if (!cmd->waiting_unambiguity) {
+ if (cmd->state == CLIENT_COMMAND_STATE_WAIT_OUTPUT) {
client_output_cmd(cmd);
if (client->output_lock != NULL)
break;
diff -r 740a17139b67 -r 5e3188213724 src/imap/client.h
--- a/src/imap/client.h Fri Jan 11 07:07:09 2008 +0200
+++ b/src/imap/client.h Sat Jan 12 06:46:28 2008 +0200
@@ -20,6 +20,18 @@ struct mailbox_keywords {
unsigned int announce_count;
};
+enum client_command_state {
+ /* Waiting for more input */
+ CLIENT_COMMAND_STATE_WAIT_INPUT,
+ /* Waiting to be able to send more output */
+ CLIENT_COMMAND_STATE_WAIT_OUTPUT,
+ /* Just waiting for execution to continue later. For example waiting
+ for other commands to finish first. */
+ CLIENT_COMMAND_STATE_WAIT,
+ /* Command is finished */
+ CLIENT_COMMAND_STATE_DONE
+};
+
struct client_command_context {
struct client_command_context *prev, *next;
struct client *client;
@@ -33,11 +45,11 @@ struct client_command_context {
void *context;
struct imap_parser *parser;
+ enum client_command_state state;
unsigned int uid:1; /* used UID command */
unsigned int cancel:1; /* command is wanted to be cancelled */
unsigned int param_error:1;
- unsigned int output_pending:1;
unsigned int waiting_unambiguity:1;
};
diff -r 740a17139b67 -r 5e3188213724 src/imap/cmd-append.c
--- a/src/imap/cmd-append.c Fri Jan 11 07:07:09 2008 +0200
+++ b/src/imap/cmd-append.c Sat Jan 12 06:46:28 2008 +0200
@@ -76,7 +76,7 @@ static void client_input_append(struct c
o_stream_cork(client->output);
finished = cmd->func(cmd);
o_stream_uncork(client->output);
- if (!finished)
+ if (!finished && cmd->state != CLIENT_COMMAND_STATE_DONE)
(void)client_handle_unfinished_cmd(cmd);
else {
client_command_free(cmd);
diff -r 740a17139b67 -r 5e3188213724 src/imap/cmd-fetch.c
--- a/src/imap/cmd-fetch.c Fri Jan 11 07:07:09 2008 +0200
+++ b/src/imap/cmd-fetch.c Sat Jan 12 06:46:28 2008 +0200
@@ -153,7 +153,7 @@ bool cmd_fetch(struct client_command_con
imap_fetch_begin(ctx, search_arg);
if ((ret = imap_fetch(ctx)) == 0) {
/* unfinished */
- cmd->output_pending = TRUE;
+ cmd->state = CLIENT_COMMAND_STATE_WAIT_OUTPUT;
cmd->func = cmd_fetch_continue;
cmd->context = ctx;
diff -r 740a17139b67 -r 5e3188213724 src/imap/cmd-idle.c
--- a/src/imap/cmd-idle.c Fri Jan 11 07:07:09 2008 +0200
+++ b/src/imap/cmd-idle.c Sat Jan 12 06:46:28 2008 +0200
@@ -151,7 +151,7 @@ static bool cmd_idle_continue(struct cli
ctx->manual_cork = FALSE;
o_stream_uncork(client->output);
}
- cmd->output_pending = TRUE;
+ cmd->state = CLIENT_COMMAND_STATE_WAIT_OUTPUT;
return FALSE;
}
@@ -171,7 +171,7 @@ static bool cmd_idle_continue(struct cli
so we return here instead of doing everything twice. */
return FALSE;
}
- cmd->output_pending = FALSE;
+ cmd->state = CLIENT_COMMAND_STATE_WAIT;
if (ctx->manual_cork) {
ctx->manual_cork = FALSE;
diff -r 740a17139b67 -r 5e3188213724 src/imap/cmd-list.c
--- a/src/imap/cmd-list.c Fri Jan 11 07:07:09 2008 +0200
+++ b/src/imap/cmd-list.c Sat Jan 12 06:46:28 2008 +0200
@@ -852,7 +852,7 @@ bool cmd_list_full(struct client_command
if (!cmd_list_continue(cmd)) {
/* unfinished */
- cmd->output_pending = TRUE;
+ cmd->state = CLIENT_COMMAND_STATE_WAIT_OUTPUT;
cmd->func = cmd_list_continue;
return FALSE;
}
diff -r 740a17139b67 -r 5e3188213724 src/imap/imap-sync.c
--- a/src/imap/imap-sync.c Fri Jan 11 07:07:09 2008 +0200
+++ b/src/imap/imap-sync.c Sat Jan 12 06:46:28 2008 +0200
@@ -246,7 +246,7 @@ bool cmd_sync(struct client_command_cont
cmd->func = cmd_sync_continue;
cmd->context = ctx;
- cmd->output_pending = TRUE;
+ cmd->state = CLIENT_COMMAND_STATE_WAIT_OUTPUT;
if (client->input_lock == cmd)
client->input_lock = NULL;
client->output_lock = NULL;
More information about the dovecot-cvs
mailing list