[SVN's EFL Migration] ecore in SLP is merged with SVN r55371.
[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      /* FIXME: should this return NULL instead? */
830      return fd_handler->data;
831      
832    fd_handler->delete_me = EINA_TRUE;
833    _ecore_main_fdh_poll_del(fd_handler);
834    fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fd_handler);
835    if (fd_handler->prep_func && fd_handlers_with_prep)
836      fd_handlers_with_prep = eina_list_remove(fd_handlers_with_prep, fd_handler);
837    if (fd_handler->buf_func && fd_handlers_with_buffer)
838      fd_handlers_with_buffer = eina_list_remove(fd_handlers_with_buffer, fd_handler);
839    return fd_handler->data;
840 }
841
842 #ifdef _WIN32
843 EAPI void *
844 ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler)
845 {
846    if (!ECORE_MAGIC_CHECK(win32_handler, ECORE_MAGIC_WIN32_HANDLER))
847      {
848         ECORE_MAGIC_FAIL(win32_handler, ECORE_MAGIC_WIN32_HANDLER,
849                          "ecore_main_win32_handler_del");
850         return NULL;
851      }
852    win32_handler->delete_me = EINA_TRUE;
853    win32_handlers_delete_me = EINA_TRUE;
854    return win32_handler->data;
855 }
856 #else
857 EAPI void *
858 ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler __UNUSED__)
859 {
860    return NULL;
861 }
862 #endif
863
864 /**
865  * @brief Set the prepare callback with data for a given #Ecore_Fd_Handler
866  * @param fd_handler The fd handler
867  * @param func The prep function
868  * @param data The data to pass to the prep function
869  * This function will be called prior to the the fd handler's callback function.
870  */
871 EAPI void
872 ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Prep_Cb func, const void *data)
873 {
874    if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
875      {
876         ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
877                          "ecore_main_fd_handler_prepare_callback_set");
878         return;
879      }
880    fd_handler->prep_func = func;
881    fd_handler->prep_data = (void *)data;
882    if (fd_handlers_with_prep && (!eina_list_data_find(fd_handlers_with_prep, fd_handler)))
883      /* FIXME: THIS WILL NOT SCALE WITH LOTS OF PREP FUNCTIONS!!! */
884      fd_handlers_with_prep = eina_list_append(fd_handlers_with_prep, fd_handler);
885 }
886
887 /**
888  * Retrieves the file descriptor that the given handler is handling.
889  * @param   fd_handler The given FD handler.
890  * @return  The file descriptor the handler is watching.
891  * @ingroup Ecore_FD_Handler_Group
892  */
893 EAPI int
894 ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler)
895 {
896    if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
897      {
898         ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
899                          "ecore_main_fd_handler_fd_get");
900         return -1;
901      }
902    return fd_handler->fd;
903 }
904
905 /**
906  * Return if read, write or error, or a combination thereof, is active on the
907  * file descriptor of the given FD handler.
908  * @param   fd_handler The given FD handler.
909  * @param   flags      The flags, @c ECORE_FD_READ, @c ECORE_FD_WRITE or
910  *                     @c ECORE_FD_ERROR to query.
911  * @return  #EINA_TRUE if any of the given flags are active. #EINA_FALSE otherwise.
912  * @ingroup Ecore_FD_Handler_Group
913  */
914 EAPI Eina_Bool
915 ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags)
916 {
917    int ret = EINA_FALSE;
918
919    if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
920      {
921         ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
922                          "ecore_main_fd_handler_active_get");
923         return EINA_FALSE;
924      }
925    if ((flags & ECORE_FD_READ) && (fd_handler->read_active)) ret = EINA_TRUE;
926    if ((flags & ECORE_FD_WRITE) && (fd_handler->write_active)) ret = EINA_TRUE;
927    if ((flags & ECORE_FD_ERROR) && (fd_handler->error_active)) ret = EINA_TRUE;
928    return ret;
929 }
930
931 /**
932  * Set what active streams the given FD handler should be monitoring.
933  * @param   fd_handler The given FD handler.
934  * @param   flags      The flags to be watching.
935  * @ingroup Ecore_FD_Handler_Group
936  */
937 EAPI void
938 ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags)
939 {
940    if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
941      {
942         ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
943                          "ecore_main_fd_handler_active_set");
944         return;
945      }
946    fd_handler->flags = flags;
947    if (_ecore_main_fdh_poll_modify(fd_handler) < 0)
948      {
949         ERR("Failed to mod epoll fd %d!", fd_handler->fd);
950      }
951 }
952
953 /**
954  * @}
955  */
956
957 /**
958  * @}
959  */
960
961 void
962 _ecore_main_shutdown(void)
963 {
964    if (in_main_loop)
965      {
966        ERR("\n"
967            "*** ECORE WARINING: Calling ecore_shutdown() while still in the main loop.\n"
968            "***                 Program may crash or behave strangely now.");
969         return;
970      }
971    while (fd_handlers)
972      {
973         Ecore_Fd_Handler *fdh;
974
975         fdh = fd_handlers;
976         fd_handlers = (Ecore_Fd_Handler *) eina_inlist_remove(EINA_INLIST_GET(fd_handlers),
977                                                               EINA_INLIST_GET(fdh));
978         ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
979         free(fdh);
980      }
981    if (fd_handlers_with_buffer)
982      fd_handlers_with_buffer = eina_list_free(fd_handlers_with_buffer);
983    if (fd_handlers_with_prep)
984      fd_handlers_with_prep = eina_list_free(fd_handlers_with_prep);
985    if (fd_handlers_to_delete)
986      fd_handlers_to_delete = eina_list_free(fd_handlers_to_delete);
987    if (fd_handlers_to_call)
988      fd_handlers_to_call = eina_list_free(fd_handlers_to_call);
989   
990    fd_handlers_to_call_current = NULL;
991    fd_handlers_to_delete = NULL;
992    fd_handler_current = NULL;
993
994 #ifdef _WIN32
995    while (win32_handlers)
996      {
997         Ecore_Win32_Handler *wh;
998
999         wh = win32_handlers;
1000         win32_handlers = (Ecore_Win32_Handler *) eina_inlist_remove(EINA_INLIST_GET(win32_handlers),
1001                                                                     EINA_INLIST_GET(wh));
1002         ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE);
1003         free(wh);
1004      }
1005    win32_handlers_delete_me = EINA_FALSE;
1006    win32_handler_current = NULL;
1007 #endif
1008 }
1009
1010 static void
1011 _ecore_main_prepare_handlers(void)
1012 {
1013    Ecore_Fd_Handler *fdh;
1014    Eina_List *l, *l2;
1015
1016    /* call the prepare callback for all handlers with prep functions */
1017    EINA_LIST_FOREACH_SAFE(fd_handlers_with_prep, l, l2, fdh)
1018      {
1019         if (!fdh)
1020           {
1021              fd_handlers_with_prep = eina_list_remove_list(l, fd_handlers_with_prep);
1022              continue;
1023           }
1024         if (!fdh->delete_me && fdh->prep_func)
1025           {
1026              fdh->references++;
1027              fdh->prep_func(fdh->prep_data, fdh);
1028              fdh->references--;
1029           }
1030         else
1031           fd_handlers_with_prep = eina_list_remove_list(fd_handlers_with_prep, l);
1032      }
1033 }
1034
1035 static int
1036 _ecore_main_select(double timeout)
1037 {
1038    struct timeval tv, *t;
1039    fd_set         rfds, wfds, exfds;
1040    int            max_fd;
1041    int            ret;
1042
1043    t = NULL;
1044    if ((!finite(timeout)) || (timeout == 0.0)) /* finite() tests for NaN, too big, too small, and infinity.  */
1045      {
1046         tv.tv_sec = 0;
1047         tv.tv_usec = 0;
1048         t = &tv;
1049      }
1050    else if (timeout > 0.0)
1051      {
1052         int sec, usec;
1053
1054 #ifdef FIX_HZ
1055         timeout += (0.5 / HZ);
1056         sec = (int)timeout;
1057         usec = (int)((timeout - (double)sec) * 1000000);
1058 #else
1059         sec = (int)timeout;
1060         usec = (int)((timeout - (double)sec) * 1000000);
1061 #endif
1062         tv.tv_sec = sec;
1063         tv.tv_usec = usec;
1064         t = &tv;
1065      }
1066    max_fd = 0;
1067    FD_ZERO(&rfds);
1068    FD_ZERO(&wfds);
1069    FD_ZERO(&exfds);
1070
1071    /* call the prepare callback for all handlers */
1072    if (fd_handlers_with_prep)
1073      _ecore_main_prepare_handlers();
1074 #ifndef HAVE_EPOLL
1075    Ecore_Fd_Handler *fdh;
1076
1077    EINA_INLIST_FOREACH(fd_handlers, fdh)
1078      {
1079         if (!fdh->delete_me)
1080           {
1081              if (fdh->flags & ECORE_FD_READ)
1082                {
1083                   FD_SET(fdh->fd, &rfds);
1084                   if (fdh->fd > max_fd) max_fd = fdh->fd;
1085                }
1086              if (fdh->flags & ECORE_FD_WRITE)
1087                {
1088                   FD_SET(fdh->fd, &wfds);
1089                   if (fdh->fd > max_fd) max_fd = fdh->fd;
1090                }
1091              if (fdh->flags & ECORE_FD_ERROR)
1092                {
1093                   FD_SET(fdh->fd, &exfds);
1094                   if (fdh->fd > max_fd) max_fd = fdh->fd;
1095                }
1096           }
1097      }
1098 #else /* HAVE_EPOLL */
1099    /* polling on the epoll fd will wake when an fd in the epoll set is active */
1100    max_fd = _ecore_get_epoll_fd();
1101    FD_SET(max_fd, &rfds);
1102 #endif /* HAVE_EPOLL */
1103
1104    if (_ecore_signal_count_get()) return -1;
1105
1106    ret = main_loop_select(max_fd + 1, &rfds, &wfds, &exfds, t);
1107
1108    _ecore_time_loop_time = ecore_time_get();
1109    if (ret < 0)
1110      {
1111 #ifndef _WIN32
1112         if (errno == EINTR) return -1;
1113         else if (errno == EBADF) _ecore_main_fd_handlers_bads_rem();
1114 #endif
1115      }
1116    if (ret > 0)
1117      {
1118 #ifdef HAVE_EPOLL
1119         _ecore_main_fdh_poll_mark_active();
1120 #else /* HAVE_EPOLL */
1121         Ecore_Fd_Handler *fdh;
1122
1123         EINA_INLIST_FOREACH(fd_handlers, fdh)
1124           {
1125              if (!fdh->delete_me)
1126                {
1127                   Eina_Bool pst, st;
1128                   pst = st = fdh->read_active | fdh->write_active | fdh->error_active;
1129                   if ((FD_ISSET(fdh->fd, &rfds)) && (!fdh->read_active))
1130                    st = fdh->read_active = EINA_TRUE;
1131                   if ((FD_ISSET(fdh->fd, &wfds)) && (!fdh->write_active))
1132                    st = fdh->write_active = EINA_TRUE;
1133                   if ((FD_ISSET(fdh->fd, &exfds)) && (!fdh->error_active))
1134                    st = fdh->error_active = EINA_TRUE;
1135                   if (pst != st)
1136                     fd_handlers_to_call = eina_list_append(fd_handlers_to_call, fdh);
1137                }
1138           }
1139 #endif /* HAVE_EPOLL */
1140         _ecore_main_fd_handlers_cleanup();
1141 #ifdef _WIN32
1142         _ecore_main_win32_handlers_cleanup();
1143 #endif
1144         return 1;
1145      }
1146    return 0;
1147 }
1148
1149 #ifndef _WIN32
1150 static void
1151 _ecore_main_fd_handlers_bads_rem(void)
1152 {
1153    Ecore_Fd_Handler *fdh;
1154    Eina_Inlist *l;
1155    int found = 0;
1156
1157    ERR("Removing bad fds");
1158    for (l = EINA_INLIST_GET(fd_handlers); l; )
1159      {
1160         fdh = (Ecore_Fd_Handler *) l;
1161         l = l->next;
1162         errno = 0;
1163
1164         if ((fcntl(fdh->fd, F_GETFD) < 0) && (errno == EBADF))
1165           {
1166              ERR("Found bad fd at index %d", fdh->fd);
1167              if (fdh->flags & ECORE_FD_ERROR)
1168                {
1169                   ERR("Fd set for error! calling user");
1170                   fdh->references++;
1171                   if (!fdh->func(fdh->data, fdh))
1172                     {
1173                        ERR("Fd function err returned 0, remove it");
1174                        if (!fdh->delete_me)
1175                          {
1176                             fdh->delete_me = EINA_TRUE;
1177                             fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh);
1178                          }
1179                        found++;
1180                     }
1181                   fdh->references--;
1182                }
1183              else
1184                {
1185                   ERR("Problematic fd found at %d! setting it for delete", fdh->fd);
1186                   if (!fdh->delete_me)
1187                     {
1188                        fdh->delete_me = EINA_TRUE;
1189                        fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh);
1190                     }
1191
1192                   found++;
1193                }
1194           }
1195     }
1196    if (found == 0)
1197      {
1198 # ifdef HAVE_GLIB
1199         ERR("No bad fd found. Maybe a foreign fd from glib?");
1200 # else        
1201         ERR("No bad fd found. EEEK!");
1202 # endif        
1203      }
1204    _ecore_main_fd_handlers_cleanup();
1205 }
1206 #endif
1207
1208 static void
1209 _ecore_main_fd_handlers_cleanup(void)
1210 {
1211    Ecore_Fd_Handler *fdh;
1212    Eina_List *l, *l2;
1213
1214    if (!fd_handlers_to_delete) return;
1215    EINA_LIST_FOREACH_SAFE(fd_handlers_to_delete, l, l2, fdh)
1216      {
1217         if (!fdh)
1218           {
1219              fd_handlers_to_delete = eina_list_remove_list(l, fd_handlers_to_delete);
1220              continue;
1221           }
1222         /* fdh->delete_me should be set for all fdhs at the start of the list */
1223         if (fdh->references)
1224           continue;
1225         if (fdh->buf_func && fd_handlers_with_buffer)
1226           fd_handlers_with_buffer = eina_list_remove(fd_handlers_with_buffer, fdh);
1227         if (fdh->prep_func && fd_handlers_with_prep)
1228           fd_handlers_with_prep = eina_list_remove(fd_handlers_with_prep, fdh);
1229         fd_handlers = (Ecore_Fd_Handler *)
1230                       eina_inlist_remove(EINA_INLIST_GET(fd_handlers), EINA_INLIST_GET(fdh));
1231         ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
1232         free(fdh);
1233         fd_handlers_to_delete = eina_list_remove_list(fd_handlers_to_delete, l);
1234      }
1235 }
1236
1237 #ifdef _WIN32
1238 static void
1239 _ecore_main_win32_handlers_cleanup(void)
1240 {
1241    Ecore_Win32_Handler *wh;
1242    Eina_Inlist *l;
1243    int deleted_in_use = 0;
1244
1245    if (!win32_handlers_delete_me) return;
1246    for (l = EINA_INLIST_GET(win32_handlers); l; )
1247      {
1248         wh = (Ecore_Win32_Handler *)l;
1249
1250         l = l->next;
1251         if (wh->delete_me)
1252           {
1253              if (wh->references)
1254                {
1255                   deleted_in_use++;
1256                   continue;
1257                }
1258              
1259              win32_handlers = (Ecore_Win32_Handler *)
1260                 eina_inlist_remove(EINA_INLIST_GET(win32_handlers),
1261                                    EINA_INLIST_GET(wh));
1262              ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE);
1263              free(wh);
1264           }
1265      }
1266    if (!deleted_in_use) win32_handlers_delete_me = EINA_FALSE;
1267 }
1268 #endif
1269
1270 static void
1271 _ecore_main_fd_handlers_call(void)
1272 {
1273    if (!fd_handlers_to_call_current)
1274      {
1275         /* regular main loop, start from head */
1276         fd_handlers_to_call_current = fd_handlers_to_call;
1277         fd_handlers_to_call_current_next = eina_list_next(fd_handlers_to_call_current);
1278      }
1279    else
1280      {
1281         /* recursive main loop, continue from where we were */
1282         fd_handlers_to_call_current = fd_handlers_to_call_current_next;
1283         fd_handlers_to_call_current_next = eina_list_next(fd_handlers_to_call_current);
1284      }
1285
1286    while (fd_handlers_to_call_current)
1287      {
1288         Ecore_Fd_Handler *fdh = fd_handlers_to_call_current->data;
1289
1290         if (!fdh->delete_me)
1291           {
1292              if ((fdh->read_active) ||
1293                  (fdh->write_active) ||
1294                  (fdh->error_active))
1295                {
1296                   fdh->references++;
1297                   if (!fdh->func(fdh->data, fdh))
1298                     {
1299                        if (!fdh->delete_me)
1300                          {
1301                             fdh->delete_me = EINA_TRUE;
1302                             fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh);
1303                          }
1304
1305                     }
1306                   fdh->references--;
1307
1308                   fdh->read_active = EINA_FALSE;
1309                   fdh->write_active = EINA_FALSE;
1310                   fdh->error_active = EINA_FALSE;
1311                }
1312           }
1313
1314         fd_handlers_to_call = eina_list_remove_list(fd_handlers_to_call, fd_handlers_to_call_current);
1315         fd_handlers_to_call_current = fd_handlers_to_call_current_next;
1316         fd_handlers_to_call_current_next = eina_list_next(fd_handlers_to_call_current_next);
1317      }
1318 }
1319
1320 static int
1321 _ecore_main_fd_handlers_buf_call(void)
1322 {
1323    Ecore_Fd_Handler *fdh;
1324    Eina_List *l, *l2;
1325    int ret;
1326
1327    ret = 0;
1328    EINA_LIST_FOREACH_SAFE(fd_handlers_with_buffer, l, l2, fdh)
1329      {
1330         if (!fdh)
1331           {
1332              fd_handlers_with_buffer = eina_list_remove_list(l, fd_handlers_with_buffer);
1333              continue;
1334           }
1335         if ((!fdh->delete_me) && fdh->buf_func)
1336           {
1337              fdh->references++;
1338              if (fdh->buf_func(fdh->buf_data, fdh))
1339                {
1340                   ret |= fdh->func(fdh->data, fdh);
1341                   if (!fdh->read_active)
1342                     {
1343                        fdh->read_active = EINA_TRUE;
1344                        if ((!fdh->write_active) && (!fdh->error_active))
1345                          fd_handlers_to_call = eina_list_append(fd_handlers_to_call, fdh);
1346                     }
1347                }
1348              fdh->references--;
1349           }
1350         else
1351           fd_handlers_with_buffer = eina_list_remove_list(fd_handlers_with_buffer, l);
1352      }
1353    return ret;
1354 }
1355
1356 #ifndef USE_G_MAIN_LOOP
1357 static void
1358 _ecore_main_loop_iterate_internal(int once_only)
1359 {
1360    double next_time = -1.0;
1361    int    have_event = 0;
1362    int    have_signal;
1363
1364    in_main_loop++;
1365    /* expire any timers */
1366    while (_ecore_timer_call(_ecore_time_loop_time));
1367    _ecore_timer_cleanup();
1368
1369    /* process signals into events .... */
1370    while (_ecore_signal_count_get()) _ecore_signal_call();
1371    if (_ecore_event_exist())
1372      {
1373         _ecore_idle_enterer_call();
1374         have_event = 1;
1375         _ecore_main_select(0.0);
1376         _ecore_time_loop_time = ecore_time_get();
1377         _ecore_timer_enable_new();
1378         goto process_events;
1379      }
1380    /* call idle enterers ... */
1381    if (!once_only) _ecore_idle_enterer_call();
1382    else
1383      {
1384         have_event = have_signal = 0;
1385
1386         if (_ecore_main_select(0.0) > 0) have_event = 1;
1387         if (_ecore_signal_count_get() > 0) have_signal = 1;
1388         if (have_signal || have_event)
1389           {
1390              _ecore_time_loop_time = ecore_time_get();
1391              _ecore_timer_enable_new();
1392              goto process_events;
1393           }
1394      }
1395
1396    /* if these calls caused any buffered events to appear - deal with them */
1397    if (fd_handlers_with_buffer)
1398      _ecore_main_fd_handlers_buf_call();
1399
1400    /* if there are any - jump to processing them */
1401    if (_ecore_event_exist())
1402      {
1403         have_event = 1;
1404         _ecore_main_select(0.0);
1405         _ecore_time_loop_time = ecore_time_get();
1406         _ecore_timer_enable_new();
1407         goto process_events;
1408      }
1409    if (once_only)
1410      {
1411         _ecore_idle_enterer_call();
1412         in_main_loop--;
1413         _ecore_time_loop_time = ecore_time_get();
1414         _ecore_timer_enable_new();
1415         return;
1416      }
1417
1418    if (_ecore_fps_debug)
1419      {
1420         t2 = ecore_time_get();
1421         if ((t1 > 0.0) && (t2 > 0.0))
1422            _ecore_fps_debug_runtime_add(t2 - t1);
1423      }
1424    start_loop:
1425    /* any timers re-added as a result of these are allowed to go */
1426    _ecore_timer_enable_new();
1427    if (do_quit)
1428      {
1429         _ecore_time_loop_time = ecore_time_get();
1430         in_main_loop--;
1431         _ecore_timer_enable_new();
1432         return;
1433      }
1434    if (!_ecore_event_exist())
1435      {
1436         /* init flags */
1437         have_event = have_signal = 0;
1438         next_time = _ecore_timer_next_get();
1439         /* no timers */
1440         if (next_time < 0)
1441           {
1442              /* no idlers */
1443              if (!_ecore_idler_exist())
1444                {
1445                   if (_ecore_main_select(-1.0) > 0) have_event = 1;
1446                }
1447              /* idlers */
1448              else
1449                {
1450                   for (;;)
1451                     {
1452                        if (!_ecore_idler_call()) goto start_loop;
1453                        if (_ecore_event_exist()) break;
1454                        if (_ecore_main_select(0.0) > 0) have_event = 1;
1455                        if (_ecore_signal_count_get() > 0) have_signal = 1;
1456                        if (have_event || have_signal) break;
1457                        if (_ecore_timers_exists()) goto start_loop;
1458                        if (do_quit) break;
1459                     }
1460                }
1461           }
1462         /* timers */
1463         else
1464           {
1465              /* no idlers */
1466              if (!_ecore_idler_exist())
1467                {
1468                   if (_ecore_main_select(next_time) > 0) have_event = 1;
1469                }
1470              /* idlers */
1471              else
1472                {
1473                   for (;;)
1474                     {
1475                        if (!_ecore_idler_call()) goto start_loop;
1476                        if (_ecore_event_exist()) break;
1477                        if (_ecore_main_select(0.0) > 0) have_event = 1;
1478                        if (_ecore_signal_count_get() > 0) have_signal = 1;
1479                        if (have_event || have_signal) break;
1480                        next_time = _ecore_timer_next_get();
1481                        if (next_time <= 0) break;
1482                        if (do_quit) break;
1483                     }
1484                }
1485           }
1486         _ecore_time_loop_time = ecore_time_get();
1487      }
1488    if (_ecore_fps_debug) t1 = ecore_time_get();
1489    /* we came out of our "wait state" so idle has exited */
1490    if (!once_only) _ecore_idle_exiter_call();
1491    /* call the fd handler per fd that became alive... */
1492    /* this should read or write any data to the monitored fd and then */
1493    /* post events onto the ecore event pipe if necessary */
1494    process_events:
1495    _ecore_main_fd_handlers_call();
1496    if (fd_handlers_with_buffer)
1497      _ecore_main_fd_handlers_buf_call();
1498    /* process signals into events .... */
1499    while (_ecore_signal_count_get()) _ecore_signal_call();
1500    /* handle events ... */
1501    _ecore_event_call();
1502    _ecore_main_fd_handlers_cleanup();
1503
1504    if (once_only) _ecore_idle_enterer_call();
1505    in_main_loop--;
1506 }
1507 #endif
1508
1509 #ifdef _WIN32
1510 static int
1511 _ecore_main_win32_select(int nfds __UNUSED__, fd_set *readfds, fd_set *writefds,
1512                          fd_set *exceptfds, struct timeval *tv)
1513 {
1514    HANDLE       objects[MAXIMUM_WAIT_OBJECTS];
1515    int          sockets[MAXIMUM_WAIT_OBJECTS];
1516    Ecore_Fd_Handler *fdh;
1517    Ecore_Win32_Handler *wh;
1518    unsigned int objects_nbr = 0;
1519    unsigned int handles_nbr = 0;
1520    unsigned int events_nbr = 0;
1521    DWORD        result;
1522    DWORD        timeout;
1523    MSG          msg;
1524    unsigned int i;
1525    int          res;
1526
1527    /* Create an event object per socket */
1528    EINA_INLIST_FOREACH(fd_handlers, fdh)
1529      {
1530         WSAEVENT event;
1531         long network_event;
1532
1533         network_event = 0;
1534         if (FD_ISSET(fdh->fd, readfds))
1535           network_event |= FD_READ;
1536         if (FD_ISSET(fdh->fd, writefds))
1537           network_event |= FD_WRITE;
1538         if (FD_ISSET(fdh->fd, exceptfds))
1539           network_event |= FD_OOB;
1540
1541         if (network_event)
1542           {
1543              event = WSACreateEvent();
1544              WSAEventSelect(fdh->fd, event, network_event);
1545              objects[objects_nbr] = event;
1546              sockets[events_nbr] = fdh->fd;
1547              events_nbr++;
1548              objects_nbr++;
1549           }
1550      }
1551
1552    /* store the HANDLEs in the objects to wait for */
1553    EINA_INLIST_FOREACH(win32_handlers, wh)
1554      {
1555         objects[objects_nbr] = wh->h;
1556         handles_nbr++;
1557         objects_nbr++;
1558      }
1559
1560    /* Empty the queue before waiting */
1561    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
1562      {
1563         TranslateMessage(&msg);
1564         DispatchMessage(&msg);
1565      }
1566
1567    /* Wait for any message sent or posted to this queue */
1568    /* or for one of the passed handles be set to signaled. */
1569    if (!tv)
1570      timeout = INFINITE;
1571    else
1572      timeout = (DWORD)((tv->tv_sec * 1000.0) + (tv->tv_usec / 1000.0));
1573
1574    if (timeout == 0) return 0;
1575
1576    result = MsgWaitForMultipleObjects(objects_nbr, (const HANDLE *)objects, EINA_FALSE,
1577                                       timeout, QS_ALLINPUT);
1578
1579    FD_ZERO(readfds);
1580    FD_ZERO(writefds);
1581    FD_ZERO(exceptfds);
1582
1583    /* The result tells us the type of event we have. */
1584    if (result == WAIT_FAILED)
1585      {
1586         char *msg;
1587
1588         msg = evil_last_error_get();
1589         ERR(" * %s\n", msg);
1590         free(msg);
1591         res = -1;
1592      }
1593    else if (result == WAIT_TIMEOUT)
1594      {
1595         /* ERR("time out\n"); */
1596         res = 0;
1597      }
1598    else if (result == (WAIT_OBJECT_0 + objects_nbr))
1599      {
1600         while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
1601           {
1602              TranslateMessage(&msg);
1603              DispatchMessage(&msg);
1604           }
1605
1606         res = 0;
1607      }
1608    else if ((result >= 0) && (result < WAIT_OBJECT_0 + events_nbr))
1609      {
1610         WSANETWORKEVENTS network_event;
1611
1612         WSAEnumNetworkEvents(sockets[result], objects[result], &network_event);
1613         
1614         if (network_event.lNetworkEvents & FD_READ)
1615            FD_SET(sockets[result], readfds);
1616         if (network_event.lNetworkEvents & FD_WRITE)
1617            FD_SET(sockets[result], writefds);
1618         if (network_event.lNetworkEvents & FD_OOB)
1619            FD_SET(sockets[result], exceptfds);
1620         
1621         res = 1;
1622      }
1623    else if ((result >= (WAIT_OBJECT_0 + events_nbr)) && 
1624             (result < (WAIT_OBJECT_0 + objects_nbr)))
1625      {
1626         if (!win32_handler_current)
1627           {
1628              /* regular main loop, start from head */
1629              win32_handler_current = win32_handlers;
1630           }
1631         else
1632           {
1633              /* recursive main loop, continue from where we were */
1634              win32_handler_current = (Ecore_Win32_Handler *)EINA_INLIST_GET(win32_handler_current)->next;
1635           }
1636
1637         while (win32_handler_current)
1638           {
1639              wh = win32_handler_current;
1640              
1641              if (objects[result - WAIT_OBJECT_0] == wh->h)
1642                {
1643                   if (!wh->delete_me)
1644                     {
1645                        wh->references++;
1646                        if (!wh->func(wh->data, wh))
1647                          {
1648                             wh->delete_me = EINA_TRUE;
1649                             win32_handlers_delete_me = EINA_TRUE;
1650                          }
1651                        wh->references--;
1652                     }
1653                }
1654              if (win32_handler_current) /* may have changed in recursive main loops */
1655                win32_handler_current = (Ecore_Win32_Handler *)EINA_INLIST_GET(win32_handler_current)->next;
1656           }
1657         res = 1;
1658      }
1659    else
1660      {
1661         ERR("unknown result...\n");
1662         res = -1;
1663      }
1664
1665    /* Remove event objects again */
1666    for (i = 0; i < events_nbr; i++) WSACloseEvent(objects[i]);
1667
1668    return res;
1669 }
1670 #endif