]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: ostream-wrapper - Properly manage parent output events for blocking operation.
authorStephan Bosch <stephan.bosch@open-xchange.com>
Thu, 23 Apr 2020 09:36:30 +0000 (11:36 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Mon, 27 Apr 2020 17:27:34 +0000 (17:27 +0000)
The problem was exposed by a panic occurring in src/lib-http/test-http-payload unit test:

Panic: file ostream-wrapper.c: line 291 (wrapper_ostream_flush_wait): assertion failed: (io_loop_have_ios(ioloop) || io_loop_have_immediate_timeouts(ioloop))

src/lib/ostream-wrapper.c

index 62416430e3845daf33ca8290f0a150dd9b8d623a..2a3b78f9633c815f557232a3a18e8f2ff033214a 100644 (file)
@@ -178,20 +178,20 @@ static void
 wrapper_ostream_output_manage(struct wrapper_ostream *wostream, bool sending)
 {
        struct ostream_private *stream = &wostream->ostream;
-       bool no_data;
+       bool must_flush, no_data;
 
        if (wostream->output_closed)
                return;
 
-       no_data = (!sending && wrapper_ostream_is_empty(wostream)) ||
-                  (stream->corked && !wostream->flushing &&
-                   !stream->finished && !wrapper_ostream_is_filled(wostream));
+       must_flush = (sending || stream->finished || wostream->flush_pending);
+       no_data = (wrapper_ostream_is_empty(wostream) ||
+                  (stream->corked && !wrapper_ostream_is_filled(wostream)));
 
-       if ((stream->ostream.closed || no_data) && !wostream->flush_pending)
+       if (!must_flush && (no_data || stream->ostream.closed))
                wrapper_ostream_output_halt(wostream);
        else {
                wrapper_ostream_output_resume(wostream);
-               if (wostream->flush_pending && wostream->output != NULL)
+               if (wostream->output != NULL && must_flush)
                        o_stream_set_flush_pending(wostream->output, TRUE);
        }
 }