8 #include "ecore_private.h"
18 Eina_Bool delete_me : 1;
22 static Ecore_Idler *idlers = NULL;
23 static Ecore_Idler *idler_current = NULL;
24 static int idlers_delete_me = 0;
27 * @addtogroup Ecore_Group Ecore - Main Loop and Job Functions.
33 * @addtogroup Ecore_Idle_Group Ecore Idle functions
35 Callbacks that are called when the program enters or exits an idle state.
37 The ecore main loop enters an idle state when it is waiting for timers
38 to time out, data to come in on a file descriptor or any other event
39 to occur. You can set callbacks to be called when the main loop
40 enters an idle state, during an idle state or just after the program
43 Enterer callbacks are good for updating your program's state, if it
44 has a state engine. Once all of the enterer handlers are called, the
45 program will enter a "sleeping" state.
47 Idler callbacks are called when the main loop has called all enterer
48 handlers. They are useful for interfaces that require polling and
49 timers would be too slow to use.
51 If no idler callbacks are specified, then the process literally goes
52 to sleep. Otherwise, the idler callbacks are called continuously
53 while the loop is "idle", using as much CPU as is available to the
56 Exiter callbacks are called when the main loop wakes up from an idle
62 * Add an idler handler.
63 * @param func The function to call when idling.
64 * @param data The data to be passed to this @p func call.
65 * @return A idler handle if successfully added. NULL otherwise.
67 * Add an idler handle to the event loop, returning a handle on success and
68 * NULL otherwise. The function @p func will be called repeatedly while
69 * no other events are ready to be processed, as long as it returns 1
70 * (or ECORE_CALLBACK_RENEW). A return of 0 (or ECORE_CALLBACK_CANCEL) deletes
73 * Idlers are useful for progressively prossessing data without blocking.
76 ecore_idler_add(Ecore_Task_Cb func, const void *data)
80 if (!func) return NULL;
81 ie = calloc(1, sizeof(Ecore_Idler));
83 ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLER);
85 ie->data = (void *)data;
86 idlers = (Ecore_Idler *) eina_inlist_append(EINA_INLIST_GET(idlers), EINA_INLIST_GET(ie));
91 * Delete an idler callback from the list to be executed.
92 * @param idler The handle of the idler callback to delete
93 * @return The data pointer passed to the idler callback on success. NULL
97 ecore_idler_del(Ecore_Idler *idler)
99 if (!ECORE_MAGIC_CHECK(idler, ECORE_MAGIC_IDLER))
101 ECORE_MAGIC_FAIL(idler, ECORE_MAGIC_IDLER,
105 EINA_SAFETY_ON_TRUE_RETURN_VAL(idler->delete_me, NULL);
106 idler->delete_me = 1;
107 idlers_delete_me = 1;
120 _ecore_idler_shutdown(void)
123 while ((ie = idlers))
125 idlers = (Ecore_Idler *) eina_inlist_remove(EINA_INLIST_GET(idlers), EINA_INLIST_GET(idlers));
126 ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
129 idlers_delete_me = 0;
130 idler_current = NULL;
134 _ecore_idler_call(void)
138 /* regular main loop, start from head */
139 idler_current = idlers;
143 /* recursive main loop, continue from where we were */
144 idler_current = (Ecore_Idler *)EINA_INLIST_GET(idler_current)->next;
147 while (idler_current)
149 Ecore_Idler *ie = (Ecore_Idler *)idler_current;
153 if (!ie->func(ie->data))
155 if (!ie->delete_me) ecore_idler_del(ie);
159 if (idler_current) /* may have changed in recursive main loops */
160 idler_current = (Ecore_Idler *)EINA_INLIST_GET(idler_current)->next;
162 if (idlers_delete_me)
165 int deleted_idlers_in_use = 0;
169 l = (Ecore_Idler *) EINA_INLIST_GET(l)->next;
174 deleted_idlers_in_use++;
178 idlers = (Ecore_Idler *) eina_inlist_remove(EINA_INLIST_GET(idlers), EINA_INLIST_GET(ie));
179 ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
183 if (!deleted_idlers_in_use)
184 idlers_delete_me = 0;
186 if (idlers) return 1;
191 _ecore_idler_exist(void)
193 if (idlers) return 1;