diff --git a/legacy/ecore/src/lib/ecore/ecore_idle_exiter.c b/legacy/ecore/src/lib/ecore/ecore_idle_exiter.c index 2c5cafeb43..1d5c6ce04d 100644 --- a/legacy/ecore/src/lib/ecore/ecore_idle_exiter.c +++ b/legacy/ecore/src/lib/ecore/ecore_idle_exiter.c @@ -16,13 +16,15 @@ struct _Ecore_Idle_Exiter { EINA_INLIST; ECORE_MAGIC; - int delete_me : 1; int (*func) (void *data); void *data; + int references; + Eina_Bool delete_me : 1; }; static Ecore_Idle_Exiter *idle_exiters = NULL; +static Ecore_Idle_Exiter *idle_exiter_current = NULL; static int idle_exiters_delete_me = 0; /** @@ -79,36 +81,62 @@ _ecore_idle_exiter_shutdown(void) free(ie); } idle_exiters_delete_me = 0; + idle_exiter_current = NULL; } void _ecore_idle_exiter_call(void) { - Ecore_Idle_Exiter *ie; - - EINA_INLIST_FOREACH(idle_exiters, ie) + if (!idle_exiter_current) { + /* regular main loop, start from head */ + idle_exiter_current = idle_exiters; + } + else + { + /* recursive main loop, continue from where we were */ + idle_exiter_current = + (Ecore_Idle_Exiter *)EINA_INLIST_GET(idle_exiter_current)->next; + } + + while (idle_exiter_current) + { + Ecore_Idle_Exiter *ie = (Ecore_Idle_Exiter *)idle_exiter_current; if (!ie->delete_me) { + ie->references++; if (!ie->func(ie->data)) ecore_idle_exiter_del(ie); + ie->references--; } + if (idle_exiter_current) /* may have changed in recursive main loops */ + idle_exiter_current = + (Ecore_Idle_Exiter *)EINA_INLIST_GET(idle_exiter_current)->next; } if (idle_exiters_delete_me) { Ecore_Idle_Exiter *l; + int deleted_idler_exiters_in_use = 0; + for (l = idle_exiters; l;) { - ie = l; + Ecore_Idle_Exiter *ie = l; l = (Ecore_Idle_Exiter *) EINA_INLIST_GET(l)->next; if (ie->delete_me) { + if (ie->references) + { + deleted_idler_exiters_in_use++; + continue; + } + idle_exiters = (Ecore_Idle_Exiter *) eina_inlist_remove(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(ie)); ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE); free(ie); } } - idle_exiters_delete_me = 0; + if (!deleted_idler_exiters_in_use) + idle_exiters_delete_me = 0; } }