ostream-multiplex.c revision 6139e5f5cae82fa04b45e8366c24facf246e6292
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeper/* Copyright (c) 2017 Dovecot authors, see the included COPYING file */
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeper/* all multiplex packets are [1 byte cid][4 byte length][data] */
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeper /* channel 0 is main channel */
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeper unsigned int remain;
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeperget_channel(struct multiplex_ostream *mstream, uint8_t cid)
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeper array_foreach_modifiable(&mstream->channels, channelp) {
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeper if (*channelp != NULL && (*channelp)->cid == cid)
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeperstatic void propagate_error(struct multiplex_ostream *mstream, int stream_errno)
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeper array_foreach_modifiable(&mstream->channels, channelp)
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeper (*channelp)->ostream.ostream.stream_errno = stream_errno;
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeperstatic struct multiplex_ochannel *get_next_channel(struct multiplex_ostream *mstream)
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeper array_foreach_modifiable(&mstream->channels, channelp)
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeper if (*channelp != NULL && (*channelp)->last_sent <= oldest &&
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reepero_stream_multiplex_sendv(struct multiplex_ostream *mstream)
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeper if (mstream->bufsize <= mstream->wbuf->used + 5)
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeper while((channel = get_next_channel(mstream)) != NULL) {
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeper size_t tmp = mstream->bufsize - mstream->wbuf->used - 5;
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeper /* ensure it fits into 32 bit int */
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeper size_t amt = I_MIN(UINT_MAX, I_MIN(tmp, channel->buf->used));
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeper buffer_append(mstream->wbuf, &channel->cid, 1);
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeper buffer_append(mstream->wbuf, channel->buf->data, amt);
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeper ret = o_stream_send(mstream->parent, mstream->wbuf->data,
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeper propagate_error(mstream, mstream->parent->stream_errno);
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reepero_stream_multiplex_ochannel_sendv(struct ostream_private *stream,
0595fb660c93faf1fdbaad7e1300eb342b5baf31Mark de Reeper const struct const_iovec *iov, unsigned int iov_count)
6406210b71fd4a97800f32f3613eea9b6a6a12ceMark de Reeper struct multiplex_ochannel *channel = (struct multiplex_ochannel*)stream;
for(unsigned int i=0; i < iov_count; i++) {
if (tmp == 0)
return ret;
return total;
if (close_parent) {
static struct ostream *