* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#ifndef EV_STANDALONE
# include "config.h"
# define EV_USE_EPOLL 1
# endif
-# if HAVE_KQUEUE && HAVE_WORKING_KQUEUE && HAVE_SYS_EVENT_H && HAVE_SYS_QUEUE_H
+# if HAVE_KQUEUE && HAVE_SYS_EVENT_H && HAVE_SYS_QUEUE_H
# define EV_USE_KQUEUE 1
# endif
struct ev_loop
{
+ ev_tstamp ev_rt_now;
#define VAR(name,decl) decl;
#include "ev_vars.h"
#undef VAR
#else
+ ev_tstamp ev_rt_now;
#define VAR(name,decl) static decl;
#include "ev_vars.h"
#undef VAR
/*****************************************************************************/
-inline ev_tstamp
+ev_tstamp
ev_time (void)
{
#if EV_USE_REALTIME
return ev_time ();
}
+#if EV_MULTIPLICITY
ev_tstamp
ev_now (EV_P)
{
- return rt_now;
+ return ev_rt_now;
}
+#endif
#define array_roundsize(type,n) ((n) | 4 & ~3)
((W)heap [k])->active = k + 1;
}
+inline void
+adjustheap (WT *heap, int N, int k, ev_tstamp at)
+{
+ ev_tstamp old_at = heap [k]->at;
+ heap [k]->at = at;
+
+ if (old_at < at)
+ downheap (heap, N, k);
+ else
+ upheap (heap, k);
+}
+
/*****************************************************************************/
typedef struct
}
#endif
- rt_now = ev_time ();
+ ev_rt_now = ev_time ();
mn_now = get_clock ();
now_floor = mn_now;
- rtmn_diff = rt_now - mn_now;
+ rtmn_diff = ev_rt_now - mn_now;
if (methods == EVMETHOD_AUTO)
if (!enable_secure () && getenv ("LIBEV_METHODS"))
/* have to use the microsoft-never-gets-it-right macro */
array_free_microshit (fdchange);
array_free_microshit (timer);
+#if EV_PERIODICS
array_free_microshit (periodic);
+#endif
array_free_microshit (idle);
array_free_microshit (prepare);
array_free_microshit (check);
if (w->repeat)
{
assert (("negative ev_timer repeat value found while processing timers", w->repeat > 0.));
- ((WT)w)->at = mn_now + w->repeat;
+
+ ((WT)w)->at += w->repeat;
+ if (((WT)w)->at < mn_now)
+ ((WT)w)->at = mn_now;
+
downheap ((WT *)timers, timercnt, 0);
}
else
}
}
+#if EV_PERIODICS
static void
periodics_reify (EV_P)
{
- while (periodiccnt && ((WT)periodics [0])->at <= rt_now)
+ while (periodiccnt && ((WT)periodics [0])->at <= ev_rt_now)
{
struct ev_periodic *w = periodics [0];
/* first reschedule or stop timer */
if (w->reschedule_cb)
{
- ev_tstamp at = ((WT)w)->at = w->reschedule_cb (w, rt_now + 0.0001);
+ ev_tstamp at = ((WT)w)->at = w->reschedule_cb (w, ev_rt_now + 0.0001);
- assert (("ev_periodic reschedule callback returned time in the past", ((WT)w)->at > rt_now));
+ assert (("ev_periodic reschedule callback returned time in the past", ((WT)w)->at > ev_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));
+ ((WT)w)->at += floor ((ev_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 > ev_rt_now));
downheap ((WT *)periodics, periodiccnt, 0);
}
else
struct ev_periodic *w = periodics [i];
if (w->reschedule_cb)
- ((WT)w)->at = w->reschedule_cb (w, rt_now);
+ ((WT)w)->at = w->reschedule_cb (w, ev_rt_now);
else if (w->interval)
- ((WT)w)->at += ceil ((rt_now - ((WT)w)->at) / w->interval) * w->interval;
+ ((WT)w)->at += ceil ((ev_rt_now - ((WT)w)->at) / w->interval) * w->interval;
}
/* now rebuild the heap */
for (i = periodiccnt >> 1; i--; )
downheap ((WT *)periodics, periodiccnt, i);
}
+#endif
inline int
time_update_monotonic (EV_P)
if (expect_true (mn_now - now_floor < MIN_TIMEJUMP * .5))
{
- rt_now = rtmn_diff + mn_now;
+ ev_rt_now = rtmn_diff + mn_now;
return 0;
}
else
{
now_floor = mn_now;
- rt_now = ev_time ();
+ ev_rt_now = ev_time ();
return 1;
}
}
for (i = 4; --i; ) /* loop a few times, before making important decisions */
{
- rtmn_diff = rt_now - mn_now;
+ rtmn_diff = ev_rt_now - mn_now;
if (fabs (odiff - rtmn_diff) < MIN_TIMEJUMP)
return; /* all is well */
- rt_now = ev_time ();
+ ev_rt_now = ev_time ();
mn_now = get_clock ();
now_floor = mn_now;
}
+# if EV_PERIODICS
periodics_reschedule (EV_A);
+# endif
/* no timer adjustment, as the monotonic clock doesn't jump */
/* timers_reschedule (EV_A_ rtmn_diff - odiff) */
}
else
#endif
{
- rt_now = ev_time ();
+ ev_rt_now = ev_time ();
- if (expect_false (mn_now > rt_now || mn_now < rt_now - MAX_BLOCKTIME - MIN_TIMEJUMP))
+ if (expect_false (mn_now > ev_rt_now || mn_now < ev_rt_now - MAX_BLOCKTIME - MIN_TIMEJUMP))
{
+#if EV_PERIODICS
periodics_reschedule (EV_A);
+#endif
/* adjust timers. this is easy, as the offset is the same for all */
for (i = 0; i < timercnt; ++i)
- ((WT)timers [i])->at += rt_now - mn_now;
+ ((WT)timers [i])->at += ev_rt_now - mn_now;
}
- mn_now = rt_now;
+ mn_now = ev_rt_now;
}
}
else
#endif
{
- rt_now = ev_time ();
- mn_now = rt_now;
+ ev_rt_now = ev_time ();
+ mn_now = ev_rt_now;
}
if (flags & EVLOOP_NONBLOCK || idlecnt)
if (block > to) block = to;
}
+#if EV_PERIODICS
if (periodiccnt)
{
- ev_tstamp to = ((WT)periodics [0])->at - rt_now + method_fudge;
+ ev_tstamp to = ((WT)periodics [0])->at - ev_rt_now + method_fudge;
if (block > to) block = to;
}
+#endif
if (block < 0.) block = 0.;
}
method_poll (EV_A_ block);
- /* update rt_now, do magic */
+ /* update ev_rt_now, do magic */
time_update (EV_A);
/* queue pending timers and reschedule them */
timers_reify (EV_A); /* relative timers called last */
+#if EV_PERIODICS
periodics_reify (EV_A); /* absolute timers called first */
+#endif
/* queue idle watchers unless io or timers are pending */
if (idlecnt && !any_pending (EV_A))
if (!ev_is_active (w))
return;
+ assert (("ev_io_start called with illegal fd (must stay constant after start!)", w->fd >= 0 && w->fd < anfdmax));
+
wlist_del ((WL *)&anfds[w->fd].head, (WL)w);
ev_stop (EV_A_ (W)w);
downheap ((WT *)timers, timercnt, ((W)w)->active - 1);
}
- ((WT)w)->at = w->repeat;
+ ((WT)w)->at -= mn_now;
ev_stop (EV_A_ (W)w);
}
if (ev_is_active (w))
{
if (w->repeat)
- {
- ((WT)w)->at = mn_now + w->repeat;
- downheap ((WT *)timers, timercnt, ((W)w)->active - 1);
- }
+ adjustheap ((WT *)timers, timercnt, ((W)w)->active - 1, mn_now + w->repeat);
else
ev_timer_stop (EV_A_ w);
}
ev_timer_start (EV_A_ w);
}
+#if EV_PERIODICS
void
ev_periodic_start (EV_P_ struct ev_periodic *w)
{
return;
if (w->reschedule_cb)
- ((WT)w)->at = w->reschedule_cb (w, rt_now);
+ ((WT)w)->at = w->reschedule_cb (w, ev_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;
+ ((WT)w)->at += ceil ((ev_rt_now - ((WT)w)->at) / w->interval) * w->interval;
}
ev_start (EV_A_ (W)w, ++periodiccnt);
void
ev_periodic_again (EV_P_ struct ev_periodic *w)
{
+ /* TODO: use adjustheap and recalculation */
ev_periodic_stop (EV_A_ w);
ev_periodic_start (EV_A_ w);
}
+#endif
void
ev_idle_start (EV_P_ struct ev_idle *w)
ev_idle_stop (EV_P_ struct ev_idle *w)
{
ev_clear_pending (EV_A_ (W)w);
- if (ev_is_active (w))
+ if (!ev_is_active (w))
return;
idles [((W)w)->active - 1] = idles [--idlecnt];
ev_prepare_stop (EV_P_ struct ev_prepare *w)
{
ev_clear_pending (EV_A_ (W)w);
- if (ev_is_active (w))
+ if (!ev_is_active (w))
return;
prepares [((W)w)->active - 1] = prepares [--preparecnt];
ev_check_stop (EV_P_ struct ev_check *w)
{
ev_clear_pending (EV_A_ (W)w);
- if (ev_is_active (w))
+ if (!ev_is_active (w))
return;
checks [((W)w)->active - 1] = checks [--checkcnt];
}
}
+#ifdef __cplusplus
+}
+#endif
+