annotate src/lib/istream-tee.c @ 22664:fea53c2725c0

director: Fix director_max_parallel_moves/kicks type Should be uint, not time.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 09 Nov 2017 12:24:16 +0200
parents 2e2563132d5f
children cb108f786fb4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
21390
2e2563132d5f Updated copyright notices to include the year 2017.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 19552
diff changeset
1 /* Copyright (c) 2006-2017 Dovecot authors, see the included COPYING file */
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
2
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
3 #include "lib.h"
13529
cf77e448295c Renamed lib/*-internal.h files to lib/*-private.h for consistency.
Timo Sirainen <tss@iki.fi>
parents: 12782
diff changeset
4 #include "istream-private.h"
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
5 #include "istream-tee.h"
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
6
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
7 struct tee_istream {
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
8 struct istream *input;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
9 struct tee_child_istream *children;
5990
14a0630a4fa9 When all child streams are destroyed, make sure the main stream's offset is
Timo Sirainen <tss@iki.fi>
parents: 5342
diff changeset
10
14a0630a4fa9 When all child streams are destroyed, make sure the main stream's offset is
Timo Sirainen <tss@iki.fi>
parents: 5342
diff changeset
11 uoff_t max_read_offset;
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
12 };
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
13
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
14 struct tee_child_istream {
6415
b0096861c390 Renamed struct _[io]stream to struct [io]stream_private. Also removed _
Timo Sirainen <tss@iki.fi>
parents: 6411
diff changeset
15 struct istream_private istream;
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
16
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
17 struct tee_istream *tee;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
18 struct tee_child_istream *next;
10392
9d878b1dc028 Added tee_i_stream_child_is_waiting().
Timo Sirainen <tss@iki.fi>
parents: 9522
diff changeset
19
9d878b1dc028 Added tee_i_stream_child_is_waiting().
Timo Sirainen <tss@iki.fi>
parents: 9522
diff changeset
20 unsigned int last_read_waiting:1;
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
21 };
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
22
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
23 static void tee_streams_update_buffer(struct tee_istream *tee)
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
24 {
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
25 struct tee_child_istream *tstream = tee->children;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
26 const unsigned char *data;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
27 size_t size, old_used;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
28
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
29 data = i_stream_get_data(tee->input, &size);
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
30 for (; tstream != NULL; tstream = tstream->next) {
5990
14a0630a4fa9 When all child streams are destroyed, make sure the main stream's offset is
Timo Sirainen <tss@iki.fi>
parents: 5342
diff changeset
31 if (tstream->istream.istream.closed) {
14a0630a4fa9 When all child streams are destroyed, make sure the main stream's offset is
Timo Sirainen <tss@iki.fi>
parents: 5342
diff changeset
32 tstream->istream.skip = tstream->istream.pos = 0;
14a0630a4fa9 When all child streams are destroyed, make sure the main stream's offset is
Timo Sirainen <tss@iki.fi>
parents: 5342
diff changeset
33 continue;
14a0630a4fa9 When all child streams are destroyed, make sure the main stream's offset is
Timo Sirainen <tss@iki.fi>
parents: 5342
diff changeset
34 }
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
35 old_used = tstream->istream.pos - tstream->istream.skip;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
36
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
37 tstream->istream.buffer = data;
17605
dffc6dd2be0d lib: istream-tee wasn't returning data correctly always.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
38 i_assert(tstream->istream.istream.v_offset >= tee->input->v_offset);
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
39 tstream->istream.skip = tstream->istream.istream.v_offset -
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
40 tee->input->v_offset;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
41 i_assert(tstream->istream.skip + old_used <= size);
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
42 tstream->istream.pos = tstream->istream.skip + old_used;
10810
de2798fbbae6 istreams: Reading sometimes returned wrong data, if parent istream had been modified.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
43
de2798fbbae6 istreams: Reading sometimes returned wrong data, if parent istream had been modified.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
44 tstream->istream.parent_expected_offset =
de2798fbbae6 istreams: Reading sometimes returned wrong data, if parent istream had been modified.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
45 tee->input->v_offset;
de2798fbbae6 istreams: Reading sometimes returned wrong data, if parent istream had been modified.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
46 tstream->istream.access_counter =
de2798fbbae6 istreams: Reading sometimes returned wrong data, if parent istream had been modified.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
47 tee->input->real_stream->access_counter;
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
48 }
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
49 }
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
50
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
51 static void tee_streams_skip(struct tee_istream *tee)
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
52 {
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
53 struct tee_child_istream *tstream = tee->children;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
54 size_t min_skip;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
55
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
56 min_skip = (size_t)-1;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
57 for (; tstream != NULL; tstream = tstream->next) {
5990
14a0630a4fa9 When all child streams are destroyed, make sure the main stream's offset is
Timo Sirainen <tss@iki.fi>
parents: 5342
diff changeset
58 if (tstream->istream.skip < min_skip &&
14a0630a4fa9 When all child streams are destroyed, make sure the main stream's offset is
Timo Sirainen <tss@iki.fi>
parents: 5342
diff changeset
59 !tstream->istream.istream.closed)
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
60 min_skip = tstream->istream.skip;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
61 }
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
62
5990
14a0630a4fa9 When all child streams are destroyed, make sure the main stream's offset is
Timo Sirainen <tss@iki.fi>
parents: 5342
diff changeset
63 if (min_skip > 0 && min_skip != (size_t)-1) {
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
64 i_stream_skip(tee->input, min_skip);
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
65 tee_streams_update_buffer(tee);
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
66 }
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
67 }
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
68
16020
6cabb95d32ec iostreams: Added close_parent flag to close() handler and clarified close/destroy APIs.
Timo Sirainen <tss@iki.fi>
parents: 15814
diff changeset
69 static void i_stream_tee_close(struct iostream_private *stream,
6cabb95d32ec iostreams: Added close_parent flag to close() handler and clarified close/destroy APIs.
Timo Sirainen <tss@iki.fi>
parents: 15814
diff changeset
70 bool close_parent ATTR_UNUSED)
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
71 {
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
72 struct tee_child_istream *tstream = (struct tee_child_istream *)stream;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
73
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
74 tee_streams_skip(tstream->tee);
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
75 }
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
76
6420
a8b515e1a26f Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents: 6415
diff changeset
77 static void i_stream_tee_destroy(struct iostream_private *stream)
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
78 {
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
79 struct tee_child_istream *tstream = (struct tee_child_istream *)stream;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
80 struct tee_istream *tee = tstream->tee;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
81 struct tee_child_istream **p;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
82
5990
14a0630a4fa9 When all child streams are destroyed, make sure the main stream's offset is
Timo Sirainen <tss@iki.fi>
parents: 5342
diff changeset
83 if (tstream->istream.istream.v_offset > tee->max_read_offset)
14a0630a4fa9 When all child streams are destroyed, make sure the main stream's offset is
Timo Sirainen <tss@iki.fi>
parents: 5342
diff changeset
84 tee->max_read_offset = tstream->istream.istream.v_offset;
14a0630a4fa9 When all child streams are destroyed, make sure the main stream's offset is
Timo Sirainen <tss@iki.fi>
parents: 5342
diff changeset
85
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
86 for (p = &tee->children; *p != NULL; p = &(*p)->next) {
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
87 if (*p == tstream) {
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
88 *p = tstream->next;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
89 break;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
90 }
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
91 }
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
92
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
93 if (tee->children == NULL) {
10810
de2798fbbae6 istreams: Reading sometimes returned wrong data, if parent istream had been modified.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
94 /* last child. the tee is now destroyed */
5990
14a0630a4fa9 When all child streams are destroyed, make sure the main stream's offset is
Timo Sirainen <tss@iki.fi>
parents: 5342
diff changeset
95 i_assert(tee->input->v_offset <= tee->max_read_offset);
14a0630a4fa9 When all child streams are destroyed, make sure the main stream's offset is
Timo Sirainen <tss@iki.fi>
parents: 5342
diff changeset
96 i_stream_skip(tee->input,
14a0630a4fa9 When all child streams are destroyed, make sure the main stream's offset is
Timo Sirainen <tss@iki.fi>
parents: 5342
diff changeset
97 tee->max_read_offset - tee->input->v_offset);
14a0630a4fa9 When all child streams are destroyed, make sure the main stream's offset is
Timo Sirainen <tss@iki.fi>
parents: 5342
diff changeset
98
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
99 i_stream_unref(&tee->input);
6142
6c0bfc35af03 Removed memory pool parameter from iostreams. Default pool was almost always
Timo Sirainen <tss@iki.fi>
parents: 5990
diff changeset
100 i_free(tee);
5990
14a0630a4fa9 When all child streams are destroyed, make sure the main stream's offset is
Timo Sirainen <tss@iki.fi>
parents: 5342
diff changeset
101 } else {
14a0630a4fa9 When all child streams are destroyed, make sure the main stream's offset is
Timo Sirainen <tss@iki.fi>
parents: 5342
diff changeset
102 tee_streams_skip(tstream->tee);
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
103 }
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
104 }
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
105
6415
b0096861c390 Renamed struct _[io]stream to struct [io]stream_private. Also removed _
Timo Sirainen <tss@iki.fi>
parents: 6411
diff changeset
106 static void
6420
a8b515e1a26f Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents: 6415
diff changeset
107 i_stream_tee_set_max_buffer_size(struct iostream_private *stream,
a8b515e1a26f Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents: 6415
diff changeset
108 size_t max_size)
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
109 {
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
110 struct tee_child_istream *tstream = (struct tee_child_istream *)stream;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
111
6559
15a9ce2cc0ab Always keep a usable value in stream->max_buffer_size.
Timo Sirainen <tss@iki.fi>
parents: 6491
diff changeset
112 tstream->istream.max_buffer_size = max_size;
6491
a43faaff06fd Compiling fix for non-gcc.
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
113 i_stream_set_max_buffer_size(tstream->tee->input, max_size);
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
114 }
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
115
6420
a8b515e1a26f Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents: 6415
diff changeset
116 static ssize_t i_stream_tee_read(struct istream_private *stream)
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
117 {
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
118 struct tee_child_istream *tstream = (struct tee_child_istream *)stream;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
119 struct istream *input = tstream->tee->input;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
120 const unsigned char *data;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
121 size_t size;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
122 uoff_t last_high_offset;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
123 ssize_t ret;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
124
10392
9d878b1dc028 Added tee_i_stream_child_is_waiting().
Timo Sirainen <tss@iki.fi>
parents: 9522
diff changeset
125 tstream->last_read_waiting = FALSE;
8722
fbc3e829ade6 istream-tee: Minor cleanups, assert and a potential fix.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
126 if (stream->buffer == NULL) {
fbc3e829ade6 istream-tee: Minor cleanups, assert and a potential fix.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
127 /* initial read */
fbc3e829ade6 istream-tee: Minor cleanups, assert and a potential fix.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
128 tee_streams_update_buffer(tstream->tee);
fbc3e829ade6 istream-tee: Minor cleanups, assert and a potential fix.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
129 }
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
130 data = i_stream_get_data(input, &size);
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
131
8722
fbc3e829ade6 istream-tee: Minor cleanups, assert and a potential fix.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
132 /* last_high_offset contains how far we have read this child tee stream
fbc3e829ade6 istream-tee: Minor cleanups, assert and a potential fix.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
133 so far. input->v_offset + size contains how much is available in
fbc3e829ade6 istream-tee: Minor cleanups, assert and a potential fix.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
134 the parent stream without having to read more. */
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
135 last_high_offset = stream->istream.v_offset +
8722
fbc3e829ade6 istream-tee: Minor cleanups, assert and a potential fix.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
136 (stream->pos - stream->skip);
8886
11d2f0fffb61 istream-tee: Added some more asserts.
Timo Sirainen <tss@iki.fi>
parents: 8722
diff changeset
137 if (stream->pos == size) {
8722
fbc3e829ade6 istream-tee: Minor cleanups, assert and a potential fix.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
138 /* we've read everything, need to read more */
8886
11d2f0fffb61 istream-tee: Added some more asserts.
Timo Sirainen <tss@iki.fi>
parents: 8722
diff changeset
139 i_assert(last_high_offset == input->v_offset + size);
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
140 tee_streams_skip(tstream->tee);
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
141 ret = i_stream_read(input);
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
142 if (ret <= 0) {
14683
9646f80ac3e9 Added i_stream_get_data_size(). Used it where possible.
Timo Sirainen <tss@iki.fi>
parents: 14133
diff changeset
143 size = i_stream_get_data_size(input);
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
144 if (ret == -2 && stream->skip != 0) {
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
145 /* someone else is holding the data,
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
146 wait for it */
10392
9d878b1dc028 Added tee_i_stream_child_is_waiting().
Timo Sirainen <tss@iki.fi>
parents: 9522
diff changeset
147 tstream->last_read_waiting = TRUE;
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
148 return 0;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
149 }
7347
34cc59e3da17 If parent stream read() fails, update our stream_errno from the parent.
Timo Sirainen <tss@iki.fi>
parents: 7086
diff changeset
150 stream->istream.stream_errno = input->stream_errno;
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
151 stream->istream.eof = input->eof;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
152 return ret;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
153 }
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
154 tee_streams_update_buffer(tstream->tee);
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
155 data = i_stream_get_data(input, &size);
5990
14a0630a4fa9 When all child streams are destroyed, make sure the main stream's offset is
Timo Sirainen <tss@iki.fi>
parents: 5342
diff changeset
156 } else {
8722
fbc3e829ade6 istream-tee: Minor cleanups, assert and a potential fix.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
157 /* there's still some data available from parent */
8886
11d2f0fffb61 istream-tee: Added some more asserts.
Timo Sirainen <tss@iki.fi>
parents: 8722
diff changeset
158 i_assert(last_high_offset < input->v_offset + size);
17605
dffc6dd2be0d lib: istream-tee wasn't returning data correctly always.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
159 tee_streams_update_buffer(tstream->tee);
8722
fbc3e829ade6 istream-tee: Minor cleanups, assert and a potential fix.
Timo Sirainen <tss@iki.fi>
parents: 8590
diff changeset
160 i_assert(stream->pos < size);
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
161 }
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
162
5990
14a0630a4fa9 When all child streams are destroyed, make sure the main stream's offset is
Timo Sirainen <tss@iki.fi>
parents: 5342
diff changeset
163 i_assert(stream->buffer == data);
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
164 ret = size - stream->pos;
8196
40a07553606c Input streams: Improved error handling and added more asserts.
Timo Sirainen <tss@iki.fi>
parents: 7347
diff changeset
165 i_assert(ret > 0);
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
166 stream->pos = size;
17605
dffc6dd2be0d lib: istream-tee wasn't returning data correctly always.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
167
dffc6dd2be0d lib: istream-tee wasn't returning data correctly always.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
168 i_assert(stream->istream.v_offset + (stream->pos - stream->skip) ==
dffc6dd2be0d lib: istream-tee wasn't returning data correctly always.
Timo Sirainen <tss@iki.fi>
parents: 17130
diff changeset
169 input->v_offset + size);
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
170 return ret;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
171 }
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
172
14964
6d2be8d8891c i_stream_stat() API changed.
Timo Sirainen <tss@iki.fi>
parents: 14683
diff changeset
173 static int
6420
a8b515e1a26f Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents: 6415
diff changeset
174 i_stream_tee_stat(struct istream_private *stream, bool exact)
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
175 {
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
176 struct tee_child_istream *tstream = (struct tee_child_istream *)stream;
14964
6d2be8d8891c i_stream_stat() API changed.
Timo Sirainen <tss@iki.fi>
parents: 14683
diff changeset
177 const struct stat *st;
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
178
14964
6d2be8d8891c i_stream_stat() API changed.
Timo Sirainen <tss@iki.fi>
parents: 14683
diff changeset
179 if (i_stream_stat(tstream->tee->input, exact, &st) < 0)
6d2be8d8891c i_stream_stat() API changed.
Timo Sirainen <tss@iki.fi>
parents: 14683
diff changeset
180 return -1;
6d2be8d8891c i_stream_stat() API changed.
Timo Sirainen <tss@iki.fi>
parents: 14683
diff changeset
181 stream->statbuf = *st;
6d2be8d8891c i_stream_stat() API changed.
Timo Sirainen <tss@iki.fi>
parents: 14683
diff changeset
182 return 0;
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
183 }
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
184
6420
a8b515e1a26f Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents: 6415
diff changeset
185 static void i_stream_tee_sync(struct istream_private *stream)
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
186 {
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
187 struct tee_child_istream *tstream = (struct tee_child_istream *)stream;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
188
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
189 tee_streams_skip(tstream->tee);
14683
9646f80ac3e9 Added i_stream_get_data_size(). Used it where possible.
Timo Sirainen <tss@iki.fi>
parents: 14133
diff changeset
190 if (i_stream_get_data_size(tstream->tee->input) != 0) {
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
191 i_panic("tee-istream: i_stream_sync() called "
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
192 "with data still buffered");
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
193 }
6491
a43faaff06fd Compiling fix for non-gcc.
Timo Sirainen <tss@iki.fi>
parents: 6429
diff changeset
194 i_stream_sync(tstream->tee->input);
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
195 }
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
196
6142
6c0bfc35af03 Removed memory pool parameter from iostreams. Default pool was almost always
Timo Sirainen <tss@iki.fi>
parents: 5990
diff changeset
197 struct tee_istream *tee_i_stream_create(struct istream *input)
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
198 {
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
199 struct tee_istream *tee;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
200
6142
6c0bfc35af03 Removed memory pool parameter from iostreams. Default pool was almost always
Timo Sirainen <tss@iki.fi>
parents: 5990
diff changeset
201 tee = i_new(struct tee_istream, 1);
12397
2a252c9cda5e istream-tee: Fixed to work right when input stream didn't start from offset 0.
Timo Sirainen <tss@iki.fi>
parents: 11039
diff changeset
202 if (input->v_offset == 0) {
2a252c9cda5e istream-tee: Fixed to work right when input stream didn't start from offset 0.
Timo Sirainen <tss@iki.fi>
parents: 11039
diff changeset
203 i_stream_ref(input);
2a252c9cda5e istream-tee: Fixed to work right when input stream didn't start from offset 0.
Timo Sirainen <tss@iki.fi>
parents: 11039
diff changeset
204 tee->input = input;
2a252c9cda5e istream-tee: Fixed to work right when input stream didn't start from offset 0.
Timo Sirainen <tss@iki.fi>
parents: 11039
diff changeset
205 } else {
2a252c9cda5e istream-tee: Fixed to work right when input stream didn't start from offset 0.
Timo Sirainen <tss@iki.fi>
parents: 11039
diff changeset
206 tee->input = i_stream_create_limit(input, (uoff_t)-1);
2a252c9cda5e istream-tee: Fixed to work right when input stream didn't start from offset 0.
Timo Sirainen <tss@iki.fi>
parents: 11039
diff changeset
207 }
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
208 return tee;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
209 }
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
210
6142
6c0bfc35af03 Removed memory pool parameter from iostreams. Default pool was almost always
Timo Sirainen <tss@iki.fi>
parents: 5990
diff changeset
211 struct istream *tee_i_stream_create_child(struct tee_istream *tee)
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
212 {
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
213 struct tee_child_istream *tstream;
10810
de2798fbbae6 istreams: Reading sometimes returned wrong data, if parent istream had been modified.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
214 struct istream *ret, *input = tee->input;
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
215
6142
6c0bfc35af03 Removed memory pool parameter from iostreams. Default pool was almost always
Timo Sirainen <tss@iki.fi>
parents: 5990
diff changeset
216 tstream = i_new(struct tee_child_istream, 1);
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
217 tstream->tee = tee;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
218
10810
de2798fbbae6 istreams: Reading sometimes returned wrong data, if parent istream had been modified.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
219 tstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
6420
a8b515e1a26f Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents: 6415
diff changeset
220 tstream->istream.iostream.close = i_stream_tee_close;
a8b515e1a26f Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents: 6415
diff changeset
221 tstream->istream.iostream.destroy = i_stream_tee_destroy;
a8b515e1a26f Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents: 6415
diff changeset
222 tstream->istream.iostream.set_max_buffer_size =
a8b515e1a26f Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents: 6415
diff changeset
223 i_stream_tee_set_max_buffer_size;
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
224
6420
a8b515e1a26f Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents: 6415
diff changeset
225 tstream->istream.read = i_stream_tee_read;
a8b515e1a26f Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents: 6415
diff changeset
226 tstream->istream.stat = i_stream_tee_stat;
a8b515e1a26f Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents: 6415
diff changeset
227 tstream->istream.sync = i_stream_tee_sync;
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
228
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
229 tstream->next = tee->children;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
230 tee->children = tstream;
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
231
10810
de2798fbbae6 istreams: Reading sometimes returned wrong data, if parent istream had been modified.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
232 ret = i_stream_create(&tstream->istream, input, i_stream_get_fd(input));
15802
eb117a619075 istream-tee: Copy the parent stream's name to child streams.
Timo Sirainen <tss@iki.fi>
parents: 14133
diff changeset
233 i_stream_set_name(&tstream->istream.istream, i_stream_get_name(input));
10810
de2798fbbae6 istreams: Reading sometimes returned wrong data, if parent istream had been modified.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
234 /* we keep the reference in tee stream, no need for extra references */
de2798fbbae6 istreams: Reading sometimes returned wrong data, if parent istream had been modified.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
235 i_stream_unref(&input);
de2798fbbae6 istreams: Reading sometimes returned wrong data, if parent istream had been modified.
Timo Sirainen <tss@iki.fi>
parents: 10582
diff changeset
236 return ret;
4266
662578b5ae22 Added tee-istream, which can be used to create multiple readable input streams from one input stream.
Timo Sirainen <timo.sirainen@movial.fi>
parents:
diff changeset
237 }
10392
9d878b1dc028 Added tee_i_stream_child_is_waiting().
Timo Sirainen <tss@iki.fi>
parents: 9522
diff changeset
238
9d878b1dc028 Added tee_i_stream_child_is_waiting().
Timo Sirainen <tss@iki.fi>
parents: 9522
diff changeset
239 bool tee_i_stream_child_is_waiting(struct istream *input)
9d878b1dc028 Added tee_i_stream_child_is_waiting().
Timo Sirainen <tss@iki.fi>
parents: 9522
diff changeset
240 {
9d878b1dc028 Added tee_i_stream_child_is_waiting().
Timo Sirainen <tss@iki.fi>
parents: 9522
diff changeset
241 struct tee_child_istream *tstream =
9d878b1dc028 Added tee_i_stream_child_is_waiting().
Timo Sirainen <tss@iki.fi>
parents: 9522
diff changeset
242 (struct tee_child_istream *)input->real_stream;
9d878b1dc028 Added tee_i_stream_child_is_waiting().
Timo Sirainen <tss@iki.fi>
parents: 9522
diff changeset
243
9d878b1dc028 Added tee_i_stream_child_is_waiting().
Timo Sirainen <tss@iki.fi>
parents: 9522
diff changeset
244 return tstream->last_read_waiting;
9d878b1dc028 Added tee_i_stream_child_is_waiting().
Timo Sirainen <tss@iki.fi>
parents: 9522
diff changeset
245 }