Mercurial > dovecot > original-hg > dovecot-1.2
changeset 7151:2ced9dd8b2cc HEAD
Use more robust command calling in output handler.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 12 Jan 2008 07:33:15 +0200 |
parents | 8a531386c856 |
children | 3e506d46655f |
files | src/imap/client.c src/imap/client.h |
diffstat | 2 files changed, 22 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/src/imap/client.c Sat Jan 12 07:16:10 2008 +0200 +++ b/src/imap/client.c Sat Jan 12 07:33:15 2008 +0200 @@ -702,7 +702,7 @@ int client_output(struct client *client) { - struct client_command_context *cmd, *next; + struct client_command_context *cmd; int ret; i_assert(!client->destroyed); @@ -717,19 +717,32 @@ return 1; } + /* mark all commands non-executed */ + for (cmd = client->command_queue; cmd != NULL; cmd = cmd->next) + cmd->temp_executed = FALSE; + o_stream_cork(client->output); - if (client->output_lock != NULL) + if (client->output_lock != NULL) { + client->output_lock->temp_executed = TRUE; client_output_cmd(client->output_lock); - if (client->output_lock == NULL) { + } + while (client->output_lock == NULL) { + /* go through the entire commands list every time in case + multiple commands were freed. temp_executed keeps track of + which messages we've called so far */ cmd = client->command_queue; - for (; cmd != NULL; cmd = next) { - next = cmd->next; - if (cmd->state == CLIENT_COMMAND_STATE_WAIT_OUTPUT) { + for (; cmd != NULL; cmd = cmd->next) { + if (!cmd->temp_executed && + cmd->state == CLIENT_COMMAND_STATE_WAIT_OUTPUT) { + cmd->temp_executed = TRUE; client_output_cmd(cmd); - if (client->output_lock != NULL) - break; + break; } } + if (cmd == NULL) { + /* all commands executed */ + break; + } } o_stream_uncork(client->output);
--- a/src/imap/client.h Sat Jan 12 07:16:10 2008 +0200 +++ b/src/imap/client.h Sat Jan 12 07:33:15 2008 +0200 @@ -49,6 +49,7 @@ unsigned int uid:1; /* used UID command */ unsigned int cancel:1; /* command is wanted to be cancelled */ unsigned int param_error:1; + unsigned int temp_executed:1; /* temporary execution state tracking */ }; struct client {