08bedb2ba3c91ba9b70e92c50dc53568361b8052
[framework/uifw/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 #ifndef HAVE_EPOLL
1043    Ecore_Fd_Handler *fdh;
1044 #endif
1045
1046    t = NULL;
1047    if ((!finite(timeout)) || (timeout == 0.0)) /* finite() tests for NaN, too big, too small, and infinity.  */
1048      {
1049         tv.tv_sec = 0;
1050         tv.tv_usec = 0;
1051         t = &tv;
1052      }
1053    else if (timeout > 0.0)
1054      {
1055         int sec, usec;
1056
1057 #ifdef FIX_HZ
1058         timeout += (0.5 / HZ);
1059         sec = (int)timeout;
1060         usec = (int)((timeout - (double)sec) * 1000000);
1061 #else
1062         sec = (int)timeout;
1063         usec = (int)((timeout - (double)sec) * 1000000);
1064 #endif
1065         tv.tv_sec = sec;
1066         tv.tv_usec = usec;
1067         t = &tv;
1068      }
1069    max_fd = 0;
1070    FD_ZERO(&rfds);
1071    FD_ZERO(&wfds);
1072    FD_ZERO(&exfds);
1073
1074    /* call the prepare callback for all handlers */
1075    if (fd_handlers_with_prep)
1076      _ecore_main_prepare_handlers();
1077 #ifndef HAVE_EPOLL
1078    EINA_INLIST_FOREACH(fd_handlers, fdh)
1079      {
1080         if (!fdh->delete_me)
1081           {
1082              if (fdh->flags & ECORE_FD_READ)
1083                {
1084                   FD_SET(fdh->fd, &rfds);
1085                   if (fdh->fd > max_fd) max_fd = fdh->fd;
1086                }
1087              if (fdh->flags & ECORE_FD_WRITE)
1088                {
1089                   FD_SET(fdh->fd, &wfds);
1090                   if (fdh->fd > max_fd) max_fd = fdh->fd;
1091                }
1092              if (fdh->flags & ECORE_FD_ERROR)
1093                {
1094                   FD_SET(fdh->fd, &exfds);
1095                   if (fdh->fd > max_fd) max_fd = fdh->fd;
1096                }
1097           }
1098      }
1099 #else /* HAVE_EPOLL */
1100    /* polling on the epoll fd will wake when an fd in the epoll set is active */
1101    max_fd = _ecore_get_epoll_fd();
1102    FD_SET(max_fd, &rfds);
1103 #endif /* HAVE_EPOLL */
1104
1105    if (_ecore_signal_count_get()) return -1;
1106
1107    ret = main_loop_select(max_fd + 1, &rfds, &wfds, &exfds, t);
1108
1109    _ecore_time_loop_time = ecore_time_get();
1110    if (ret < 0)
1111      {
1112 #ifndef _WIN32
1113         if (errno == EINTR) return -1;
1114         else if (errno == EBADF) _ecore_main_fd_handlers_bads_rem();
1115 #endif
1116      }
1117    if (ret > 0)
1118      {
1119 #ifdef HAVE_EPOLL
1120         _ecore_main_fdh_poll_mark_active();
1121 #else /* HAVE_EPOLL */
1122         Ecore_Fd_Handler *fdh;
1123
1124         EINA_INLIST_FOREACH(fd_handlers, fdh)
1125           {
1126              if (!fdh->delete_me)
1127                {
1128                   Eina_Bool pst, st;
1129                   pst = st = fdh->read_active | fdh->write_active | fdh->error_active;
1130                   if ((FD_ISSET(fdh->fd, &rfds)) && (!fdh->read_active))
1131                    st = fdh->read_active = EINA_TRUE;
1132                   if ((FD_ISSET(fdh->fd, &wfds)) && (!fdh->write_active))
1133                    st = fdh->write_active = EINA_TRUE;
1134                   if ((FD_ISSET(fdh->fd, &exfds)) && (!fdh->error_active))
1135                    st = fdh->error_active = EINA_TRUE;
1136                   if (pst != st)
1137                     fd_handlers_to_call = eina_list_append(fd_handlers_to_call, fdh);
1138                }
1139           }
1140 #endif /* HAVE_EPOLL */
1141         _ecore_main_fd_handlers_cleanup();
1142 #ifdef _WIN32
1143         _ecore_main_win32_handlers_cleanup();
1144 #endif
1145         return 1;
1146      }
1147    return 0;
1148 }
1149
1150 #ifndef _WIN32
1151 static void
1152 _ecore_main_fd_handlers_bads_rem(void)
1153 {
1154    Ecore_Fd_Handler *fdh;
1155    Eina_Inlist *l;
1156    int found = 0;
1157
1158    ERR("Removing bad fds");
1159    for (l = EINA_INLIST_GET(fd_handlers); l; )
1160      {
1161         fdh = (Ecore_Fd_Handler *) l;
1162         l = l->next;
1163         errno = 0;
1164
1165         if ((fcntl(fdh->fd, F_GETFD) < 0) && (errno == EBADF))
1166           {
1167              ERR("Found bad fd at index %d", fdh->fd);
1168              if (fdh->flags & ECORE_FD_ERROR)
1169                {
1170                   ERR("Fd set for error! calling user");
1171                   fdh->references++;
1172                   if (!fdh->func(fdh->data, fdh))
1173                     {
1174                        ERR("Fd function err returned 0, remove it");
1175                        if (!fdh->delete_me)
1176                          {
1177                             fdh->delete_me = EINA_TRUE;
1178                             fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh);
1179                          }
1180                        found++;
1181                     }
1182                   fdh->references--;
1183                }
1184              else
1185                {
1186                   ERR("Problematic fd found at %d! setting it for delete", fdh->fd);
1187                   if (!fdh->delete_me)
1188                     {
1189                        fdh->delete_me = EINA_TRUE;
1190                        fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh);
1191                     }
1192
1193                   found++;
1194                }
1195           }
1196     }
1197    if (found == 0)
1198      {
1199 # ifdef HAVE_GLIB
1200         ERR("No bad fd found. Maybe a foreign fd from glib?");
1201 # else        
1202         ERR("No bad fd found. EEEK!");
1203 # endif        
1204      }
1205    _ecore_main_fd_handlers_cleanup();
1206 }
1207 #endif
1208
1209 static void
1210 _ecore_main_fd_handlers_cleanup(void)
1211 {
1212    Ecore_Fd_Handler *fdh;
1213    Eina_List *l, *l2;
1214
1215    if (!fd_handlers_to_delete) return;
1216    EINA_LIST_FOREACH_SAFE(fd_handlers_to_delete, l, l2, fdh)
1217      {
1218         if (!fdh)
1219           {
1220              fd_handlers_to_delete = eina_list_remove_list(l, fd_handlers_to_delete);
1221              continue;
1222           }
1223         /* fdh->delete_me should be set for all fdhs at the start of the list */
1224         if (fdh->references)
1225           continue;
1226         if (fdh->buf_func && fd_handlers_with_buffer)
1227           fd_handlers_with_buffer = eina_list_remove(fd_handlers_with_buffer, fdh);
1228         if (fdh->prep_func && fd_handlers_with_prep)
1229           fd_handlers_with_prep = eina_list_remove(fd_handlers_with_prep, fdh);
1230         fd_handlers = (Ecore_Fd_Handler *)
1231                       eina_inlist_remove(EINA_INLIST_GET(fd_handlers), EINA_INLIST_GET(fdh));
1232         ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
1233         free(fdh);
1234         fd_handlers_to_delete = eina_list_remove_list(fd_handlers_to_delete, l);
1235      }
1236 }
1237
1238 #ifdef _WIN32
1239 static void
1240 _ecore_main_win32_handlers_cleanup(void)
1241 {
1242    Ecore_Win32_Handler *wh;
1243    Eina_Inlist *l;
1244    int deleted_in_use = 0;
1245
1246    if (!win32_handlers_delete_me) return;
1247    for (l = EINA_INLIST_GET(win32_handlers); l; )
1248      {
1249         wh = (Ecore_Win32_Handler *)l;
1250
1251         l = l->next;
1252         if (wh->delete_me)
1253           {
1254              if (wh->references)
1255                {
1256                   deleted_in_use++;
1257                   continue;
1258                }
1259              
1260              win32_handlers = (Ecore_Win32_Handler *)
1261                 eina_inlist_remove(EINA_INLIST_GET(win32_handlers),
1262                                    EINA_INLIST_GET(wh));
1263              ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE);
1264              free(wh);
1265           }
1266      }
1267    if (!deleted_in_use) win32_handlers_delete_me = EINA_FALSE;
1268 }
1269 #endif
1270
1271 static void
1272 _ecore_main_fd_handlers_call(void)
1273 {
1274    if (!fd_handlers_to_call_current)
1275      {
1276         /* regular main loop, start from head */
1277         fd_handlers_to_call_current = fd_handlers_to_call;
1278         fd_handlers_to_call_current_next = eina_list_next(fd_handlers_to_call_current);
1279      }
1280    else
1281      {
1282         /* recursive main loop, continue from where we were */
1283         fd_handlers_to_call_current = fd_handlers_to_call_current_next;
1284         fd_handlers_to_call_current_next = eina_list_next(fd_handlers_to_call_current);
1285      }
1286
1287    while (fd_handlers_to_call_current)
1288      {
1289         Ecore_Fd_Handler *fdh = fd_handlers_to_call_current->data;
1290
1291         if (!fdh->delete_me)
1292           {
1293              if ((fdh->read_active) ||
1294                  (fdh->write_active) ||
1295                  (fdh->error_active))
1296                {
1297                   fdh->references++;
1298                   if (!fdh->func(fdh->data, fdh))
1299                     {
1300                        if (!fdh->delete_me)
1301                          {
1302                             fdh->delete_me = EINA_TRUE;
1303                             fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh);
1304                          }
1305
1306                     }
1307                   fdh->references--;
1308
1309                   fdh->read_active = EINA_FALSE;
1310                   fdh->write_active = EINA_FALSE;
1311                   fdh->error_active = EINA_FALSE;
1312                }
1313           }
1314
1315         fd_handlers_to_call = eina_list_remove_list(fd_handlers_to_call, fd_handlers_to_call_current);
1316         fd_handlers_to_call_current = fd_handlers_to_call_current_next;
1317         fd_handlers_to_call_current_next = eina_list_next(fd_handlers_to_call_current_next);
1318      }
1319 }
1320
1321 static int
1322 _ecore_main_fd_handlers_buf_call(void)
1323 {
1324    Ecore_Fd_Handler *fdh;
1325    Eina_List *l, *l2;
1326    int ret;
1327
1328    ret = 0;
1329    EINA_LIST_FOREACH_SAFE(fd_handlers_with_buffer, l, l2, fdh)
1330      {
1331         if (!fdh)
1332           {
1333              fd_handlers_with_buffer = eina_list_remove_list(l, fd_handlers_with_buffer);
1334              continue;
1335           }
1336         if ((!fdh->delete_me) && fdh->buf_func)
1337           {
1338              fdh->references++;
1339              if (fdh->buf_func(fdh->buf_data, fdh))
1340                {
1341                   ret |= fdh->func(fdh->data, fdh);
1342                   if (!fdh->read_active)
1343                     {
1344                        fdh->read_active = EINA_TRUE;
1345                        if ((!fdh->write_active) && (!fdh->error_active))
1346                          fd_handlers_to_call = eina_list_append(fd_handlers_to_call, fdh);
1347                     }
1348                }
1349              fdh->references--;
1350           }
1351         else
1352           fd_handlers_with_buffer = eina_list_remove_list(fd_handlers_with_buffer, l);
1353      }
1354    return ret;
1355 }
1356
1357 #ifndef USE_G_MAIN_LOOP
1358 static void
1359 _ecore_main_loop_iterate_internal(int once_only)
1360 {
1361    double next_time = -1.0;
1362    int    have_event = 0;
1363    int    have_signal;
1364
1365    in_main_loop++;
1366    /* expire any timers */
1367    while (_ecore_timer_call(_ecore_time_loop_time));
1368    _ecore_timer_cleanup();
1369
1370    /* process signals into events .... */
1371    while (_ecore_signal_count_get()) _ecore_signal_call();
1372    if (_ecore_event_exist())
1373      {
1374         _ecore_idle_enterer_call();
1375         have_event = 1;
1376         _ecore_main_select(0.0);
1377         _ecore_time_loop_time = ecore_time_get();
1378         _ecore_timer_enable_new();
1379         goto process_events;
1380      }
1381    /* call idle enterers ... */
1382    if (!once_only) _ecore_idle_enterer_call();
1383    else
1384      {
1385         have_event = have_signal = 0;
1386
1387         if (_ecore_main_select(0.0) > 0) have_event = 1;
1388         if (_ecore_signal_count_get() > 0) have_signal = 1;
1389         if (have_signal || have_event)
1390           {
1391              _ecore_time_loop_time = ecore_time_get();
1392              _ecore_timer_enable_new();
1393              goto process_events;
1394           }
1395      }
1396
1397    /* if these calls caused any buffered events to appear - deal with them */
1398    if (fd_handlers_with_buffer)
1399      _ecore_main_fd_handlers_buf_call();
1400
1401    /* if there are any - jump to processing them */
1402    if (_ecore_event_exist())
1403      {
1404         have_event = 1;
1405         _ecore_main_select(0.0);
1406         _ecore_time_loop_time = ecore_time_get();
1407         _ecore_timer_enable_new();
1408         goto process_events;
1409      }
1410    if (once_only)
1411      {
1412         _ecore_idle_enterer_call();
1413         in_main_loop--;
1414         _ecore_time_loop_time = ecore_time_get();
1415         _ecore_timer_enable_new();
1416         return;
1417      }
1418
1419    if (_ecore_fps_debug)
1420      {
1421         t2 = ecore_time_get();
1422         if ((t1 > 0.0) && (t2 > 0.0))
1423            _ecore_fps_debug_runtime_add(t2 - t1);
1424      }
1425    start_loop:
1426    /* any timers re-added as a result of these are allowed to go */
1427    _ecore_timer_enable_new();
1428    if (do_quit)
1429      {
1430         _ecore_time_loop_time = ecore_time_get();
1431         in_main_loop--;
1432         _ecore_timer_enable_new();
1433         return;
1434      }
1435    if (!_ecore_event_exist())
1436      {
1437         /* init flags */
1438         have_event = have_signal = 0;
1439         next_time = _ecore_timer_next_get();
1440         /* no timers */
1441         if (next_time < 0)
1442           {
1443              /* no idlers */
1444              if (!_ecore_idler_exist())
1445                {
1446                   if (_ecore_main_select(-1.0) > 0) have_event = 1;
1447                }
1448              /* idlers */
1449              else
1450                {
1451                   for (;;)
1452                     {
1453                        if (!_ecore_idler_call()) goto start_loop;
1454                        if (_ecore_event_exist()) break;
1455                        if (_ecore_main_select(0.0) > 0) have_event = 1;
1456                        if (_ecore_signal_count_get() > 0) have_signal = 1;
1457                        if (have_event || have_signal) break;
1458                        if (_ecore_timers_exists()) goto start_loop;
1459                        if (do_quit) break;
1460                     }
1461                }
1462           }
1463         /* timers */
1464         else
1465           {
1466              /* no idlers */
1467              if (!_ecore_idler_exist())
1468                {
1469                   if (_ecore_main_select(next_time) > 0) have_event = 1;
1470                }
1471              /* idlers */
1472              else
1473                {
1474                   for (;;)
1475                     {
1476                        if (!_ecore_idler_call()) goto start_loop;
1477                        if (_ecore_event_exist()) break;
1478                        if (_ecore_main_select(0.0) > 0) have_event = 1;
1479                        if (_ecore_signal_count_get() > 0) have_signal = 1;
1480                        if (have_event || have_signal) break;
1481                        next_time = _ecore_timer_next_get();
1482                        if (next_time <= 0) break;
1483                        if (do_quit) break;
1484                     }
1485                }
1486           }
1487         _ecore_time_loop_time = ecore_time_get();
1488      }
1489    if (_ecore_fps_debug) t1 = ecore_time_get();
1490    /* we came out of our "wait state" so idle has exited */
1491    if (!once_only) _ecore_idle_exiter_call();
1492    /* call the fd handler per fd that became alive... */
1493    /* this should read or write any data to the monitored fd and then */
1494    /* post events onto the ecore event pipe if necessary */
1495    process_events:
1496    _ecore_main_fd_handlers_call();
1497    if (fd_handlers_with_buffer)
1498      _ecore_main_fd_handlers_buf_call();
1499    /* process signals into events .... */
1500    while (_ecore_signal_count_get()) _ecore_signal_call();
1501    /* handle events ... */
1502    _ecore_event_call();
1503    _ecore_main_fd_handlers_cleanup();
1504
1505    if (once_only) _ecore_idle_enterer_call();
1506    in_main_loop--;
1507 }
1508 #endif
1509
1510 #ifdef _WIN32
1511 static int
1512 _ecore_main_win32_select(int nfds __UNUSED__, fd_set *readfds, fd_set *writefds,
1513                          fd_set *exceptfds, struct timeval *tv)
1514 {
1515    HANDLE       objects[MAXIMUM_WAIT_OBJECTS];
1516    int          sockets[MAXIMUM_WAIT_OBJECTS];
1517    Ecore_Fd_Handler *fdh;
1518    Ecore_Win32_Handler *wh;
1519    unsigned int objects_nbr = 0;
1520    unsigned int handles_nbr = 0;
1521    unsigned int events_nbr = 0;
1522    DWORD        result;
1523    DWORD        timeout;
1524    MSG          msg;
1525    unsigned int i;
1526    int          res;
1527
1528    /* Create an event object per socket */
1529    EINA_INLIST_FOREACH(fd_handlers, fdh)
1530      {
1531         WSAEVENT event;
1532         long network_event;
1533
1534         network_event = 0;
1535         if (FD_ISSET(fdh->fd, readfds))
1536           network_event |= FD_READ;
1537         if (FD_ISSET(fdh->fd, writefds))
1538           network_event |= FD_WRITE;
1539         if (FD_ISSET(fdh->fd, exceptfds))
1540           network_event |= FD_OOB;
1541
1542         if (network_event)
1543           {
1544              event = WSACreateEvent();
1545              WSAEventSelect(fdh->fd, event, network_event);
1546              objects[objects_nbr] = event;
1547              sockets[events_nbr] = fdh->fd;
1548              events_nbr++;
1549              objects_nbr++;
1550           }
1551      }
1552
1553    /* store the HANDLEs in the objects to wait for */
1554    EINA_INLIST_FOREACH(win32_handlers, wh)
1555      {
1556         objects[objects_nbr] = wh->h;
1557         handles_nbr++;
1558         objects_nbr++;
1559      }
1560
1561    /* Empty the queue before waiting */
1562    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
1563      {
1564         TranslateMessage(&msg);
1565         DispatchMessage(&msg);
1566      }
1567
1568    /* Wait for any message sent or posted to this queue */
1569    /* or for one of the passed handles be set to signaled. */
1570    if (!tv)
1571      timeout = INFINITE;
1572    else
1573      timeout = (DWORD)((tv->tv_sec * 1000.0) + (tv->tv_usec / 1000.0));
1574
1575    if (timeout == 0) return 0;
1576
1577    result = MsgWaitForMultipleObjects(objects_nbr, (const HANDLE *)objects, EINA_FALSE,
1578                                       timeout, QS_ALLINPUT);
1579
1580    FD_ZERO(readfds);
1581    FD_ZERO(writefds);
1582    FD_ZERO(exceptfds);
1583
1584    /* The result tells us the type of event we have. */
1585    if (result == WAIT_FAILED)
1586      {
1587         char *msg;
1588
1589         msg = evil_last_error_get();
1590         ERR(" * %s\n", msg);
1591         free(msg);
1592         res = -1;
1593      }
1594    else if (result == WAIT_TIMEOUT)
1595      {
1596         /* ERR("time out\n"); */
1597         res = 0;
1598      }
1599    else if (result == (WAIT_OBJECT_0 + objects_nbr))
1600      {
1601         while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
1602           {
1603              TranslateMessage(&msg);
1604              DispatchMessage(&msg);
1605           }
1606
1607         res = 0;
1608      }
1609    else if ((result >= 0) && (result < WAIT_OBJECT_0 + events_nbr))
1610      {
1611         WSANETWORKEVENTS network_event;
1612
1613         WSAEnumNetworkEvents(sockets[result], objects[result], &network_event);
1614         
1615         if (network_event.lNetworkEvents & FD_READ)
1616            FD_SET(sockets[result], readfds);
1617         if (network_event.lNetworkEvents & FD_WRITE)
1618            FD_SET(sockets[result], writefds);
1619         if (network_event.lNetworkEvents & FD_OOB)
1620            FD_SET(sockets[result], exceptfds);
1621         
1622         res = 1;
1623      }
1624    else if ((result >= (WAIT_OBJECT_0 + events_nbr)) && 
1625             (result < (WAIT_OBJECT_0 + objects_nbr)))
1626      {
1627         if (!win32_handler_current)
1628           {
1629              /* regular main loop, start from head */
1630              win32_handler_current = win32_handlers;
1631           }
1632         else
1633           {
1634              /* recursive main loop, continue from where we were */
1635              win32_handler_current = (Ecore_Win32_Handler *)EINA_INLIST_GET(win32_handler_current)->next;
1636           }
1637
1638         while (win32_handler_current)
1639           {
1640              wh = win32_handler_current;
1641              
1642              if (objects[result - WAIT_OBJECT_0] == wh->h)
1643                {
1644                   if (!wh->delete_me)
1645                     {
1646                        wh->references++;
1647                        if (!wh->func(wh->data, wh))
1648                          {
1649                             wh->delete_me = EINA_TRUE;
1650                             win32_handlers_delete_me = EINA_TRUE;
1651                          }
1652                        wh->references--;
1653                     }
1654                }
1655              if (win32_handler_current) /* may have changed in recursive main loops */
1656                win32_handler_current = (Ecore_Win32_Handler *)EINA_INLIST_GET(win32_handler_current)->next;
1657           }
1658         res = 1;
1659      }
1660    else
1661      {
1662         ERR("unknown result...\n");
1663         res = -1;
1664      }
1665
1666    /* Remove event objects again */
1667    for (i = 0; i < events_nbr; i++) WSACloseEvent(objects[i]);
1668
1669    return res;
1670 }
1671 #endif