annotate src/lib/istream-multiplex.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 09164094f254
children cb108f786fb4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
22553
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
1 /* Copyright (c) 2017 Dovecot authors, see the included COPYING file */
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
2
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
3 #include "lib.h"
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
4 #include "ioloop.h"
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
5 #include "array.h"
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
6 #include "istream-private.h"
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
7 #include "istream-multiplex.h"
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
8
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
9 /* all multiplex packets are [1 byte cid][4 byte length][data] */
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
10
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
11 struct multiplex_istream;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
12
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
13 struct multiplex_ichannel {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
14 struct istream_private istream;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
15 struct multiplex_istream *mstream;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
16 uint8_t cid;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
17 size_t pending_pos;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
18 bool closed:1;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
19 };
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
20
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
21 struct multiplex_istream {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
22 struct istream *parent;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
23
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
24 /* channel 0 is main channel */
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
25 uint8_t cur_channel;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
26 unsigned int remain;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
27 size_t bufsize;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
28 ARRAY(struct multiplex_ichannel *) channels;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
29
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
30 bool blocking:1;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
31 };
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
32
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
33 static ssize_t i_stream_multiplex_ichannel_read(struct istream_private *stream);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
34
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
35 static struct multiplex_ichannel *
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
36 get_channel(struct multiplex_istream *mstream, uint8_t cid)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
37 {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
38 struct multiplex_ichannel **channelp;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
39 i_assert(mstream != NULL);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
40 array_foreach_modifiable(&mstream->channels, channelp) {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
41 if (*channelp != NULL && (*channelp)->cid == cid)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
42 return *channelp;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
43 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
44 return NULL;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
45 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
46
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
47 static void propagate_error(struct multiplex_istream *mstream, int stream_errno)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
48 {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
49 struct multiplex_ichannel **channelp;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
50 array_foreach_modifiable(&mstream->channels, channelp)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
51 if (*channelp != NULL)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
52 (*channelp)->istream.istream.stream_errno = stream_errno;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
53 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
54
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
55 static void propagate_eof(struct multiplex_istream *mstream)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
56 {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
57 struct multiplex_ichannel **channelp;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
58 array_foreach_modifiable(&mstream->channels, channelp) {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
59 if (*channelp != NULL) {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
60 (*channelp)->istream.istream.eof = TRUE;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
61 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
62 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
63 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
64
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
65 static ssize_t
22601
09164094f254 lib: istream-multiplex - Minor optimization
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22584
diff changeset
66 i_stream_multiplex_read(struct multiplex_istream *mstream,
09164094f254 lib: istream-multiplex - Minor optimization
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22584
diff changeset
67 struct multiplex_ichannel *req_channel)
22553
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
68 {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
69 const unsigned char *data;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
70 size_t len = 0, used, wanted, avail;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
71 ssize_t ret, got = 0;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
72
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
73 if (mstream->parent == NULL) {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
74 req_channel->istream.istream.eof = TRUE;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
75 return -1;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
76 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
77
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
78 data = i_stream_get_data(mstream->parent, &len);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
79
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
80 if (len == 0 && mstream->parent->closed) {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
81 req_channel->istream.istream.eof = TRUE;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
82 return -1;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
83 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
84
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
85 if (((mstream->remain > 0 && len == 0) ||
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
86 (mstream->remain == 0 && len < 5)) &&
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
87 (ret = i_stream_read(mstream->parent)) <= 0) {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
88 propagate_error(mstream, mstream->parent->stream_errno);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
89 if (mstream->parent->eof)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
90 propagate_eof(mstream);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
91 return ret;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
92 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
93
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
94 for(;;) {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
95 data = i_stream_get_data(mstream->parent, &len);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
96 if (len == 0) {
22576
707ae9de3812 lib: istream-multiplex - Minor code cleanup
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22553
diff changeset
97 if (got == 0 && mstream->blocking) {
707ae9de3812 lib: istream-multiplex - Minor code cleanup
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22553
diff changeset
98 /* can't return 0 with blocking istreams,
707ae9de3812 lib: istream-multiplex - Minor code cleanup
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22553
diff changeset
99 so try again from the beginning. */
22601
09164094f254 lib: istream-multiplex - Minor optimization
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22584
diff changeset
100 return i_stream_multiplex_read(mstream, req_channel);
22576
707ae9de3812 lib: istream-multiplex - Minor code cleanup
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22553
diff changeset
101 }
22553
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
102 break;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
103 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
104
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
105 if (mstream->remain > 0) {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
106 struct multiplex_ichannel *channel =
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
107 get_channel(mstream, mstream->cur_channel);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
108 wanted = I_MIN(len, mstream->remain);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
109 /* is it open? */
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
110 if (channel != NULL && !channel->closed) {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
111 struct istream_private *stream = &channel->istream;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
112 stream->pos += channel->pending_pos;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
113 bool alloc_ret = i_stream_try_alloc(stream, wanted, &avail);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
114 stream->pos -= channel->pending_pos;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
115 if (!alloc_ret) {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
116 i_stream_set_input_pending(&stream->istream, TRUE);
22601
09164094f254 lib: istream-multiplex - Minor optimization
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22584
diff changeset
117 if (channel->cid != req_channel->cid)
22553
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
118 return 0;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
119 if (got > 0)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
120 break;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
121 return -2;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
122 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
123
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
124 used = I_MIN(wanted, avail);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
125
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
126 /* dump into buffer */
22601
09164094f254 lib: istream-multiplex - Minor optimization
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22584
diff changeset
127 if (channel->cid != req_channel->cid) {
22553
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
128 i_assert(stream->pos + channel->pending_pos + used <= stream->buffer_size);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
129 memcpy(stream->w_buffer + stream->pos + channel->pending_pos,
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
130 data, used);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
131 channel->pending_pos += used;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
132 i_stream_set_input_pending(&stream->istream, TRUE);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
133 } else {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
134 i_assert(stream->pos + used <= stream->buffer_size);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
135 memcpy(stream->w_buffer + stream->pos, data, used);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
136 stream->pos += used;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
137 got += used;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
138 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
139 } else {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
140 used = wanted;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
141 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
142 mstream->remain -= used;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
143 i_stream_skip(mstream->parent, used);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
144 /* see if there is more to read */
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
145 continue;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
146 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
147 if (mstream->remain == 0) {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
148 /* need more data */
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
149 if (len < 5) {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
150 ret = i_stream_multiplex_ichannel_read(&req_channel->istream);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
151 if (ret > 0)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
152 got += ret;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
153 break;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
154 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
155 /* channel ID */
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
156 mstream->cur_channel = data[0];
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
157 /* data length */
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
158 mstream->remain = be32_to_cpu_unaligned(data+1);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
159 i_stream_skip(mstream->parent, 5);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
160 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
161 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
162
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
163 propagate_error(mstream, mstream->parent->stream_errno);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
164 if (mstream->parent->eof)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
165 propagate_eof(mstream);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
166
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
167 return got;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
168 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
169
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
170 static ssize_t i_stream_multiplex_ichannel_read(struct istream_private *stream)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
171 {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
172 struct multiplex_ichannel *channel = (struct multiplex_ichannel*)stream;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
173 /* if previous multiplex read dumped data for us
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
174 actually serve it here. */
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
175 if (channel->pending_pos > 0) {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
176 ssize_t ret = channel->pending_pos;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
177 stream->pos += channel->pending_pos;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
178 channel->pending_pos = 0;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
179 return ret;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
180 }
22601
09164094f254 lib: istream-multiplex - Minor optimization
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22584
diff changeset
181 return i_stream_multiplex_read(channel->mstream, channel);
22553
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
182 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
183
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
184 static void
22584
51b74dbe1ce9 lib: istream-multiplex - Forward i_stream_switch_ioloop() to parent
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22576
diff changeset
185 i_stream_multiplex_ichannel_switch_ioloop(struct istream_private *stream)
51b74dbe1ce9 lib: istream-multiplex - Forward i_stream_switch_ioloop() to parent
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22576
diff changeset
186 {
51b74dbe1ce9 lib: istream-multiplex - Forward i_stream_switch_ioloop() to parent
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22576
diff changeset
187 struct multiplex_ichannel *channel = (struct multiplex_ichannel*)stream;
51b74dbe1ce9 lib: istream-multiplex - Forward i_stream_switch_ioloop() to parent
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22576
diff changeset
188
51b74dbe1ce9 lib: istream-multiplex - Forward i_stream_switch_ioloop() to parent
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22576
diff changeset
189 i_stream_switch_ioloop(channel->mstream->parent);
51b74dbe1ce9 lib: istream-multiplex - Forward i_stream_switch_ioloop() to parent
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22576
diff changeset
190 }
51b74dbe1ce9 lib: istream-multiplex - Forward i_stream_switch_ioloop() to parent
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22576
diff changeset
191
51b74dbe1ce9 lib: istream-multiplex - Forward i_stream_switch_ioloop() to parent
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22576
diff changeset
192 static void
22553
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
193 i_stream_multiplex_ichannel_close(struct iostream_private *stream, bool close_parent)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
194 {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
195 struct multiplex_ichannel *const *channelp;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
196 struct multiplex_ichannel *channel = (struct multiplex_ichannel*)stream;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
197 channel->closed = TRUE;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
198 if (close_parent) {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
199 array_foreach(&channel->mstream->channels, channelp)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
200 if (*channelp != NULL && !(*channelp)->closed)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
201 return;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
202 i_stream_close(channel->mstream->parent);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
203 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
204 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
205
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
206 static void i_stream_multiplex_try_destroy(struct multiplex_istream *mstream)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
207 {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
208 struct multiplex_ichannel **channelp;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
209 /* can't do anything until they are all closed */
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
210 array_foreach_modifiable(&mstream->channels, channelp)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
211 if (*channelp != NULL)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
212 return;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
213 i_stream_unref(&mstream->parent);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
214 array_free(&mstream->channels);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
215 i_free(mstream);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
216 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
217
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
218 static void i_stream_multiplex_ichannel_destroy(struct iostream_private *stream)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
219 {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
220 struct multiplex_ichannel **channelp;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
221 struct multiplex_ichannel *channel = (struct multiplex_ichannel*)stream;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
222 i_stream_multiplex_ichannel_close(stream, TRUE);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
223 i_free(channel->istream.w_buffer);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
224 array_foreach_modifiable(&channel->mstream->channels, channelp) {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
225 if (*channelp == channel) {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
226 *channelp = NULL;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
227 break;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
228 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
229 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
230 i_stream_multiplex_try_destroy(channel->mstream);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
231 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
232
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
233 static struct istream *
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
234 i_stream_add_channel_real(struct multiplex_istream *mstream, uint8_t cid)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
235 {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
236 struct multiplex_ichannel *channel = i_new(struct multiplex_ichannel, 1);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
237 channel->cid = cid;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
238 channel->mstream = mstream;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
239 channel->istream.read = i_stream_multiplex_ichannel_read;
22584
51b74dbe1ce9 lib: istream-multiplex - Forward i_stream_switch_ioloop() to parent
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 22576
diff changeset
240 channel->istream.switch_ioloop = i_stream_multiplex_ichannel_switch_ioloop;
22553
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
241 channel->istream.iostream.close = i_stream_multiplex_ichannel_close;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
242 channel->istream.iostream.destroy = i_stream_multiplex_ichannel_destroy;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
243 channel->istream.max_buffer_size = mstream->bufsize;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
244 channel->istream.istream.blocking = mstream->blocking;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
245 if (cid == 0)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
246 channel->istream.fd = i_stream_get_fd(mstream->parent);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
247 else
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
248 channel->istream.fd = -1;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
249 array_append(&channel->mstream->channels, &channel, 1);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
250
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
251 return i_stream_create(&channel->istream, NULL, channel->istream.fd);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
252 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
253
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
254 struct istream *i_stream_multiplex_add_channel(struct istream *stream, uint8_t cid)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
255 {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
256 struct multiplex_ichannel *chan =
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
257 (struct multiplex_ichannel *)stream->real_stream;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
258 i_assert(get_channel(chan->mstream, cid) == NULL);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
259
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
260 return i_stream_add_channel_real(chan->mstream, cid);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
261 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
262
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
263 struct istream *i_stream_create_multiplex(struct istream *parent, size_t bufsize)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
264 {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
265 struct multiplex_istream *mstream;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
266
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
267 mstream = i_new(struct multiplex_istream, 1);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
268 mstream->parent = parent;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
269 mstream->bufsize = bufsize;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
270 mstream->blocking = parent->blocking;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
271 i_array_init(&mstream->channels, 8);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
272 i_stream_ref(parent);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
273
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
274 return i_stream_add_channel_real(mstream, 0);
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
275 }
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
276
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
277 uint8_t i_stream_multiplex_get_channel_id(struct istream *stream)
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
278 {
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
279 struct multiplex_ichannel *channel =
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
280 (struct multiplex_ichannel *)stream->real_stream;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
281 return channel->cid;
7db517071db5 lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
282 }