]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Add o_stream_set_finish_also_parent() and _finish_via_child()
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Tue, 31 Oct 2017 15:07:44 +0000 (17:07 +0200)
committerTimo Sirainen <tss@dovecot.fi>
Wed, 1 Nov 2017 00:22:19 +0000 (02:22 +0200)
These allow controlling on both directions whether o_stream_finish() should
be finishing the parent stream. If either one is set to FALSE, the parent
stream isn't finished. Which one of these to use depends on the situation.

src/lib/ostream-private.h
src/lib/ostream.c
src/lib/ostream.h

index 609ba80b4d5984ebaa2efcd43ffea4c35f45748c..d694fca577b2f896afaad4b7d2a8125307e50b7f 100644 (file)
@@ -43,6 +43,8 @@ struct ostream_private {
        bool last_errors_not_checked:1;
        bool error_handling_disabled:1;
        bool noverflow:1;
+       bool finish_also_parent:1;
+       bool finish_via_child:1;
 };
 
 struct ostream *
index 7985fc9efda0d6b2897986ded0917b2a2b099980..05ec0955721d8d7d4f1ce96a90b4d93b4a1bbff9 100644 (file)
@@ -340,6 +340,16 @@ int o_stream_finish(struct ostream *stream)
        return o_stream_flush(stream);
 }
 
+void o_stream_set_finish_also_parent(struct ostream *stream, bool set)
+{
+       stream->real_stream->finish_also_parent = set;
+}
+
+void o_stream_set_finish_via_child(struct ostream *stream, bool set)
+{
+       stream->real_stream->finish_via_child = set;
+}
+
 void o_stream_ignore_last_errors(struct ostream *stream)
 {
        while (stream != NULL) {
@@ -550,7 +560,8 @@ int o_stream_flush_parent(struct ostream_private *_stream)
 
        i_assert(_stream->parent != NULL);
 
-       if (!_stream->finished)
+       if (!_stream->finished || !_stream->finish_also_parent ||
+           !_stream->parent->real_stream->finish_via_child)
                ret = o_stream_flush(_stream->parent);
        else
                ret = o_stream_finish(_stream->parent);
@@ -642,6 +653,8 @@ static void o_stream_default_switch_ioloop(struct ostream_private *_stream)
 struct ostream *
 o_stream_create(struct ostream_private *_stream, struct ostream *parent, int fd)
 {
+       _stream->finish_also_parent = TRUE;
+       _stream->finish_via_child = TRUE;
        _stream->fd = fd;
        _stream->ostream.real_stream = _stream;
        if (parent != NULL) {
index 41968e0bf86ee8be5955765ea34b315a08fb99d8..7b149a64f95ccc4c0b9272fc86209e3da97a47cf 100644 (file)
@@ -166,6 +166,12 @@ void o_stream_nsend_str(struct ostream *stream, const char *str);
    assert-crash. Returns the same as o_stream_flush(). Afterwards any calls to
    this function are identical to o_stream_flush(). */
 int o_stream_finish(struct ostream *stream);
+/* Specify whether calling o_stream_finish() will cause the parent stream to
+   be finished as well. The default is yes. */
+void o_stream_set_finish_also_parent(struct ostream *stream, bool set);
+/* Specify whether calling o_stream_finish() on a child stream will cause
+   this stream to be finished as well. The default is yes. */
+void o_stream_set_finish_via_child(struct ostream *stream, bool set);
 /* Marks the stream's error handling as completed to avoid i_panic() on
    destroy. */
 void o_stream_ignore_last_errors(struct ostream *stream);