blob: 6f0f8b7dbd4c253a07b414663e2872dfb041c128 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
#ifndef ISTREAM_TRY_H
#define ISTREAM_TRY_H
/* Read from the first input stream that doesn't fail with EINVAL. If any of
the streams fail with non-EINVAL, it's treated as a fatal failure and the
error is immediately returned. If a stream returns 0, more data is waited
for before continuing to the next stream. This allows the last stream to
be a fallback stream that always succeeds.
Once the stream is detected, all the other streams are unreferenced.
The streams should usually be children of the same parent tee-istream.
Detecting whether istream-tee buffer is full or not is a bit tricky.
There's no visible difference between non-blocking istream returning 0 and
istream-tee buffer being full. To work around this, we treat used buffer
sizes <= min_buffer_full_size as being non-blocking istreams, while
buffer sizes > min_buffer_full_size are assumed to be due to istream-tee
max buffer size being reached. Practically this means that
min_buffer_full_size must be smaller than the smallest of the istreams'
maximum buffer sizes, but large enough that all the istreams would have
returned EINVAL on invalid input by that position. */
struct istream *istream_try_create(struct istream *const input[],
size_t min_buffer_full_size);
#endif
|