This makes sure that the istream size can't grow too large and waste memory.
Previously the istream max_buffer_size was dynamically changed to be the
smallest seen max_buffer_size in chained istreams. This mostly worked, but
sometimes the istream-chain's max_buffer_size was requested before even the
first istream was added to it.
Having an explicit max_buffer_size avoids all the problems of it being
dynamic, and there's not really any need for it anyway.
if (cat_list != NULL) {
ctx->cat_msg_size = 0;
- ctx->input = i_stream_create_chain(&ctx->catchain);
- i_stream_set_max_buffer_size(ctx->input, IO_BLOCK_SIZE);
+ ctx->input = i_stream_create_chain(&ctx->catchain,
+ IO_BLOCK_SIZE);
} else {
if (ctx->literal_size == 0) {
/* no message data, abort */
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n");
}
- chain_input = i_stream_create_chain(&chain);
+ chain_input = i_stream_create_chain(&chain, IO_BLOCK_SIZE);
input = i_stream_create_copy_from_data(str_data(payload),
str_len(payload));
i_assert(data_cmd->chunk_first);
i_assert(conn->state.data_chain_input == NULL);
conn->state.data_chain_input =
- i_stream_create_chain(&conn->state.data_chain);
+ i_stream_create_chain(&conn->state.data_chain,
+ IO_BLOCK_SIZE);
}
}
cmd = pop3c_client_cmd_line_async(client, cmdline, callback, context);
- input = i_stream_create_chain(&cmd->chain);
+ input = i_stream_create_chain(&cmd->chain, POP3C_MAX_INBUF_SIZE);
inputs[0] = i_stream_create_dot(input, TRUE);
inputs[1] = NULL;
cmd->input = i_stream_create_seekable(inputs, POP3C_MAX_INBUF_SIZE,
the beginning of the current link's stream. */
size_t prev_stream_left;
size_t prev_skip;
- bool have_explicit_max_buffer_size;
struct istream_chain chain;
};
i_stream_ref(stream);
if (chain->head == NULL && stream != NULL) {
- struct chain_istream *cstream = chain->stream;
-
- if (cstream->have_explicit_max_buffer_size) {
- i_stream_set_max_buffer_size(stream,
- chain->stream->istream.max_buffer_size);
- } else {
- size_t max_size = i_stream_get_max_buffer_size(stream);
-
- if (cstream->istream.max_buffer_size < max_size)
- cstream->istream.max_buffer_size = max_size;
- }
+ i_stream_set_max_buffer_size(stream,
+ chain->stream->istream.max_buffer_size);
}
DLLIST2_APPEND(&chain->head, &chain->tail, link);
/* if io_add_istream() has been added to this chain stream, notify
container_of(stream, struct chain_istream, istream.iostream);
struct istream_chain_link *link = cstream->chain.head;
- cstream->have_explicit_max_buffer_size = TRUE;
cstream->istream.max_buffer_size = max_size;
while (link != NULL) {
if (link->stream != NULL)
return snapshot;
}
-struct istream *i_stream_create_chain(struct istream_chain **chain_r)
+struct istream *i_stream_create_chain(struct istream_chain **chain_r,
+ size_t max_buffer_size)
{
struct chain_istream *cstream;
cstream = i_new(struct chain_istream, 1);
cstream->chain.stream = cstream;
+ cstream->istream.max_buffer_size = max_buffer_size;
cstream->istream.iostream.close = i_stream_chain_close;
cstream->istream.iostream.destroy = i_stream_chain_destroy;
NULL. Streams that were finished to EOF are unreferenced. The chain stream
is obviously not seekable and it has no determinable size. The chain_r
argument returns a pointer to the chain object. */
-struct istream *i_stream_create_chain(struct istream_chain **chain_r);
+struct istream *i_stream_create_chain(struct istream_chain **chain_r,
+ size_t max_buffer_size);
/* Append an input stream to the chain. */
void i_stream_chain_append(struct istream_chain *chain, struct istream *stream);
test_input = test_istream_create("stream1");
test_input2 = test_istream_create("STREAM2");
- input = i_stream_create_chain(&chain);
+ input = i_stream_create_chain(&chain, IO_BLOCK_SIZE);
/* no input */
test_assert(i_stream_read(input) == 0);
/* stream1 input */
test_istream_set_size(test_input, 3);
test_istream_set_allow_eof(test_input, FALSE);
- input = i_stream_create_chain(&chain);
+ input = i_stream_create_chain(&chain, IO_BLOCK_SIZE);
i_stream_chain_append(chain, test_input);
test_assert(i_stream_read(input) == 3);
test_istream_set_size(test_input, 5);
test_istreams[3] = test_istream_create("z1y2x3w4v5u6t7s8r9q0p.o,n");
test_istreams[4] = test_istream_create("aAbBcCdDeEfFgGhHiIjJ");
- input = i_stream_create_chain(&chain);
+ input = i_stream_create_chain(&chain, IO_BLOCK_SIZE);
/* no input */
test_assert(i_stream_read(input) == 0);