istream-timeout.c revision decdff03c32cb5d0e99d71c5678fd008714de70b
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen/* Copyright (c) 2014 Dovecot authors, see the included COPYING file */
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainenstatic void i_stream_timeout_close(struct iostream_private *stream,
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen struct timeout_istream *tstream = (struct timeout_istream *)stream;
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainenstatic void i_stream_timeout_switch_ioloop(struct istream_private *stream)
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen struct timeout_istream *tstream = (struct timeout_istream *)stream;
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen tstream->to = io_loop_move_timeout(&tstream->to);
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainenstatic void i_stream_timeout(struct timeout_istream *tstream)
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen unsigned int msecs;
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen diff = timeval_diff_msecs(&ioloop_timeval, &tstream->last_read_timestamp);
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen /* we haven't reached the read timeout yet, update it */
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen tstream->to = timeout_add(tstream->timeout_msecs - diff,
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen io_stream_set_error(&tstream->istream.iostream,
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen "Read timeout in %u%s s after %"PRIuUOFF_T" bytes",
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen msecs == 0 ? "" : t_strdup_printf(".%u", msecs),
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen tstream->istream.istream.stream_errno = ETIMEDOUT;
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen i_stream_set_input_pending(tstream->istream.parent, TRUE);
854b4074ac77a138b3983d72510b4d8779d15040Timo Siraineni_stream_timeout_read(struct istream_private *stream)
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen struct timeout_istream *tstream = (struct timeout_istream *)stream;
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen i_stream_seek(stream->parent, stream->parent_start_offset +
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen ret = i_stream_read_copy_from_parent(&stream->istream);
decdff03c32cb5d0e99d71c5678fd008714de70bTimo Sirainen io_stream_set_error(&tstream->istream.iostream,
decdff03c32cb5d0e99d71c5678fd008714de70bTimo Sirainen "%s (opened %d secs ago)",
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen /* first read. add the timeout here instead of in init
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen in case the stream is created long before it's actually
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen read from. */
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen tstream->to = tstream->timeout_msecs == 0 ? NULL :
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen tstream->last_read_timestamp = ioloop_timeval;
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen /* we read something, reset the timeout */
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen /* make sure we get called again on the next ioloop run.
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen this updates the timeout to the timestamp where we actually
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen would have wanted to start waiting for more data (so if
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen there is long-running code outside the ioloop it's not
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen tstream->last_read_timestamp = ioloop_timeval;
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen i_stream_set_input_pending(&stream->istream, TRUE);
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen tstream->last_read_timestamp = ioloop_timeval;
854b4074ac77a138b3983d72510b4d8779d15040Timo Siraineni_stream_create_timeout(struct istream *input, unsigned int timeout_msecs)
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen tstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen tstream->istream.stream_size_passthrough = TRUE;
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen tstream->istream.read = i_stream_timeout_read;
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen tstream->istream.switch_ioloop = i_stream_timeout_switch_ioloop;
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen tstream->istream.iostream.close = i_stream_timeout_close;
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen tstream->istream.istream.blocking = input->blocking;
854b4074ac77a138b3983d72510b4d8779d15040Timo Sirainen tstream->istream.istream.seekable = input->seekable;