summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ev.c13
-rw-r--r--ev.pod5
2 files changed, 16 insertions, 2 deletions
diff --git a/ev.c b/ev.c
index 352c3f1..fc4f443 100644
--- a/ev.c
+++ b/ev.c
@@ -1651,9 +1651,18 @@ periodics_reify (EV_P)
else if (w->interval)
{
ev_at (w) = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval;
- if (ev_at (w) - ev_rt_now <= TIME_EPSILON) ev_at (w) += w->interval;
+ /* if next trigger time is not sufficiently in the future, put it there */
+ /* this might happen because of floating point inexactness */
+ if (ev_at (w) - ev_rt_now < TIME_EPSILON)
+ {
+ ev_at (w) += w->interval;
- assert (("ev_periodic timeout in the past detected while processing timers, negative interval?", ev_at (w) >= ev_rt_now));
+ /* if interval is unreasonably low we might still have a time in the past */
+ /* so correct this. this will make the periodic very inexact, but the user */
+ /* has effectively asked to get triggered more often than possible */
+ if (ev_at (w) < ev_rt_now)
+ ev_at (w) = ev_rt_now;
+ }
ANHE_at_set (periodics [HEAP0]);
downheap (periodics, periodiccnt, HEAP0);
diff --git a/ev.pod b/ev.pod
index fd53709..569c711 100644
--- a/ev.pod
+++ b/ev.pod
@@ -1335,6 +1335,11 @@ For numerical stability it is preferable that the C<at> value is near
C<ev_now ()> (the current time), but there is no range requirement for
this value, and in fact is often specified as zero.
+Note also that there is an upper limit to how often a timer can fire (cpu
+speed for example), so if C<interval> is very small then timing stability
+will of course detoriate. Libev itself tries to be exact to be about one
+millisecond (if the OS supports it and the machine is fast enough).
+
=item * manual reschedule mode (at and interval ignored, reschedule_cb = callback)
In this mode the values for C<interval> and C<at> are both being