From: Timo Sirainen Date: Mon, 23 Nov 2009 20:42:55 +0000 (-0500) Subject: Added tee_i_stream_child_is_waiting(). X-Git-Tag: 2.0.beta1~87 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=34435ce4a468dc13b23db69dbdd09fe20be88816;p=thirdparty%2Fdovecot%2Fcore.git Added tee_i_stream_child_is_waiting(). --HG-- branch : HEAD --- diff --git a/src/lib/istream-tee.c b/src/lib/istream-tee.c index 41dc68b63e..2d0d5649d9 100644 --- a/src/lib/istream-tee.c +++ b/src/lib/istream-tee.c @@ -16,6 +16,8 @@ struct tee_child_istream { struct tee_istream *tee; struct tee_child_istream *next; + + unsigned int last_read_waiting:1; }; static void tee_streams_update_buffer(struct tee_istream *tee) @@ -112,6 +114,7 @@ static ssize_t i_stream_tee_read(struct istream_private *stream) uoff_t last_high_offset; ssize_t ret; + tstream->last_read_waiting = FALSE; if (stream->buffer == NULL) { /* initial read */ tee_streams_update_buffer(tstream->tee); @@ -133,6 +136,7 @@ static ssize_t i_stream_tee_read(struct istream_private *stream) if (ret == -2 && stream->skip != 0) { /* someone else is holding the data, wait for it */ + tstream->last_read_waiting = TRUE; return 0; } stream->istream.stream_errno = input->stream_errno; @@ -212,3 +216,11 @@ struct istream *tee_i_stream_create_child(struct tee_istream *tee) return i_stream_create(&tstream->istream, NULL, i_stream_get_fd(tee->input)); } + +bool tee_i_stream_child_is_waiting(struct istream *input) +{ + struct tee_child_istream *tstream = + (struct tee_child_istream *)input->real_stream; + + return tstream->last_read_waiting; +} diff --git a/src/lib/istream-tee.h b/src/lib/istream-tee.h index 8009a3eee6..82c0c931a4 100644 --- a/src/lib/istream-tee.h +++ b/src/lib/istream-tee.h @@ -8,6 +8,9 @@ If the stream's buffer gets full because some child isn't consuming the data, other streams get returned 0 by i_stream_read(). */ struct tee_istream *tee_i_stream_create(struct istream *input); +/* Returns TRUE if last read() operation returned 0, because it was waiting + for another tee stream to read more of its data. */ +bool tee_i_stream_child_is_waiting(struct istream *input); struct istream *tee_i_stream_create_child(struct tee_istream *tee); diff --git a/src/lib/test-istream-tee.c b/src/lib/test-istream-tee.c index dbf185f312..9af90b0571 100644 --- a/src/lib/test-istream-tee.c +++ b/src/lib/test-istream-tee.c @@ -30,7 +30,9 @@ static void test_istream_tee_tailing(const char *str) test_istream_set_size(test_input, len); for (i = 0; i < CHILD_COUNT; i++) { test_assert(i_stream_read(child_input[i]) == 1); + test_assert(!tee_i_stream_child_is_waiting(child_input[i])); test_assert(i_stream_read(child_input[i]) == 0); + test_assert(!tee_i_stream_child_is_waiting(child_input[i])); } } @@ -38,27 +40,37 @@ static void test_istream_tee_tailing(const char *str) for (i = 0; i < CHILD_COUNT; i++) { test_assert(i_stream_read(child_input[i]) == 1); test_assert(i_stream_read(child_input[i]) == -2); + test_assert(!tee_i_stream_child_is_waiting(child_input[i])); } for (len++; len <= TEST_STR_LEN; len++) { test_istream_set_size(test_input, len); - for (i = 0; i < CHILD_COUNT; i++) + for (i = 0; i < CHILD_COUNT; i++) { test_assert(i_stream_read(child_input[i]) == -2); + test_assert(!tee_i_stream_child_is_waiting(child_input[i])); + } for (i = 0; i < CHILD_COUNT-1; i++) { i_stream_skip(child_input[i], 1); test_assert(i_stream_read(child_input[i]) == 0); + test_assert(tee_i_stream_child_is_waiting(child_input[i])); } i_stream_skip(child_input[i], 1); for (i = 0; i < CHILD_COUNT; i++) { test_assert(i_stream_read(child_input[i]) == 1); test_assert(i_stream_read(child_input[i]) == -2); + test_assert(!tee_i_stream_child_is_waiting(child_input[i])); } } - for (i = 0; i < CHILD_COUNT; i++) { + for (i = 0; i < CHILD_COUNT-1; i++) { i_stream_skip(child_input[i], 1); test_assert(i_stream_read(child_input[i]) == 0); + test_assert(tee_i_stream_child_is_waiting(child_input[i])); } + i_stream_skip(child_input[i], 1); + test_assert(i_stream_read(child_input[i]) == 0); + test_assert(!tee_i_stream_child_is_waiting(child_input[i])); + test_istream_set_allow_eof(test_input, TRUE); for (i = 0; i < CHILD_COUNT; i++) { test_assert(i_stream_read(child_input[i]) == -1);