dovecot: When pipelining commands another command could have wri...

dovecot at dovecot.org dovecot at dovecot.org
Sat Dec 22 00:21:13 EET 2007


details:   http://hg.dovecot.org/dovecot/rev/80d3b8fcec09
changeset: 7017:80d3b8fcec09
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Dec 22 00:21:09 2007 +0200
description:
When pipelining commands another command could have written output in the
middle of FETCH literal.

diffstat:

1 file changed, 20 insertions(+), 20 deletions(-)
src/imap/imap-fetch.c |   40 ++++++++++++++++++++--------------------

diffs (91 lines):

diff -r ac32dc7ae0c1 -r 80d3b8fcec09 src/imap/imap-fetch.c
--- a/src/imap/imap-fetch.c	Fri Dec 21 22:58:11 2007 +0200
+++ b/src/imap/imap-fetch.c	Sat Dec 22 00:21:09 2007 +0200
@@ -232,7 +232,7 @@ static int imap_fetch_send_nil_reply(str
 	return 0;
 }
 
-int imap_fetch(struct imap_fetch_context *ctx)
+static int imap_fetch_more(struct imap_fetch_context *ctx)
 {
 	struct client *client = ctx->client;
 	const struct imap_fetch_context_handler *handlers;
@@ -245,7 +245,7 @@ int imap_fetch(struct imap_fetch_context
 			return 0;
 
 		if (ret < 0) {
-			if (ctx->client->output->closed)
+			if (client->output->closed)
 				return -1;
 
 			if (ctx->cur_mail->expunged) {
@@ -265,23 +265,13 @@ int imap_fetch(struct imap_fetch_context
 			i_stream_unref(&ctx->cur_input);
 	}
 
-	/* assume initially that we're locking it */
-	i_assert(client->output_lock == NULL ||
-		 client->output_lock == ctx->cmd);
-	client->output_lock = ctx->cmd;
-
 	handlers = array_get(&ctx->handlers, &count);
 	for (;;) {
 		if (o_stream_get_buffer_used_size(client->output) >=
 		    CLIENT_OUTPUT_OPTIMAL_SIZE) {
 			ret = o_stream_flush(client->output);
-			if (ret <= 0) {
-				if (!ctx->line_partial) {
-					/* last line was fully sent */
-					client->output_lock = NULL;
-				}
+			if (ret <= 0)
 				return ret;
-			}
 		}
 
 		if (ctx->cur_mail == NULL) {
@@ -317,13 +307,8 @@ int imap_fetch(struct imap_fetch_context
 						 h->context);
 			);
 
-			if (ret == 0) {
-				if (!ctx->line_partial) {
-					/* last line was fully sent */
-					client->output_lock = NULL;
-				}
+			if (ret == 0)
 				return 0;
-			}
 
 			if (ret < 0) {
 				if (ctx->cur_mail->expunged) {
@@ -354,13 +339,28 @@ int imap_fetch(struct imap_fetch_context
 		ctx->line_partial = FALSE;
 		if (o_stream_send(client->output, ")\r\n", 3) < 0)
 			return -1;
-		ctx->client->last_output = ioloop_time;
+		client->last_output = ioloop_time;
 
 		ctx->cur_mail = NULL;
 		ctx->cur_handler = 0;
 	}
 
 	return 1;
+}
+
+int imap_fetch(struct imap_fetch_context *ctx)
+{
+	int ret;
+
+	i_assert(ctx->client->output_lock == NULL ||
+		 ctx->client->output_lock == ctx->cmd);
+
+	ret = imap_fetch_more(ctx);
+	if (ctx->line_partial) {
+		/* nothing can be sent until FETCH is finished */
+		ctx->client->output_lock = ctx->cmd;
+	}
+	return ret;
 }
 
 int imap_fetch_deinit(struct imap_fetch_context *ctx)


More information about the dovecot-cvs mailing list