MINOR: filters: Add check_timeouts callback to handle timers expiration on streams

A filter can now be notified when a stream is woken up because of an expired
timer.

The documentation and the TRACE filter have been updated.
diff --git a/src/filters.c b/src/filters.c
index 8c3485e..91404a4 100644
--- a/src/filters.c
+++ b/src/filters.c
@@ -398,6 +398,21 @@
 }
 
 /*
+ * Calls 'check_timeouts' for all filters attached to a stream. This happens when
+ * the stream is woken up because of expired timer.
+ */
+void
+flt_stream_check_timeouts(struct stream *s)
+{
+	struct filter *filter;
+
+	list_for_each_entry(filter, &strm_flt(s)->filters, list) {
+		if (FLT_OPS(filter)->check_timeouts)
+			FLT_OPS(filter)->check_timeouts(s, filter);
+	}
+}
+
+/*
  * Called when a backend is set for a stream. If the frontend and the backend
  * are not the same, this function attaches all backend filters to the
  * stream. Returns -1 if an error occurs, 0 otherwise.
diff --git a/src/flt_trace.c b/src/flt_trace.c
index 76081b2..96ce2ac 100644
--- a/src/flt_trace.c
+++ b/src/flt_trace.c
@@ -214,6 +214,16 @@
 		   __FUNCTION__);
 }
 
+/* Called when the stream is woken up because of an expired timer */
+static void
+trace_check_timeouts(struct stream *s, struct filter *filter)
+{
+	struct trace_config *conf = FLT_CONF(filter);
+
+	STRM_TRACE(conf, s, "%-25s",
+		   __FUNCTION__);
+}
+
 /**************************************************************************
  * Hooks to handle channels activity
  *************************************************************************/
@@ -509,6 +519,7 @@
 	.stream_start       = trace_stream_start,
 	.stream_set_backend = trace_stream_set_backend,
 	.stream_stop        = trace_stream_stop,
+	.check_timeouts     = trace_check_timeouts,
 
 	/* Handle channels activity */
 	.channel_start_analyze = trace_chn_start_analyze,
diff --git a/src/stream.c b/src/stream.c
index a5d80a3..288d36d 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -1620,6 +1620,9 @@
 			si_shutr(si_b);
 		}
 
+		if (HAS_FILTERS(s))
+			flt_stream_check_timeouts(s);
+
 		/* Once in a while we're woken up because the task expires. But
 		 * this does not necessarily mean that a timeout has been reached.
 		 * So let's not run a whole stream processing if only an expiration
@@ -2365,8 +2368,9 @@
 
 	update_exp_and_leave:
 		/* Note: please ensure that if you branch here you disable SI_FL_DONT_WAKE */
-		t->expire = tick_first(tick_first(req->rex, req->wex),
-				       tick_first(res->rex, res->wex));
+		t->expire = tick_first((tick_is_expired(t->expire, now_ms) ? 0 : t->expire),
+				       tick_first(tick_first(req->rex, req->wex),
+						  tick_first(res->rex, res->wex)));
 		if (!req->analysers)
 			req->analyse_exp = TICK_ETERNITY;