]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Add o_stream_get_last_write_time()
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Sun, 29 Oct 2017 22:59:01 +0000 (00:59 +0200)
committerTimo Sirainen <tss@dovecot.fi>
Mon, 6 Nov 2017 23:09:00 +0000 (01:09 +0200)
src/lib/ostream-private.h
src/lib/ostream.c
src/lib/ostream.h

index d694fca577b2f896afaad4b7d2a8125307e50b7f..e0a7d81be7bad0ed05701f57ee1b7f1413cb59c9 100644 (file)
@@ -34,6 +34,8 @@ struct ostream_private {
        struct ostream *parent; /* for filter streams */
 
        int fd;
+       struct timeval last_write_timeval;
+
        stream_flush_callback_t *callback;
        void *context;
 
index 03d33df273be71b0f43a4dbe39b3d38cf0eeb027..ca2c506e13932a929051f5c0ed16a8323dff7631 100644 (file)
@@ -275,6 +275,8 @@ o_stream_sendv_int(struct ostream *stream, const struct const_iovec *iov,
 
        i_assert(!_stream->finished);
        ret = _stream->sendv(_stream, iov, iov_count);
+       if (ret > 0)
+               stream->real_stream->last_write_timeval = ioloop_timeval;
        if (unlikely(ret != (ssize_t)total_size)) {
                if (ret < 0) {
                        i_assert(stream->stream_errno != 0);
@@ -406,6 +408,9 @@ o_stream_send_istream(struct ostream *outstream, struct istream *instream)
        /* non-failure - make sure stream offsets match */
        i_assert((outstream->offset - old_outstream_offset) ==
                 (instream->v_offset - old_instream_offset));
+
+       if (outstream->offset != old_outstream_offset)
+               outstream->real_stream->last_write_timeval = ioloop_timeval;
        return res;
 }
 
@@ -447,13 +452,21 @@ int o_stream_pwrite(struct ostream *stream, const void *data, size_t size,
        i_assert(!stream->real_stream->finished);
        ret = stream->real_stream->write_at(stream->real_stream,
                                            data, size, offset);
-       if (unlikely(ret < 0)) {
+       if (ret > 0)
+               stream->real_stream->last_write_timeval = ioloop_timeval;
+       else if (unlikely(ret < 0)) {
                i_assert(stream->stream_errno != 0);
                errno = stream->stream_errno;
        }
+
        return ret;
 }
 
+void o_stream_get_last_write_time(struct ostream *stream, struct timeval *tv_r)
+{
+       *tv_r = stream->real_stream->last_write_timeval;
+}
+
 enum ostream_send_istream_result
 io_stream_copy(struct ostream *outstream, struct istream *instream)
 {
index 7b149a64f95ccc4c0b9272fc86209e3da97a47cf..4f7d550ca1a2f9be3315c8f98a6c387ca85f0337 100644 (file)
@@ -200,6 +200,11 @@ void o_stream_nsend_istream(struct ostream *outstream, struct istream *instream)
 int o_stream_pwrite(struct ostream *stream, const void *data, size_t size,
                    uoff_t offset);
 
+/* Return the last timestamp when something was successfully sent to the
+   ostream's internal buffers (no guarantees that anything was sent further).
+   The timestamp is 0 if nothing has ever been written. */
+void o_stream_get_last_write_time(struct ostream *stream, struct timeval *tv_r);
+
 /* If there are any I/O loop items associated with the stream, move all of
    them to current_ioloop. */
 void o_stream_switch_ioloop(struct ostream *stream);