ecore/main: only update loop_time during loop iteration if the change is monotonic

Summary:
in the case where the user has called loop_time_set with a value in the future,
avoid setting the loop time to something that would potentially cause a callback
to occur with a loop_time value before a previous occurrence of that callback

@fix

Reviewers: ManMower

Reviewed By: ManMower

Subscribers: ManMower, #reviewers, cedric, #committers

Tags: #efl_main_loop

Differential Revision: https://phab.enlightenment.org/D6764
This commit is contained in:
Mike Blumenkrantz 2018-08-14 17:09:32 -04:00
parent 55a2e77d60
commit 8e6d66450d
1 changed files with 22 additions and 14 deletions

View File

@ -212,6 +212,14 @@ static gboolean _ecore_glib_idle_enterer_called;
static gboolean ecore_fds_ready;
#endif
static inline void
_update_loop_time(Efl_Loop_Data *pd)
{
double loop_time = ecore_time_get();
if (loop_time > pd->loop_time)
pd->loop_time = loop_time;
}
#ifdef EFL_EXTRA_SANITY_CHECKS
static inline void
_ecore_fd_valid(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED)
@ -627,7 +635,7 @@ _ecore_main_gsource_prepare(GSource *source EINA_UNUSED,
if ((!ecore_idling) && (!_ecore_glib_idle_enterer_called))
{
pd->loop_time = ecore_time_get();
_update_loop_time(pd);
_efl_loop_timer_expired_timers_call(obj, pd, pd->loop_time);
efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_ENTER, NULL);
@ -766,7 +774,7 @@ _ecore_main_gsource_dispatch(GSource *source EINA_UNUSED,
gboolean events_ready, timers_ready, idlers_ready;
double next_time;
pd->loop_time = ecore_time_get();
_update_loop_time(pd);
_efl_loop_timer_enable_new(obj, pd);
next_time = _efl_loop_timer_next_get(obj, pd);
@ -859,7 +867,7 @@ _ecore_main_loop_timer_run(uv_timer_t *timer EINA_UNUSED)
efl_event_callback_call(obj, EFL_LOOP_EVENT_IDLE_EXIT, NULL);
_ecore_animator_run_reset();
}
pd->loop_time = ecore_time_get();
_update_loop_time(pd);
_ecore_main_loop_uv_check(NULL);
_ecore_main_loop_uv_prepare(NULL);
}
@ -1099,7 +1107,7 @@ _ecore_main_loop_iterate(Eo *obj, Efl_Loop_Data *pd)
{
#endif
#ifndef USE_G_MAIN_LOOP
pd->loop_time = ecore_time_get();
_update_loop_time(pd);
_ecore_main_loop_iterate_internal(obj, pd, 1);
#else
g_main_context_iteration(NULL, 0);
@ -1113,7 +1121,7 @@ _ecore_main_loop_iterate(Eo *obj, Efl_Loop_Data *pd)
else
{
#ifndef USE_G_MAIN_LOOP
pd->loop_time = ecore_time_get();
_update_loop_time(pd);
_ecore_main_loop_iterate_internal(obj, pd, 1);
#else
g_main_context_iteration(NULL, 0);
@ -1133,7 +1141,7 @@ _ecore_main_loop_iterate_may_block(Eo *obj, Efl_Loop_Data *pd, int may_block)
#ifndef USE_G_MAIN_LOOP
in_main_loop++;
pd->in_loop = in_main_loop;
pd->loop_time = ecore_time_get();
_update_loop_time(pd);
_ecore_main_loop_iterate_internal(obj, pd, !may_block);
in_main_loop--;
pd->in_loop = in_main_loop;
@ -1152,7 +1160,7 @@ _ecore_main_loop_iterate_may_block(Eo *obj, Efl_Loop_Data *pd, int may_block)
{
#ifndef USE_G_MAIN_LOOP
pd->in_loop++;
pd->loop_time = ecore_time_get();
_update_loop_time(pd);
_ecore_main_loop_iterate_internal(obj, pd, !may_block);
pd->in_loop--;
return pd->message_queue ? 1 : 0;
@ -1178,7 +1186,7 @@ _ecore_main_loop_begin(Eo *obj, Efl_Loop_Data *pd)
#ifndef USE_G_MAIN_LOOP
in_main_loop++;
pd->in_loop = in_main_loop;
pd->loop_time = ecore_time_get();
_update_loop_time(pd);
while (!pd->do_quit)
_ecore_main_loop_iterate_internal(obj, pd, 0);
pd->do_quit = 0;
@ -1200,7 +1208,7 @@ _ecore_main_loop_begin(Eo *obj, Efl_Loop_Data *pd)
DBG("uv_run");
in_main_loop++;
pd->in_loop = in_main_loop;
pd->loop_time = ecore_time_get();
_update_loop_time(pd);
while (!pd->do_quit)
_dl_uv_run(_dl_uv_default_loop(), UV_RUN_DEFAULT);
in_main_loop--;
@ -1214,7 +1222,7 @@ _ecore_main_loop_begin(Eo *obj, Efl_Loop_Data *pd)
{
#ifndef USE_G_MAIN_LOOP
pd->in_loop++;
pd->loop_time = ecore_time_get();
_update_loop_time(pd);
while (!pd->do_quit)
_ecore_main_loop_iterate_internal(obj, pd, 0);
pd->do_quit = 0;
@ -1839,7 +1847,7 @@ _ecore_main_select(Eo *obj, Efl_Loop_Data *pd, double timeout)
eina_evlog("!WAKE", NULL, 0.0, NULL);
eina_evlog(">RUN", NULL, 0.0, NULL);
pd->loop_time = ecore_time_get();
_update_loop_time(pd);
if (ret < 0)
{
#ifndef _WIN32
@ -2212,14 +2220,14 @@ _ecore_main_loop_uv_prepare(uv_prepare_t *handle EINA_UNUSED)
_ecore_main_uv_idling = EINA_FALSE;
}
t = -1;
pd->loop_time = ecore_time_get();
_update_loop_time(pd);
_efl_loop_timer_enable_new(obj, pd);
goto done;
}
assert(!pd->fd_handlers_to_call);
pd->loop_time = ecore_time_get();
_update_loop_time(pd);
_efl_loop_timer_enable_new(obj, pd);
if (_efl_loop_timers_exists(obj, pd) || (t >= 0))
{
@ -2257,7 +2265,7 @@ static int
_ecore_main_loop_spin_core(Eo *obj, Efl_Loop_Data *pd)
{
// as we are spinning we need to update loop time per spin
pd->loop_time = ecore_time_get();
_update_loop_time(pd);
// call all idlers
_ecore_main_idler_all_call(obj);
// which returns false if no more idelrs exist