8 #include "ecore_private.h"
10 struct _Ecore_Idle_Exiter
17 Eina_Bool delete_me : 1;
19 GENERIC_ALLOC_SIZE_DECLARE(Ecore_Idle_Exiter);
21 static Ecore_Idle_Exiter *idle_exiters = NULL;
22 static Ecore_Idle_Exiter *idle_exiter_current = NULL;
23 static int idle_exiters_delete_me = 0;
26 _ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter);
29 * @addtogroup Ecore_Idle_Group
35 * Add an idle exiter handler.
36 * @param func The function to call when exiting an idle state.
37 * @param data The data to be passed to the @p func call
38 * @return A handle to the idle exiter callback on success. NULL otherwise.
39 * @note The function func will be called every time the main loop is exiting
40 * idle state, as long as it returns 1 (or ECORE_CALLBACK_RENEW). A return of 0
41 * (or ECORE_CALLBACK_CANCEL) deletes the idle exiter.
43 EAPI Ecore_Idle_Exiter *
44 ecore_idle_exiter_add(Ecore_Task_Cb func,
47 Ecore_Idle_Exiter *ie = NULL;
49 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
51 if (!func) goto unlock;
52 ie = ecore_idle_exiter_calloc(1);
54 ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_EXITER);
56 ie->data = (void *)data;
57 idle_exiters = (Ecore_Idle_Exiter *)eina_inlist_append(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(ie));
64 * Delete an idle exiter handler from the list to be run on exiting idle state.
65 * @param idle_exiter The idle exiter to delete
66 * @return The data pointer that was being being passed to the handler if
67 * successful. NULL otherwise.
70 ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter)
74 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
75 if (!ECORE_MAGIC_CHECK(idle_exiter, ECORE_MAGIC_IDLE_EXITER))
77 ECORE_MAGIC_FAIL(idle_exiter, ECORE_MAGIC_IDLE_EXITER,
78 "ecore_idle_exiter_del");
82 data = _ecore_idle_exiter_del(idle_exiter);
92 _ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter)
94 EINA_SAFETY_ON_TRUE_RETURN_VAL(idle_exiter->delete_me, NULL);
95 idle_exiter->delete_me = 1;
96 idle_exiters_delete_me = 1;
97 return idle_exiter->data;
101 _ecore_idle_exiter_shutdown(void)
103 Ecore_Idle_Exiter *ie;
104 while ((ie = idle_exiters))
106 idle_exiters = (Ecore_Idle_Exiter *)eina_inlist_remove(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(idle_exiters));
107 ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
108 ecore_idle_exiter_mp_free(ie);
110 idle_exiters_delete_me = 0;
111 idle_exiter_current = NULL;
115 _ecore_idle_exiter_call(void)
117 if (!idle_exiter_current)
119 /* regular main loop, start from head */
120 idle_exiter_current = idle_exiters;
124 /* recursive main loop, continue from where we were */
125 idle_exiter_current =
126 (Ecore_Idle_Exiter *)EINA_INLIST_GET(idle_exiter_current)->next;
129 while (idle_exiter_current)
131 Ecore_Idle_Exiter *ie = (Ecore_Idle_Exiter *)idle_exiter_current;
135 if (!_ecore_call_task_cb(ie->func, ie->data))
137 if (!ie->delete_me) _ecore_idle_exiter_del(ie);
141 if (idle_exiter_current) /* may have changed in recursive main loops */
142 idle_exiter_current =
143 (Ecore_Idle_Exiter *)EINA_INLIST_GET(idle_exiter_current)->next;
145 if (idle_exiters_delete_me)
147 Ecore_Idle_Exiter *l;
148 int deleted_idler_exiters_in_use = 0;
150 for (l = idle_exiters; l; )
152 Ecore_Idle_Exiter *ie = l;
154 l = (Ecore_Idle_Exiter *)EINA_INLIST_GET(l)->next;
159 deleted_idler_exiters_in_use++;
163 idle_exiters = (Ecore_Idle_Exiter *)eina_inlist_remove(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(ie));
164 ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
165 ecore_idle_exiter_mp_free(ie);
168 if (!deleted_idler_exiters_in_use)
169 idle_exiters_delete_me = 0;
174 _ecore_idle_exiter_exist(void)
176 if (idle_exiters) return 1;