mirror of /home/gitosis/repositories/libev.git
timing changes, from <= to <
parent
283b5127ad
commit
4c1334c3e1
1
Changes
1
Changes
|
@ -3,6 +3,7 @@ Revision history for libev, a high-performance and full-featured event loop.
|
|||
3.4
|
||||
- work around an (undocumented) bug in winsocket select: if you
|
||||
provide only empty fd sets then select returns WSAEINVAL. how sucky.
|
||||
- improve timer scheduling stability and reduce use of time_epsilon.
|
||||
- use 1-based 2-heap for EV_MINIMAL, simplifies code, reduces
|
||||
codesize and makes for better cache-efficiency.
|
||||
- use 3-based 4-heap for !EV_MINIMAL. this makes better use
|
||||
|
|
10
ev.c
10
ev.c
|
@ -1603,7 +1603,7 @@ idle_reify (EV_P)
|
|||
void inline_size
|
||||
timers_reify (EV_P)
|
||||
{
|
||||
while (timercnt && ANHE_at (timers [HEAP0]) <= mn_now)
|
||||
while (timercnt && ANHE_at (timers [HEAP0]) < mn_now)
|
||||
{
|
||||
ev_timer *w = (ev_timer *)ANHE_w (timers [HEAP0]);
|
||||
|
||||
|
@ -1632,7 +1632,7 @@ timers_reify (EV_P)
|
|||
void inline_size
|
||||
periodics_reify (EV_P)
|
||||
{
|
||||
while (periodiccnt && ANHE_at (periodics [HEAP0]) <= ev_rt_now)
|
||||
while (periodiccnt && ANHE_at (periodics [HEAP0]) < ev_rt_now)
|
||||
{
|
||||
ev_periodic *w = (ev_periodic *)ANHE_w (periodics [HEAP0]);
|
||||
|
||||
|
@ -1641,9 +1641,9 @@ periodics_reify (EV_P)
|
|||
/* first reschedule or stop timer */
|
||||
if (w->reschedule_cb)
|
||||
{
|
||||
ev_at (w) = w->reschedule_cb (w, ev_rt_now + TIME_EPSILON);
|
||||
ev_at (w) = w->reschedule_cb (w, ev_rt_now);
|
||||
|
||||
assert (("ev_periodic reschedule callback returned time in the past", ev_at (w) > ev_rt_now));
|
||||
assert (("ev_periodic reschedule callback returned time in the past", ev_at (w) >= ev_rt_now));
|
||||
|
||||
ANHE_at_set (periodics [HEAP0]);
|
||||
downheap (periodics, periodiccnt, HEAP0);
|
||||
|
@ -1653,7 +1653,7 @@ periodics_reify (EV_P)
|
|||
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;
|
||||
|
||||
assert (("ev_periodic timeout in the past detected while processing timers, negative interval?", ev_at (w) > ev_rt_now));
|
||||
assert (("ev_periodic timeout in the past detected while processing timers, negative interval?", ev_at (w) >= ev_rt_now));
|
||||
|
||||
ANHE_at_set (periodics [HEAP0]);
|
||||
downheap (periodics, periodiccnt, HEAP0);
|
||||
|
|
73
ev.pod
73
ev.pod
|
@ -1153,8 +1153,8 @@ Timer watchers are simple relative timers that generate an event after a
|
|||
given time, and optionally repeating in regular intervals after that.
|
||||
|
||||
The timers are based on real time, that is, if you register an event that
|
||||
times out after an hour and you reset your system clock to last years
|
||||
time, it will still time out after (roughly) and hour. "Roughly" because
|
||||
times out after an hour and you reset your system clock to january last
|
||||
year, it will still time out after (roughly) and hour. "Roughly" because
|
||||
detecting time jumps is hard, and some inaccuracies are unavoidable (the
|
||||
monotonic clock option helps a lot here).
|
||||
|
||||
|
@ -1166,7 +1166,7 @@ on the current time, use something like this to adjust for this:
|
|||
|
||||
ev_timer_set (&timer, after + ev_now () - ev_time (), 0.);
|
||||
|
||||
The callback is guarenteed to be invoked only when its timeout has passed,
|
||||
The callback is guarenteed to be invoked only after its timeout has passed,
|
||||
but if multiple timers become ready during the same loop iteration then
|
||||
order of execution is undefined.
|
||||
|
||||
|
@ -1178,16 +1178,17 @@ order of execution is undefined.
|
|||
|
||||
=item ev_timer_set (ev_timer *, ev_tstamp after, ev_tstamp repeat)
|
||||
|
||||
Configure the timer to trigger after C<after> seconds. If C<repeat> is
|
||||
C<0.>, then it will automatically be stopped. If it is positive, then the
|
||||
timer will automatically be configured to trigger again C<repeat> seconds
|
||||
later, again, and again, until stopped manually.
|
||||
Configure the timer to trigger after C<after> seconds. If C<repeat>
|
||||
is C<0.>, then it will automatically be stopped once the timeout is
|
||||
reached. If it is positive, then the timer will automatically be
|
||||
configured to trigger again C<repeat> seconds later, again, and again,
|
||||
until stopped manually.
|
||||
|
||||
The timer itself will do a best-effort at avoiding drift, that is, if you
|
||||
configure a timer to trigger every 10 seconds, then it will trigger at
|
||||
exactly 10 second intervals. If, however, your program cannot keep up with
|
||||
the timer (because it takes longer than those 10 seconds to do stuff) the
|
||||
timer will not fire more than once per event loop iteration.
|
||||
The timer itself will do a best-effort at avoiding drift, that is, if
|
||||
you configure a timer to trigger every 10 seconds, then it will normally
|
||||
trigger at exactly 10 second intervals. If, however, your program cannot
|
||||
keep up with the timer (because it takes longer than those 10 seconds to
|
||||
do stuff) the timer will not fire more than once per event loop iteration.
|
||||
|
||||
=item ev_timer_again (loop, ev_timer *)
|
||||
|
||||
|
@ -1274,18 +1275,19 @@ Periodic watchers are also timers of a kind, but they are very versatile
|
|||
|
||||
Unlike C<ev_timer>'s, they are not based on real time (or relative time)
|
||||
but on wallclock time (absolute time). You can tell a periodic watcher
|
||||
to trigger "at" some specific point in time. For example, if you tell a
|
||||
to trigger after some specific point in time. For example, if you tell a
|
||||
periodic watcher to trigger in 10 seconds (by specifiying e.g. C<ev_now ()
|
||||
+ 10.>) and then reset your system clock to the last year, then it will
|
||||
take a year to trigger the event (unlike an C<ev_timer>, which would trigger
|
||||
roughly 10 seconds later).
|
||||
+ 10.>, that is, an absolute time not a delay) and then reset your system
|
||||
clock to january of the previous year, then it will take more than year
|
||||
to trigger the event (unlike an C<ev_timer>, which would still trigger
|
||||
roughly 10 seconds later as it uses a relative timeout).
|
||||
|
||||
They can also be used to implement vastly more complex timers, such as
|
||||
triggering an event on each midnight, local time or other, complicated,
|
||||
rules.
|
||||
C<ev_periodic>s can also be used to implement vastly more complex timers,
|
||||
such as triggering an event on each "midnight, local time", or other
|
||||
complicated, rules.
|
||||
|
||||
As with timers, the callback is guarenteed to be invoked only when the
|
||||
time (C<at>) has been passed, but if multiple periodic timers become ready
|
||||
time (C<at>) has passed, but if multiple periodic timers become ready
|
||||
during the same loop iteration then order of execution is undefined.
|
||||
|
||||
=head3 Watcher-Specific Functions and Data Members
|
||||
|
@ -1303,10 +1305,10 @@ operation, and we will explain them from simplest to complex:
|
|||
|
||||
=item * absolute timer (at = time, interval = reschedule_cb = 0)
|
||||
|
||||
In this configuration the watcher triggers an event at the wallclock time
|
||||
C<at> and doesn't repeat. It will not adjust when a time jump occurs,
|
||||
that is, if it is to be run at January 1st 2011 then it will run when the
|
||||
system time reaches or surpasses this time.
|
||||
In this configuration the watcher triggers an event after the wallclock
|
||||
time C<at> has passed and doesn't repeat. It will not adjust when a time
|
||||
jump occurs, that is, if it is to be run at January 1st 2011 then it will
|
||||
run when the system time reaches or surpasses this time.
|
||||
|
||||
=item * repeating interval timer (at = offset, interval > 0, reschedule_cb = 0)
|
||||
|
||||
|
@ -1315,7 +1317,8 @@ C<at + N * interval> time (for some integer N, which can also be negative)
|
|||
and then repeat, regardless of any time jumps.
|
||||
|
||||
This can be used to create timers that do not drift with respect to system
|
||||
time:
|
||||
time, for example, here is a C<ev_periodic> that triggers each hour, on
|
||||
the hour:
|
||||
|
||||
ev_periodic_set (&periodic, 0., 3600., 0);
|
||||
|
||||
|
@ -1330,7 +1333,7 @@ time where C<time = at (mod interval)>, regardless of any time jumps.
|
|||
|
||||
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.
|
||||
this value, and in fact is often specified as zero.
|
||||
|
||||
=item * manual reschedule mode (at and interval ignored, reschedule_cb = callback)
|
||||
|
||||
|
@ -1340,12 +1343,14 @@ reschedule callback will be called with the watcher as first, and the
|
|||
current time as second argument.
|
||||
|
||||
NOTE: I<This callback MUST NOT stop or destroy any periodic watcher,
|
||||
ever, or make any event loop modifications>. If you need to stop it,
|
||||
return C<now + 1e30> (or so, fudge fudge) and stop it afterwards (e.g. by
|
||||
starting an C<ev_prepare> watcher, which is legal).
|
||||
ever, or make ANY event loop modifications whatsoever>.
|
||||
|
||||
Its prototype is C<ev_tstamp (*reschedule_cb)(struct ev_periodic *w,
|
||||
ev_tstamp now)>, e.g.:
|
||||
If you need to stop it, return C<now + 1e30> (or so, fudge fudge) and stop
|
||||
it afterwards (e.g. by starting an C<ev_prepare> watcher, which is the
|
||||
only event loop modification you are allowed to do).
|
||||
|
||||
The callback prototype is C<ev_tstamp (*reschedule_cb)(struct ev_periodic
|
||||
*w, ev_tstamp now)>, e.g.:
|
||||
|
||||
static ev_tstamp my_rescheduler (struct ev_periodic *w, ev_tstamp now)
|
||||
{
|
||||
|
@ -1357,11 +1362,11 @@ It must return the next time to trigger, based on the passed time value
|
|||
will usually be called just before the callback will be triggered, but
|
||||
might be called at other times, too.
|
||||
|
||||
NOTE: I<< This callback must always return a time that is later than the
|
||||
passed C<now> value >>. Not even C<now> itself will do, it I<must> be larger.
|
||||
NOTE: I<< This callback must always return a time that is higher than or
|
||||
equal to the passed C<now> value >>.
|
||||
|
||||
This can be used to create very complex timers, such as a timer that
|
||||
triggers on each midnight, local time. To do this, you would calculate the
|
||||
triggers on "next midnight, local time". To do this, you would calculate the
|
||||
next midnight after C<now> and return the timestamp value for this. How
|
||||
you do this is, again, up to you (but it is not trivial, which is the main
|
||||
reason I omitted it as an example).
|
||||
|
|
Loading…
Reference in New Issue