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