]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Add o_stream_finish()
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Fri, 27 Oct 2017 22:15:14 +0000 (01:15 +0300)
committerTimo Sirainen <tss@dovecot.fi>
Mon, 30 Oct 2017 11:04:53 +0000 (13:04 +0200)
This marks the ostream as fully finished, with no further writes coming to
it. Otherwise it behaves like o_stream_flush().

The ostream.flush() methods are supposed to write their trailer (if the
ostream has one) when they see that ostream.finished is set. These will be
implemented by the following commits.

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

index f35d472362c0910a061024a1e3ce21502ad4b2d8..d9d4fa5f7cd01f6cf7d22a2e401480eb33e39636 100644 (file)
@@ -38,6 +38,7 @@ struct ostream_private {
        void *context;
 
        bool corked:1;
+       bool finished:1;
        bool closing:1;
        bool last_errors_not_checked:1;
        bool error_handling_disabled:1;
index 9b27293ff983f6767a22c41fb486c4d3b7784a72..15e23d44f72f052edc90078a04d8a2163111d54e 100644 (file)
@@ -264,6 +264,7 @@ o_stream_sendv_int(struct ostream *stream, const struct const_iovec *iov,
        if (total_size == 0)
                return 0;
 
+       i_assert(!_stream->finished);
        ret = _stream->sendv(_stream, iov, iov_count);
        if (unlikely(ret != (ssize_t)total_size)) {
                if (ret < 0) {
@@ -325,6 +326,12 @@ void o_stream_nsend_str(struct ostream *stream, const char *str)
        o_stream_nsend(stream, str, strlen(str));
 }
 
+int o_stream_finish(struct ostream *stream)
+{
+       stream->real_stream->finished = TRUE;
+       return o_stream_flush(stream);
+}
+
 void o_stream_ignore_last_errors(struct ostream *stream)
 {
        while (stream != NULL) {
@@ -355,6 +362,7 @@ o_stream_send_istream(struct ostream *outstream, struct istream *instream)
                return OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT;
        }
 
+       i_assert(!_outstream->finished);
        res = _outstream->send_istream(_outstream, instream);
        switch (res) {
        case OSTREAM_SEND_ISTREAM_RESULT_FINISHED:
@@ -417,6 +425,7 @@ int o_stream_pwrite(struct ostream *stream, const void *data, size_t size,
                return -1;
        }
 
+       i_assert(!stream->real_stream->finished);
        ret = stream->real_stream->write_at(stream->real_stream,
                                            data, size, offset);
        if (unlikely(ret < 0)) {
index 586747f3733d8d5c478193343b73157cb4283dbb..b93fd2d4e448a9e3f5e1207577e2c459003e8b56 100644 (file)
@@ -159,6 +159,11 @@ static inline int o_stream_nfinish(struct ostream *stream)
 {
        return o_stream_flush(stream) < 0 ? -1 : 0;
 }
+/* Mark the ostream as finished and flush it. If the ostream has a footer,
+   it's written here. Any further write attempts to the ostream will
+   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);
 /* Marks the stream's error handling as completed to avoid i_panic() on
    destroy. */
 void o_stream_ignore_last_errors(struct ostream *stream);