Mercurial > dovecot > original-hg > dovecot-1.2
changeset 7148:5e3188213724 HEAD
Added "command state" for running commands. Use it instead of some bitfields
to test for the current state.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 12 Jan 2008 06:46:28 +0200 |
parents | 740a17139b67 |
children | 323b425a0f46 |
files | src/imap/client.c src/imap/client.h src/imap/cmd-append.c src/imap/cmd-fetch.c src/imap/cmd-idle.c src/imap/cmd-list.c src/imap/imap-sync.c |
diffstat | 7 files changed, 39 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- 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 @@ 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 @@ "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 @@ /* 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 @@ 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 @@ bool client_handle_unfinished_cmd(struct client_command_context *cmd) { - if (!cmd->output_pending) { - /* need more input */ + 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 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 @@ 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 @@ 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 @@ 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;
--- 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 @@ 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 @@ 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; };
--- 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 @@ 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);
--- 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 @@ 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;
--- 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 @@ 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 @@ 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;
--- 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 @@ if (!cmd_list_continue(cmd)) { /* unfinished */ - cmd->output_pending = TRUE; + cmd->state = CLIENT_COMMAND_STATE_WAIT_OUTPUT; cmd->func = cmd_list_continue; return FALSE; }
--- 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 @@ 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;