]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Added tee_i_stream_child_is_waiting().
authorTimo Sirainen <tss@iki.fi>
Mon, 23 Nov 2009 20:42:55 +0000 (15:42 -0500)
committerTimo Sirainen <tss@iki.fi>
Mon, 23 Nov 2009 20:42:55 +0000 (15:42 -0500)
--HG--
branch : HEAD

src/lib/istream-tee.c
src/lib/istream-tee.h
src/lib/test-istream-tee.c

index 41dc68b63e8310752b3f2c090df01d1dd4682783..2d0d5649d9fea58313277b8c93b4d8dbb9a16609 100644 (file)
@@ -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;
+}
index 8009a3eee66958815f9b8121f592dc5afe260c75..82c0c931a438676fcd5d06d3e13fa60a9a4b4f2b 100644 (file)
@@ -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);
 
index dbf185f312d96cbcb9c6c9749ad9bb7eade522e0..9af90b0571e9640ddc11ca83fcb9c5f5956d6936 100644 (file)
@@ -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);