dovecot-1.2: imap: Cleaned up "command pending" handling code. S...

dovecot at dovecot.org dovecot at dovecot.org
Tue May 26 21:22:22 EEST 2009


details:   http://hg.dovecot.org/dovecot-1.2/rev/9a0aa39a3a14
changeset: 9095:9a0aa39a3a14
user:      Timo Sirainen <tss at iki.fi>
date:      Tue May 26 14:21:59 2009 -0400
description:
imap: Cleaned up "command pending" handling code. Should fix hangs caused by recent changes.

diffstat:

5 files changed, 51 insertions(+), 49 deletions(-)
src/imap/client.c      |   72 ++++++++++++++++++++++--------------------------
src/imap/client.h      |    2 -
src/imap/cmd-append.c  |   13 ++++----
src/imap/cmd-idle.c    |    7 +++-
src/imap/imap-search.c |    6 +++-

diffs (219 lines):

diff -r 60204e3f7c4d -r 9a0aa39a3a14 src/imap/client.c
--- a/src/imap/client.c	Tue May 26 14:20:23 2009 -0400
+++ b/src/imap/client.c	Tue May 26 14:21:59 2009 -0400
@@ -509,19 +509,11 @@ static void client_add_missing_io(struct
 	}
 }
 
-void client_continue_pending_input(struct client **_client)
-{
-	struct client *client = *_client;
+void client_continue_pending_input(struct client *client)
+{
 	size_t size;
 
 	i_assert(!client->handling_input);
-
-	if (client->disconnected) {
-		if (!client->destroyed)
-			client_destroy(client, NULL);
-		*_client = NULL;
-		return;
-	}
 
 	if (client->input_lock != NULL) {
 		/* there's a command that has locked the input */
@@ -534,8 +526,10 @@ void client_continue_pending_input(struc
 		   commands to finish. */
 		if (client_command_check_ambiguity(cmd)) {
 			/* we could be waiting for existing sync to finish */
-			cmd_sync_delayed(client);
-			return;
+			if (!cmd_sync_delayed(client))
+				return;
+			if (client_command_check_ambiguity(cmd))
+				return;
 		}
 		cmd->state = CLIENT_COMMAND_STATE_WAIT_INPUT;
 	}
@@ -544,8 +538,10 @@ void client_continue_pending_input(struc
 
 	/* if there's unread data in buffer, handle it. */
 	(void)i_stream_get_data(client->input, &size);
-	if (size > 0)
-		(void)client_handle_input(client);
+	if (size > 0 && !client->disconnected) {
+		if (client_handle_input(client))
+			client_continue_pending_input(client);
+	}
 }
 
 /* Skip incoming data until newline is found,
@@ -705,6 +701,8 @@ bool client_handle_input(struct client *
 {
 	bool ret, remove_io, handled_commands = FALSE;
 
+	i_assert(!client->disconnected);
+
 	client->handling_input = TRUE;
 	do {
 		T_BEGIN {
@@ -715,23 +713,16 @@ bool client_handle_input(struct client *
 	} while (ret && !client->disconnected && client->io != NULL);
 	client->handling_input = FALSE;
 
-	if (client->output->closed) {
-		client_destroy(client, NULL);
-		return TRUE;
-	} else {
-		if (remove_io)
-			io_remove(&client->io);
-		else
-			client_add_missing_io(client);
-		if (!handled_commands)
-			return FALSE;
-
-		ret = client->input_lock != NULL ? TRUE :
-			cmd_sync_delayed(client);
-		if (ret)
-			client_continue_pending_input(&client);
-		return TRUE;
-	}
+	if (remove_io)
+		io_remove(&client->io);
+	else
+		client_add_missing_io(client);
+	if (!handled_commands)
+		return FALSE;
+
+	if (client->input_lock == NULL)
+		cmd_sync_delayed(client);
+	return TRUE;
 }
 
 void client_input(struct client *client)
@@ -768,6 +759,11 @@ void client_input(struct client *client)
 	}
 	o_stream_uncork(output);
 	o_stream_unref(&output);
+
+	if (client->disconnected)
+		client_destroy(client, NULL);
+	else
+		client_continue_pending_input(client);
 }
 
 static void client_output_cmd(struct client_command_context *cmd)
@@ -830,15 +826,13 @@ int client_output(struct client *client)
 		}
 	}
 
-	if (client->output->closed) {
+	(void)cmd_sync_delayed(client);
+	o_stream_uncork(client->output);
+	if (client->disconnected)
 		client_destroy(client, NULL);
-		return 1;
-	} else {
-		(void)cmd_sync_delayed(client);
-		o_stream_uncork(client->output);
-		client_continue_pending_input(&client);
-		return ret;
-	}
+	else
+		client_continue_pending_input(client);
+	return ret;
 }
 
 bool client_handle_search_save_ambiguity(struct client_command_context *cmd)
diff -r 60204e3f7c4d -r 9a0aa39a3a14 src/imap/client.h
--- a/src/imap/client.h	Tue May 26 14:20:23 2009 -0400
+++ b/src/imap/client.h	Tue May 26 14:21:59 2009 -0400
@@ -186,7 +186,7 @@ void client_command_free(struct client_c
 void client_command_free(struct client_command_context **cmd);
 
 bool client_handle_unfinished_cmd(struct client_command_context *cmd);
-void client_continue_pending_input(struct client **_client);
+void client_continue_pending_input(struct client *client);
 
 void client_input(struct client *client);
 bool client_handle_input(struct client *client);
diff -r 60204e3f7c4d -r 9a0aa39a3a14 src/imap/cmd-append.c
--- a/src/imap/cmd-append.c	Tue May 26 14:20:23 2009 -0400
+++ b/src/imap/cmd-append.c	Tue May 26 14:21:59 2009 -0400
@@ -44,7 +44,6 @@ static void client_input_append(struct c
 {
 	struct cmd_append_context *ctx = cmd->context;
 	struct client *client = cmd->client;
-	struct ostream *output = client->output;
 	bool finished;
 
 	i_assert(!client->destroyed);
@@ -80,17 +79,19 @@ static void client_input_append(struct c
 		return;
 	}
 
-	o_stream_ref(output);
-	o_stream_cork(output);
+	o_stream_cork(client->output);
 	finished = cmd->func(cmd);
 	if (!finished && cmd->state != CLIENT_COMMAND_STATE_DONE)
 		(void)client_handle_unfinished_cmd(cmd);
 	else
 		client_command_free(&cmd);
 	(void)cmd_sync_delayed(client);
-	client_continue_pending_input(&client);
-	o_stream_uncork(output);
-	o_stream_unref(&output);
+	o_stream_uncork(client->output);
+
+	if (client->disconnected)
+		client_destroy(client, NULL);
+	else
+		client_continue_pending_input(client);
 }
 
 /* Returns -1 = error, 0 = need more data, 1 = successful. flags and
diff -r 60204e3f7c4d -r 9a0aa39a3a14 src/imap/cmd-idle.c
--- a/src/imap/cmd-idle.c	Tue May 26 14:20:23 2009 -0400
+++ b/src/imap/cmd-idle.c	Tue May 26 14:21:59 2009 -0400
@@ -73,7 +73,7 @@ static void idle_client_input(struct cmd
 	case -2:
 		client->input_skip_line = TRUE;
 		idle_finish(ctx, FALSE, TRUE);
-		client_continue_pending_input(&client);
+		client_continue_pending_input(client);
 		return;
 	}
 
@@ -89,10 +89,13 @@ static void idle_client_input(struct cmd
 			client->input_skip_line = FALSE;
 		else {
 			idle_finish(ctx, strcasecmp(line, "DONE") == 0, TRUE);
-			client_continue_pending_input(&client);
 			break;
 		}
 	}
+	if (client->disconnected)
+		client_destroy(client, NULL);
+	else
+		client_continue_pending_input(client);
 }
 
 static void keepalive_timeout(struct cmd_idle_context *ctx)
diff -r 60204e3f7c4d -r 9a0aa39a3a14 src/imap/imap-search.c
--- a/src/imap/imap-search.c	Tue May 26 14:20:23 2009 -0400
+++ b/src/imap/imap-search.c	Tue May 26 14:21:59 2009 -0400
@@ -439,7 +439,11 @@ static void cmd_search_more_callback(str
 	else
 		client_command_free(&cmd);
 	(void)cmd_sync_delayed(client);
-	client_continue_pending_input(&client);
+
+	if (client->disconnected)
+		client_destroy(client, NULL);
+	else
+		client_continue_pending_input(client);
 }
 
 int cmd_search_parse_return_if_found(struct imap_search_context *ctx,


More information about the dovecot-cvs mailing list