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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }