Mercurial > dovecot > core-2.2
changeset 18921:c143d037fd54
lib: istream-timeout could have triggered timeout too early after long-running code.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 07 Aug 2015 12:58:30 +0300 |
parents | 35d3777cc4d2 |
children | 91005181b997 |
files | src/lib/istream-timeout.c |
diffstat | 1 files changed, 20 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/istream-timeout.c Fri Aug 07 11:31:29 2015 +0300 +++ b/src/lib/istream-timeout.c Fri Aug 07 12:58:30 2015 +0300 @@ -41,6 +41,13 @@ unsigned int msecs; int diff; + if (tstream->update_timestamp) { + /* we came here after a long-running code. timeouts are handled + before IOs, so wait for i_stream_read() to be called again + before assuming that we've timed out. */ + return; + } + timeout_remove(&tstream->to); diff = timeval_diff_msecs(&ioloop_timeval, &tstream->last_read_timestamp); @@ -64,6 +71,17 @@ i_stream_set_input_pending(tstream->istream.parent, TRUE); } +static void i_stream_timeout_set_pending(struct timeout_istream *tstream) +{ + /* make sure we get called again on the next ioloop run. this updates + the timeout to the timestamp where we actually would have wanted to + start waiting for more data (so if there is long-running code + outside the ioloop it's not counted) */ + tstream->update_timestamp = TRUE; + tstream->last_read_timestamp = ioloop_timeval; + i_stream_set_input_pending(&tstream->istream.istream, TRUE); +} + static ssize_t i_stream_timeout_read(struct istream_private *stream) { @@ -90,19 +108,11 @@ tstream->to = tstream->timeout_msecs == 0 ? NULL : timeout_add(tstream->timeout_msecs, i_stream_timeout, tstream); - tstream->update_timestamp = TRUE; - tstream->last_read_timestamp = ioloop_timeval; + i_stream_timeout_set_pending(tstream); } else if (ret > 0 && tstream->to != NULL) { /* we read something, reset the timeout */ timeout_reset(tstream->to); - /* make sure we get called again on the next ioloop run. - this updates the timeout to the timestamp where we actually - would have wanted to start waiting for more data (so if - there is long-running code outside the ioloop it's not - counted) */ - tstream->update_timestamp = TRUE; - tstream->last_read_timestamp = ioloop_timeval; - i_stream_set_input_pending(&stream->istream, TRUE); + i_stream_timeout_set_pending(tstream); } else if (tstream->update_timestamp) { tstream->update_timestamp = FALSE; tstream->last_read_timestamp = ioloop_timeval;