dovecot: Use more robust command calling in output handler.

dovecot at dovecot.org dovecot at dovecot.org
Sat Jan 12 08:51:21 EET 2008


details:   http://hg.dovecot.org/dovecot/rev/2ced9dd8b2cc
changeset: 7151:2ced9dd8b2cc
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Jan 12 07:33:15 2008 +0200
description:
Use more robust command calling in output handler.

diffstat:

2 files changed, 22 insertions(+), 8 deletions(-)
src/imap/client.c |   29 +++++++++++++++++++++--------
src/imap/client.h |    1 +

diffs (62 lines):

diff -r 8a531386c856 -r 2ced9dd8b2cc src/imap/client.c
--- 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 @@ static void client_output_cmd(struct cli
 
 int client_output(struct client *client)
 {
-	struct client_command_context *cmd, *next;
+	struct client_command_context *cmd;
 	int ret;
 
 	i_assert(!client->destroyed);
@@ -717,18 +717,31 @@ int client_output(struct client *client)
 		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);
diff -r 8a531386c856 -r 2ced9dd8b2cc src/imap/client.h
--- 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 @@ struct client_command_context {
 	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 {


More information about the dovecot-cvs mailing list