dovecot-2.2: lib: istream-timeout could have triggered timeout t...
dovecot at dovecot.org
dovecot at dovecot.org
Fri Aug 7 09:59:10 UTC 2015
details: http://hg.dovecot.org/dovecot-2.2/rev/c143d037fd54
changeset: 18921:c143d037fd54
user: Timo Sirainen <tss at iki.fi>
date: Fri Aug 07 12:58:30 2015 +0300
description:
lib: istream-timeout could have triggered timeout too early after long-running code.
diffstat:
src/lib/istream-timeout.c | 30 ++++++++++++++++++++----------
1 files changed, 20 insertions(+), 10 deletions(-)
diffs (57 lines):
diff -r 35d3777cc4d2 -r c143d037fd54 src/lib/istream-timeout.c
--- 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;
More information about the dovecot-cvs
mailing list