From 98a4ffa84c6267db828449cc2defa732b5d01bcd Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Thu, 20 Jan 2022 14:13:48 +0100 Subject: [PATCH] lib: ostream-multiplex - Call flush callbacks also when stream has failed It may be important for the flush callbacks to know when ostream has been closed. This is a partial fix to prevent doveadm-server hanging when it's printing lots of output and doveadm client disconnects. --- src/lib/ostream-multiplex.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/lib/ostream-multiplex.c b/src/lib/ostream-multiplex.c index 30cdccc166..6c3bf8536e 100644 --- a/src/lib/ostream-multiplex.c +++ b/src/lib/ostream-multiplex.c @@ -121,25 +121,26 @@ static int o_stream_multiplex_flush(struct multiplex_ostream *mstream) int ret = o_stream_flush(mstream->parent); if (ret >= 0) { if (!o_stream_multiplex_sendv(mstream)) - ret = 0; + return 0; } - if (ret <= 0) - return ret; - /* Everything is flushed. See if one of the callbacks' flush callbacks - wants to write more data. */ + /* a) Everything is flushed. See if one of the callbacks' flush + callbacks wants to write more data. + b) ostream failed. Notify the callbacks in case they need to know. */ struct multiplex_ochannel *channel; bool unfinished = FALSE; + bool failed = FALSE; array_foreach_elem(&mstream->channels, channel) { if (channel != NULL && channel->ostream.callback != NULL) { ret = channel->ostream.callback(channel->ostream.context); if (ret < 0) - return -1; - if (ret == 0) + failed = TRUE; + else if (ret == 0) unfinished = TRUE; } } - return unfinished ? 0 : 1; + return failed ? -1 : + (unfinished ? 0 : 1); } static int o_stream_multiplex_ochannel_flush(struct ostream_private *stream) -- 2.47.3