8 #include "ecore_private.h"
15 unsigned char delete_me : 1;
19 GENERIC_ALLOC_SIZE_DECLARE(Ecore_Poller);
21 static Ecore_Timer *timer = NULL;
22 static int min_interval = -1;
23 static int interval_incr = 0;
24 static int at_tick = 0;
25 static int just_added_poller = 0;
26 static int poller_delete_count = 0;
27 static int poller_walking = 0;
28 static double poll_interval = 0.125;
29 static double poll_cur_interval = 0.0;
30 static double last_tick = 0.0;
31 static Ecore_Poller *pollers[16] =
33 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
34 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
36 static unsigned short poller_counters[16] =
38 0, 0, 0, 0, 0, 0, 0, 0,
39 0, 0, 0, 0, 0, 0, 0, 0
42 static void _ecore_poller_next_tick_eval(void);
43 static Eina_Bool _ecore_poller_cb_timer(void *data);
46 _ecore_poller_next_tick_eval(void)
52 for (i = 0; i < 15; i++)
65 ecore_timer_del(timer);
70 interval_incr = (1 << min_interval);
71 interval = interval_incr * poll_interval;
72 /* we are at the tick callback - so no need to do inter-tick adjustments
73 * so we can fasttrack this as t -= last_tick in theory is 0.0 (though
74 * in practice it will be a very very very small value. also the tick
75 * callback will adjust the timer interval at the end anyway */
79 timer = ecore_timer_add(interval, _ecore_poller_cb_timer, NULL);
86 timer = ecore_timer_add(interval, _ecore_poller_cb_timer, NULL);
90 if (interval != poll_cur_interval)
92 t -= last_tick; /* time since we last ticked */
93 /* delete the timer and reset it to tick off in the new
94 * time interval. at the tick this will be adjusted */
95 ecore_timer_del(timer);
96 timer = ecore_timer_add(interval - t,
97 _ecore_poller_cb_timer, NULL);
101 poll_cur_interval = interval;
105 _ecore_poller_cb_timer(void *data __UNUSED__)
108 Ecore_Poller *poller, *l;
112 last_tick = ecore_time_get();
113 /* we have 16 counters - each increments every time the poller counter
114 * "ticks". it increments by the minimum interval (which can be 1, 2, 4,
115 * 7, 16 etc. up to 32768) */
116 for (i = 0; i < 15; i++)
118 poller_counters[i] += interval_incr;
119 /* wrap back to 0 if we exceed out loop count for the counter */
120 if (poller_counters[i] >= (1 << i)) poller_counters[i] = 0;
123 just_added_poller = 0;
124 /* walk the pollers now */
126 for (i = 0; i < 15; i++)
128 /* if the counter is @ 0 - this means that counter "went off" this
129 * tick interval, so run all pollers hooked to that counter */
130 if (poller_counters[i] == 0)
132 EINA_INLIST_FOREACH(pollers[i], poller)
134 if (!poller->delete_me)
136 if (!poller->func(poller->data))
138 if (!poller->delete_me)
140 poller->delete_me = 1;
141 poller_delete_count++;
150 /* handle deletes afterwards */
151 if (poller_delete_count > 0)
153 /* FIXME: walk all pollers and remove deleted ones */
154 for (i = 0; i < 15; i++)
156 for (l = pollers[i]; l; )
159 l = (Ecore_Poller *)EINA_INLIST_GET(l)->next;
160 if (poller->delete_me)
162 pollers[i] = (Ecore_Poller *)eina_inlist_remove(EINA_INLIST_GET(pollers[i]), EINA_INLIST_GET(poller));
163 ecore_poller_mp_free(poller);
164 poller_delete_count--;
166 if (poller_delete_count <= 0) break;
169 if (poller_delete_count <= 0) break;
172 /* if we deleted or added any pollers, then we need to re-evaluate our
173 * minimum poll interval */
174 if ((changes > 0) || (just_added_poller > 0))
175 _ecore_poller_next_tick_eval();
177 just_added_poller = 0;
178 poller_delete_count = 0;
182 /* if the timer was deleted then there is no point returning 1 - ambiguous
183 * if we do as it implies keep running me" but we have been deleted
185 if (!timer) return ECORE_CALLBACK_CANCEL;
187 /* adjust interval */
188 ecore_timer_interval_set(timer, poll_cur_interval);
189 return ECORE_CALLBACK_RENEW;
193 ecore_poller_poll_interval_set(Ecore_Poller_Type type __UNUSED__,
196 EINA_MAIN_LOOP_CHECK_RETURN;
200 ERR("Poll time %f less than zero, ignored", poll_time);
204 poll_interval = poll_time;
205 _ecore_poller_next_tick_eval();
209 ecore_poller_poll_interval_get(Ecore_Poller_Type type __UNUSED__)
211 EINA_MAIN_LOOP_CHECK_RETURN_VAL(0.0);
212 return poll_interval;
216 ecore_poller_add(Ecore_Poller_Type type __UNUSED__,
221 Ecore_Poller *poller;
224 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
225 if (!func) return NULL;
226 if (interval < 1) interval = 1;
228 poller = ecore_poller_calloc(1);
229 if (!poller) return NULL;
230 ECORE_MAGIC_SET(poller, ECORE_MAGIC_POLLER);
231 /* interval MUST be a power of 2, so enforce it */
232 if (interval < 1) interval = 1;
234 while (interval != 0)
239 /* only allow up to 32768 - i.e. ibit == 15, so limit it */
240 if (ibit > 15) ibit = 15;
244 poller->data = (void *)data;
245 pollers[poller->ibit] = (Ecore_Poller *)eina_inlist_prepend(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
249 _ecore_poller_next_tick_eval();
254 ecore_poller_poller_interval_set(Ecore_Poller *poller,
259 EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE);
260 if (!ECORE_MAGIC_CHECK(poller, ECORE_MAGIC_POLLER))
262 ECORE_MAGIC_FAIL(poller, ECORE_MAGIC_POLLER,
263 "ecore_poller_poller_interval_set");
267 /* interval MUST be a power of 2, so enforce it */
268 if (interval < 1) interval = 1;
270 while (interval != 0)
275 /* only allow up to 32768 - i.e. ibit == 15, so limit it */
276 if (ibit > 15) ibit = 15;
277 /* if interval specified is the same as interval set, return true without wasting time */
278 if (poller->ibit == ibit)
280 pollers[poller->ibit] = (Ecore_Poller *)eina_inlist_remove(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
282 pollers[poller->ibit] = (Ecore_Poller *)eina_inlist_prepend(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
286 _ecore_poller_next_tick_eval();
291 ecore_poller_poller_interval_get(Ecore_Poller *poller)
293 int ibit, interval = 1;
295 EINA_MAIN_LOOP_CHECK_RETURN_VAL(0);
296 if (!ECORE_MAGIC_CHECK(poller, ECORE_MAGIC_POLLER))
298 ECORE_MAGIC_FAIL(poller, ECORE_MAGIC_POLLER,
299 "ecore_poller_poller_interval_get");
313 ecore_poller_del(Ecore_Poller *poller)
317 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
318 if (!ECORE_MAGIC_CHECK(poller, ECORE_MAGIC_POLLER))
320 ECORE_MAGIC_FAIL(poller, ECORE_MAGIC_POLLER,
324 /* we are walking the poller list - a bad idea to remove from it while
325 * walking it, so just flag it as delete_me and come back to it after
326 * the loop has finished */
327 if (poller_walking > 0)
329 poller_delete_count++;
330 poller->delete_me = 1;
333 /* not in loop so safe - delete immediately */
335 pollers[poller->ibit] = (Ecore_Poller *)eina_inlist_remove(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
336 ecore_poller_mp_free(poller);
337 _ecore_poller_next_tick_eval();
346 _ecore_poller_shutdown(void)
349 Ecore_Poller *poller;
351 for (i = 0; i < 15; i++)
353 while ((poller = pollers[i]))
355 pollers[i] = (Ecore_Poller *)eina_inlist_remove(EINA_INLIST_GET(pollers[i]), EINA_INLIST_GET(pollers[i]));
356 ecore_poller_mp_free(poller);