From: Aki Tuomi Date: Wed, 10 Jul 2019 08:25:14 +0000 (+0300) Subject: lib: ostream-multiplex - Fix last_sent X-Git-Tag: 2.3.9~375 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1127208022e2d9fe8054ce1f540ed066b5e7656f;p=thirdparty%2Fdovecot%2Fcore.git lib: ostream-multiplex - Fix last_sent The intention was to choose oldest channel. The old code however always chose last channel to send, which was not really the point. Using unix timestamp is also problematic due to sub-second granularity. --- diff --git a/src/lib/ostream-multiplex.c b/src/lib/ostream-multiplex.c index 71cb871be1..352fe3acdc 100644 --- a/src/lib/ostream-multiplex.c +++ b/src/lib/ostream-multiplex.c @@ -15,7 +15,7 @@ struct multiplex_ochannel { struct multiplex_ostream *mstream; uint8_t cid; buffer_t *buf; - time_t last_sent; + uint64_t last_sent_counter; bool closed:1; bool corked:1; }; @@ -27,6 +27,7 @@ struct multiplex_ostream { uint8_t cur_channel; unsigned int remain; size_t bufsize; + uint64_t send_counter; ARRAY(struct multiplex_ochannel *) channels; bool destroyed:1; @@ -54,13 +55,18 @@ static void propagate_error(struct multiplex_ostream *mstream, int stream_errno) static struct multiplex_ochannel *get_next_channel(struct multiplex_ostream *mstream) { - time_t oldest = ioloop_time; struct multiplex_ochannel *channel = NULL; struct multiplex_ochannel **channelp; - array_foreach_modifiable(&mstream->channels, channelp) - if (*channelp != NULL && (*channelp)->last_sent <= oldest && - (*channelp)->buf->used > 0) + uint64_t last_counter = mstream->send_counter; + + array_foreach_modifiable(&mstream->channels, channelp) { + if (*channelp != NULL && + (*channelp)->last_sent_counter <= last_counter && + (*channelp)->buf->used > 0) { + last_counter = (*channelp)->last_sent_counter; channel = *channelp; + } + } return channel; } @@ -97,7 +103,7 @@ o_stream_multiplex_sendv(struct multiplex_ostream *mstream) break; } buffer_delete(channel->buf, 0, amt); - channel->last_sent = ioloop_time; + channel->last_sent_counter = ++mstream->send_counter; } if (o_stream_is_corked(mstream->parent)) o_stream_uncork(mstream->parent);