dovecot-2.0: istreams: Fixed some parent stream seeking issues.

dovecot at dovecot.org dovecot at dovecot.org
Fri May 1 21:50:24 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/ef0c861608d9
changeset: 9196:ef0c861608d9
user:      Timo Sirainen <tss at iki.fi>
date:      Fri May 01 14:50:08 2009 -0400
description:
istreams: Fixed some parent stream seeking issues.

diffstat:

5 files changed, 47 insertions(+), 56 deletions(-)
src/lib-mail/istream-header-filter.c       |   23 -------------------
src/lib-storage/index/istream-mail-stats.c |   33 +++++-----------------------
src/lib/istream-internal.h                 |    1 
src/lib/istream-limit.c                    |   14 +++++------
src/lib/istream.c                          |   32 +++++++++++++++++++++++++++

diffs (175 lines):

diff -r 01c0d64e5f91 -r ef0c861608d9 src/lib-mail/istream-header-filter.c
--- a/src/lib-mail/istream-header-filter.c	Fri May 01 14:49:08 2009 -0400
+++ b/src/lib-mail/istream-header-filter.c	Fri May 01 14:50:08 2009 -0400
@@ -295,7 +295,6 @@ static ssize_t i_stream_header_filter_re
 	struct header_filter_istream *mstream =
 		(struct header_filter_istream *)stream;
 	ssize_t ret;
-	size_t pos;
 
 	if (!mstream->header_read ||
 	    stream->istream.v_offset < mstream->header_size.virtual_size) {
@@ -313,27 +312,7 @@ static ssize_t i_stream_header_filter_re
 		      stream->istream.v_offset -
 		      mstream->header_size.virtual_size +
 		      mstream->header_size.physical_size);
-
-	stream->pos -= stream->skip;
-	stream->skip = 0;
-
-	stream->buffer = i_stream_get_data(stream->parent, &pos);
-	if (pos <= stream->pos) {
-		if ((ret = i_stream_read(stream->parent)) == -2) {
-			i_assert(stream->skip != stream->pos);
-			return -2;
-		}
-		stream->istream.stream_errno = stream->parent->stream_errno;
-		stream->istream.eof = stream->parent->eof;
-		stream->buffer = i_stream_get_data(stream->parent, &pos);
-	} else {
-		ret = 0;
-	}
-
-	ret = pos > stream->pos ? (ssize_t)(pos - stream->pos) :
-		(ret == 0 ? 0 : -1);
-	stream->pos = pos;
-	return ret;
+	return i_stream_read_copy_from_parent(&stream->istream);
 }
 
 static void parse_header(struct header_filter_istream *mstream)
diff -r 01c0d64e5f91 -r ef0c861608d9 src/lib-storage/index/istream-mail-stats.c
--- a/src/lib-storage/index/istream-mail-stats.c	Fri May 01 14:49:08 2009 -0400
+++ b/src/lib-storage/index/istream-mail-stats.c	Fri May 01 14:50:08 2009 -0400
@@ -36,7 +36,6 @@ i_stream_mail_stats_read_mail_stats(stru
 {
 	struct mail_stats_istream *mstream =
 		(struct mail_stats_istream *)stream;
-	size_t pos;
 	ssize_t ret;
 
 	if (stream->parent->v_offset !=
@@ -45,34 +44,14 @@ i_stream_mail_stats_read_mail_stats(stru
 			      stream->istream.v_offset);
 	}
 
-	stream->buffer = i_stream_get_data(stream->parent, &pos);
-	if (pos <= stream->pos) {
-		if ((ret = i_stream_read(stream->parent)) == -2)
-			return -2;
-
-		if (ret > 0) {
-			mstream->mail->stats_files_read_bytes+= ret;
-			if (!mstream->files_read_increased) {
-				mstream->files_read_increased = TRUE;
-				mstream->mail->stats_files_read_count++;
-			}
+	ret = i_stream_read_copy_from_parent(&stream->istream);
+	if (ret > 0) {
+		mstream->mail->stats_files_read_bytes += ret;
+		if (!mstream->files_read_increased) {
+			mstream->files_read_increased = TRUE;
+			mstream->mail->stats_files_read_count++;
 		}
-
-		stream->istream.stream_errno = stream->parent->stream_errno;
-		stream->istream.eof = stream->parent->eof;
-		stream->buffer = i_stream_get_data(stream->parent, &pos);
-	} else {
-		ret = 0;
 	}
-
-	stream->pos -= stream->skip;
-	stream->skip = 0;
-
-	ret = pos > stream->pos ? (ssize_t)(pos - stream->pos) :
-		(ret == 0 ? 0 : -1);
-	stream->pos = pos;
-	i_assert(ret != -1 || stream->istream.eof ||
-		 stream->istream.stream_errno != 0);
 	return ret;
 }
 
diff -r 01c0d64e5f91 -r ef0c861608d9 src/lib/istream-internal.h
--- a/src/lib/istream-internal.h	Fri May 01 14:49:08 2009 -0400
+++ b/src/lib/istream-internal.h	Fri May 01 14:50:08 2009 -0400
@@ -45,5 +45,6 @@ void i_stream_grow_buffer(struct istream
 void i_stream_grow_buffer(struct istream_private *stream, size_t bytes);
 bool i_stream_get_buffer_space(struct istream_private *stream,
 			       size_t wanted_size, size_t *size_r);
+ssize_t i_stream_read_copy_from_parent(struct istream *istream);
 
 #endif
diff -r 01c0d64e5f91 -r ef0c861608d9 src/lib/istream-limit.c
--- a/src/lib/istream-limit.c	Fri May 01 14:49:08 2009 -0400
+++ b/src/lib/istream-limit.c	Fri May 01 14:50:08 2009 -0400
@@ -54,20 +54,20 @@ static ssize_t i_stream_limit_read(struc
 			      stream->istream.v_offset);
 	}
 
+	stream->pos -= stream->skip;
+	stream->skip = 0;
+
 	stream->buffer = i_stream_get_data(stream->parent, &pos);
-	if (pos <= stream->pos) {
+	if (pos > stream->pos)
+		ret = 0;
+	else do {
 		if ((ret = i_stream_read(stream->parent)) == -2)
 			return -2;
 
 		stream->istream.stream_errno = stream->parent->stream_errno;
 		stream->istream.eof = stream->parent->eof;
 		stream->buffer = i_stream_get_data(stream->parent, &pos);
-	} else {
-		ret = 0;
-	}
-
-	stream->pos -= stream->skip;
-	stream->skip = 0;
+	} while (pos <= stream->pos && ret > 0);
 
 	if (lstream->v_size != (uoff_t)-1) {
 		left = lstream->v_size - stream->istream.v_offset;
diff -r 01c0d64e5f91 -r ef0c861608d9 src/lib/istream.c
--- a/src/lib/istream.c	Fri May 01 14:49:08 2009 -0400
+++ b/src/lib/istream.c	Fri May 01 14:50:08 2009 -0400
@@ -102,6 +102,38 @@ ssize_t i_stream_read(struct istream *st
 	return ret;
 }
 
+ssize_t i_stream_read_copy_from_parent(struct istream *istream)
+{
+	struct istream_private *stream = istream->real_stream;
+	size_t pos;
+	ssize_t ret;
+
+	stream->pos -= stream->skip;
+	stream->skip = 0;
+
+	stream->buffer = i_stream_get_data(stream->parent, &pos);
+	if (pos > stream->pos)
+		ret = 0;
+	else do {
+		if ((ret = i_stream_read(stream->parent)) == -2)
+			return -2;
+
+		stream->istream.stream_errno = stream->parent->stream_errno;
+		stream->istream.eof = stream->parent->eof;
+		stream->buffer = i_stream_get_data(stream->parent, &pos);
+		/* check again, in case the parent stream had been seeked
+		   backwards and the previous read() didn't get us far
+		   enough. */
+	} while (pos <= stream->pos && ret > 0);
+
+	ret = pos > stream->pos ? (ssize_t)(pos - stream->pos) :
+		(ret == 0 ? 0 : -1);
+	stream->pos = pos;
+	i_assert(ret != -1 || stream->istream.eof ||
+		 stream->istream.stream_errno != 0);
+	return ret;
+}
+
 void i_stream_skip(struct istream *stream, uoff_t count)
 {
 	struct istream_private *_stream = stream->real_stream;


More information about the dovecot-cvs mailing list