dovecot-2.2: dict-client: If dict iteration was aborted, the res...

dovecot at dovecot.org dovecot at dovecot.org
Wed Sep 23 20:01:52 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/bc9b61338985
changeset: 19199:bc9b61338985
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Sep 23 22:59:55 2015 +0300
description:
dict-client: If dict iteration was aborted, the rest of the connection state became broken.
We never continued skipping over the rest of the iteration, instead the
iteration replies were treated as replies to the following commands.

diffstat:

 src/lib-dict/dict-client.c |  20 ++++++++++++++++++++
 1 files changed, 20 insertions(+), 0 deletions(-)

diffs (65 lines):

diff -r 7363b1c77795 -r bc9b61338985 src/lib-dict/dict-client.c
--- a/src/lib-dict/dict-client.c	Wed Sep 23 22:57:55 2015 +0300
+++ b/src/lib-dict/dict-client.c	Wed Sep 23 22:59:55 2015 +0300
@@ -46,6 +46,7 @@
 	unsigned int connect_counter;
 	unsigned int transaction_id_counter;
 	unsigned int async_commits;
+	unsigned int iter_replies_skip;
 
 	unsigned int in_iteration:1;
 	unsigned int handshaked:1;
@@ -56,6 +57,7 @@
 
 	pool_t pool;
 	bool failed;
+	bool finished;
 };
 
 struct client_dict_transaction_context {
@@ -366,6 +368,19 @@
 		client_dict_finish_transaction(dict, id, ret);
 		return 0;
 	}
+	if (dict->iter_replies_skip > 0) {
+		/* called aborted the iteration before finishing it.
+		   skip over the iteration reply */
+		if (*line == DICT_PROTOCOL_REPLY_OK)
+			return 0;
+		if (*line != '\0' && *line != DICT_PROTOCOL_REPLY_FAIL) {
+			i_error("dict-client: Invalid iteration reply line: %s",
+				line);
+			return -1;
+		}
+		dict->iter_replies_skip--;
+		return 0;
+	}
 	*line_r = line;
 	return 1;
 }
@@ -463,6 +478,7 @@
 
 	dict->connect_counter++;
 	dict->handshaked = FALSE;
+	dict->iter_replies_skip = 0;
 
 	/* abort all pending async commits */
 	for (ctx = dict->transactions; ctx != NULL; ctx = next) {
@@ -649,6 +665,7 @@
 
 	if (*line == '\0') {
 		/* end of iteration */
+		ctx->finished = TRUE;
 		return FALSE;
 	}
 
@@ -686,6 +703,9 @@
 		(struct client_dict_iterate_context *)_ctx;
 	int ret = ctx->failed ? -1 : 0;
 
+	if (!ctx->finished)
+		dict->iter_replies_skip++;
+
 	pool_unref(&ctx->pool);
 	i_free(ctx);
 	dict->in_iteration = FALSE;


More information about the dovecot-cvs mailing list