Mercurial > dovecot > core-2.2
annotate src/lib/ostream-multiplex.c @ 23017:c1d36f2575c7 default tip
lib-imap: Fix "Don't accept strings with NULs" cherry-pick
author | Timo Sirainen <timo.sirainen@open-xchange.com> |
---|---|
date | Thu, 29 Aug 2019 09:55:25 +0300 |
parents | cb108f786fb4 |
children |
rev | line source |
---|---|
22713
cb108f786fb4
Updated copyright notices to include the year 2018.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
22603
diff
changeset
|
1 /* Copyright (c) 2017-2018 Dovecot authors, see the included COPYING file */ |
22553
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 "ostream-private.h" |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
7 #include "ostream-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_ostream; |
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_ochannel { |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
14 struct ostream_private ostream; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
15 struct multiplex_ostream *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 buffer_t *buf; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
18 time_t last_sent; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
19 bool closed:1; |
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 |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
22 struct multiplex_ostream { |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
23 struct ostream *parent; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
24 |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
25 /* channel 0 is main channel */ |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
26 uint8_t cur_channel; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
27 unsigned int remain; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
28 buffer_t *wbuf; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
29 size_t bufsize; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
30 ARRAY(struct multiplex_ochannel *) channels; |
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 bool destroyed:1; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
33 }; |
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_ochannel * |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
36 get_channel(struct multiplex_ostream *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_ochannel **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_ostream *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_ochannel **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)->ostream.ostream.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 struct multiplex_ochannel *get_next_channel(struct multiplex_ostream *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 time_t oldest = ioloop_time; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
58 struct multiplex_ochannel *channel = NULL; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
59 struct multiplex_ochannel **channelp; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
60 array_foreach_modifiable(&mstream->channels, channelp) |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
61 if (*channelp != NULL && (*channelp)->last_sent <= oldest && |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
62 (*channelp)->buf->used > 0) |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
63 channel = *channelp; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
64 return channel; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
65 } |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
66 |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
67 static ssize_t |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
68 o_stream_multiplex_sendv(struct multiplex_ostream *mstream) |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
69 { |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
70 struct multiplex_ochannel *channel; |
22602
f36d7c6d7533
lib: ostream-multiplex - remove unnecessary flushes
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
22599
diff
changeset
|
71 ssize_t ret = 0; |
22553
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
72 if (mstream->bufsize <= mstream->wbuf->used + 5) |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
73 return -2; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
74 |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
75 while((channel = get_next_channel(mstream)) != NULL) { |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
76 size_t tmp = mstream->bufsize - mstream->wbuf->used - 5; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
77 /* ensure it fits into 32 bit int */ |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
78 size_t amt = I_MIN(UINT_MAX, I_MIN(tmp, channel->buf->used)); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
79 if (tmp == 0) |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
80 break; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
81 uint32_t len = cpu32_to_be(amt); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
82 buffer_append(mstream->wbuf, &channel->cid, 1); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
83 buffer_append(mstream->wbuf, &len, 4); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
84 buffer_append(mstream->wbuf, channel->buf->data, amt); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
85 buffer_delete(channel->buf, 0, amt); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
86 channel->last_sent = ioloop_time; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
87 } |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
88 |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
89 if (mstream->wbuf->used > 0) { |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
90 ret = o_stream_send(mstream->parent, mstream->wbuf->data, |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
91 mstream->wbuf->used); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
92 if (ret < 0) { |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
93 propagate_error(mstream, mstream->parent->stream_errno); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
94 return ret; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
95 } |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
96 buffer_delete(mstream->wbuf, 0, ret); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
97 } |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
98 return ret; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
99 } |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
100 |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
101 static ssize_t |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
102 o_stream_multiplex_ochannel_sendv(struct ostream_private *stream, |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
103 const struct const_iovec *iov, unsigned int iov_count) |
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 struct multiplex_ochannel *channel = (struct multiplex_ochannel*)stream; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
106 ssize_t ret; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
107 size_t total = 0; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
108 if (channel->mstream->bufsize <= channel->buf->used) |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
109 return -2; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
110 |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
111 for(unsigned int i=0; i < iov_count; i++) { |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
112 /* copy data to buffer */ |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
113 size_t tmp = channel->mstream->bufsize - channel->buf->used; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
114 if (tmp == 0) |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
115 break; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
116 buffer_append(channel->buf, iov[i].iov_base, |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
117 I_MIN(tmp, iov[i].iov_len)); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
118 total += I_MIN(tmp, iov[i].iov_len); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
119 } |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
120 |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
121 stream->ostream.offset += total; |
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 if ((ret = o_stream_multiplex_sendv(channel->mstream)) < 0) |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
124 return ret; |
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 return total; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
127 } |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
128 |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
129 static void |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
130 o_stream_multiplex_ochannel_close(struct iostream_private *stream, bool close_parent) |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
131 { |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
132 struct multiplex_ochannel *const *channelp; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
133 struct multiplex_ochannel *channel = (struct multiplex_ochannel*)stream; |
22603
c6ad67e373f5
lib: ostream-multiplex - ignore flush return value
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
22602
diff
changeset
|
134 (void)o_stream_flush(&channel->ostream.ostream); |
22553
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
135 |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
136 channel->closed = TRUE; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
137 if (close_parent) { |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
138 array_foreach(&channel->mstream->channels, channelp) |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
139 if (*channelp !=NULL && !(*channelp)->closed) |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
140 return; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
141 o_stream_close(channel->mstream->parent); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
142 } |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
143 } |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
144 |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
145 static void o_stream_multiplex_try_destroy(struct multiplex_ostream *mstream) |
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 struct multiplex_ochannel **channelp; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
148 /* can't do anything until they are all closed */ |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
149 array_foreach_modifiable(&mstream->channels, channelp) |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
150 if (*channelp != NULL) |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
151 return; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
152 o_stream_unref(&mstream->parent); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
153 array_free(&mstream->channels); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
154 buffer_free(&mstream->wbuf); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
155 i_free(mstream); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
156 } |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
157 |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
158 static void o_stream_multiplex_ochannel_destroy(struct iostream_private *stream) |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
159 { |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
160 struct multiplex_ochannel **channelp; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
161 struct multiplex_ochannel *channel = (struct multiplex_ochannel*)stream; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
162 o_stream_multiplex_ochannel_close(stream, TRUE); |
22588
041460202062
ostream-multiplex: Unreference stream parent
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
22585
diff
changeset
|
163 o_stream_unref(&channel->ostream.parent); |
22553
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
164 if (channel->buf != NULL) |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
165 buffer_free(&channel->buf); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
166 /* delete the channel */ |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
167 array_foreach_modifiable(&channel->mstream->channels, channelp) { |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
168 if (*channelp != NULL && (*channelp)->cid == channel->cid) { |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
169 *channelp = NULL; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
170 break; |
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 } |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
173 o_stream_multiplex_try_destroy(channel->mstream); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
174 } |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
175 |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
176 static struct ostream * |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
177 o_stream_add_channel_real(struct multiplex_ostream *mstream, uint8_t cid) |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
178 { |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
179 struct multiplex_ochannel *channel = i_new(struct multiplex_ochannel, 1); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
180 channel->cid = cid; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
181 channel->buf = buffer_create_dynamic(default_pool, 256); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
182 channel->mstream = mstream; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
183 channel->ostream.sendv = o_stream_multiplex_ochannel_sendv; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
184 channel->ostream.iostream.close = o_stream_multiplex_ochannel_close; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
185 channel->ostream.iostream.destroy = o_stream_multiplex_ochannel_destroy; |
22585
e1ad624fc2ad
lib: ostream-multiplex - set ostream_private.parent
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
22553
diff
changeset
|
186 channel->ostream.fd = o_stream_get_fd(mstream->parent); |
22553
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
187 array_append(&channel->mstream->channels, &channel, 1); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
188 |
22585
e1ad624fc2ad
lib: ostream-multiplex - set ostream_private.parent
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
22553
diff
changeset
|
189 return o_stream_create(&channel->ostream, mstream->parent, |
e1ad624fc2ad
lib: ostream-multiplex - set ostream_private.parent
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
22553
diff
changeset
|
190 mstream->bufsize); |
22553
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
191 } |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
192 |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
193 struct ostream *o_stream_multiplex_add_channel(struct ostream *stream, uint8_t cid) |
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_ochannel *chan = |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
196 (struct multiplex_ochannel *)stream->real_stream; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
197 i_assert(get_channel(chan->mstream, cid) == NULL); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
198 |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
199 return o_stream_add_channel_real(chan->mstream, cid); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
200 } |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
201 |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
202 struct ostream *o_stream_create_multiplex(struct ostream *parent, size_t bufsize) |
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 struct multiplex_ostream *mstream; |
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 mstream = i_new(struct multiplex_ostream, 1); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
207 mstream->parent = parent; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
208 mstream->bufsize = bufsize; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
209 mstream->wbuf = buffer_create_dynamic(default_pool, 256); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
210 i_array_init(&mstream->channels, 8); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
211 o_stream_ref(parent); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
212 |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
213 return o_stream_add_channel_real(mstream, 0); |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
214 } |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
215 |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
216 uint8_t o_stream_multiplex_get_channel_id(struct ostream *stream) |
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 struct multiplex_ochannel *channel = |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
219 (struct multiplex_ochannel *)stream->real_stream; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
220 return channel->cid; |
7db517071db5
lib: Add multiplex stream support
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff
changeset
|
221 } |