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