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