8 #include "ecore_private.h"
16 unsigned char delete_me : 1;
22 static Ecore_Timer *timer = NULL;
23 static int min_interval = -1;
24 static int interval_incr = 0;
25 static int at_tick = 0;
26 static int just_added_poller = 0;
27 static int poller_delete_count = 0;
28 static int poller_walking = 0;
29 static double poll_interval = 0.125;
30 static double poll_cur_interval = 0.0;
31 static double last_tick = 0.0;
32 static Ecore_Poller *pollers[16] =
34 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
35 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
37 static unsigned short poller_counters[16] =
43 static void _ecore_poller_next_tick_eval(void);
44 static Eina_Bool _ecore_poller_cb_timer(void *data);
47 _ecore_poller_next_tick_eval(void)
53 for (i = 0; i < 15; i++)
66 ecore_timer_del(timer);
71 interval_incr = (1 << min_interval);
72 interval = interval_incr * poll_interval;
73 /* we are at the tick callback - so no need to do inter-tick adjustments
74 * so we can fasttrack this as t -= last_tick in theory is 0.0 (though
75 * in practice it will be a very very very small value. also the tick
76 * callback will adjust the timer interval at the end anyway */
80 timer = ecore_timer_add(interval, _ecore_poller_cb_timer, NULL);
87 timer = ecore_timer_add(interval, _ecore_poller_cb_timer, NULL);
91 if (interval != poll_cur_interval)
93 t -= last_tick; /* time since we last ticked */
94 /* delete the timer and reset it to tick off in the new
95 * time interval. at the tick this will be adjusted */
96 ecore_timer_del(timer);
97 timer = ecore_timer_add(interval - t,
98 _ecore_poller_cb_timer, NULL);
102 poll_cur_interval = interval;
106 _ecore_poller_cb_timer(void *data __UNUSED__)
109 Ecore_Poller *poller, *l;
113 last_tick = ecore_time_get();
114 /* we have 16 counters - each incriments every time the poller counter
115 * "ticks". it incriments by the minimum interval (which can be 1, 2, 4,
116 * 7, 16 etc. up to 32768) */
117 for (i = 0; i < 15; i++)
119 poller_counters[i] += interval_incr;
120 /* wrap back to 0 if we exceed out loop count for the counter */
121 if (poller_counters[i] >= (1 << i)) poller_counters[i] = 0;
124 just_added_poller = 0;
125 /* walk the pollers now */
127 for (i = 0; i < 15; i++)
129 /* if the counter is @ 0 - this means that counter "went off" this
130 * tick interval, so run all pollers hooked to that counter */
131 if (poller_counters[i] == 0)
133 EINA_INLIST_FOREACH(pollers[i], poller)
135 if (!poller->delete_me)
137 if (!poller->func(poller->data))
139 if (!poller->delete_me)
141 poller->delete_me = 1;
142 poller_delete_count++;
151 /* handle deletes afterwards */
152 if (poller_delete_count > 0)
154 /* FIXME: walk all pollers and remove deleted ones */
155 for (i = 0; i < 15; i++)
157 for (l = pollers[i]; l;)
160 l = (Ecore_Poller *) EINA_INLIST_GET(l)->next;
161 if (poller->delete_me)
163 pollers[i] = (Ecore_Poller *) eina_inlist_remove(EINA_INLIST_GET(pollers[i]), EINA_INLIST_GET(poller));
165 poller_delete_count--;
167 if (poller_delete_count <= 0) break;
170 if (poller_delete_count <= 0) break;
173 /* if we deleted or added any pollers, then we need to re-evaluate our
174 * minimum poll interval */
175 if ((changes > 0) || (just_added_poller > 0))
176 _ecore_poller_next_tick_eval();
178 just_added_poller = 0;
179 poller_delete_count = 0;
183 /* if the timer was deleted then there is no point returning 1 - ambiguous
184 * if we do as it im plies "keep running me" but we have been deleted
186 if (!timer) return ECORE_CALLBACK_CANCEL;
188 /* adjust interval */
189 ecore_timer_interval_set(timer, poll_cur_interval);
190 return ECORE_CALLBACK_RENEW;
194 * @defgroup Ecore_Poll_Group Ecore Poll Functions
196 * These functions are for the need to poll information, but provide a shared
197 * abstracted API to pool such polling to minimise wakeup and ensure all the
198 * polling happens in as few spots as possible areound a core poll interval.
199 * For now only 1 core poller type is supprted: ECORE_POLLER_CORE
204 * Sets the time between ticks (in seconds) for the given ticker clock.
205 * @param type The ticker type to adjust
206 * @param poll_time The time (in seconds) between ticks of the clock
207 * @ingroup Ecore_Poller_Group
209 * This will adjust the time between ticks of the given ticker type defined
210 * by @p type to the time period defined by @p poll_time.
213 ecore_poller_poll_interval_set(Ecore_Poller_Type type __UNUSED__, double poll_time)
215 poll_interval = poll_time;
216 _ecore_poller_next_tick_eval();
220 * Gets the time between ticks (in seconds) for the given ticker clock.
221 * @param type The ticker type to query
222 * @return The time in seconds between ticks of the ticker clock
223 * @ingroup Ecore_Poller_Group
225 * This will get the time between ticks of the specifider ticker clock.
228 ecore_poller_poll_interval_get(Ecore_Poller_Type type __UNUSED__)
230 return poll_interval;
234 * Creates a poller to call the given function at a particular tick interval.
235 * @param type The ticker type to attach the poller to
236 * @param interval The poll interval
237 * @param func The given function. If @p func returns 1, the poller is
238 * rescheduled for the next tick interval.
239 * @param data Data to pass to @p func when it is called.
240 * @return A poller object on success. @c NULL on failure.
241 * @ingroup Ecore_Poller_Group
243 * This function adds a poller callback that is to be called regularly
244 * along with all other poller callbacks so the pollers are synchronized with
245 * all other pollers running off the same poller type and at the same tick
246 * interval. This should be used for polling things when polling is desired
247 * or required, and you do not have specific requirements on the exact times
248 * to poll and want to avoid extra process wakeups for polling. This will
249 * save power as the CPU has more of a chance to go into a low power state
250 * the longer it is asleep for, so this should be used if you are at all
253 * The @p type parameter defines the poller tick type (there is a virtual
254 * clock ticking all the time - though ecore avoids making it tick when
255 * there will not be any work to do at that tick point). There is only one
256 * ticker at the moment - that is ECORE_POLLER_CORE. This is here for future
257 * expansion if multiple clocks with different frequencies are really required.
258 * The default time between ticks for the ECORE_POLLER_CORE ticker is 0.125
261 * The @p interval is the number of ticker ticks that will pass by in between
262 * invocations of the @p func callback. This must be between 1 and 32768
263 * inclusive, and must be a power of 2 (i.e. 1, 2, 4, 8, 16, ... 16384, 32768).
264 * If it is 1, then the function will be called every tick. if it is 2, then it
265 * will be called every 2nd tick, if it is 8, then every 8th tick etc. Exactly
266 * which tick is undefined, as only the interval between calls can be defined.
267 * Ecore will endeavour to keep pollers synchronised and to call as many in
268 * 1 wakeup event as possible.
270 * This function adds a poller and returns its handle on success and NULL on
271 * failure. The function @p func will be called at tick intervals described
272 * above. The function will be passed the @p data pointer as its parameter.
274 * When the poller @p func is called, it must return a value of either
275 * 1 (or ECORE_CALLBACK_RENEW) or 0 (or ECORE_CALLBACK_CANCEL). If it
276 * returns 1, it will be called again at the next tick, or if it returns
277 * 0 it will be deleted automatically making any references/handles for it
281 ecore_poller_add(Ecore_Poller_Type type __UNUSED__, int interval, Ecore_Task_Cb func, const void *data)
283 Ecore_Poller *poller;
286 if (!func) return NULL;
287 if (interval < 1) interval = 1;
289 poller = calloc(1, sizeof(Ecore_Poller));
290 if (!poller) return NULL;
291 ECORE_MAGIC_SET(poller, ECORE_MAGIC_POLLER);
292 /* interval MUST be a power of 2, so enforce it */
293 if (interval < 1) interval = 1;
295 while (interval != 0)
300 /* only allow up to 32768 - i.e. ibit == 15, so limit it */
301 if (ibit > 15) ibit = 15;
305 poller->data = (void *)data;
306 pollers[poller->ibit] = (Ecore_Poller *) eina_inlist_prepend(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
310 _ecore_poller_next_tick_eval();
315 * Changes the polling interval rate of @p poller.
317 * @param poller The Ecore_Poller to change the interval of
318 * @param interval The tick interval to set; must be a power of 2 but <= 32768
319 * @return Returns true on success, false on failure
321 * This allows the changing of a poller's polling interval. It is useful when you want to alter
322 * a poll rate without deleting and re-creating a poller.
323 * @ingroup Ecore_Poller_Group
326 ecore_poller_poller_interval_set(Ecore_Poller *poller, int interval)
330 if (!ECORE_MAGIC_CHECK(poller, ECORE_MAGIC_POLLER))
332 ECORE_MAGIC_FAIL(poller, ECORE_MAGIC_POLLER,
333 "ecore_poller_poller_interval_set");
337 /* interval MUST be a power of 2, so enforce it */
338 if (interval < 1) interval = 1;
340 while (interval != 0)
345 /* only allow up to 32768 - i.e. ibit == 15, so limit it */
346 if (ibit > 15) ibit = 15;
347 /* if interval specified is the same as interval set, return true without wasting time */
348 if (poller->ibit == ibit)
350 pollers[poller->ibit] = (Ecore_Poller *) eina_inlist_remove(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
352 pollers[poller->ibit] = (Ecore_Poller *) eina_inlist_prepend(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
356 _ecore_poller_next_tick_eval();
361 * Gets the polling interval rate of @p poller.
363 * @param poller The Ecore_Poller to change the interval of
364 * @return Returns the interval, in ticks, that @p poller polls at
366 * This returns a poller's polling interval, or 0 on error.
367 * @ingroup Ecore_Poller_Group
370 ecore_poller_poller_interval_get(Ecore_Poller *poller)
372 int ibit, interval = 1;
374 if (!ECORE_MAGIC_CHECK(poller, ECORE_MAGIC_POLLER))
376 ECORE_MAGIC_FAIL(poller, ECORE_MAGIC_POLLER,
377 "ecore_poller_poller_interval_get");
391 * Delete the specified poller from the timer list.
392 * @param poller The poller to delete.
393 * @return The data pointer set for the timer when @ref ecore_poller_add was
394 * called. @c NULL is returned if the function is unsuccessful.
395 * @ingroup Ecore_Poller_Group
397 * Note: @p poller must be a valid handle. If the poller function has already
398 * returned 0, the handle is no longer valid (and does not need to be delete).
401 ecore_poller_del(Ecore_Poller *poller)
405 if (!ECORE_MAGIC_CHECK(poller, ECORE_MAGIC_POLLER))
407 ECORE_MAGIC_FAIL(poller, ECORE_MAGIC_POLLER,
411 /* we are walking the poller list - a bad idea to remove from it while
412 * walking it, so just flag it as delete_me and come back to it after
413 * the loop has finished */
414 if (poller_walking > 0)
416 poller_delete_count++;
417 poller->delete_me = 1;
420 /* not in loop so safe - delete immediately */
422 pollers[poller->ibit] = (Ecore_Poller *) eina_inlist_remove(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
424 _ecore_poller_next_tick_eval();
429 _ecore_poller_shutdown(void)
432 Ecore_Poller *poller;
434 for (i = 0; i < 15; i++)
436 while ((poller = pollers[i]))
438 pollers[i] = (Ecore_Poller *) eina_inlist_remove(EINA_INLIST_GET(pollers[i]), EINA_INLIST_GET(pollers[i]));