mirror of /home/gitosis/repositories/libev.git
implement periodic reschedule callbacks
parent
cc1e33fc2f
commit
02fdea7be3
49
ev.c
49
ev.c
|
@ -962,7 +962,14 @@ periodics_reify (EV_P)
|
|||
assert (("inactive timer on periodic heap detected", ev_is_active (w)));
|
||||
|
||||
/* first reschedule or stop timer */
|
||||
if (w->interval)
|
||||
if (w->reschedule_cb)
|
||||
{
|
||||
ev_tstamp at = ((WT)w)->at = w->reschedule_cb (w, rt_now + 0.0001);
|
||||
|
||||
assert (("ev_periodic reschedule callback returned time in the past", ((WT)w)->at > rt_now));
|
||||
downheap ((WT *)periodics, periodiccnt, 0);
|
||||
}
|
||||
else if (w->interval)
|
||||
{
|
||||
((WT)w)->at += floor ((rt_now - ((WT)w)->at) / w->interval + 1.) * w->interval;
|
||||
assert (("ev_periodic timeout in the past detected while processing timers, negative interval?", ((WT)w)->at > rt_now));
|
||||
|
@ -985,19 +992,15 @@ periodics_reschedule (EV_P)
|
|||
{
|
||||
struct ev_periodic *w = periodics [i];
|
||||
|
||||
if (w->interval)
|
||||
{
|
||||
ev_tstamp diff = ceil ((rt_now - ((WT)w)->at) / w->interval) * w->interval;
|
||||
|
||||
if (fabs (diff) >= 1e-4)
|
||||
{
|
||||
ev_periodic_stop (EV_A_ w);
|
||||
ev_periodic_start (EV_A_ w);
|
||||
|
||||
i = 0; /* restart loop, inefficient, but time jumps should be rare */
|
||||
}
|
||||
}
|
||||
if (w->reschedule_cb)
|
||||
((WT)w)->at = w->reschedule_cb (w, rt_now);
|
||||
else if (w->interval)
|
||||
((WT)w)->at += ceil ((rt_now - ((WT)w)->at) / w->interval) * w->interval;
|
||||
}
|
||||
|
||||
/* now rebuild the heap */
|
||||
for (i = periodiccnt >> 1; i--; )
|
||||
downheap ((WT *)periodics, periodiccnt, i);
|
||||
}
|
||||
|
||||
inline int
|
||||
|
@ -1311,11 +1314,14 @@ ev_periodic_start (EV_P_ struct ev_periodic *w)
|
|||
if (ev_is_active (w))
|
||||
return;
|
||||
|
||||
assert (("ev_periodic_start called with negative interval value", w->interval >= 0.));
|
||||
|
||||
/* this formula differs from the one in periodic_reify because we do not always round up */
|
||||
if (w->interval)
|
||||
((WT)w)->at += ceil ((rt_now - ((WT)w)->at) / w->interval) * w->interval;
|
||||
if (w->reschedule_cb)
|
||||
((WT)w)->at = w->reschedule_cb (w, rt_now);
|
||||
else if (w->interval)
|
||||
{
|
||||
assert (("ev_periodic_start called with negative interval value", w->interval >= 0.));
|
||||
/* this formula differs from the one in periodic_reify because we do not always round up */
|
||||
((WT)w)->at += ceil ((rt_now - ((WT)w)->at) / w->interval) * w->interval;
|
||||
}
|
||||
|
||||
ev_start (EV_A_ (W)w, ++periodiccnt);
|
||||
array_needsize (struct ev_periodic *, periodics, periodicmax, periodiccnt, (void));
|
||||
|
@ -1343,6 +1349,13 @@ ev_periodic_stop (EV_P_ struct ev_periodic *w)
|
|||
ev_stop (EV_A_ (W)w);
|
||||
}
|
||||
|
||||
void
|
||||
ev_periodic_again (EV_P_ struct ev_periodic *w)
|
||||
{
|
||||
ev_periodic_stop (EV_A_ w);
|
||||
ev_periodic_start (EV_A_ w);
|
||||
}
|
||||
|
||||
void
|
||||
ev_idle_start (EV_P_ struct ev_idle *w)
|
||||
{
|
||||
|
|
6
ev.h
6
ev.h
|
@ -141,6 +141,7 @@ struct ev_periodic
|
|||
EV_WATCHER_TIME (ev_periodic);
|
||||
|
||||
ev_tstamp interval; /* rw */
|
||||
ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now); /* rw */
|
||||
};
|
||||
|
||||
/* invoked when fd is either EV_READable or EV_WRITEable */
|
||||
|
@ -298,7 +299,7 @@ void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revent
|
|||
|
||||
#define ev_io_set(ev,fd_,events_) do { (ev)->fd = (fd_); (ev)->events = (events_); } while (0)
|
||||
#define ev_timer_set(ev,after_,repeat_) do { (ev)->at = (after_); (ev)->repeat = (repeat_); } while (0)
|
||||
#define ev_periodic_set(ev,at_,interval_) do { (ev)->at = (at_); (ev)->interval = (interval_); } while (0)
|
||||
#define ev_periodic_set(ev,at_,ival_,res_) do { (ev)->at = (at_); (ev)->interval = (ival_); (ev)->reschedule_cb= (res_); } while (0)
|
||||
#define ev_signal_set(ev,signum_) do { (ev)->signum = (signum_); } while (0)
|
||||
#define ev_idle_set(ev) /* nop, yes, this is a serious in-joke */
|
||||
#define ev_prepare_set(ev) /* nop, yes, this is a serious in-joke */
|
||||
|
@ -307,7 +308,7 @@ void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revent
|
|||
|
||||
#define ev_io_init(ev,cb,fd,events) do { ev_watcher_init ((ev), (cb)); ev_io_set ((ev),(fd),(events)); } while (0)
|
||||
#define ev_timer_init(ev,cb,after,repeat) do { ev_watcher_init ((ev), (cb)); ev_timer_set ((ev),(after),(repeat)); } while (0)
|
||||
#define ev_periodic_init(ev,cb,at,interval) do { ev_watcher_init ((ev), (cb)); ev_periodic_set ((ev),(at),(interval)); } while (0)
|
||||
#define ev_periodic_init(ev,cb,at,ival,res) do { ev_watcher_init ((ev), (cb)); ev_periodic_set ((ev),(at),(ival),(res)); } while (0)
|
||||
#define ev_signal_init(ev,cb,signum) do { ev_watcher_init ((ev), (cb)); ev_signal_set ((ev), (signum)); } while (0)
|
||||
#define ev_idle_init(ev,cb) do { ev_watcher_init ((ev), (cb)); ev_idle_set ((ev)); } while (0)
|
||||
#define ev_prepare_init(ev,cb) do { ev_watcher_init ((ev), (cb)); ev_prepare_set ((ev)); } while (0)
|
||||
|
@ -335,6 +336,7 @@ void ev_timer_again (EV_P_ struct ev_timer *w);
|
|||
|
||||
void ev_periodic_start (EV_P_ struct ev_periodic *w);
|
||||
void ev_periodic_stop (EV_P_ struct ev_periodic *w);
|
||||
void ev_periodic_again (EV_P_ struct ev_periodic *w);
|
||||
|
||||
void ev_idle_start (EV_P_ struct ev_idle *w);
|
||||
void ev_idle_stop (EV_P_ struct ev_idle *w);
|
||||
|
|
Loading…
Reference in New Issue