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