Bug Summary

File:tests/suite/ecore/src/lib/ecore_main.c
Location:line 1252, column 58
Description:Value stored to 'have_event' is never read

Annotated Source Code

1#ifdef HAVE_CONFIG_H1
2# include <config.h>
3#endif
4
5#ifdef _WIN32
6# define WIN32_LEAN_AND_MEAN
7# include <winsock2.h>
8# undef WIN32_LEAN_AND_MEAN
9# ifndef USER_TIMER_MINIMUM
10# define USER_TIMER_MINIMUM 0x0a
11# endif
12#endif
13
14#ifdef __SUNPRO_C
15# include <ieeefp.h>
16# include <string.h>
17#endif
18
19#include <stdlib.h>
20#include <stdio.h>
21#include <math.h>
22#include <sys/types.h>
23#include <errno(*__errno_location ()).h>
24#include <fcntl.h>
25
26#ifndef _MSC_VER
27#include <sys/time.h>
28# include <unistd.h>
29#else
30# include <float.h>
31#endif
32
33#define FIX_HZ1 1
34
35#ifdef FIX_HZ1
36# ifndef _MSC_VER
37# include <sys/param.h>
38# endif
39# ifndef HZ100
40# define HZ100 100
41# endif
42#endif
43
44#ifdef HAVE_EVIL
45# include <Evil.h>
46#endif
47
48#include "Ecore.h"
49#include "ecore_private.h"
50
51#ifdef HAVE_SYS_EPOLL_H
52# define HAVE_EPOLL
53# include <sys/epoll.h>
54#endif
55
56#ifdef USE_G_MAIN_LOOP
57#include <glib.h>
58#endif
59
60struct _Ecore_Fd_Handler
61{
62 EINA_INLISTEina_Inlist __in_list;
63 ECORE_MAGICEcore_Magic __magic;
64 int fd;
65 Ecore_Fd_Handler_Flags flags;
66 Ecore_Fd_Cb func;
67 void *data;
68 Ecore_Fd_Cb buf_func;
69 void *buf_data;
70 Ecore_Fd_Prep_Cb prep_func;
71 void *prep_data;
72 int references;
73 Eina_Bool read_active : 1;
74 Eina_Bool write_active : 1;
75 Eina_Bool error_active : 1;
76 Eina_Bool delete_me : 1;
77};
78
79#ifdef _WIN32
80struct _Ecore_Win32_Handler
81{
82 EINA_INLISTEina_Inlist __in_list;
83 ECORE_MAGICEcore_Magic __magic;
84 HANDLE h;
85 Ecore_Fd_Win32_Cb func;
86 void *data;
87 int references;
88 Eina_Bool delete_me : 1;
89};
90#endif
91
92
93static int _ecore_main_select(double timeout);
94static void _ecore_main_prepare_handlers(void);
95static void _ecore_main_fd_handlers_cleanup(void);
96#ifndef _WIN32
97static void _ecore_main_fd_handlers_bads_rem(void);
98#endif
99static void _ecore_main_fd_handlers_call(void);
100static int _ecore_main_fd_handlers_buf_call(void);
101#ifndef USE_G_MAIN_LOOP
102static void _ecore_main_loop_iterate_internal(int once_only);
103#endif
104
105#ifdef _WIN32
106static int _ecore_main_win32_select(int nfds, fd_set *readfds, fd_set *writefds,
107 fd_set *exceptfds, struct timeval *timeout);
108static void _ecore_main_win32_handlers_cleanup(void);
109#endif
110
111static int in_main_loop = 0;
112static int do_quit = 0;
113static Ecore_Fd_Handler *fd_handlers = NULL((void*)0);
114static Ecore_Fd_Handler *fd_handler_current = NULL((void*)0);
115static int fd_handlers_delete_me = 0;
116#ifdef _WIN32
117static Ecore_Win32_Handler *win32_handlers = NULL((void*)0);
118static Ecore_Win32_Handler *win32_handler_current = NULL((void*)0);
119static int win32_handlers_delete_me = 0;
120#endif
121
122#ifdef _WIN32
123static Ecore_Select_Function main_loop_select = _ecore_main_win32_select;
124#else
125static Ecore_Select_Function main_loop_select = select;
126#endif
127
128static double t1 = 0.0;
129static double t2 = 0.0;
130
131#ifdef HAVE_EPOLL
132static int epoll_fd = -1;
133#endif
134
135#ifdef USE_G_MAIN_LOOP
136static GSource *ecore_epoll_source;
137static GPollFD ecore_epoll_fd;
138static guint ecore_epoll_id;
139static GMainLoop* ecore_main_loop;
140static gboolean ecore_idling;
141static gboolean ecore_fds_ready;
142#endif
143
144#ifdef HAVE_EPOLL
145static inline int _ecore_poll_events_from_fdh(Ecore_Fd_Handler *fdh)
146{
147 int events = 0;
148 if (fdh->flags & ECORE_FD_READ) events |= EPOLLIN;
149 if (fdh->flags & ECORE_FD_WRITE) events |= EPOLLOUT;
150 if (fdh->flags & ECORE_FD_ERROR) events |= EPOLLERR;
151 return events;
152}
153#else
154static inline int _ecore_poll_events_from_fdh(Ecore_Fd_Handler *fdh __UNUSED__)
155{
156 return 0;
157}
158#endif
159
160#ifdef HAVE_EPOLL
161static inline int _ecore_main_fdh_epoll_add(Ecore_Fd_Handler *fdh)
162{
163 int r = 0;
164 struct epoll_event ev;
165
166 memset(&ev, 0, sizeof (ev));
167 ev.events = _ecore_poll_events_from_fdh(fdh);
168 ev.data.ptr = fdh;
169 INF("adding poll on %d %08x", fdh->fd, ev.events)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 169, "adding poll on %d %08x", fdh->fd, ev
.events)
;
170 r = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fdh->fd, &ev);
171 return r;
172}
173#else
174static inline int _ecore_main_fdh_epoll_add(Ecore_Fd_Handler *fdh __UNUSED__)
175{
176 return 0;
177}
178#endif
179
180#ifdef HAVE_EPOLL
181static inline void _ecore_main_fdh_epoll_del(Ecore_Fd_Handler *fdh)
182{
183 struct epoll_event ev;
184
185 memset(&ev, 0, sizeof (ev));
186 INF("removing poll on %d", fdh->fd)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 186, "removing poll on %d", fdh->fd)
;
187 /* could get an EBADF if somebody closed the FD before removing it */
188 if ((epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fdh->fd, &ev) < 0) &&
189 (errno(*__errno_location ()) != EBADF9))
190 {
191 ERR("Failed to delete epoll fd %d! (errno=%d)", fdh->fd, errno)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 191, "Failed to delete epoll fd %d! (errno=%d)"
, fdh->fd, (*__errno_location ()))
;
192 }
193}
194#else
195static inline void _ecore_main_fdh_epoll_del(Ecore_Fd_Handler *fdh __UNUSED__)
196{
197}
198#endif
199
200#ifdef HAVE_EPOLL
201static inline int _ecore_main_fdh_epoll_modify(Ecore_Fd_Handler *fdh)
202{
203 int r = 0;
204 struct epoll_event ev;
205
206 memset(&ev, 0, sizeof (ev));
207 ev.events = _ecore_poll_events_from_fdh(fdh);
208 ev.data.ptr = fdh;
209 INF("modifing epoll on %d to %08x", fdh->fd, ev.events)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 209, "modifing epoll on %d to %08x", fdh->
fd, ev.events)
;
210 r = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fdh->fd, &ev);
211 return r;
212}
213#else
214static inline int _ecore_main_fdh_epoll_modify(Ecore_Fd_Handler *fdh __UNUSED__)
215{
216 return 0;
217}
218#endif
219
220#ifdef HAVE_EPOLL
221static inline int _ecore_main_fdh_epoll_mark_active(void)
222{
223 struct epoll_event ev[32];
224 int i, ret;
225
226 memset(&ev, 0, sizeof (ev));
227 ret = epoll_wait(epoll_fd, ev, sizeof(ev) / sizeof(struct epoll_event), 0);
228 if (ret < 0)
229 {
230 if (errno(*__errno_location ()) == EINTR4) return -1;
231 ERR("epoll_wait failed %d", errno)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 231, "epoll_wait failed %d", (*__errno_location
()))
;
232 return -1;
233 }
234
235 for (i = 0; i < ret; i++)
236 {
237 Ecore_Fd_Handler *fdh;
238
239 fdh = ev[i].data.ptr;
240 if (!ECORE_MAGIC_CHECK(fdh, ECORE_MAGIC_FD_HANDLER)((fdh) && ((fdh)->__magic == (0xf7a416f1))))
241 {
242 ECORE_MAGIC_FAIL(fdh, ECORE_MAGIC_FD_HANDLER,_ecore_magic_fail((fdh), (fdh) ? (fdh)->__magic : 0, (0xf7a416f1
), ("_ecore_main_fdh_epoll_mark_active"));
243 "_ecore_main_fdh_epoll_mark_active")_ecore_magic_fail((fdh), (fdh) ? (fdh)->__magic : 0, (0xf7a416f1
), ("_ecore_main_fdh_epoll_mark_active"));
;
244 continue;
245 }
246 if (fdh->delete_me)
247 {
248 ERR("deleted fd in epoll")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 248, "deleted fd in epoll")
;
249 continue;
250 }
251 if (ev->events & EPOLLIN)
252 fdh->read_active = 1;
253 if (ev->events & EPOLLOUT)
254 fdh->write_active = 1;
255 if (ev->events & EPOLLERR)
256 fdh->error_active = 1;
257 }
258
259 return ret;
260}
261#endif
262
263#ifdef USE_G_MAIN_LOOP
264
265/* like we are about to enter main_loop_select in _ecore_main_select */
266static gboolean
267_ecore_main_gsource_prepare(GSource *source, gint *next_time)
268{
269 double t = _ecore_timer_next_get();
270 gboolean running;
271
272 INF("enter, next timeout in %.1f", t)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 272, "enter, next timeout in %.1f", t)
;
273 in_main_loop++;
274
275 if (!ecore_idling)
276 {
277 while (_ecore_timer_call(_ecore_time_loop_time));
278 _ecore_timer_cleanup();
279
280 /* when idling, busy loop checking the fds only */
281 if (!ecore_idling) _ecore_idle_enterer_call();
282 }
283
284 /* don't check fds if somebody quit */
285 running = g_main_loop_is_running(ecore_main_loop);
286 if (running)
287 {
288 /* only set idling state in dispatch */
289 if (ecore_idling && !_ecore_idler_exist())
290 {
291 if (_ecore_timers_exists())
292 {
293 double t = _ecore_timer_next_get();
294 *next_time = (t / 1000.0);
295 }
296 else
297 *next_time = -1;
298 }
299 else
300 *next_time = 0;
301
302 _ecore_main_prepare_handlers();
303 }
304
305 in_main_loop--;
306 INF("leave, timeout = %d", *next_time)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 306, "leave, timeout = %d", *next_time)
;
307
308 /* ready if we're not running (about to quit) */
309 return !running;
310}
311
312static gboolean
313_ecore_main_gsource_check(GSource *source)
314{
315 INF("enter")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 315, "enter")
;
316 in_main_loop++;
317
318 ecore_fds_ready = (_ecore_main_fdh_epoll_mark_active() > 0);
319 _ecore_main_fd_handlers_cleanup();
320
321 _ecore_time_loop_time = ecore_time_get();
322 _ecore_timer_enable_new();
323
324 in_main_loop--;
325 INF("leave")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 325, "leave")
;
326
327 return TRUE; /* always dispatch */
328}
329
330/* like we just came out of main_loop_select in _ecore_main_select */
331static gboolean
332_ecore_main_gsource_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
333{
334 gboolean events_ready, timers_ready, idlers_ready, signals_ready;
335 double next_time = _ecore_timer_next_get();
336
337 events_ready = _ecore_event_exist();
338 timers_ready = _ecore_timers_exists() && (0.0 <= next_time);
339 idlers_ready = _ecore_idler_exist();
340 signals_ready = (_ecore_signal_count_get() > 0);
341
342 in_main_loop++;
343 INF("enter idling=%d fds=%d events=%d signals=%d timers=%d (next=%.2f) idlers=%d",eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 345, "enter idling=%d fds=%d events=%d signals=%d timers=%d (next=%.2f) idlers=%d"
, ecore_idling, ecore_fds_ready, events_ready, signals_ready,
_ecore_timers_exists(), next_time, idlers_ready)
344 ecore_idling, ecore_fds_ready, events_ready, signals_ready,eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 345, "enter idling=%d fds=%d events=%d signals=%d timers=%d (next=%.2f) idlers=%d"
, ecore_idling, ecore_fds_ready, events_ready, signals_ready,
_ecore_timers_exists(), next_time, idlers_ready)
345 _ecore_timers_exists(), next_time, idlers_ready)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 345, "enter idling=%d fds=%d events=%d signals=%d timers=%d (next=%.2f) idlers=%d"
, ecore_idling, ecore_fds_ready, events_ready, signals_ready,
_ecore_timers_exists(), next_time, idlers_ready)
;
346
347 if (ecore_idling && events_ready)
348 {
349 INF("calling idle exiters")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 349, "calling idle exiters")
;
350 _ecore_idle_exiter_call();
351 ecore_idling = 0;
352 }
353 else if (!ecore_idling && !events_ready)
354 {
355 INF("start idling")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 355, "start idling")
;
356 ecore_idling = 1;
357 }
358
359 if (ecore_idling)
360 {
361 INF("calling idler")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 361, "calling idler")
;
362 _ecore_idler_call();
363
364 events_ready = _ecore_event_exist();
365 timers_ready = _ecore_timers_exists() && (0.0 <= next_time);
366 idlers_ready = _ecore_idler_exist();
367
368 if ((ecore_fds_ready || events_ready || timers_ready || idlers_ready || signals_ready))
369 {
370 INF("calling idle exiters")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 370, "calling idle exiters")
;
371 _ecore_idle_exiter_call();
372 ecore_idling = 0;
373 }
374 }
375
376 /* process events */
377 if (!ecore_idling)
378 {
379 INF("work")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 379, "work")
;
380 _ecore_main_fd_handlers_call();
381 _ecore_main_fd_handlers_buf_call();
382 while (_ecore_signal_count_get()) _ecore_signal_call();
383 _ecore_event_call();
384 _ecore_main_fd_handlers_cleanup();
385 }
386
387 in_main_loop--;
388
389 INF("leave")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 389, "leave")
;
390
391 return TRUE; /* what should be returned here? */
392}
393
394static void
395_ecore_main_gsource_finalize(GSource *source)
396{
397 INF("finalize")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 397, "finalize")
;
398}
399
400static GSourceFuncs ecore_gsource_funcs =
401{
402 .prepare = _ecore_main_gsource_prepare,
403 .check = _ecore_main_gsource_check,
404 .dispatch = _ecore_main_gsource_dispatch,
405 .finalize = _ecore_main_gsource_finalize,
406};
407
408#endif
409
410void
411_ecore_main_loop_init(void)
412{
413 INF("enter")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 413, "enter")
;
414#ifdef HAVE_EPOLL
415 epoll_fd = epoll_create(1);
416 if (epoll_fd < 0)
417 CRIT("Failed to create epoll fd!")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_CRITICAL, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 417, "Failed to create epoll fd!")
;
418#endif
419
420#ifdef USE_G_MAIN_LOOP
421 ecore_epoll_source = g_source_new(&ecore_gsource_funcs, sizeof (GSource));
422 if (!ecore_epoll_source)
423 CRIT("Failed to create glib source for epoll!")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_CRITICAL, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 423, "Failed to create glib source for epoll!"
)
;
424 else
425 {
426 ecore_epoll_fd.fd = epoll_fd;
427 ecore_epoll_fd.events = G_IO_IN;
428 ecore_epoll_fd.revents = 0;
429 g_source_add_poll(ecore_epoll_source, &ecore_epoll_fd);
430 ecore_epoll_id = g_source_attach(ecore_epoll_source, NULL((void*)0));
431 if (ecore_epoll_id <= 0)
432 CRIT("Failed to attach glib source to default context")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_CRITICAL, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 432, "Failed to attach glib source to default context"
)
;
433 }
434#endif
435 INF("leave")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 435, "leave")
;
436}
437
438void
439_ecore_main_loop_shutdown(void)
440{
441#ifdef USE_G_MAIN_LOOP
442 if (ecore_epoll_source)
443 {
444 g_source_destroy(ecore_epoll_source);
445 ecore_epoll_source = NULL((void*)0);
446 }
447#endif
448
449#ifdef HAVE_EPOLL
450 if (epoll_fd >= 0)
451 {
452 close(epoll_fd);
453 epoll_fd = -1;
454 }
455#endif
456}
457
458
459/**
460 * @defgroup Ecore_Main_Loop_Group Main Loop Functions
461 *
462 * These functions control the Ecore event handling loop. This loop is
463 * designed to work on embedded systems all the way to large and
464 * powerful mutli-cpu workstations.
465 *
466 * It serialises all system signals and events into a single event
467 * queue, that can be easily processed without needing to worry about
468 * concurrency. A properly written, event-driven program using this
469 * kind of programming does not need threads. It makes the program very
470 * robust and easy to follow.
471 *
472 * Here is an example of simple program and its basic event loop flow:
473 * @image html prog_flow.png
474 *
475 * For examples of setting up and using a main loop, see
476 * @ref event_handler_example.c and @ref timer_example.c.
477 */
478
479/**
480 * Runs a single iteration of the main loop to process everything on the
481 * queue.
482 * @ingroup Ecore_Main_Loop_Group
483 */
484EAPI__attribute__ ((visibility("default"))) void
485ecore_main_loop_iterate(void)
486{
487#ifndef USE_G_MAIN_LOOP
488 _ecore_main_loop_iterate_internal(1);
489#else
490 g_main_context_iteration(NULL((void*)0), 1);
491#endif
492}
493
494/**
495 * Runs the application main loop.
496 *
497 * This function will not return until @ref ecore_main_loop_quit is called.
498 *
499 * @ingroup Ecore_Main_Loop_Group
500 */
501EAPI__attribute__ ((visibility("default"))) void
502ecore_main_loop_begin(void)
503{
504#ifndef USE_G_MAIN_LOOP
505 in_main_loop++;
506 while (do_quit == 0) _ecore_main_loop_iterate_internal(0);
507 do_quit = 0;
508 in_main_loop--;
509#else
510 ecore_main_loop = g_main_loop_new(NULL((void*)0), FALSE);
511 g_main_loop_run(ecore_main_loop);
512#endif
513}
514
515/**
516 * Quits the main loop once all the events currently on the queue have
517 * been processed.
518 * @ingroup Ecore_Main_Loop_Group
519 */
520EAPI__attribute__ ((visibility("default"))) void
521ecore_main_loop_quit(void)
522{
523#ifndef USE_G_MAIN_LOOP
524 do_quit = 1;
525#else
526 INF("enter")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 526, "enter")
;
527 g_main_loop_quit(ecore_main_loop);
528 INF("leave")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 528, "leave")
;
529#endif
530}
531
532/**
533 * Sets the function to use when monitoring multiple file descriptors,
534 * and waiting until one of more of the file descriptors before ready
535 * for some class of I/O operation.
536 *
537 * This function will be used instead of the system call select and
538 * could possible be used to integrate the Ecore event loop with an
539 * external event loop.
540 *
541 * @warning you don't know how to use, don't even try to use it.
542 *
543 * @ingroup Ecore_Main_Loop_Group
544 */
545EAPI__attribute__ ((visibility("default"))) void
546ecore_main_loop_select_func_set(Ecore_Select_Function func)
547{
548 main_loop_select = func;
549}
550
551/**
552 * Gets the select function set by ecore_select_func_set(),
553 * or the native select function if none was set.
554 *
555 * @ingroup Ecore_Main_Loop_Group
556 */
557EAPI__attribute__ ((visibility("default"))) void *
558ecore_main_loop_select_func_get(void)
559{
560 return main_loop_select;
561}
562
563/**
564 * @defgroup Ecore_FD_Handler_Group File Event Handling Functions
565 *
566 * Functions that deal with file descriptor handlers.
567 */
568
569/**
570 * Adds a callback for activity on the given file descriptor.
571 *
572 * @p func will be called during the execution of @ref ecore_main_loop_begin
573 * when the file descriptor is available for reading, or writing, or both.
574 *
575 * Normally the return value from the @p func is "zero means this handler is
576 * finished and can be deleted" as is usual for handler callbacks. However,
577 * if the @p buf_func is supplied, then the return value from the @p func is
578 * "non zero means the handler should be called again in a tight loop".
579 *
580 * @p buf_func is called during event loop handling to check if data that has
581 * been read from the file descriptor is in a buffer and is available to
582 * read. Some systems (notably xlib) handle their own buffering, and would
583 * otherwise not work with select(). These systems should use a @p buf_func.
584 * This is a most annoying hack, only ecore_x uses it, so refer to that for
585 * an example. NOTE - @p func should probably return "one" always if
586 * @p buf_func is used, to avoid confusion with the other return value
587 * semantics.
588 *
589 * @param fd The file descriptor to watch.
590 * @param flags To watch it for read (@c ECORE_FD_READ) and/or
591 * (@c ECORE_FD_WRITE) write ability. @c ECORE_FD_ERROR
592 *
593 * @param func The callback function.
594 * @param data The data to pass to the callback.
595 * @param buf_func The function to call to check if any data has been
596 * buffered and already read from the fd. Can be @c NULL.
597 * @param buf_data The data to pass to the @p buf_func function.
598 * @return A fd handler handle if successful. @c NULL otherwise.
599 * @ingroup Ecore_FD_Handler_Group
600 */
601EAPI__attribute__ ((visibility("default"))) Ecore_Fd_Handler *
602ecore_main_fd_handler_add(int fd, Ecore_Fd_Handler_Flags flags, Ecore_Fd_Cb func, const void *data,
603 Ecore_Fd_Cb buf_func, const void *buf_data)
604{
605 Ecore_Fd_Handler *fdh;
606
607 if ((fd < 0) || (flags == 0) || (!func)) return NULL((void*)0);
608
609 fdh = calloc(1, sizeof(Ecore_Fd_Handler));
610 if (!fdh) return NULL((void*)0);
611 ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER)(fdh)->__magic = (0xf7a416f1);
612 fdh->fd = fd;
613 fdh->flags = flags;
614 if (0 > _ecore_main_fdh_epoll_add(fdh))
615 {
616 ERR("Failed to add epoll fd %d (errno = %d)!", fd, errno)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 616, "Failed to add epoll fd %d (errno = %d)!"
, fd, (*__errno_location ()))
;
617 free(fdh);
618 return NULL((void*)0);
619 }
620 fdh->read_active = 0;
621 fdh->write_active = 0;
622 fdh->error_active = 0;
623 fdh->delete_me = 0;
624 fdh->func = func;
625 fdh->data = (void *)data;
626 fdh->buf_func = buf_func;
627 fdh->buf_data = (void *)buf_data;
628 fd_handlers = (Ecore_Fd_Handler *)
629 eina_inlist_append(EINA_INLIST_GET(fd_handlers)(& ((fd_handlers)->__in_list)),
630 EINA_INLIST_GET(fdh)(& ((fdh)->__in_list)));
631 return fdh;
632}
633
634#ifdef _WIN32
635EAPI__attribute__ ((visibility("default"))) Ecore_Win32_Handler *
636ecore_main_win32_handler_add(void *h, Ecore_Fd_Win32_Cb func, const void *data)
637{
638 Ecore_Win32_Handler *wh;
639
640 if (!h || !func) return NULL((void*)0);
641
642 wh = calloc(1, sizeof(Ecore_Win32_Handler));
643 if (!wh) return NULL((void*)0);
644 ECORE_MAGIC_SET(wh, ECORE_MAGIC_WIN32_HANDLER)(wh)->__magic = (0xf7e8f1a3);
645 wh->h = (HANDLE)h;
646 wh->delete_me = 0;
647 wh->func = func;
648 wh->data = (void *)data;
649 win32_handlers = (Ecore_Win32_Handler *)
650 eina_inlist_append(EINA_INLIST_GET(win32_handlers)(& ((win32_handlers)->__in_list)),
651 EINA_INLIST_GET(wh)(& ((wh)->__in_list)));
652 return wh;
653}
654#else
655EAPI__attribute__ ((visibility("default"))) Ecore_Win32_Handler *
656ecore_main_win32_handler_add(void *h __UNUSED__, Ecore_Fd_Win32_Cb func __UNUSED__,
657 const void *data __UNUSED__)
658{
659 return NULL((void*)0);
660}
661#endif
662
663/**
664 * Deletes the given FD handler.
665 * @param fd_handler The given FD handler.
666 * @return The data pointer set using @ref ecore_main_fd_handler_add,
667 * for @p fd_handler on success. @c NULL otherwise.
668 * @ingroup Ecore_FD_Handler_Group
669 *
670 * Beware that if the fd is already closed, ecore may complain if it uses
671 * epoll internally, and that in some rare cases this may be able to cause
672 * crashes and instability. Remember to delete your fd handlers before the
673 * fd's they listen to are closed.
674 */
675EAPI__attribute__ ((visibility("default"))) void *
676ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler)
677{
678 if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)((fd_handler) && ((fd_handler)->__magic == (0xf7a416f1
)))
)
679 {
680 ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,_ecore_magic_fail((fd_handler), (fd_handler) ? (fd_handler)->
__magic : 0, (0xf7a416f1), ("ecore_main_fd_handler_del"));
681 "ecore_main_fd_handler_del")_ecore_magic_fail((fd_handler), (fd_handler) ? (fd_handler)->
__magic : 0, (0xf7a416f1), ("ecore_main_fd_handler_del"));
;
682 return NULL((void*)0);
683 }
684 fd_handler->delete_me = 1;
685 fd_handlers_delete_me = 1;
686 _ecore_main_fdh_epoll_del(fd_handler);
687 return fd_handler->data;
688}
689
690#ifdef _WIN32
691EAPI__attribute__ ((visibility("default"))) void *
692ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler)
693{
694 if (!ECORE_MAGIC_CHECK(win32_handler, ECORE_MAGIC_WIN32_HANDLER)((win32_handler) && ((win32_handler)->__magic == (
0xf7e8f1a3)))
)
695 {
696 ECORE_MAGIC_FAIL(win32_handler, ECORE_MAGIC_WIN32_HANDLER,_ecore_magic_fail((win32_handler), (win32_handler) ? (win32_handler
)->__magic : 0, (0xf7e8f1a3), ("ecore_main_win32_handler_del"
));
697 "ecore_main_win32_handler_del")_ecore_magic_fail((win32_handler), (win32_handler) ? (win32_handler
)->__magic : 0, (0xf7e8f1a3), ("ecore_main_win32_handler_del"
));
;
698 return NULL((void*)0);
699 }
700 win32_handler->delete_me = 1;
701 win32_handlers_delete_me = 1;
702 return win32_handler->data;
703}
704#else
705EAPI__attribute__ ((visibility("default"))) void *
706ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler __UNUSED__)
707{
708 return NULL((void*)0);
709}
710#endif
711
712EAPI__attribute__ ((visibility("default"))) void
713ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Prep_Cb func, const void *data)
714{
715 if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)((fd_handler) && ((fd_handler)->__magic == (0xf7a416f1
)))
)
716 {
717 ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,_ecore_magic_fail((fd_handler), (fd_handler) ? (fd_handler)->
__magic : 0, (0xf7a416f1), ("ecore_main_fd_handler_prepare_callback_set"
));
718 "ecore_main_fd_handler_prepare_callback_set")_ecore_magic_fail((fd_handler), (fd_handler) ? (fd_handler)->
__magic : 0, (0xf7a416f1), ("ecore_main_fd_handler_prepare_callback_set"
));
;
719 return;
720 }
721 fd_handler->prep_func = func;
722 fd_handler->prep_data = (void *) data;
723}
724
725/**
726 * Retrieves the file descriptor that the given handler is handling.
727 * @param fd_handler The given FD handler.
728 * @return The file descriptor the handler is watching.
729 * @ingroup Ecore_FD_Handler_Group
730 */
731EAPI__attribute__ ((visibility("default"))) int
732ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler)
733{
734 if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)((fd_handler) && ((fd_handler)->__magic == (0xf7a416f1
)))
)
735 {
736 ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,_ecore_magic_fail((fd_handler), (fd_handler) ? (fd_handler)->
__magic : 0, (0xf7a416f1), ("ecore_main_fd_handler_fd_get"));
737 "ecore_main_fd_handler_fd_get")_ecore_magic_fail((fd_handler), (fd_handler) ? (fd_handler)->
__magic : 0, (0xf7a416f1), ("ecore_main_fd_handler_fd_get"));
;
738 return -1;
739 }
740 return fd_handler->fd;
741}
742
743/**
744 * Return if read, write or error, or a combination thereof, is active on the
745 * file descriptor of the given FD handler.
746 * @param fd_handler The given FD handler.
747 * @param flags The flags, @c ECORE_FD_READ, @c ECORE_FD_WRITE or
748 * @c ECORE_FD_ERROR to query.
749 * @return #EINA_TRUE if any of the given flags are active. #EINA_FALSE otherwise.
750 * @ingroup Ecore_FD_Handler_Group
751 */
752EAPI__attribute__ ((visibility("default"))) Eina_Bool
753ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags)
754{
755 int ret = EINA_FALSE((Eina_Bool)0);
756
757 if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)((fd_handler) && ((fd_handler)->__magic == (0xf7a416f1
)))
)
758 {
759 ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,_ecore_magic_fail((fd_handler), (fd_handler) ? (fd_handler)->
__magic : 0, (0xf7a416f1), ("ecore_main_fd_handler_active_get"
));
760 "ecore_main_fd_handler_active_get")_ecore_magic_fail((fd_handler), (fd_handler) ? (fd_handler)->
__magic : 0, (0xf7a416f1), ("ecore_main_fd_handler_active_get"
));
;
761 return EINA_FALSE((Eina_Bool)0);
762 }
763 if ((flags & ECORE_FD_READ) && (fd_handler->read_active)) ret = EINA_TRUE((Eina_Bool)1);
764 if ((flags & ECORE_FD_WRITE) && (fd_handler->write_active)) ret = EINA_TRUE((Eina_Bool)1);
765 if ((flags & ECORE_FD_ERROR) && (fd_handler->error_active)) ret = EINA_TRUE((Eina_Bool)1);
766 return ret;
767}
768
769/**
770 * Set what active streams the given FD handler should be monitoring.
771 * @param fd_handler The given FD handler.
772 * @param flags The flags to be watching.
773 * @ingroup Ecore_FD_Handler_Group
774 */
775EAPI__attribute__ ((visibility("default"))) void
776ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags)
777{
778 if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER)((fd_handler) && ((fd_handler)->__magic == (0xf7a416f1
)))
)
779 {
780 ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,_ecore_magic_fail((fd_handler), (fd_handler) ? (fd_handler)->
__magic : 0, (0xf7a416f1), ("ecore_main_fd_handler_active_set"
));
781 "ecore_main_fd_handler_active_set")_ecore_magic_fail((fd_handler), (fd_handler) ? (fd_handler)->
__magic : 0, (0xf7a416f1), ("ecore_main_fd_handler_active_set"
));
;
782 return;
783 }
784 fd_handler->flags = flags;
785 if (0 > _ecore_main_fdh_epoll_modify(fd_handler))
786 {
787 ERR("Failed to mod epoll fd %d!", fd_handler->fd)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 787, "Failed to mod epoll fd %d!", fd_handler
->fd)
;
788 }
789}
790
791void
792_ecore_main_shutdown(void)
793{
794 if (in_main_loop)
795 {
796 ERR("\n"eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 798, "\n" "*** ECORE WARINING: Calling ecore_shutdown() while still in the main loop.\n"
"*** Program may crash or behave strangely now."
)
797 "*** ECORE WARINING: Calling ecore_shutdown() while still in the main loop.\n"eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 798, "\n" "*** ECORE WARINING: Calling ecore_shutdown() while still in the main loop.\n"
"*** Program may crash or behave strangely now."
)
798 "*** Program may crash or behave strangely now.")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 798, "\n" "*** ECORE WARINING: Calling ecore_shutdown() while still in the main loop.\n"
"*** Program may crash or behave strangely now."
)
;
799 return;
800 }
801 while (fd_handlers)
802 {
803 Ecore_Fd_Handler *fdh;
804
805 fdh = fd_handlers;
806 fd_handlers = (Ecore_Fd_Handler *) eina_inlist_remove(EINA_INLIST_GET(fd_handlers)(& ((fd_handlers)->__in_list)),
807 EINA_INLIST_GET(fdh)(& ((fdh)->__in_list)));
808 ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE)(fdh)->__magic = (0x1234fedc);
809 free(fdh);
810 }
811 fd_handlers_delete_me = 0;
812 fd_handler_current = NULL((void*)0);
813
814#ifdef _WIN32
815 while (win32_handlers)
816 {
817 Ecore_Win32_Handler *wh;
818
819 wh = win32_handlers;
820 win32_handlers = (Ecore_Win32_Handler *) eina_inlist_remove(EINA_INLIST_GET(win32_handlers)(& ((win32_handlers)->__in_list)),
821 EINA_INLIST_GET(wh)(& ((wh)->__in_list)));
822 ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE)(wh)->__magic = (0x1234fedc);
823 free(wh);
824 }
825 win32_handlers_delete_me = 0;
826 win32_handler_current = NULL((void*)0);
827#endif
828}
829
830static void
831_ecore_main_prepare_handlers(void)
832{
833 Ecore_Fd_Handler *fdh;
834
835 /* call the prepare callback for all handlers */
836 EINA_INLIST_FOREACH(fd_handlers, fdh)for (fdh = ((void*)0), fdh = (fd_handlers ? (void *)((char *)
(fd_handlers) - ((char *)&(fdh)->__in_list - (char *)(
fdh))) : ((void*)0)); fdh; fdh = ((& ((fdh)->__in_list
))->next ? (void *)((char *)((& ((fdh)->__in_list))
->next) - ((char *)&(fdh)->__in_list - (char *)(fdh
))) : ((void*)0)))
837 {
838 if (!fdh->delete_me && fdh->prep_func)
839 {
840 fdh->references++;
841 fdh->prep_func (fdh->prep_data, fdh);
842 fdh->references--;
843 }
844 }
845}
846
847static int
848_ecore_main_select(double timeout)
849{
850 struct timeval tv, *t;
851 fd_set rfds, wfds, exfds;
852 int max_fd;
853 int ret;
854
855 t = NULL((void*)0);
856 if ((!finite(timeout)) || (timeout == 0.0)) /* finite() tests for NaN, too big, too small, and infinity. */
857 {
858 tv.tv_sec = 0;
859 tv.tv_usec = 0;
860 t = &tv;
861 }
862 else if (timeout > 0.0)
863 {
864 int sec, usec;
865
866#ifdef FIX_HZ1
867 timeout += (0.5 / HZ100);
868 sec = (int)timeout;
869 usec = (int)((timeout - (double)sec) * 1000000);
870#else
871 sec = (int)timeout;
872 usec = (int)((timeout - (double)sec) * 1000000);
873#endif
874 tv.tv_sec = sec;
875 tv.tv_usec = usec;
876 t = &tv;
877 }
878 max_fd = 0;
879 FD_ZERO(&rfds)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&rfds)->fds_bits)[0]
) : "memory"); } while (0)
;
880 FD_ZERO(&wfds)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&wfds)->fds_bits)[0]
) : "memory"); } while (0)
;
881 FD_ZERO(&exfds)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&exfds)->fds_bits)[0
]) : "memory"); } while (0)
;
882
883 /* call the prepare callback for all handlers */
884 _ecore_main_prepare_handlers();
885#ifndef HAVE_EPOLL
886 Ecore_Fd_Handler *fdh;
887
888 EINA_INLIST_FOREACH(fd_handlers, fdh)for (fdh = ((void*)0), fdh = (fd_handlers ? (void *)((char *)
(fd_handlers) - ((char *)&(fdh)->__in_list - (char *)(
fdh))) : ((void*)0)); fdh; fdh = ((& ((fdh)->__in_list
))->next ? (void *)((char *)((& ((fdh)->__in_list))
->next) - ((char *)&(fdh)->__in_list - (char *)(fdh
))) : ((void*)0)))
889 {
890 if (!fdh->delete_me)
891 {
892 if (fdh->flags & ECORE_FD_READ)
893 {
894 FD_SET(fdh->fd, &rfds)(((&rfds)->fds_bits)[((fdh->fd) / (8 * (int) sizeof
(__fd_mask)))] |= ((__fd_mask) 1 << ((fdh->fd) % (8
* (int) sizeof (__fd_mask)))))
;
895 if (fdh->fd > max_fd) max_fd = fdh->fd;
896 }
897 if (fdh->flags & ECORE_FD_WRITE)
898 {
899 FD_SET(fdh->fd, &wfds)(((&wfds)->fds_bits)[((fdh->fd) / (8 * (int) sizeof
(__fd_mask)))] |= ((__fd_mask) 1 << ((fdh->fd) % (8
* (int) sizeof (__fd_mask)))))
;
900 if (fdh->fd > max_fd) max_fd = fdh->fd;
901 }
902 if (fdh->flags & ECORE_FD_ERROR)
903 {
904 FD_SET(fdh->fd, &exfds)(((&exfds)->fds_bits)[((fdh->fd) / (8 * (int) sizeof
(__fd_mask)))] |= ((__fd_mask) 1 << ((fdh->fd) % (8
* (int) sizeof (__fd_mask)))))
;
905 if (fdh->fd > max_fd) max_fd = fdh->fd;
906 }
907 }
908 }
909#else /* HAVE_EPOLL */
910 /* polling on the epoll fd will wake when an fd in the epoll set is active */
911 FD_SET(epoll_fd, &rfds)(((&rfds)->fds_bits)[((epoll_fd) / (8 * (int) sizeof (
__fd_mask)))] |= ((__fd_mask) 1 << ((epoll_fd) % (8 * (
int) sizeof (__fd_mask)))))
;
912 max_fd = epoll_fd;
913#endif /* HAVE_EPOLL */
914
915 if (_ecore_signal_count_get()) return -1;
916
917 ret = main_loop_select(max_fd + 1, &rfds, &wfds, &exfds, t);
918
919 _ecore_time_loop_time = ecore_time_get();
920 if (ret < 0)
921 {
922#ifndef _WIN32
923 if (errno(*__errno_location ()) == EINTR4) return -1;
924 else if (errno(*__errno_location ()) == EBADF9) _ecore_main_fd_handlers_bads_rem();
925#endif
926 }
927 if (ret > 0)
928 {
929#ifdef HAVE_EPOLL
930 _ecore_main_fdh_epoll_mark_active();
931#else /* HAVE_EPOLL */
932 Ecore_Fd_Handler *fdh;
933
934 EINA_INLIST_FOREACH(fd_handlers, fdh)for (fdh = ((void*)0), fdh = (fd_handlers ? (void *)((char *)
(fd_handlers) - ((char *)&(fdh)->__in_list - (char *)(
fdh))) : ((void*)0)); fdh; fdh = ((& ((fdh)->__in_list
))->next ? (void *)((char *)((& ((fdh)->__in_list))
->next) - ((char *)&(fdh)->__in_list - (char *)(fdh
))) : ((void*)0)))
935 {
936 if (!fdh->delete_me)
937 {
938 if (FD_ISSET(fdh->fd, &rfds)((((&rfds)->fds_bits)[((fdh->fd) / (8 * (int) sizeof
(__fd_mask)))] & ((__fd_mask) 1 << ((fdh->fd) %
(8 * (int) sizeof (__fd_mask))))) != 0)
)
939 fdh->read_active = 1;
940 if (FD_ISSET(fdh->fd, &wfds)((((&wfds)->fds_bits)[((fdh->fd) / (8 * (int) sizeof
(__fd_mask)))] & ((__fd_mask) 1 << ((fdh->fd) %
(8 * (int) sizeof (__fd_mask))))) != 0)
)
941 fdh->write_active = 1;
942 if (FD_ISSET(fdh->fd, &exfds)((((&exfds)->fds_bits)[((fdh->fd) / (8 * (int) sizeof
(__fd_mask)))] & ((__fd_mask) 1 << ((fdh->fd) %
(8 * (int) sizeof (__fd_mask))))) != 0)
)
943 fdh->error_active = 1;
944 }
945 }
946#endif /* HAVE_EPOLL */
947 _ecore_main_fd_handlers_cleanup();
948#ifdef _WIN32
949 _ecore_main_win32_handlers_cleanup();
950#endif
951 return 1;
952 }
953 return 0;
954}
955
956#ifndef _WIN32
957static void
958_ecore_main_fd_handlers_bads_rem(void)
959{
960 Ecore_Fd_Handler *fdh;
961 Eina_Inlist *l;
962 int found = 0;
963
964 ERR("Removing bad fds")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 964, "Removing bad fds")
;
965 for (l = EINA_INLIST_GET(fd_handlers)(& ((fd_handlers)->__in_list)); l; )
966 {
967 fdh = (Ecore_Fd_Handler *) l;
968 l = l->next;
969 errno(*__errno_location ()) = 0;
970
971 if ((fcntl(fdh->fd, F_GETFD1) < 0) && (errno(*__errno_location ()) == EBADF9))
972 {
973 ERR("Found bad fd at index %d", fdh->fd)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 973, "Found bad fd at index %d", fdh->fd)
;
974 if (fdh->flags & ECORE_FD_ERROR)
975 {
976 ERR("Fd set for error! calling user")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 976, "Fd set for error! calling user")
;
977 fdh->references++;
978 if (!fdh->func(fdh->data, fdh))
979 {
980 ERR("Fd function err returned 0, remove it")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 980, "Fd function err returned 0, remove it")
;
981 fdh->delete_me = 1;
982 fd_handlers_delete_me = 1;
983 found++;
984 }
985 fdh->references--;
986 }
987 else
988 {
989 ERR("Problematic fd found at %d! setting it for delete", fdh->fd)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 989, "Problematic fd found at %d! setting it for delete"
, fdh->fd)
;
990 fdh->delete_me = 1;
991 fd_handlers_delete_me = 1;
992 found++;
993 }
994 }
995 }
996 if (found == 0)
997 {
998#ifdef HAVE_GLIB
999 ERR("No bad fd found. Maybe a foreign fd from glib?")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 999, "No bad fd found. Maybe a foreign fd from glib?"
)
;
1000#else
1001 ERR("No bad fd found. EEEK!")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 1001, "No bad fd found. EEEK!")
;
1002#endif
1003 }
1004 _ecore_main_fd_handlers_cleanup();
1005}
1006#endif
1007
1008static void
1009_ecore_main_fd_handlers_cleanup(void)
1010{
1011 Ecore_Fd_Handler *fdh;
1012 Eina_Inlist *l;
1013 int deleted_in_use = 0;
1014
1015 if (!fd_handlers_delete_me) return;
1016 for (l = EINA_INLIST_GET(fd_handlers)(& ((fd_handlers)->__in_list)); l; )
1017 {
1018 fdh = (Ecore_Fd_Handler *) l;
1019
1020 l = l->next;
1021 if (fdh->delete_me)
1022 {
1023 if (fdh->references)
1024 {
1025 deleted_in_use++;
1026 continue;
1027 }
1028
1029 fd_handlers = (Ecore_Fd_Handler *)
1030 eina_inlist_remove(EINA_INLIST_GET(fd_handlers)(& ((fd_handlers)->__in_list)),
1031 EINA_INLIST_GET(fdh)(& ((fdh)->__in_list)));
1032 ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE)(fdh)->__magic = (0x1234fedc);
1033 free(fdh);
1034 }
1035 }
1036 if (!deleted_in_use) fd_handlers_delete_me = 0;
1037}
1038
1039#ifdef _WIN32
1040static void
1041_ecore_main_win32_handlers_cleanup(void)
1042{
1043 Ecore_Win32_Handler *wh;
1044 Eina_Inlist *l;
1045 int deleted_in_use = 0;
1046
1047 if (!win32_handlers_delete_me) return;
1048 for (l = EINA_INLIST_GET(win32_handlers)(& ((win32_handlers)->__in_list)); l; )
1049 {
1050 wh = (Ecore_Win32_Handler *)l;
1051
1052 l = l->next;
1053 if (wh->delete_me)
1054 {
1055 if (wh->references)
1056 {
1057 deleted_in_use++;
1058 continue;
1059 }
1060
1061 win32_handlers = (Ecore_Win32_Handler *)
1062 eina_inlist_remove(EINA_INLIST_GET(win32_handlers)(& ((win32_handlers)->__in_list)),
1063 EINA_INLIST_GET(wh)(& ((wh)->__in_list)));
1064 ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE)(wh)->__magic = (0x1234fedc);
1065 free(wh);
1066 }
1067 }
1068 if (!deleted_in_use) win32_handlers_delete_me = 0;
1069}
1070#endif
1071
1072static void
1073_ecore_main_fd_handlers_call(void)
1074{
1075 if (!fd_handler_current)
1076 {
1077 /* regular main loop, start from head */
1078 fd_handler_current = fd_handlers;
1079 }
1080 else
1081 {
1082 /* recursive main loop, continue from where we were */
1083 fd_handler_current = (Ecore_Fd_Handler *)EINA_INLIST_GET(fd_handler_current)(& ((fd_handler_current)->__in_list))->next;
1084 }
1085
1086 while (fd_handler_current)
1087 {
1088 Ecore_Fd_Handler *fdh = fd_handler_current;
1089
1090 if (!fdh->delete_me)
1091 {
1092 if ((fdh->read_active) ||
1093 (fdh->write_active) ||
1094 (fdh->error_active))
1095 {
1096 fdh->references++;
1097 if (!fdh->func(fdh->data, fdh))
1098 {
1099 fdh->delete_me = 1;
1100 fd_handlers_delete_me = 1;
1101 }
1102 fdh->references--;
1103
1104 fdh->read_active = 0;
1105 fdh->write_active = 0;
1106 fdh->error_active = 0;
1107 }
1108 }
1109
1110 if (fd_handler_current) /* may have changed in recursive main loops */
1111 fd_handler_current = (Ecore_Fd_Handler *)EINA_INLIST_GET(fd_handler_current)(& ((fd_handler_current)->__in_list))->next;
1112 }
1113}
1114
1115static int
1116_ecore_main_fd_handlers_buf_call(void)
1117{
1118 Ecore_Fd_Handler *fdh;
1119 int ret;
1120
1121 ret = 0;
1122 EINA_INLIST_FOREACH(fd_handlers, fdh)for (fdh = ((void*)0), fdh = (fd_handlers ? (void *)((char *)
(fd_handlers) - ((char *)&(fdh)->__in_list - (char *)(
fdh))) : ((void*)0)); fdh; fdh = ((& ((fdh)->__in_list
))->next ? (void *)((char *)((& ((fdh)->__in_list))
->next) - ((char *)&(fdh)->__in_list - (char *)(fdh
))) : ((void*)0)))
1123 {
1124 if (!fdh->delete_me)
1125 {
1126 if (fdh->buf_func)
1127 {
1128 fdh->references++;
1129 if (fdh->buf_func(fdh->buf_data, fdh))
1130 {
1131 ret |= fdh->func(fdh->data, fdh);
1132 fdh->read_active = 1;
1133 }
1134 fdh->references--;
1135 }
1136 }
1137 }
1138 return ret;
1139}
1140
1141#ifndef USE_G_MAIN_LOOP
1142static void
1143_ecore_main_loop_iterate_internal(int once_only)
1144{
1145 double next_time = -1.0;
1146 int have_event = 0;
1147 int have_signal;
1148
1149 in_main_loop++;
1150 /* expire any timers */
1151 while (_ecore_timer_call(_ecore_time_loop_time));
1152 _ecore_timer_cleanup();
1153
1154 /* process signals into events .... */
1155 while (_ecore_signal_count_get()) _ecore_signal_call();
1156 if (_ecore_event_exist())
1157 {
1158 _ecore_idle_enterer_call();
1159 have_event = 1;
1160 _ecore_main_select(0.0);
1161 _ecore_time_loop_time = ecore_time_get();
1162 _ecore_timer_enable_new();
1163 goto process_events;
1164 }
1165 /* call idle enterers ... */
1166 if (!once_only) _ecore_idle_enterer_call();
1167 else
1168 {
1169 have_event = have_signal = 0;
1170
1171 if (_ecore_main_select(0.0) > 0) have_event = 1;
1172 if (_ecore_signal_count_get() > 0) have_signal = 1;
1173 if (have_signal || have_event)
1174 {
1175 _ecore_time_loop_time = ecore_time_get();
1176 _ecore_timer_enable_new();
1177 goto process_events;
1178 }
1179 }
1180
1181 /* if these calls caused any buffered events to appear - deal with them */
1182 _ecore_main_fd_handlers_buf_call();
1183
1184 /* if there are any - jump to processing them */
1185 if (_ecore_event_exist())
1186 {
1187 have_event = 1;
1188 _ecore_main_select(0.0);
1189 _ecore_time_loop_time = ecore_time_get();
1190 _ecore_timer_enable_new();
1191 goto process_events;
1192 }
1193 if (once_only)
1194 {
1195 _ecore_idle_enterer_call();
1196 in_main_loop--;
1197 _ecore_time_loop_time = ecore_time_get();
1198 _ecore_timer_enable_new();
1199 return;
1200 }
1201
1202 if (_ecore_fps_debug)
1203 {
1204 t2 = ecore_time_get();
1205 if ((t1 > 0.0) && (t2 > 0.0))
1206 _ecore_fps_debug_runtime_add(t2 - t1);
1207 }
1208 start_loop:
1209 /* any timers re-added as a result of these are allowed to go */
1210 _ecore_timer_enable_new();
1211 if (do_quit)
1212 {
1213 _ecore_time_loop_time = ecore_time_get();
1214 in_main_loop--;
1215 _ecore_timer_enable_new();
1216 return;
1217 }
1218 if (!_ecore_event_exist())
1219 {
1220 /* init flags */
1221 have_event = have_signal = 0;
1222 next_time = _ecore_timer_next_get();
1223 /* no timers */
1224 if (next_time < 0)
1225 {
1226 /* no idlers */
1227 if (!_ecore_idler_exist())
1228 {
1229 if (_ecore_main_select(-1.0) > 0) have_event = 1;
1230 }
1231 /* idlers */
1232 else
1233 {
1234 for (;;)
1235 {
1236 if (!_ecore_idler_call()) goto start_loop;
1237 if (_ecore_event_exist()) break;
1238 if (_ecore_main_select(0.0) > 0) have_event = 1;
1239 if (_ecore_signal_count_get() > 0) have_signal = 1;
1240 if (have_event || have_signal) break;
1241 if (_ecore_timers_exists()) goto start_loop;
1242 if (do_quit) break;
1243 }
1244 }
1245 }
1246 /* timers */
1247 else
1248 {
1249 /* no idlers */
1250 if (!_ecore_idler_exist())
1251 {
1252 if (_ecore_main_select(next_time) > 0) have_event = 1;
Value stored to 'have_event' is never read
1253 }
1254 /* idlers */
1255 else
1256 {
1257 for (;;)
1258 {
1259 if (!_ecore_idler_call()) goto start_loop;
1260 if (_ecore_event_exist()) break;
1261 if (_ecore_main_select(0.0) > 0) have_event = 1;
1262 if (_ecore_signal_count_get() > 0) have_signal = 1;
1263 if (have_event || have_signal) break;
1264 next_time = _ecore_timer_next_get();
1265 if (next_time <= 0) break;
1266 if (do_quit) break;
1267 }
1268 }
1269 }
1270 _ecore_time_loop_time = ecore_time_get();
1271 }
1272 if (_ecore_fps_debug) t1 = ecore_time_get();
1273 /* we came out of our "wait state" so idle has exited */
1274 if (!once_only) _ecore_idle_exiter_call();
1275 /* call the fd handler per fd that became alive... */
1276 /* this should read or write any data to the monitored fd and then */
1277 /* post events onto the ecore event pipe if necessary */
1278 process_events:
1279 _ecore_main_fd_handlers_call();
1280 _ecore_main_fd_handlers_buf_call();
1281 /* process signals into events .... */
1282 while (_ecore_signal_count_get()) _ecore_signal_call();
1283 /* handle events ... */
1284 _ecore_event_call();
1285 _ecore_main_fd_handlers_cleanup();
1286
1287 if (once_only) _ecore_idle_enterer_call();
1288 in_main_loop--;
1289}
1290#endif
1291
1292#ifdef _WIN32
1293static int
1294_ecore_main_win32_select(int nfds __UNUSED__, fd_set *readfds, fd_set *writefds,
1295 fd_set *exceptfds, struct timeval *tv)
1296{
1297 HANDLE objects[MAXIMUM_WAIT_OBJECTS];
1298 int sockets[MAXIMUM_WAIT_OBJECTS];
1299 Ecore_Fd_Handler *fdh;
1300 Ecore_Win32_Handler *wh;
1301 unsigned int objects_nbr = 0;
1302 unsigned int handles_nbr = 0;
1303 unsigned int events_nbr = 0;
1304 DWORD result;
1305 DWORD timeout;
1306 MSG msg;
1307 unsigned int i;
1308 int res;
1309
1310 /* Create an event object per socket */
1311 EINA_INLIST_FOREACH(fd_handlers, fdh)for (fdh = ((void*)0), fdh = (fd_handlers ? (void *)((char *)
(fd_handlers) - ((char *)&(fdh)->__in_list - (char *)(
fdh))) : ((void*)0)); fdh; fdh = ((& ((fdh)->__in_list
))->next ? (void *)((char *)((& ((fdh)->__in_list))
->next) - ((char *)&(fdh)->__in_list - (char *)(fdh
))) : ((void*)0)))
1312 {
1313 WSAEVENT event;
1314 long network_event;
1315
1316 network_event = 0;
1317 if (FD_ISSET(fdh->fd, readfds)((((readfds)->fds_bits)[((fdh->fd) / (8 * (int) sizeof (
__fd_mask)))] & ((__fd_mask) 1 << ((fdh->fd) % (
8 * (int) sizeof (__fd_mask))))) != 0)
)
1318 network_event |= FD_READ;
1319 if (FD_ISSET(fdh->fd, writefds)((((writefds)->fds_bits)[((fdh->fd) / (8 * (int) sizeof
(__fd_mask)))] & ((__fd_mask) 1 << ((fdh->fd) %
(8 * (int) sizeof (__fd_mask))))) != 0)
)
1320 network_event |= FD_WRITE;
1321 if (FD_ISSET(fdh->fd, exceptfds)((((exceptfds)->fds_bits)[((fdh->fd) / (8 * (int) sizeof
(__fd_mask)))] & ((__fd_mask) 1 << ((fdh->fd) %
(8 * (int) sizeof (__fd_mask))))) != 0)
)
1322 network_event |= FD_OOB;
1323
1324 if (network_event)
1325 {
1326 event = WSACreateEvent();
1327 WSAEventSelect(fdh->fd, event, network_event);
1328 objects[objects_nbr] = event;
1329 sockets[events_nbr] = fdh->fd;
1330 events_nbr++;
1331 objects_nbr++;
1332 }
1333 }
1334
1335 /* store the HANDLEs in the objects to wait for */
1336 EINA_INLIST_FOREACH(win32_handlers, wh)for (wh = ((void*)0), wh = (win32_handlers ? (void *)((char *
)(win32_handlers) - ((char *)&(wh)->__in_list - (char *
)(wh))) : ((void*)0)); wh; wh = ((& ((wh)->__in_list))
->next ? (void *)((char *)((& ((wh)->__in_list))->
next) - ((char *)&(wh)->__in_list - (char *)(wh))) : (
(void*)0)))
1337 {
1338 objects[objects_nbr] = wh->h;
1339 handles_nbr++;
1340 objects_nbr++;
1341 }
1342
1343 /* Empty the queue before waiting */
1344 while (PeekMessage(&msg, NULL((void*)0), 0, 0, PM_REMOVE))
1345 {
1346 TranslateMessage(&msg);
1347 DispatchMessage(&msg);
1348 }
1349
1350 /* Wait for any message sent or posted to this queue */
1351 /* or for one of the passed handles be set to signaled. */
1352 if (!tv)
1353 timeout = INFINITE;
1354 else
1355 timeout = (DWORD)((tv->tv_sec * 1000.0) + (tv->tv_usec / 1000.0));
1356
1357 if (timeout == 0) return 0;
1358
1359 result = MsgWaitForMultipleObjects(objects_nbr, (const HANDLE *)objects, EINA_FALSE((Eina_Bool)0),
1360 timeout, QS_ALLINPUT);
1361
1362 FD_ZERO(readfds)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((readfds)->fds_bits)[0]) :
"memory"); } while (0)
;
1363 FD_ZERO(writefds)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((writefds)->fds_bits)[0])
: "memory"); } while (0)
;
1364 FD_ZERO(exceptfds)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((exceptfds)->fds_bits)[0]
) : "memory"); } while (0)
;
1365
1366 /* The result tells us the type of event we have. */
1367 if (result == WAIT_FAILED)
1368 {
1369 char *msg;
1370
1371 msg = evil_last_error_get();
1372 ERR(" * %s\n", msg)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 1372, " * %s\n", msg)
;
1373 free(msg);
1374 res = -1;
1375 }
1376 else if (result == WAIT_TIMEOUT)
1377 {
1378 /* ERR("time out\n"); */
1379 res = 0;
1380 }
1381 else if (result == (WAIT_OBJECT_0 + objects_nbr))
1382 {
1383 while (PeekMessage(&msg, NULL((void*)0), 0, 0, PM_REMOVE))
1384 {
1385 TranslateMessage(&msg);
1386 DispatchMessage(&msg);
1387 }
1388
1389 res = 0;
1390 }
1391 else if ((result >= 0) && (result < WAIT_OBJECT_0 + events_nbr))
1392 {
1393 WSANETWORKEVENTS network_event;
1394
1395 WSAEnumNetworkEvents(sockets[result], objects[result], &network_event);
1396
1397 if (network_event.lNetworkEvents & FD_READ)
1398 FD_SET(sockets[result], readfds)(((readfds)->fds_bits)[((sockets[result]) / (8 * (int) sizeof
(__fd_mask)))] |= ((__fd_mask) 1 << ((sockets[result])
% (8 * (int) sizeof (__fd_mask)))))
;
1399 if (network_event.lNetworkEvents & FD_WRITE)
1400 FD_SET(sockets[result], writefds)(((writefds)->fds_bits)[((sockets[result]) / (8 * (int) sizeof
(__fd_mask)))] |= ((__fd_mask) 1 << ((sockets[result])
% (8 * (int) sizeof (__fd_mask)))))
;
1401 if (network_event.lNetworkEvents & FD_OOB)
1402 FD_SET(sockets[result], exceptfds)(((exceptfds)->fds_bits)[((sockets[result]) / (8 * (int) sizeof
(__fd_mask)))] |= ((__fd_mask) 1 << ((sockets[result])
% (8 * (int) sizeof (__fd_mask)))))
;
1403
1404 res = 1;
1405 }
1406 else if ((result >= (WAIT_OBJECT_0 + events_nbr)) &&
1407 (result < (WAIT_OBJECT_0 + objects_nbr)))
1408 {
1409 if (!win32_handler_current)
1410 {
1411 /* regular main loop, start from head */
1412 win32_handler_current = win32_handlers;
1413 }
1414 else
1415 {
1416 /* recursive main loop, continue from where we were */
1417 win32_handler_current = (Ecore_Win32_Handler *)EINA_INLIST_GET(win32_handler_current)(& ((win32_handler_current)->__in_list))->next;
1418 }
1419
1420 while (win32_handler_current)
1421 {
1422 wh = win32_handler_current;
1423
1424 if (objects[result - WAIT_OBJECT_0] == wh->h)
1425 {
1426 if (!wh->delete_me)
1427 {
1428 wh->references++;
1429 if (!wh->func(wh->data, wh))
1430 {
1431 wh->delete_me = 1;
1432 win32_handlers_delete_me = 1;
1433 }
1434 wh->references--;
1435 }
1436 }
1437 if (win32_handler_current) /* may have changed in recursive main loops */
1438 win32_handler_current = (Ecore_Win32_Handler *)EINA_INLIST_GET(win32_handler_current)(& ((win32_handler_current)->__in_list))->next;
1439 }
1440 res = 1;
1441 }
1442 else
1443 {
1444 ERR("unknown result...\n")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_main.c"
, __FUNCTION__, 1444, "unknown result...\n")
;
1445 res = -1;
1446 }
1447
1448 /* Remove event objects again */
1449 for (i = 0; i < events_nbr; i++) WSACloseEvent(objects[i]);
1450
1451 return res;
1452}
1453#endif