various fixes for vc++. I'll add the Visual Studio projects later
[profile/ivi/ecore.git] / src / lib / ecore / ecore_main.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 #ifdef HAVE_CONFIG_H
6 # include <config.h>
7 #endif
8
9 #ifdef _WIN32
10 # define WIN32_LEAN_AND_MEAN
11 # include <winsock2.h>
12 # undef WIN32_LEAN_AND_MEAN
13 # ifndef USER_TIMER_MINIMUM
14 #  define USER_TIMER_MINIMUM 0x0a
15 # endif
16 #endif
17
18 #ifdef __SUNPRO_C
19 # include <ieeefp.h>
20 # include <string.h>
21 #endif
22
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <math.h>
26 #include <sys/types.h>
27 #include <errno.h>
28 #include <fcntl.h>
29
30 #ifndef _MSC_VER
31 #include <sys/time.h>
32 # include <unistd.h>
33 #else
34 # include <float.h>
35 #endif
36
37 #define FIX_HZ 1
38
39 #ifdef FIX_HZ
40 # ifndef _MSC_VER
41 #  include <sys/param.h>
42 # endif
43 # ifndef HZ
44 #  define HZ 100
45 # endif
46 #endif
47
48 #ifdef HAVE_EVIL
49 # include <Evil.h>
50 #endif
51
52 #include "Ecore.h"
53 #include "ecore_private.h"
54
55
56 struct _Ecore_Fd_Handler
57 {
58    EINA_INLIST;
59    ECORE_MAGIC;
60    int                      fd;
61    Ecore_Fd_Handler_Flags   flags;
62    int                    (*func) (void *data, Ecore_Fd_Handler *fd_handler);
63    void                    *data;
64    int                    (*buf_func) (void *data, Ecore_Fd_Handler *fd_handler);
65    void                    *buf_data;
66    void                   (*prep_func) (void *data, Ecore_Fd_Handler *fd_handler);
67    void                    *prep_data;
68    int                      references;
69    Eina_Bool                read_active : 1;
70    Eina_Bool                write_active : 1;
71    Eina_Bool                error_active : 1;
72    Eina_Bool                delete_me : 1;
73 };
74
75 #ifdef _WIN32
76 struct _Ecore_Win32_Handler
77 {
78    EINA_INLIST;
79    ECORE_MAGIC;
80    HANDLE         h;
81    int          (*func) (void *data, Ecore_Win32_Handler *win32_handler);
82    void          *data;
83    int            references;
84    Eina_Bool      delete_me : 1;
85 };
86 #endif
87
88
89 static int  _ecore_main_select(double timeout);
90 static void _ecore_main_fd_handlers_cleanup(void);
91 #ifndef _WIN32
92 static void _ecore_main_fd_handlers_bads_rem(void);
93 #endif
94 static void _ecore_main_fd_handlers_call(void);
95 static int  _ecore_main_fd_handlers_buf_call(void);
96 static void _ecore_main_loop_iterate_internal(int once_only);
97
98 #ifdef _WIN32
99 static int _ecore_main_win32_select(int nfds, fd_set *readfds, fd_set *writefds,
100                                     fd_set *exceptfds, struct timeval *timeout);
101 static void _ecore_main_win32_handlers_cleanup(void);
102 #endif
103
104 static int               in_main_loop = 0;
105 static int               do_quit = 0;
106 static Ecore_Fd_Handler *fd_handlers = NULL;
107 static Ecore_Fd_Handler *fd_handler_current = NULL;
108 static int               fd_handlers_delete_me = 0;
109 #ifdef _WIN32
110 static Ecore_Win32_Handler *win32_handlers = NULL;
111 static Ecore_Win32_Handler *win32_handler_current = NULL;
112 static int                  win32_handlers_delete_me = 0;
113 #endif
114
115 #ifdef _WIN32
116 static int (*main_loop_select)(int , fd_set *, fd_set *, fd_set *, struct timeval *) = _ecore_main_win32_select;
117 #else
118 static int (*main_loop_select)(int , fd_set *, fd_set *, fd_set *, struct timeval *) = select;
119 #endif
120
121 static double            t1 = 0.0;
122 static double            t2 = 0.0;
123
124 /**
125  * @defgroup Ecore_Main_Loop_Group Main Loop Functions
126  *
127  * These functions control the Ecore event handling loop.  This loop is
128  * designed to work on embedded systems all the way to large and
129  * powerful mutli-cpu workstations.
130  *
131  * It serialises all system signals and events into a single event
132  * queue, that can be easily processed without needing to worry about
133  * concurrency.  A properly written, event-driven program using this
134  * kind of programming does not need threads.  It makes the program very
135  * robust and easy to follow.
136  *
137  * Here is an example of simple program and its basic event loop flow:
138  * @image html prog_flow.png
139  *
140  * For examples of setting up and using a main loop, see
141  * @ref event_handler_example.c and @ref timer_example.c.
142  */
143
144 /**
145  * Runs a single iteration of the main loop to process everything on the
146  * queue.
147  * @ingroup Ecore_Main_Loop_Group
148  */
149 EAPI void
150 ecore_main_loop_iterate(void)
151 {
152    _ecore_main_loop_iterate_internal(1);
153 }
154
155 /**
156  * Runs the application main loop.
157  *
158  * This function will not return until @ref ecore_main_loop_quit is called.
159  *
160  * @ingroup Ecore_Main_Loop_Group
161  */
162 EAPI void
163 ecore_main_loop_begin(void)
164 {
165    in_main_loop++;
166    for (;do_quit == 0;) _ecore_main_loop_iterate_internal(0);
167    do_quit = 0;
168    in_main_loop--;
169 }
170
171 /**
172  * Quits the main loop once all the events currently on the queue have
173  * been processed.
174  * @ingroup Ecore_Main_Loop_Group
175  */
176 EAPI void
177 ecore_main_loop_quit(void)
178 {
179    do_quit = 1;
180 }
181
182 /**
183  * Sets the function to use when monitoring multiple file descriptors,
184  * and waiting until one of more of the file descriptors before ready
185  * for some class of I/O operation.
186  *
187  * This function will be used instead of the system call select and
188  * could possible be used to integrate the Ecore event loop with an
189  * external event loop.
190  *
191  * @warning you don't know how to use, don't even try to use it.
192  *
193  * @ingroup Ecore_Main_Loop_Group
194  */
195 EAPI void
196 ecore_main_loop_select_func_set(int (*func)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout))
197 {
198    main_loop_select = func;
199 }
200
201 /**
202  * Gets the select function set by ecore_select_func_set(),
203  * or the native select function if none was set.
204  *
205  * @ingroup Ecore_Main_Loop_Group
206  */
207 EAPI void *
208 ecore_main_loop_select_func_get(void)
209 {
210    return main_loop_select;
211 }
212
213 /**
214  * @defgroup Ecore_FD_Handler_Group File Event Handling Functions
215  *
216  * Functions that deal with file descriptor handlers.
217  */
218
219 /**
220  * Adds a callback for activity on the given file descriptor.
221  *
222  * @p func will be called during the execution of @ref ecore_main_loop_begin
223  * when the file descriptor is available for reading, or writing, or both.
224  *
225  * Normally the return value from the @p func is "zero means this handler is
226  * finished and can be deleted" as is usual for handler callbacks.  However,
227  * if the @p buf_func is supplied, then the return value from the @p func is
228  * "non zero means the handler should be called again in a tight loop".
229  *
230  * @p buf_func is called during event loop handling to check if data that has
231  * been read from the file descriptor is in a buffer and is available to
232  * read.  Some systems (notably xlib) handle their own buffering, and would
233  * otherwise not work with select().  These systems should use a @p buf_func.
234  * This is a most annoying hack, only ecore_x uses it, so refer to that for
235  * an example.  NOTE - @p func should probably return "one" always if
236  * @p buf_func is used, to avoid confusion with the other return value
237  * semantics.
238  *
239  * @param   fd       The file descriptor to watch.
240  * @param   flags    To watch it for read (@c ECORE_FD_READ) and/or
241  *                   (@c ECORE_FD_WRITE) write ability.  @c ECORE_FD_ERROR
242  *
243  * @param   func     The callback function.
244  * @param   data     The data to pass to the callback.
245  * @param   buf_func The function to call to check if any data has been
246  *                   buffered and already read from the fd.  Can be @c NULL.
247  * @param   buf_data The data to pass to the @p buf_func function.
248  * @return  A fd handler handle if successful.  @c NULL otherwise.
249  * @ingroup Ecore_FD_Handler_Group
250  */
251 EAPI Ecore_Fd_Handler *
252 ecore_main_fd_handler_add(int fd, Ecore_Fd_Handler_Flags flags, int (*func) (void *data, Ecore_Fd_Handler *fd_handler), const void *data, int (*buf_func) (void *buf_data, Ecore_Fd_Handler *fd_handler), const void *buf_data)
253 {
254    Ecore_Fd_Handler *fdh;
255
256    if ((fd < 0) ||
257        (flags == 0) ||
258        (!func)) return NULL;
259
260    fdh = calloc(1, sizeof(Ecore_Fd_Handler));
261    if (!fdh) return NULL;
262    ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER);
263    fdh->fd = fd;
264    fdh->flags = flags;
265    fdh->read_active = 0;
266    fdh->write_active = 0;
267    fdh->error_active = 0;
268    fdh->delete_me = 0;
269    fdh->func = func;
270    fdh->data = (void *)data;
271    fdh->buf_func = buf_func;
272    fdh->buf_data = (void *)buf_data;
273    fd_handlers = (Ecore_Fd_Handler *) eina_inlist_append(EINA_INLIST_GET(fd_handlers),
274                                                          EINA_INLIST_GET(fdh));
275    return fdh;
276 }
277
278 #ifdef _WIN32
279 EAPI Ecore_Win32_Handler *
280 ecore_main_win32_handler_add(void *h,
281                              int (*func) (void *data, Ecore_Win32_Handler *wh),
282                              const void *data)
283 {
284    Ecore_Win32_Handler *wh;
285
286    if (!h || !func)
287      return NULL;
288
289    wh = calloc(1, sizeof(Ecore_Win32_Handler));
290    if (!wh) return NULL;
291    ECORE_MAGIC_SET(wh, ECORE_MAGIC_WIN32_HANDLER);
292    wh->h = (HANDLE)h;
293    wh->delete_me = 0;
294    wh->func = func;
295    wh->data = (void *)data;
296    win32_handlers = (Ecore_Win32_Handler *)eina_inlist_append(EINA_INLIST_GET(win32_handlers),
297                                                               EINA_INLIST_GET(wh));
298    return wh;
299 }
300 #else
301 EAPI Ecore_Win32_Handler *
302 ecore_main_win32_handler_add(void *h __UNUSED__,
303                              int (*func) (void *data, Ecore_Win32_Handler *wh) __UNUSED__,
304                              const void *data __UNUSED__)
305 {
306    return NULL;
307 }
308 #endif
309
310 /**
311  * Deletes the given FD handler.
312  * @param   fd_handler The given FD handler.
313  * @return  The data pointer set using @ref ecore_main_fd_handler_add,
314  *          for @p fd_handler on success.  @c NULL otherwise.
315  * @ingroup Ecore_FD_Handler_Group
316  */
317 EAPI void *
318 ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler)
319 {
320    if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
321      {
322         ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
323                          "ecore_main_fd_handler_del");
324         return NULL;
325      }
326    fd_handler->delete_me = 1;
327    fd_handlers_delete_me = 1;
328    return fd_handler->data;
329 }
330
331 #ifdef _WIN32
332 EAPI void *
333 ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler)
334 {
335    if (!ECORE_MAGIC_CHECK(win32_handler, ECORE_MAGIC_WIN32_HANDLER))
336      {
337         ECORE_MAGIC_FAIL(win32_handler, ECORE_MAGIC_WIN32_HANDLER,
338                          "ecore_main_win32_handler_del");
339         return NULL;
340      }
341    win32_handler->delete_me = 1;
342    win32_handlers_delete_me = 1;
343    return win32_handler->data;
344 }
345 #else
346 EAPI void *
347 ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler __UNUSED__)
348 {
349    return NULL;
350 }
351 #endif
352
353 EAPI void
354 ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, void (*func) (void *data, Ecore_Fd_Handler *fd_handler), const void *data)
355 {
356    if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
357      {
358         ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
359                          "ecore_main_fd_handler_prepare_callback_set");
360         return;
361      }
362    fd_handler->prep_func = func;
363    fd_handler->prep_data = (void *) data;
364 }
365
366 /**
367  * Retrieves the file descriptor that the given handler is handling.
368  * @param   fd_handler The given FD handler.
369  * @return  The file descriptor the handler is watching.
370  * @ingroup Ecore_FD_Handler_Group
371  */
372 EAPI int
373 ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler)
374 {
375    if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
376      {
377         ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
378                          "ecore_main_fd_handler_fd_get");
379         return -1;
380      }
381    return fd_handler->fd;
382 }
383
384 /**
385  * Return if read, write or error, or a combination thereof, is active on the
386  * file descriptor of the given FD handler.
387  * @param   fd_handler The given FD handler.
388  * @param   flags      The flags, @c ECORE_FD_READ, @c ECORE_FD_WRITE or
389  *                     @c ECORE_FD_ERROR to query.
390  * @return  @c 1 if any of the given flags are active. @c 0 otherwise.
391  * @ingroup Ecore_FD_Handler_Group
392  */
393 EAPI int
394 ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags)
395 {
396    int ret;
397
398    if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
399      {
400         ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
401                          "ecore_main_fd_handler_active_get");
402         return 0;
403      }
404    ret = 0;
405    if ((flags & ECORE_FD_READ) && (fd_handler->read_active)) ret = 1;
406    if ((flags & ECORE_FD_WRITE) && (fd_handler->write_active)) ret = 1;
407    if ((flags & ECORE_FD_ERROR) && (fd_handler->error_active)) ret = 1;
408    return ret;
409 }
410
411 /**
412  * Set what active streams the given FD handler should be monitoring.
413  * @param   fd_handler The given FD handler.
414  * @param   flags      The flags to be watching.
415  * @ingroup Ecore_FD_Handler_Group
416  */
417 EAPI void
418 ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags)
419 {
420    if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
421      {
422         ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
423                          "ecore_main_fd_handler_active_set");
424         return;
425      }
426    fd_handler->flags = flags;
427 }
428
429 void
430 _ecore_main_shutdown(void)
431 {
432    if (in_main_loop)
433      {
434        ERR("\n"
435            "*** ECORE WARINING: Calling ecore_shutdown() while still in the main loop.\n"
436            "***                 Program may crash or behave strangely now.");
437         return;
438      }
439    while (fd_handlers)
440      {
441         Ecore_Fd_Handler *fdh;
442
443         fdh = fd_handlers;
444         fd_handlers = (Ecore_Fd_Handler *) eina_inlist_remove(EINA_INLIST_GET(fd_handlers),
445                                                               EINA_INLIST_GET(fdh));
446         ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
447         free(fdh);
448      }
449    fd_handlers_delete_me = 0;
450    fd_handler_current = NULL;
451
452 #ifdef _WIN32
453    while (win32_handlers)
454      {
455         Ecore_Win32_Handler *wh;
456
457         wh = win32_handlers;
458         win32_handlers = (Ecore_Win32_Handler *) eina_inlist_remove(EINA_INLIST_GET(win32_handlers),
459                                                                     EINA_INLIST_GET(wh));
460         ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE);
461         free(wh);
462      }
463    win32_handlers_delete_me = 0;
464    win32_handler_current = NULL;
465 #endif
466 }
467
468 static int
469 _ecore_main_select(double timeout)
470 {
471    struct timeval tv, *t;
472    fd_set         rfds, wfds, exfds;
473    int            max_fd;
474    int            ret;
475    Ecore_Fd_Handler *fdh;
476
477    t = NULL;
478    if ((!finite(timeout)) || (timeout == 0.0))  /* finite() tests for NaN, too big, too small, and infinity.  */
479      {
480         tv.tv_sec = 0;
481         tv.tv_usec = 0;
482         t = &tv;
483      }
484    else if (timeout > 0.0)
485      {
486         int sec, usec;
487
488 #ifdef FIX_HZ
489         timeout += (0.5 / HZ);
490         sec = (int)timeout;
491         usec = (int)((timeout - (double)sec) * 1000000);
492 #else
493         sec = (int)timeout;
494         usec = (int)((timeout - (double)sec) * 1000000);
495 #endif
496         tv.tv_sec = sec;
497         tv.tv_usec = usec;
498         t = &tv;
499      }
500    max_fd = 0;
501    FD_ZERO(&rfds);
502    FD_ZERO(&wfds);
503    FD_ZERO(&exfds);
504
505    /* call the prepare callback for all handlers */
506    EINA_INLIST_FOREACH(fd_handlers, fdh)
507      if (!fdh->delete_me && fdh->prep_func)
508        {
509           fdh->references++;
510           fdh->prep_func (fdh->prep_data, fdh);
511           fdh->references--;
512        }
513    EINA_INLIST_FOREACH(fd_handlers, fdh)
514      if (!fdh->delete_me)
515        {
516           if (fdh->flags & ECORE_FD_READ)
517             {
518                FD_SET(fdh->fd, &rfds);
519                if (fdh->fd > max_fd) max_fd = fdh->fd;
520             }
521           if (fdh->flags & ECORE_FD_WRITE)
522             {
523                FD_SET(fdh->fd, &wfds);
524                if (fdh->fd > max_fd) max_fd = fdh->fd;
525             }
526           if (fdh->flags & ECORE_FD_ERROR)
527             {
528                FD_SET(fdh->fd, &exfds);
529                if (fdh->fd > max_fd) max_fd = fdh->fd;
530             }
531        }
532    if (_ecore_signal_count_get()) return -1;
533
534    ret = main_loop_select(max_fd + 1, &rfds, &wfds, &exfds, t);
535
536    _ecore_loop_time = ecore_time_get();
537    if (ret < 0)
538      {
539 #ifndef _WIN32
540         if (errno == EINTR) return -1;
541         else if (errno == EBADF)
542              _ecore_main_fd_handlers_bads_rem();
543 #endif
544      }
545    if (ret > 0)
546      {
547         EINA_INLIST_FOREACH(fd_handlers, fdh)
548           if (!fdh->delete_me)
549             {
550                if (FD_ISSET(fdh->fd, &rfds))
551                  fdh->read_active = 1;
552                if (FD_ISSET(fdh->fd, &wfds))
553                  fdh->write_active = 1;
554                if (FD_ISSET(fdh->fd, &exfds))
555                  fdh->error_active = 1;
556             }
557         _ecore_main_fd_handlers_cleanup();
558 #ifdef _WIN32
559         _ecore_main_win32_handlers_cleanup();
560 #endif
561         return 1;
562      }
563    return 0;
564 }
565
566 #ifndef _WIN32
567 static void
568 _ecore_main_fd_handlers_bads_rem(void)
569 {
570    ERR("Removing bad fds");
571    Ecore_Fd_Handler *fdh;
572    Eina_Inlist *l;
573
574    for (l = EINA_INLIST_GET(fd_handlers); l; )
575      {
576         fdh = (Ecore_Fd_Handler *) l;
577         l = l->next;
578         errno = 0;
579
580         if ((fcntl(fdh->fd, F_GETFD) < 0) && (errno == EBADF))
581           {
582              ERR("Found bad fd at index %d", fdh->fd);
583              if (fdh->flags & ECORE_FD_ERROR)
584                {
585                   ERR("Fd set for error! calling user");
586                   fdh->references++;
587                   if (!fdh->func(fdh->data, fdh))
588                     {
589                        ERR("Fd function err returned 0, remove it");
590                        fdh->delete_me = 1;
591                        fd_handlers_delete_me = 1;
592                     }
593                   fdh->references--;
594                }
595              else
596                {
597                   ERR("Problematic fd found at %d! setting it for delete", fdh->fd);
598                   fdh->delete_me = 1;
599                   fd_handlers_delete_me = 1;
600                }
601           }
602     }
603
604    _ecore_main_fd_handlers_cleanup();
605 }
606 #endif
607
608 static void
609 _ecore_main_fd_handlers_cleanup(void)
610 {
611    Ecore_Fd_Handler *fdh;
612    Eina_Inlist *l;
613    int deleted_in_use = 0;
614
615    if (!fd_handlers_delete_me) return;
616    for (l = EINA_INLIST_GET(fd_handlers); l; )
617      {
618         fdh = (Ecore_Fd_Handler *) l;
619
620         l = l->next;
621         if (fdh->delete_me)
622           {
623 //           ERR("Removing fd %d", fdh->fd);
624
625              if (fdh->references)
626                {
627                   deleted_in_use++;
628                   continue;
629                }
630
631              fd_handlers = (Ecore_Fd_Handler *) eina_inlist_remove(EINA_INLIST_GET(fd_handlers),
632                                                                    EINA_INLIST_GET(fdh));
633              ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
634              free(fdh);
635           }
636      }
637    if (!deleted_in_use)
638      fd_handlers_delete_me = 0;
639 }
640
641 #ifdef _WIN32
642 static void
643 _ecore_main_win32_handlers_cleanup(void)
644 {
645    Ecore_Win32_Handler *wh;
646    Eina_Inlist *l;
647    int deleted_in_use = 0;
648
649    if (!win32_handlers_delete_me) return;
650    for (l = EINA_INLIST_GET(win32_handlers); l; )
651      {
652         wh = (Ecore_Win32_Handler *)l;
653
654         l = l->next;
655         if (wh->delete_me)
656           {
657              if (wh->references)
658                {
659                   deleted_in_use++;
660                   continue;
661                }
662
663              win32_handlers = (Ecore_Win32_Handler *)eina_inlist_remove(EINA_INLIST_GET(win32_handlers),
664                                                                         EINA_INLIST_GET(wh));
665              ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE);
666              free(wh);
667           }
668      }
669    if (!deleted_in_use)
670      win32_handlers_delete_me = 0;
671 }
672 #endif
673
674 static void
675 _ecore_main_fd_handlers_call(void)
676 {
677    if (!fd_handler_current)
678      {
679         /* regular main loop, start from head */
680         fd_handler_current = fd_handlers;
681      }
682    else
683      {
684         /* recursive main loop, continue from where we were */
685         fd_handler_current = (Ecore_Fd_Handler *)EINA_INLIST_GET(fd_handler_current)->next;
686      }
687
688    while (fd_handler_current)
689      {
690         Ecore_Fd_Handler *fdh = fd_handler_current;
691
692         if (!fdh->delete_me)
693           {
694              if ((fdh->read_active) ||
695                  (fdh->write_active) ||
696                  (fdh->error_active))
697                {
698                   fdh->references++;
699                   if (!fdh->func(fdh->data, fdh))
700                     {
701                        fdh->delete_me = 1;
702                        fd_handlers_delete_me = 1;
703                     }
704                   fdh->references--;
705
706                   fdh->read_active = 0;
707                   fdh->write_active = 0;
708                   fdh->error_active = 0;
709                }
710           }
711
712         if (fd_handler_current) /* may have changed in recursive main loops */
713           fd_handler_current = (Ecore_Fd_Handler *)EINA_INLIST_GET(fd_handler_current)->next;
714      }
715 }
716
717 static int
718 _ecore_main_fd_handlers_buf_call(void)
719 {
720    Ecore_Fd_Handler *fdh;
721    int ret;
722
723    ret = 0;
724    EINA_INLIST_FOREACH(fd_handlers, fdh)
725      if (!fdh->delete_me)
726        {
727           if (fdh->buf_func)
728             {
729                fdh->references++;
730                if (fdh->buf_func(fdh->buf_data, fdh))
731                  {
732                     ret |= fdh->func(fdh->data, fdh);
733                     fdh->read_active = 1;
734                  }
735                fdh->references--;
736             }
737        }
738
739    return ret;
740 }
741
742 static void
743 _ecore_main_loop_iterate_internal(int once_only)
744 {
745    double next_time = -1.0;
746    int    have_event = 0;
747    int    have_signal;
748
749    in_main_loop++;
750    /* expire any timers */
751    while (_ecore_timer_call(_ecore_loop_time));
752    _ecore_timer_cleanup();
753
754    /* process signals into events .... */
755    while (_ecore_signal_count_get()) _ecore_signal_call();
756    if (_ecore_event_exist())
757      {
758         _ecore_idle_enterer_call();
759         have_event = 1;
760         _ecore_main_select(0.0);
761         _ecore_loop_time = ecore_time_get();
762         _ecore_timer_enable_new();
763         goto process_events;
764      }
765    /* call idle enterers ... */
766    if (!once_only) _ecore_idle_enterer_call();
767    else
768      {
769         have_event = have_signal = 0;
770
771         if (_ecore_main_select(0.0) > 0) have_event = 1;
772         if (_ecore_signal_count_get() > 0) have_signal = 1;
773         if (have_signal || have_event)
774           {
775              _ecore_loop_time = ecore_time_get();
776              _ecore_timer_enable_new();
777              goto process_events;
778           }
779      }
780
781    /* if these calls caused any buffered events to appear - deal with them */
782    _ecore_main_fd_handlers_buf_call();
783
784    /* if ther are any - jump to processing them */
785    if (_ecore_event_exist())
786      {
787         have_event = 1;
788         _ecore_main_select(0.0);
789         _ecore_loop_time = ecore_time_get();
790         _ecore_timer_enable_new();
791         goto process_events;
792      }
793    if (once_only)
794      {
795         _ecore_idle_enterer_call();
796         in_main_loop--;
797         _ecore_loop_time = ecore_time_get();
798         _ecore_timer_enable_new();
799         return;
800      }
801
802    if (_ecore_fps_debug)
803      {
804         t2 = ecore_time_get();
805         if ((t1 > 0.0) && (t2 > 0.0))
806           _ecore_fps_debug_runtime_add(t2 - t1);
807      }
808    start_loop:
809    /* any timers re-added as a result of these are allowed to go */
810    _ecore_timer_enable_new();
811    if (do_quit)
812      {
813         _ecore_loop_time = ecore_time_get();
814         in_main_loop--;
815         _ecore_timer_enable_new();
816         return;
817      }
818    if (!_ecore_event_exist())
819      {
820         /* init flags */
821         have_event = have_signal = 0;
822         next_time = _ecore_timer_next_get();
823         /* no timers */
824         if (next_time < 0)
825           {
826              /* no idlers */
827              if (!_ecore_idler_exist())
828                {
829                   if (_ecore_main_select(-1.0) > 0) have_event = 1;
830                }
831              /* idlers */
832              else
833                {
834                   for (;;)
835                     {
836                        if (!_ecore_idler_call()) goto start_loop;
837                        if (_ecore_event_exist()) break;
838                        if (_ecore_main_select(0.0) > 0) have_event = 1;
839                        if (_ecore_signal_count_get() > 0) have_signal = 1;
840                        if (have_event || have_signal) break;
841                        if (_ecore_timers_exists()) goto start_loop;
842                        if (do_quit) break;
843                     }
844                }
845           }
846         /* timers */
847         else
848           {
849              /* no idlers */
850              if (!_ecore_idler_exist())
851                {
852                   if (_ecore_main_select(next_time) > 0) have_event = 1;
853                }
854              /* idlers */
855              else
856                {
857                   for (;;)
858                     {
859                        if (!_ecore_idler_call()) goto start_loop;
860                        if (_ecore_event_exist()) break;
861                        if (_ecore_main_select(0.0) > 0) have_event = 1;
862                        if (_ecore_signal_count_get() > 0) have_signal = 1;
863                        if (have_event || have_signal) break;
864                        next_time = _ecore_timer_next_get();
865                        if (next_time <= 0) break;
866                        if (do_quit) break;
867                     }
868                }
869           }
870         _ecore_loop_time = ecore_time_get();
871      }
872    if (_ecore_fps_debug)
873      {
874         t1 = ecore_time_get();
875      }
876    /* we came out of our "wait state" so idle has exited */
877    if (!once_only)
878      _ecore_idle_exiter_call();
879    /* call the fd handler per fd that became alive... */
880    /* this should read or write any data to the monitored fd and then */
881    /* post events onto the ecore event pipe if necessary */
882    process_events:
883 //   if (have_event) 
884    _ecore_main_fd_handlers_call();
885    _ecore_main_fd_handlers_buf_call();
886 //   do
887 //     {
888         /* process signals into events .... */
889         while (_ecore_signal_count_get()) _ecore_signal_call();
890         /* handle events ... */
891         _ecore_event_call();
892         _ecore_main_fd_handlers_cleanup();
893 //     }
894 //   while (_ecore_main_fd_handlers_buf_call());
895
896 /* ok - too much optimising. let's call idle enterers more often. if we
897  * have events that place more events or jobs etc. on the event queue
898  * we may never get to call an idle enterer
899    if (once_only)
900  */
901    if (once_only)
902      _ecore_idle_enterer_call();
903    in_main_loop--;
904 }
905
906 #ifdef _WIN32
907 static int
908 _ecore_main_win32_select(int nfds, fd_set *readfds, fd_set *writefds,
909                          fd_set *exceptfds, struct timeval *tv)
910 {
911    HANDLE objects[MAXIMUM_WAIT_OBJECTS];
912    int    sockets[MAXIMUM_WAIT_OBJECTS];
913    Ecore_Win32_Handler *wh;
914    unsigned int objects_nbr = 0;
915    unsigned int handles_nbr = 0;
916    unsigned int events_nbr = 0;
917    DWORD  result;
918    DWORD  timeout;
919    MSG    msg;
920    int    i;
921    int    res;
922
923    /* Create an event object per socket */
924    for(i = 0; i < nfds; i++)
925      {
926         WSAEVENT event;
927         long network_event;
928
929         network_event = 0;
930         if(FD_ISSET(i, readfds))
931           network_event |= FD_READ;
932         if(FD_ISSET(i, writefds))
933           network_event |= FD_WRITE;
934         if(FD_ISSET(i, exceptfds))
935           network_event |= FD_OOB;
936
937         if(network_event)
938           {
939              event = WSACreateEvent();
940              WSAEventSelect(i, event, network_event);
941              objects[objects_nbr] = event;
942              sockets[events_nbr] = i;
943              events_nbr++;
944              objects_nbr++;
945           }
946      }
947
948    /* store the HANDLEs in the objects to wait for */
949    EINA_INLIST_FOREACH(win32_handlers, wh)
950      {
951         objects[objects_nbr] = wh->h;
952         handles_nbr++;
953         objects_nbr++;
954      }
955
956    /* Empty the queue before waiting */
957    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
958      {
959         TranslateMessage(&msg);
960         DispatchMessage(&msg);
961      }
962
963    /* Wait for any message sent or posted to this queue */
964    /* or for one of the passed handles be set to signaled. */
965    if(tv == NULL)
966      timeout = INFINITE;
967    else
968      timeout = (DWORD)(tv->tv_sec * 1000.0 + tv->tv_usec / 1000.0);
969
970    if (timeout == 0) return 0;
971
972    result = MsgWaitForMultipleObjects(objects_nbr, (const HANDLE *)objects, EINA_FALSE,
973                                       timeout, QS_ALLINPUT);
974
975    FD_ZERO(readfds);
976    FD_ZERO(writefds);
977    FD_ZERO(exceptfds);
978
979    /* The result tells us the type of event we have. */
980    if (result == WAIT_FAILED)
981      {
982         char *msg;
983
984         msg = evil_last_error_get();
985         ERR(" * %s\n", msg);
986         free(msg);
987         res = -1;
988      }
989    else if (result == WAIT_TIMEOUT)
990      {
991         ERR("time out\n");
992         res = 0;
993      }
994    else if (result == (WAIT_OBJECT_0 + objects_nbr))
995      {
996         while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
997           {
998              TranslateMessage(&msg);
999              DispatchMessage(&msg);
1000           }
1001
1002         res = 0;
1003      }
1004    else if ((result >= 0) && (result < WAIT_OBJECT_0 + events_nbr))
1005      {
1006         WSANETWORKEVENTS network_event;
1007
1008         WSAEnumNetworkEvents(sockets[result], objects[result], &network_event);
1009
1010         if(network_event.lNetworkEvents & FD_READ)
1011           FD_SET(sockets[result], readfds);
1012         if(network_event.lNetworkEvents & FD_WRITE)
1013           FD_SET(sockets[result], writefds);
1014         if(network_event.lNetworkEvents & FD_OOB)
1015           FD_SET(sockets[result], exceptfds);
1016
1017         res = 1;
1018      }
1019    else if ((result >= WAIT_OBJECT_0 + events_nbr) && (result < WAIT_OBJECT_0 + objects_nbr))
1020      {
1021
1022         if (!win32_handler_current)
1023           {
1024              /* regular main loop, start from head */
1025              win32_handler_current = win32_handlers;
1026           }
1027         else
1028           {
1029              /* recursive main loop, continue from where we were */
1030              win32_handler_current = (Ecore_Win32_Handler *)EINA_INLIST_GET(win32_handler_current)->next;
1031           }
1032
1033         while (win32_handler_current)
1034           {
1035              wh = win32_handler_current;
1036
1037              if (objects[result - WAIT_OBJECT_0] == wh->h)
1038                if (!wh->delete_me)
1039                  {
1040                     wh->references++;
1041                     if (!wh->func(wh->data, wh))
1042                       {
1043                          wh->delete_me = 1;
1044                          win32_handlers_delete_me = 1;
1045                       }
1046                     wh->references--;
1047                  }
1048           }
1049         res = 1;
1050      }
1051    else
1052      {
1053         ERR("unknown result...\n");
1054         res = -1;
1055      }
1056
1057    /* Remove event objects again */
1058    for(i = 0; i < (int)events_nbr; i++)
1059      WSACloseEvent(objects[i]);
1060
1061    return res;
1062 }
1063 #endif