aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore/ecore_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ecore/src/lib/ecore/ecore_main.c')
-rw-r--r--libraries/ecore/src/lib/ecore/ecore_main.c1958
1 files changed, 0 insertions, 1958 deletions
diff --git a/libraries/ecore/src/lib/ecore/ecore_main.c b/libraries/ecore/src/lib/ecore/ecore_main.c
deleted file mode 100644
index 587c83b..0000000
--- a/libraries/ecore/src/lib/ecore/ecore_main.c
+++ /dev/null
@@ -1,1958 +0,0 @@
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#ifdef HAVE_ISFINITE
34# define ECORE_FINITE(t) isfinite(t)
35#else
36# ifdef _MSC_VER
37# define ECORE_FINITE(t) _finite(t)
38# else
39# define ECORE_FINITE(t) finite(t)
40# endif
41#endif
42
43//#define FIX_HZ 1
44
45#ifdef FIX_HZ
46# ifndef _MSC_VER
47# include <sys/param.h>
48# endif
49# ifndef HZ
50# define HZ 100
51# endif
52#endif
53
54#ifdef HAVE_EVIL
55# include <Evil.h>
56#endif
57
58#include "Ecore.h"
59#include "ecore_private.h"
60
61#ifdef HAVE_SYS_EPOLL_H
62# define HAVE_EPOLL 1
63# include <sys/epoll.h>
64#else
65
66# define HAVE_EPOLL 0
67# define EPOLLIN 1
68# define EPOLLOUT 2
69# define EPOLLERR 8
70
71#define EPOLL_CTL_ADD 1
72#define EPOLL_CTL_DEL 2
73#define EPOLL_CTL_MOD 3
74
75typedef union epoll_data {
76 void *ptr;
77 int fd;
78 uint32_t u32;
79 uint64_t u64;
80} epoll_data_t;
81
82struct epoll_event
83{
84 uint32_t events;
85 epoll_data_t data;
86};
87
88static inline int
89epoll_create(int size __UNUSED__)
90{
91 return -1;
92}
93
94static inline int
95epoll_wait(int epfd __UNUSED__,
96 struct epoll_event *events __UNUSED__,
97 int maxevents __UNUSED__,
98 int timeout __UNUSED__)
99{
100 return -1;
101}
102
103static inline int
104epoll_ctl(int epfd __UNUSED__,
105 int op __UNUSED__,
106 int fd __UNUSED__,
107 struct epoll_event *event __UNUSED__)
108{
109 return -1;
110}
111
112#endif
113
114#ifdef HAVE_SYS_TIMERFD_H
115#include <sys/timerfd.h>
116#else
117/* fallback code if we don't have real timerfd - reduces number of ifdefs */
118#ifndef CLOCK_MONOTONIC
119#define CLOCK_MONOTONIC 0 /* bogus value */
120#endif
121#ifndef TFD_NONBLOCK
122#define TFD_NONBLOCK 0 /* bogus value */
123#endif
124static inline int
125timerfd_create(int clockid __UNUSED__,
126 int flags __UNUSED__)
127{
128 return -1;
129}
130
131static inline int
132timerfd_settime(int fd __UNUSED__,
133 int flags __UNUSED__,
134 const struct itimerspec *new_value __UNUSED__,
135 struct itimerspec *old_value __UNUSED__)
136{
137 return -1;
138}
139
140#endif /* HAVE_SYS_TIMERFD_H */
141
142#ifdef USE_G_MAIN_LOOP
143# include <glib.h>
144#endif
145
146#define NS_PER_SEC (1000.0 * 1000.0 * 1000.0)
147
148struct _Ecore_Fd_Handler
149{
150 EINA_INLIST;
151 ECORE_MAGIC;
152 Ecore_Fd_Handler *next_ready;
153 int fd;
154 Ecore_Fd_Handler_Flags flags;
155 Ecore_Fd_Cb func;
156 void *data;
157 Ecore_Fd_Cb buf_func;
158 void *buf_data;
159 Ecore_Fd_Prep_Cb prep_func;
160 void *prep_data;
161 int references;
162 Eina_Bool read_active : 1;
163 Eina_Bool write_active : 1;
164 Eina_Bool error_active : 1;
165 Eina_Bool delete_me : 1;
166#if defined(USE_G_MAIN_LOOP)
167 GPollFD gfd;
168#endif
169};
170GENERIC_ALLOC_SIZE_DECLARE(Ecore_Fd_Handler);
171
172#ifdef _WIN32
173struct _Ecore_Win32_Handler
174{
175 EINA_INLIST;
176 ECORE_MAGIC;
177 HANDLE h;
178 Ecore_Win32_Handle_Cb func;
179 void *data;
180 int references;
181 Eina_Bool delete_me : 1;
182};
183GENERIC_ALLOC_SIZE_DECLARE(Ecore_Win32_Handler);
184#endif
185
186#ifndef USE_G_MAIN_LOOP
187static int _ecore_main_select(double timeout);
188#endif
189static void _ecore_main_prepare_handlers(void);
190static void _ecore_main_fd_handlers_cleanup(void);
191#ifndef _WIN32
192# ifndef USE_G_MAIN_LOOP
193static void _ecore_main_fd_handlers_bads_rem(void);
194# endif
195#endif
196static void _ecore_main_fd_handlers_call(void);
197static int _ecore_main_fd_handlers_buf_call(void);
198#ifndef USE_G_MAIN_LOOP
199static void _ecore_main_loop_iterate_internal(int once_only);
200#endif
201
202#ifdef _WIN32
203static int _ecore_main_win32_select(int nfds,
204 fd_set *readfds,
205 fd_set *writefds,
206 fd_set *exceptfds,
207 struct timeval *timeout);
208static void _ecore_main_win32_handlers_cleanup(void);
209#endif
210
211static int in_main_loop = 0;
212static int do_quit = 0;
213static Ecore_Fd_Handler *fd_handlers = NULL;
214static Ecore_Fd_Handler *fd_handler_current = NULL;
215static Eina_List *fd_handlers_with_prep = NULL;
216static Eina_List *fd_handlers_with_buffer = NULL;
217static Eina_List *fd_handlers_to_delete = NULL;
218
219/* single linked list of ready fdhs, terminated by loop to self */
220static Ecore_Fd_Handler *fd_handlers_to_call;
221static Ecore_Fd_Handler *fd_handlers_to_call_current;
222
223#ifdef _WIN32
224static Ecore_Win32_Handler *win32_handlers = NULL;
225static Ecore_Win32_Handler *win32_handler_current = NULL;
226static Eina_Bool win32_handlers_delete_me = EINA_FALSE;
227#endif
228
229#ifdef _WIN32
230Ecore_Select_Function main_loop_select = _ecore_main_win32_select;
231#else
232# if !defined EXOTIC_NO_SELECT
233# ifdef HAVE_SYS_SELECT_H
234# include <sys/select.h>
235# endif
236Ecore_Select_Function main_loop_select = select;
237# else
238Ecore_Select_Function main_loop_select = NULL;
239# endif
240#endif
241
242#ifndef USE_G_MAIN_LOOP
243static double t1 = 0.0;
244static double t2 = 0.0;
245#endif
246
247static int timer_fd = -1;
248static int epoll_fd = -1;
249static pid_t epoll_pid;
250
251#ifdef USE_G_MAIN_LOOP
252static GPollFD ecore_epoll_fd;
253static GPollFD ecore_timer_fd;
254static GSource *ecore_glib_source;
255static guint ecore_glib_source_id;
256static GMainLoop *ecore_main_loop;
257static gboolean ecore_idling;
258static gboolean _ecore_glib_idle_enterer_called;
259static gboolean ecore_fds_ready;
260#endif
261
262static inline void
263_ecore_fd_valid(void)
264{
265 if (HAVE_EPOLL && epoll_fd >= 0)
266 {
267 if (fcntl(epoll_fd, F_GETFD) < 0)
268 {
269 ERR("arghhh you caught me! report a backtrace to edevel!");
270 pause();
271 }
272 }
273}
274
275static inline void
276_ecore_try_add_to_call_list(Ecore_Fd_Handler *fdh)
277{
278 /* check if this fdh is already in the list */
279 if (fdh->next_ready)
280 return;
281 if (fdh->read_active || fdh->write_active || fdh->error_active)
282 {
283 /*
284 * make sure next_ready is non-null by pointing to ourselves
285 * use that to indicate this fdh is in the ready list
286 * insert at the head of the list to avoid trouble
287 */
288 fdh->next_ready = fd_handlers_to_call ? fd_handlers_to_call : fdh;
289 fd_handlers_to_call = fdh;
290 }
291}
292
293static inline int
294_ecore_get_epoll_fd(void)
295{
296 if (epoll_pid && epoll_pid != getpid())
297 {
298 /* forked! */
299 _ecore_main_loop_shutdown();
300 }
301 if (epoll_pid == 0 && epoll_fd < 0)
302 {
303 _ecore_main_loop_init();
304 }
305 return epoll_fd;
306}
307
308static inline int
309_ecore_epoll_add(int efd,
310 int fd,
311 int events,
312 void *ptr)
313{
314 struct epoll_event ev;
315
316 memset(&ev, 0, sizeof (ev));
317 ev.events = events;
318 ev.data.ptr = ptr;
319 INF("adding poll on %d %08x", fd, events);
320 return epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ev);
321}
322
323static inline int
324_ecore_poll_events_from_fdh(Ecore_Fd_Handler *fdh)
325{
326 int events = 0;
327 if (fdh->flags & ECORE_FD_READ) events |= EPOLLIN;
328 if (fdh->flags & ECORE_FD_WRITE) events |= EPOLLOUT;
329 if (fdh->flags & ECORE_FD_ERROR) events |= EPOLLERR;
330 return events;
331}
332
333#ifdef USE_G_MAIN_LOOP
334static inline int
335_gfd_events_from_fdh(Ecore_Fd_Handler *fdh)
336{
337 int events = 0;
338 if (fdh->flags & ECORE_FD_READ) events |= G_IO_IN;
339 if (fdh->flags & ECORE_FD_WRITE) events |= G_IO_OUT;
340 if (fdh->flags & ECORE_FD_ERROR) events |= G_IO_ERR;
341 return events;
342}
343
344#endif
345
346static inline int
347_ecore_main_fdh_poll_add(Ecore_Fd_Handler *fdh)
348{
349 int r = 0;
350
351 if (HAVE_EPOLL && epoll_fd >= 0)
352 {
353 r = _ecore_epoll_add(_ecore_get_epoll_fd(), fdh->fd,
354 _ecore_poll_events_from_fdh(fdh), fdh);
355 }
356 else
357 {
358#ifdef USE_G_MAIN_LOOP
359 fdh->gfd.fd = fdh->fd;
360 fdh->gfd.events = _gfd_events_from_fdh(fdh);
361 fdh->gfd.revents = 0;
362 INF("adding gpoll on %d %08x", fdh->fd, fdh->gfd.events);
363 g_source_add_poll(ecore_glib_source, &fdh->gfd);
364#endif
365 }
366 return r;
367}
368
369static inline void
370_ecore_main_fdh_poll_del(Ecore_Fd_Handler *fdh)
371{
372 if (HAVE_EPOLL && epoll_fd >= 0)
373 {
374 struct epoll_event ev;
375 int efd = _ecore_get_epoll_fd();
376
377 memset(&ev, 0, sizeof (ev));
378 INF("removing poll on %d", fdh->fd);
379 /* could get an EBADF if somebody closed the FD before removing it */
380 if ((epoll_ctl(efd, EPOLL_CTL_DEL, fdh->fd, &ev) < 0))
381 {
382 if (errno == EBADF)
383 {
384 WRN("fd %d was closed, can't remove from epoll - reinit!",
385 fdh->fd);
386 _ecore_main_loop_shutdown();
387 _ecore_main_loop_init();
388 }
389 else
390 {
391 ERR("Failed to delete epoll fd %d! (errno=%d)", fdh->fd, errno);
392 }
393 }
394 }
395 else
396 {
397#ifdef USE_G_MAIN_LOOP
398 fdh->gfd.fd = fdh->fd;
399 fdh->gfd.events = _gfd_events_from_fdh(fdh);
400 fdh->gfd.revents = 0;
401 INF("adding gpoll on %d %08x", fdh->fd, fdh->gfd.events);
402 g_source_add_poll(ecore_glib_source, &fdh->gfd);
403#endif
404 }
405}
406
407static inline int
408_ecore_main_fdh_poll_modify(Ecore_Fd_Handler *fdh)
409{
410 int r = 0;
411 if (HAVE_EPOLL && epoll_fd >= 0)
412 {
413 struct epoll_event ev;
414 int efd = _ecore_get_epoll_fd();
415
416 memset(&ev, 0, sizeof (ev));
417 ev.events = _ecore_poll_events_from_fdh(fdh);
418 ev.data.ptr = fdh;
419 INF("modifing epoll on %d to %08x", fdh->fd, ev.events);
420 r = epoll_ctl(efd, EPOLL_CTL_MOD, fdh->fd, &ev);
421 }
422 else
423 {
424#ifdef USE_G_MAIN_LOOP
425 fdh->gfd.fd = fdh->fd;
426 fdh->gfd.events = _gfd_events_from_fdh(fdh);
427 fdh->gfd.revents = 0;
428 INF("modifing gpoll on %d to %08x", fdh->fd, fdh->gfd.events);
429#endif
430 }
431 return r;
432}
433
434static inline int
435_ecore_main_fdh_epoll_mark_active(void)
436{
437 struct epoll_event ev[32];
438 int i, ret;
439 int efd = _ecore_get_epoll_fd();
440
441 memset(&ev, 0, sizeof (ev));
442 ret = epoll_wait(efd, ev, sizeof(ev) / sizeof(struct epoll_event), 0);
443 if (ret < 0)
444 {
445 if (errno == EINTR) return -1;
446 ERR("epoll_wait failed %d", errno);
447 return -1;
448 }
449
450 for (i = 0; i < ret; i++)
451 {
452 Ecore_Fd_Handler *fdh;
453
454 fdh = ev[i].data.ptr;
455 if (!ECORE_MAGIC_CHECK(fdh, ECORE_MAGIC_FD_HANDLER))
456 {
457 ECORE_MAGIC_FAIL(fdh, ECORE_MAGIC_FD_HANDLER,
458 "_ecore_main_fdh_epoll_mark_active");
459 continue;
460 }
461 if (fdh->delete_me)
462 {
463 ERR("deleted fd in epoll");
464 continue;
465 }
466
467 if (ev[i].events & EPOLLIN)
468 fdh->read_active = EINA_TRUE;
469 if (ev[i].events & EPOLLOUT)
470 fdh->write_active = EINA_TRUE;
471 if (ev[i].events & EPOLLERR)
472 fdh->error_active = EINA_TRUE;
473
474 _ecore_try_add_to_call_list(fdh);
475 }
476
477 return ret;
478}
479
480#ifdef USE_G_MAIN_LOOP
481
482static inline int
483_ecore_main_fdh_glib_mark_active(void)
484{
485 Ecore_Fd_Handler *fdh;
486 int ret = 0;
487
488 /* call the prepare callback for all handlers */
489 EINA_INLIST_FOREACH(fd_handlers, fdh)
490 {
491 if (fdh->delete_me)
492 continue;
493
494 if (fdh->gfd.revents & G_IO_IN)
495 fdh->read_active = EINA_TRUE;
496 if (fdh->gfd.revents & G_IO_OUT)
497 fdh->write_active = EINA_TRUE;
498 if (fdh->gfd.revents & G_IO_ERR)
499 fdh->error_active = EINA_TRUE;
500
501 _ecore_try_add_to_call_list(fdh);
502
503 if (fdh->gfd.revents & (G_IO_IN | G_IO_OUT | G_IO_ERR)) ret++;
504 }
505
506 return ret;
507}
508
509/* like we are about to enter main_loop_select in _ecore_main_select */
510static gboolean
511_ecore_main_gsource_prepare(GSource *source __UNUSED__,
512 gint *next_time)
513{
514 gboolean ready = FALSE;
515
516 _ecore_lock();
517 in_main_loop++;
518
519 if (!ecore_idling && !_ecore_glib_idle_enterer_called)
520 {
521 _ecore_time_loop_time = ecore_time_get();
522 _ecore_timer_expired_timers_call(_ecore_time_loop_time);
523 _ecore_timer_cleanup();
524
525 _ecore_idle_enterer_call();
526 _ecore_throttle();
527 _ecore_glib_idle_enterer_called = FALSE;
528
529 if (fd_handlers_with_buffer)
530 _ecore_main_fd_handlers_buf_call();
531 }
532
533 _ecore_signal_received_process();
534
535 /* don't check fds if somebody quit */
536 if (g_main_loop_is_running(ecore_main_loop))
537 {
538 /* only set idling state in dispatch */
539 if (ecore_idling && !_ecore_idler_exist() && !_ecore_event_exist())
540 {
541 if (_ecore_timers_exists())
542 {
543 int r = -1;
544 double t = _ecore_timer_next_get();
545 if (timer_fd >= 0 && t > 0.0)
546 {
547 struct itimerspec ts;
548
549 ts.it_interval.tv_sec = 0;
550 ts.it_interval.tv_nsec = 0;
551 ts.it_value.tv_sec = t;
552 ts.it_value.tv_nsec = fmod(t * NS_PER_SEC, NS_PER_SEC);
553
554 /* timerfd cannot sleep for 0 time */
555 if (ts.it_value.tv_sec || ts.it_value.tv_nsec)
556 {
557 r = timerfd_settime(timer_fd, 0, &ts, NULL);
558 if (r < 0)
559 {
560 ERR("timer set returned %d (errno=%d)", r, errno);
561 close(timer_fd);
562 timer_fd = -1;
563 }
564 else
565 INF("sleeping for %ld s %06ldus",
566 ts.it_value.tv_sec,
567 ts.it_value.tv_nsec / 1000);
568 }
569 }
570 if (r == -1)
571 {
572 *next_time = ceil(t * 1000.0);
573 if (t == 0.0)
574 ready = TRUE;
575 }
576 }
577 else
578 *next_time = -1;
579 }
580 else
581 {
582 *next_time = 0;
583 if (_ecore_event_exist())
584 ready = TRUE;
585 }
586
587 if (fd_handlers_with_prep)
588 _ecore_main_prepare_handlers();
589 }
590 else
591 ready = TRUE;
592
593 in_main_loop--;
594 INF("leave, timeout = %d", *next_time);
595 _ecore_unlock();
596
597 /* ready if we're not running (about to quit) */
598 return ready;
599}
600
601static gboolean
602_ecore_main_gsource_check(GSource *source __UNUSED__)
603{
604 gboolean ret = FALSE;
605
606 _ecore_lock();
607 in_main_loop++;
608
609 /* check if old timers expired */
610 if (ecore_idling && !_ecore_idler_exist() && !_ecore_event_exist())
611 {
612 if (timer_fd >= 0)
613 {
614 uint64_t count = 0;
615 int r = read(timer_fd, &count, sizeof count);
616 if (r == -1 && errno == EAGAIN)
617 ;
618 else if (r == sizeof count)
619 ret = TRUE;
620 else
621 {
622 /* unexpected things happened... fail back to old way */
623 ERR("timer read returned %d (errno=%d)", r, errno);
624 close(timer_fd);
625 timer_fd = -1;
626 }
627 }
628 }
629 else
630 ret = TRUE;
631
632 /* check if fds are ready */
633 if (HAVE_EPOLL && epoll_fd >= 0)
634 ecore_fds_ready = (_ecore_main_fdh_epoll_mark_active() > 0);
635 else
636 ecore_fds_ready = (_ecore_main_fdh_glib_mark_active() > 0);
637 _ecore_main_fd_handlers_cleanup();
638 if (ecore_fds_ready)
639 ret = TRUE;
640
641 /* check timers after updating loop time */
642 if (!ret && _ecore_timers_exists())
643 ret = (0.0 == _ecore_timer_next_get());
644
645 in_main_loop--;
646 _ecore_unlock();
647
648 return ret;
649}
650
651/* like we just came out of main_loop_select in _ecore_main_select */
652static gboolean
653_ecore_main_gsource_dispatch(GSource *source __UNUSED__,
654 GSourceFunc callback __UNUSED__,
655 gpointer user_data __UNUSED__)
656{
657 gboolean events_ready, timers_ready, idlers_ready;
658 double next_time;
659
660 _ecore_lock();
661 _ecore_time_loop_time = ecore_time_get();
662 _ecore_timer_enable_new();
663 next_time = _ecore_timer_next_get();
664
665 events_ready = _ecore_event_exist();
666 timers_ready = _ecore_timers_exists() && (0.0 == next_time);
667 idlers_ready = _ecore_idler_exist();
668
669 in_main_loop++;
670 INF("enter idling=%d fds=%d events=%d timers=%d (next=%.2f) idlers=%d",
671 ecore_idling, ecore_fds_ready, events_ready,
672 timers_ready, next_time, idlers_ready);
673
674 if (ecore_idling && events_ready)
675 {
676 _ecore_idle_exiter_call();
677 ecore_idling = 0;
678 }
679 else if (!ecore_idling && !events_ready)
680 {
681 ecore_idling = 1;
682 }
683
684 if (ecore_idling)
685 {
686 _ecore_idler_all_call();
687
688 events_ready = _ecore_event_exist();
689
690 if (ecore_fds_ready || events_ready || timers_ready)
691 {
692 _ecore_idle_exiter_call();
693 ecore_idling = 0;
694 }
695 }
696
697 /* process events */
698 if (!ecore_idling)
699 {
700 _ecore_main_fd_handlers_call();
701 if (fd_handlers_with_buffer)
702 _ecore_main_fd_handlers_buf_call();
703 _ecore_signal_received_process();
704 _ecore_event_call();
705 _ecore_main_fd_handlers_cleanup();
706
707 _ecore_timer_expired_timers_call(_ecore_time_loop_time);
708 _ecore_timer_cleanup();
709
710 _ecore_idle_enterer_call();
711 _ecore_throttle();
712 _ecore_glib_idle_enterer_called = TRUE;
713
714 if (fd_handlers_with_buffer)
715 _ecore_main_fd_handlers_buf_call();
716 }
717
718 in_main_loop--;
719 _ecore_unlock();
720
721 return TRUE; /* what should be returned here? */
722}
723
724static void
725_ecore_main_gsource_finalize(GSource *source __UNUSED__)
726{
727}
728
729static GSourceFuncs ecore_gsource_funcs =
730{
731 .prepare = _ecore_main_gsource_prepare,
732 .check = _ecore_main_gsource_check,
733 .dispatch = _ecore_main_gsource_dispatch,
734 .finalize = _ecore_main_gsource_finalize,
735};
736
737#endif
738
739void
740_ecore_main_loop_init(void)
741{
742 epoll_fd = epoll_create(1);
743 if (epoll_fd < 0)
744 WRN("Failed to create epoll fd!");
745 epoll_pid = getpid();
746
747 /* add polls on all our file descriptors */
748 Ecore_Fd_Handler *fdh;
749 EINA_INLIST_FOREACH(fd_handlers, fdh)
750 {
751 if (fdh->delete_me)
752 continue;
753 _ecore_epoll_add(epoll_fd, fdh->fd,
754 _ecore_poll_events_from_fdh(fdh), fdh);
755 _ecore_main_fdh_poll_add(fdh);
756 }
757
758 /* setup for the g_main_loop only integration */
759#ifdef USE_G_MAIN_LOOP
760 ecore_glib_source = g_source_new(&ecore_gsource_funcs, sizeof (GSource));
761 if (!ecore_glib_source)
762 CRIT("Failed to create glib source for epoll!");
763 else
764 {
765 g_source_set_priority(ecore_glib_source, G_PRIORITY_HIGH_IDLE + 20);
766 if (HAVE_EPOLL && epoll_fd >= 0)
767 {
768 /* epoll multiplexes fds into the g_main_loop */
769 ecore_epoll_fd.fd = epoll_fd;
770 ecore_epoll_fd.events = G_IO_IN;
771 ecore_epoll_fd.revents = 0;
772 g_source_add_poll(ecore_glib_source, &ecore_epoll_fd);
773 }
774
775 /* timerfd gives us better than millisecond accuracy in g_main_loop */
776 timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
777 if (timer_fd < 0)
778 WRN("failed to create timer fd!");
779 else
780 {
781 ecore_timer_fd.fd = timer_fd;
782 ecore_timer_fd.events = G_IO_IN;
783 ecore_timer_fd.revents = 0;
784 g_source_add_poll(ecore_glib_source, &ecore_timer_fd);
785 }
786
787 ecore_glib_source_id = g_source_attach(ecore_glib_source, NULL);
788 if (ecore_glib_source_id <= 0)
789 CRIT("Failed to attach glib source to default context");
790 }
791#endif
792}
793
794void
795_ecore_main_loop_shutdown(void)
796{
797#ifdef USE_G_MAIN_LOOP
798 if (ecore_glib_source)
799 {
800 g_source_destroy(ecore_glib_source);
801 ecore_glib_source = NULL;
802 }
803#endif
804
805 if (epoll_fd >= 0)
806 {
807 close(epoll_fd);
808 epoll_fd = -1;
809 }
810 epoll_pid = 0;
811
812 if (timer_fd >= 0)
813 {
814 close(timer_fd);
815 timer_fd = -1;
816 }
817}
818
819void *
820_ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler)
821{
822 if (fd_handler->delete_me)
823 {
824 ERR("fdh %p deleted twice", fd_handler);
825 return NULL;
826 }
827
828 _ecore_main_fdh_poll_del(fd_handler);
829 fd_handler->delete_me = EINA_TRUE;
830 fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fd_handler);
831 if (fd_handler->prep_func && fd_handlers_with_prep)
832 fd_handlers_with_prep = eina_list_remove(fd_handlers_with_prep, fd_handler);
833 if (fd_handler->buf_func && fd_handlers_with_buffer)
834 fd_handlers_with_buffer = eina_list_remove(fd_handlers_with_buffer, fd_handler);
835 return fd_handler->data;
836}
837
838/**
839 * @addtogroup Ecore_Main_Loop_Group
840 *
841 * @{
842 */
843
844/**
845 * Runs a single iteration of the main loop to process everything on the
846 * queue.
847 *
848 * It does everything that is already done inside an @c Ecore main loop, like
849 * checking for expired timers, idlers, etc. But it will do it only once and
850 * return, instead of keep watching for new events.
851 *
852 * DO NOT use this function unless you are the person God comes to ask for
853 * advice when He has trouble managing the Universe.
854 */
855
856EAPI int
857ecore_main_loop_iterate_may_block(int may_block)
858{
859#ifndef USE_G_MAIN_LOOP
860 _ecore_lock();
861in_main_loop++;
862 _ecore_main_loop_iterate_internal(!may_block);
863in_main_loop--;
864 _ecore_unlock();
865 return _ecore_event_exist();
866#else
867 return g_main_context_iteration(NULL, may_block);
868#endif
869}
870EAPI void
871ecore_main_loop_iterate(void)
872{
873#ifndef USE_G_MAIN_LOOP
874 _ecore_lock();
875 _ecore_main_loop_iterate_internal(1);
876 _ecore_unlock();
877#else
878 g_main_context_iteration(NULL, 0);
879#endif
880}
881
882/**
883 * Runs the application main loop.
884 *
885 * This function will not return until @ref ecore_main_loop_quit is called. It
886 * will check for expired timers, idlers, file descriptors being watched by fd
887 * handlers, etc. Once everything is done, before entering again on idle state,
888 * any callback set as @c Idle_Enterer will be called.
889 *
890 * Each main loop iteration is done by calling ecore_main_loop_iterate()
891 * internally.
892 *
893 * The polling (select) function used can be changed with
894 * ecore_main_loop_select_func_set().
895 *
896 * The function used to check for file descriptors, events, and that has a
897 * timeout for the timers can be changed using
898 * ecore_main_loop_select_func_set().
899 */
900EAPI void
901ecore_main_loop_begin(void)
902{
903#ifndef USE_G_MAIN_LOOP
904 _ecore_lock();
905 in_main_loop++;
906 while (do_quit == 0) _ecore_main_loop_iterate_internal(0);
907 do_quit = 0;
908 in_main_loop--;
909 _ecore_unlock();
910#else
911 if (!do_quit)
912 {
913 if (!ecore_main_loop)
914 ecore_main_loop = g_main_loop_new(NULL, FALSE);
915 g_main_loop_run(ecore_main_loop);
916 }
917 do_quit = 0;
918#endif
919}
920
921/**
922 * Quits the main loop once all the events currently on the queue have
923 * been processed.
924 *
925 * This function returns immediately, but will mark the ecore_main_loop_begin()
926 * function to return at the end of the current main loop iteration.
927 */
928EAPI void
929ecore_main_loop_quit(void)
930{
931 do_quit = 1;
932#ifdef USE_G_MAIN_LOOP
933 if (ecore_main_loop)
934 g_main_loop_quit(ecore_main_loop);
935#endif
936}
937
938/**
939 * Sets the function to use when monitoring multiple file descriptors,
940 * and waiting until one of more of the file descriptors before ready
941 * for some class of I/O operation.
942 *
943 * This function will be used instead of the system call select and
944 * could possible be used to integrate the Ecore event loop with an
945 * external event loop.
946 *
947 * @warning you don't know how to use, don't even try to use it.
948 *
949 */
950EAPI void
951ecore_main_loop_select_func_set(Ecore_Select_Function func)
952{
953 main_loop_select = func;
954}
955
956/**
957 * Gets the select function set by ecore_select_func_set(),
958 * or the native select function if none was set.
959 *
960 */
961EAPI Ecore_Select_Function
962ecore_main_loop_select_func_get(void)
963{
964 return main_loop_select;
965}
966
967EAPI Ecore_Fd_Handler *
968ecore_main_fd_handler_add(int fd,
969 Ecore_Fd_Handler_Flags flags,
970 Ecore_Fd_Cb func,
971 const void *data,
972 Ecore_Fd_Cb buf_func,
973 const void *buf_data)
974{
975 Ecore_Fd_Handler *fdh = NULL;
976
977 _ecore_lock();
978
979 if ((fd < 0) || (flags == 0) || (!func)) goto unlock;
980
981 fdh = ecore_fd_handler_calloc(1);
982 if (!fdh) goto unlock;
983 ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER);
984 fdh->next_ready = NULL;
985 fdh->fd = fd;
986 fdh->flags = flags;
987 if (_ecore_main_fdh_poll_add(fdh) < 0)
988 {
989 int err = errno;
990 ERR("Failed to add poll on fd %d (errno = %d: %s)!", fd, err, strerror(err));
991 ecore_fd_handler_mp_free(fdh);
992 fdh = NULL;
993 goto unlock;
994 }
995 fdh->read_active = EINA_FALSE;
996 fdh->write_active = EINA_FALSE;
997 fdh->error_active = EINA_FALSE;
998 fdh->delete_me = EINA_FALSE;
999 fdh->func = func;
1000 fdh->data = (void *)data;
1001 fdh->buf_func = buf_func;
1002 if (buf_func)
1003 fd_handlers_with_buffer = eina_list_append(fd_handlers_with_buffer, fdh);
1004 fdh->buf_data = (void *)buf_data;
1005 fd_handlers = (Ecore_Fd_Handler *)
1006 eina_inlist_append(EINA_INLIST_GET(fd_handlers),
1007 EINA_INLIST_GET(fdh));
1008unlock:
1009 _ecore_unlock();
1010
1011 return fdh;
1012}
1013
1014#ifdef _WIN32
1015EAPI Ecore_Win32_Handler *
1016ecore_main_win32_handler_add(void *h,
1017 Ecore_Win32_Handle_Cb func,
1018 const void *data)
1019{
1020 Ecore_Win32_Handler *wh;
1021
1022 if (!h || !func) return NULL;
1023
1024 wh = ecore_win32_handler_calloc(1);
1025 if (!wh) return NULL;
1026 ECORE_MAGIC_SET(wh, ECORE_MAGIC_WIN32_HANDLER);
1027 wh->h = (HANDLE)h;
1028 wh->delete_me = EINA_FALSE;
1029 wh->func = func;
1030 wh->data = (void *)data;
1031 win32_handlers = (Ecore_Win32_Handler *)
1032 eina_inlist_append(EINA_INLIST_GET(win32_handlers),
1033 EINA_INLIST_GET(wh));
1034 return wh;
1035}
1036
1037#else
1038EAPI Ecore_Win32_Handler *
1039ecore_main_win32_handler_add(void *h __UNUSED__,
1040 Ecore_Win32_Handle_Cb func __UNUSED__,
1041 const void *data __UNUSED__)
1042{
1043 return NULL;
1044}
1045
1046#endif
1047
1048EAPI void *
1049ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler)
1050{
1051 void *ret = NULL;
1052
1053 _ecore_lock();
1054
1055 if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
1056 {
1057 ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
1058 "ecore_main_fd_handler_del");
1059 goto unlock;
1060 }
1061 ret = _ecore_main_fd_handler_del(fd_handler);
1062unlock:
1063 _ecore_unlock();
1064 return ret;
1065}
1066
1067#ifdef _WIN32
1068EAPI void *
1069ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler)
1070{
1071 if (!ECORE_MAGIC_CHECK(win32_handler, ECORE_MAGIC_WIN32_HANDLER))
1072 {
1073 ECORE_MAGIC_FAIL(win32_handler, ECORE_MAGIC_WIN32_HANDLER,
1074 "ecore_main_win32_handler_del");
1075 return NULL;
1076 }
1077 win32_handler->delete_me = EINA_TRUE;
1078 win32_handlers_delete_me = EINA_TRUE;
1079 return win32_handler->data;
1080}
1081
1082#else
1083EAPI void *
1084ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler __UNUSED__)
1085{
1086 return NULL;
1087}
1088
1089#endif
1090
1091EAPI void
1092ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler,
1093 Ecore_Fd_Prep_Cb func,
1094 const void *data)
1095{
1096 _ecore_lock();
1097
1098 if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
1099 {
1100 ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
1101 "ecore_main_fd_handler_prepare_callback_set");
1102 goto unlock;
1103 }
1104 fd_handler->prep_func = func;
1105 fd_handler->prep_data = (void *)data;
1106 if ((!fd_handlers_with_prep) ||
1107 (fd_handlers_with_prep && (!eina_list_data_find(fd_handlers_with_prep, fd_handler))))
1108 /* FIXME: THIS WILL NOT SCALE WITH LOTS OF PREP FUNCTIONS!!! */
1109 fd_handlers_with_prep = eina_list_append(fd_handlers_with_prep, fd_handler);
1110unlock:
1111 _ecore_unlock();
1112}
1113
1114EAPI int
1115ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler)
1116{
1117 int fd = -1;
1118
1119 _ecore_lock();
1120
1121 if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
1122 {
1123 ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
1124 "ecore_main_fd_handler_fd_get");
1125 goto unlock;
1126 }
1127 fd = fd_handler->fd;
1128unlock:
1129 _ecore_unlock();
1130 return fd;
1131}
1132
1133EAPI Eina_Bool
1134ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler,
1135 Ecore_Fd_Handler_Flags flags)
1136{
1137 int ret = EINA_FALSE;
1138
1139 _ecore_lock();
1140
1141 if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
1142 {
1143 ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
1144 "ecore_main_fd_handler_active_get");
1145 goto unlock;
1146 }
1147 if ((flags & ECORE_FD_READ) && (fd_handler->read_active)) ret = EINA_TRUE;
1148 if ((flags & ECORE_FD_WRITE) && (fd_handler->write_active)) ret = EINA_TRUE;
1149 if ((flags & ECORE_FD_ERROR) && (fd_handler->error_active)) ret = EINA_TRUE;
1150unlock:
1151 _ecore_unlock();
1152 return ret;
1153}
1154
1155EAPI void
1156ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler,
1157 Ecore_Fd_Handler_Flags flags)
1158{
1159 int ret;
1160
1161 _ecore_lock();
1162
1163 if (!ECORE_MAGIC_CHECK(fd_handler, ECORE_MAGIC_FD_HANDLER))
1164 {
1165 ECORE_MAGIC_FAIL(fd_handler, ECORE_MAGIC_FD_HANDLER,
1166 "ecore_main_fd_handler_active_set");
1167 goto unlock;
1168 }
1169 fd_handler->flags = flags;
1170 ret = _ecore_main_fdh_poll_modify(fd_handler);
1171 if (ret < 0)
1172 {
1173 ERR("Failed to mod epoll fd %d: %s!", fd_handler->fd, strerror(ret));
1174 }
1175unlock:
1176 _ecore_unlock();
1177}
1178
1179/**
1180 * @}
1181 */
1182
1183void
1184_ecore_main_shutdown(void)
1185{
1186 if (in_main_loop)
1187 {
1188 ERR("\n"
1189 "*** ECORE WARINING: Calling ecore_shutdown() while still in the main loop.\n"
1190 "*** Program may crash or behave strangely now.");
1191 return;
1192 }
1193 while (fd_handlers)
1194 {
1195 Ecore_Fd_Handler *fdh;
1196
1197 fdh = fd_handlers;
1198 fd_handlers = (Ecore_Fd_Handler *)eina_inlist_remove(EINA_INLIST_GET(fd_handlers),
1199 EINA_INLIST_GET(fdh));
1200 ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
1201 ecore_fd_handler_mp_free(fdh);
1202 }
1203 if (fd_handlers_with_buffer)
1204 fd_handlers_with_buffer = eina_list_free(fd_handlers_with_buffer);
1205 if (fd_handlers_with_prep)
1206 fd_handlers_with_prep = eina_list_free(fd_handlers_with_prep);
1207 if (fd_handlers_to_delete)
1208 fd_handlers_to_delete = eina_list_free(fd_handlers_to_delete);
1209
1210 fd_handlers_to_call = NULL;
1211 fd_handlers_to_call_current = NULL;
1212 fd_handlers_to_delete = NULL;
1213 fd_handler_current = NULL;
1214
1215#ifdef _WIN32
1216 while (win32_handlers)
1217 {
1218 Ecore_Win32_Handler *wh;
1219
1220 wh = win32_handlers;
1221 win32_handlers = (Ecore_Win32_Handler *)eina_inlist_remove(EINA_INLIST_GET(win32_handlers),
1222 EINA_INLIST_GET(wh));
1223 ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE);
1224 ecore_win32_handler_mp_free(wh);
1225 }
1226 win32_handlers_delete_me = EINA_FALSE;
1227 win32_handler_current = NULL;
1228#endif
1229}
1230
1231static void
1232_ecore_main_prepare_handlers(void)
1233{
1234 Ecore_Fd_Handler *fdh;
1235 Eina_List *l, *l2;
1236
1237 /* call the prepare callback for all handlers with prep functions */
1238 EINA_LIST_FOREACH_SAFE(fd_handlers_with_prep, l, l2, fdh)
1239 {
1240 if (!fdh)
1241 {
1242 fd_handlers_with_prep = eina_list_remove_list(l, fd_handlers_with_prep);
1243 continue;
1244 }
1245 if (!fdh->delete_me && fdh->prep_func)
1246 {
1247 fdh->references++;
1248 _ecore_call_prep_cb(fdh->prep_func, fdh->prep_data, fdh);
1249 fdh->references--;
1250 }
1251 else
1252 fd_handlers_with_prep = eina_list_remove_list(fd_handlers_with_prep, l);
1253 }
1254}
1255
1256#ifndef USE_G_MAIN_LOOP
1257static int
1258_ecore_main_select(double timeout)
1259{
1260 struct timeval tv, *t;
1261 fd_set rfds, wfds, exfds;
1262 int max_fd;
1263 int ret;
1264
1265 t = NULL;
1266 if ((!ECORE_FINITE(timeout)) || (timeout == 0.0)) /* finite() tests for NaN, too big, too small, and infinity. */
1267 {
1268 tv.tv_sec = 0;
1269 tv.tv_usec = 0;
1270 t = &tv;
1271 }
1272 else if (timeout > 0.0)
1273 {
1274 int sec, usec;
1275
1276#ifdef FIX_HZ
1277 timeout += (0.5 / HZ);
1278 sec = (int)timeout;
1279 usec = (int)((timeout - (double)sec) * 1000000);
1280#else
1281 sec = (int)timeout;
1282 usec = (int)((timeout - (double)sec) * 1000000);
1283#endif
1284 tv.tv_sec = sec;
1285 tv.tv_usec = usec;
1286 t = &tv;
1287 }
1288 max_fd = 0;
1289 FD_ZERO(&rfds);
1290 FD_ZERO(&wfds);
1291 FD_ZERO(&exfds);
1292
1293 /* call the prepare callback for all handlers */
1294 if (fd_handlers_with_prep)
1295 _ecore_main_prepare_handlers();
1296
1297 if (!HAVE_EPOLL || epoll_fd < 0)
1298 {
1299 Ecore_Fd_Handler *fdh;
1300
1301 EINA_INLIST_FOREACH(fd_handlers, fdh)
1302 {
1303 if (!fdh->delete_me)
1304 {
1305 if (fdh->flags & ECORE_FD_READ)
1306 {
1307 FD_SET(fdh->fd, &rfds);
1308 if (fdh->fd > max_fd) max_fd = fdh->fd;
1309 }
1310 if (fdh->flags & ECORE_FD_WRITE)
1311 {
1312 FD_SET(fdh->fd, &wfds);
1313 if (fdh->fd > max_fd) max_fd = fdh->fd;
1314 }
1315 if (fdh->flags & ECORE_FD_ERROR)
1316 {
1317 FD_SET(fdh->fd, &exfds);
1318 if (fdh->fd > max_fd) max_fd = fdh->fd;
1319 }
1320 }
1321 }
1322 }
1323 else
1324 {
1325 /* polling on the epoll fd will wake when an fd in the epoll set is active */
1326 max_fd = _ecore_get_epoll_fd();
1327 FD_SET(max_fd, &rfds);
1328 }
1329
1330 if (_ecore_signal_count_get()) return -1;
1331
1332 _ecore_unlock();
1333 ret = main_loop_select(max_fd + 1, &rfds, &wfds, &exfds, t);
1334 _ecore_lock();
1335
1336 _ecore_time_loop_time = ecore_time_get();
1337 if (ret < 0)
1338 {
1339#ifndef _WIN32
1340 if (errno == EINTR) return -1;
1341 else if (errno == EBADF)
1342 _ecore_main_fd_handlers_bads_rem();
1343#endif
1344 }
1345 if (ret > 0)
1346 {
1347 if (HAVE_EPOLL && epoll_fd >= 0)
1348 _ecore_main_fdh_epoll_mark_active();
1349 else
1350 {
1351 Ecore_Fd_Handler *fdh;
1352
1353 EINA_INLIST_FOREACH(fd_handlers, fdh)
1354 {
1355 if (!fdh->delete_me)
1356 {
1357 if (FD_ISSET(fdh->fd, &rfds))
1358 fdh->read_active = EINA_TRUE;
1359 if (FD_ISSET(fdh->fd, &wfds))
1360 fdh->write_active = EINA_TRUE;
1361 if (FD_ISSET(fdh->fd, &exfds))
1362 fdh->error_active = EINA_TRUE;
1363 _ecore_try_add_to_call_list(fdh);
1364 }
1365 }
1366 }
1367
1368 _ecore_main_fd_handlers_cleanup();
1369#ifdef _WIN32
1370 _ecore_main_win32_handlers_cleanup();
1371#endif
1372 return 1;
1373 }
1374 return 0;
1375}
1376
1377#endif
1378
1379#ifndef _WIN32
1380# ifndef USE_G_MAIN_LOOP
1381static void
1382_ecore_main_fd_handlers_bads_rem(void)
1383{
1384 Ecore_Fd_Handler *fdh;
1385 Eina_Inlist *l;
1386 int found = 0;
1387
1388 ERR("Removing bad fds");
1389 for (l = EINA_INLIST_GET(fd_handlers); l; )
1390 {
1391 fdh = (Ecore_Fd_Handler *)l;
1392 l = l->next;
1393 errno = 0;
1394
1395 if ((fcntl(fdh->fd, F_GETFD) < 0) && (errno == EBADF))
1396 {
1397 ERR("Found bad fd at index %d", fdh->fd);
1398 if (fdh->flags & ECORE_FD_ERROR)
1399 {
1400 ERR("Fd set for error! calling user");
1401 fdh->references++;
1402 if (!_ecore_call_fd_cb(fdh->func, fdh->data, fdh))
1403 {
1404 ERR("Fd function err returned 0, remove it");
1405 if (!fdh->delete_me)
1406 {
1407 fdh->delete_me = EINA_TRUE;
1408 fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh);
1409 }
1410 found++;
1411 }
1412 fdh->references--;
1413 }
1414 else
1415 {
1416 ERR("Problematic fd found at %d! setting it for delete", fdh->fd);
1417 if (!fdh->delete_me)
1418 {
1419 fdh->delete_me = EINA_TRUE;
1420 fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh);
1421 }
1422
1423 found++;
1424 }
1425 }
1426 }
1427 if (found == 0)
1428 {
1429# ifdef HAVE_GLIB
1430 ERR("No bad fd found. Maybe a foreign fd from glib?");
1431# else
1432 ERR("No bad fd found. EEEK!");
1433# endif
1434 }
1435 _ecore_main_fd_handlers_cleanup();
1436}
1437
1438# endif
1439#endif
1440
1441static void
1442_ecore_main_fd_handlers_cleanup(void)
1443{
1444 Ecore_Fd_Handler *fdh;
1445 Eina_List *l, *l2;
1446
1447 if (!fd_handlers_to_delete) return;
1448 EINA_LIST_FOREACH_SAFE(fd_handlers_to_delete, l, l2, fdh)
1449 {
1450 if (!fdh)
1451 {
1452 fd_handlers_to_delete = eina_list_remove_list(l, fd_handlers_to_delete);
1453 continue;
1454 }
1455 /* fdh->delete_me should be set for all fdhs at the start of the list */
1456 if (fdh->references)
1457 continue;
1458 if (fdh->buf_func && fd_handlers_with_buffer)
1459 fd_handlers_with_buffer = eina_list_remove(fd_handlers_with_buffer, fdh);
1460 if (fdh->prep_func && fd_handlers_with_prep)
1461 fd_handlers_with_prep = eina_list_remove(fd_handlers_with_prep, fdh);
1462 fd_handlers = (Ecore_Fd_Handler *)
1463 eina_inlist_remove(EINA_INLIST_GET(fd_handlers), EINA_INLIST_GET(fdh));
1464 ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
1465 ecore_fd_handler_mp_free(fdh);
1466 fd_handlers_to_delete = eina_list_remove_list(fd_handlers_to_delete, l);
1467 }
1468}
1469
1470#ifdef _WIN32
1471static void
1472_ecore_main_win32_handlers_cleanup(void)
1473{
1474 Ecore_Win32_Handler *wh;
1475 Eina_Inlist *l;
1476 int deleted_in_use = 0;
1477
1478 if (!win32_handlers_delete_me) return;
1479 for (l = EINA_INLIST_GET(win32_handlers); l; )
1480 {
1481 wh = (Ecore_Win32_Handler *)l;
1482
1483 l = l->next;
1484 if (wh->delete_me)
1485 {
1486 if (wh->references)
1487 {
1488 deleted_in_use++;
1489 continue;
1490 }
1491
1492 win32_handlers = (Ecore_Win32_Handler *)
1493 eina_inlist_remove(EINA_INLIST_GET(win32_handlers),
1494 EINA_INLIST_GET(wh));
1495 ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE);
1496 ecore_win32_handler_mp_free(wh);
1497 }
1498 }
1499 if (!deleted_in_use) win32_handlers_delete_me = EINA_FALSE;
1500}
1501
1502#endif
1503
1504static void
1505_ecore_main_fd_handlers_call(void)
1506{
1507 /* grab a new list */
1508 if (!fd_handlers_to_call_current)
1509 {
1510 fd_handlers_to_call_current = fd_handlers_to_call;
1511 fd_handlers_to_call = NULL;
1512 }
1513
1514 while (fd_handlers_to_call_current)
1515 {
1516 Ecore_Fd_Handler *fdh = fd_handlers_to_call_current;
1517
1518 if (!fdh->delete_me)
1519 {
1520 if ((fdh->read_active) ||
1521 (fdh->write_active) ||
1522 (fdh->error_active))
1523 {
1524 fdh->references++;
1525 if (!_ecore_call_fd_cb(fdh->func, fdh->data, fdh))
1526 {
1527 if (!fdh->delete_me)
1528 {
1529 fdh->delete_me = EINA_TRUE;
1530 fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh);
1531 }
1532 }
1533 fdh->references--;
1534 _ecore_fd_valid();
1535
1536 fdh->read_active = EINA_FALSE;
1537 fdh->write_active = EINA_FALSE;
1538 fdh->error_active = EINA_FALSE;
1539 }
1540 }
1541
1542 /* stop when we point to ourselves */
1543 if (fdh->next_ready == fdh)
1544 {
1545 fdh->next_ready = NULL;
1546 fd_handlers_to_call_current = NULL;
1547 break;
1548 }
1549
1550 fd_handlers_to_call_current = fdh->next_ready;
1551 fdh->next_ready = NULL;
1552 }
1553}
1554
1555static int
1556_ecore_main_fd_handlers_buf_call(void)
1557{
1558 Ecore_Fd_Handler *fdh;
1559 Eina_List *l, *l2;
1560 int ret;
1561
1562 ret = 0;
1563 EINA_LIST_FOREACH_SAFE(fd_handlers_with_buffer, l, l2, fdh)
1564 {
1565 if (!fdh)
1566 {
1567 fd_handlers_with_buffer = eina_list_remove_list(l, fd_handlers_with_buffer);
1568 continue;
1569 }
1570 if ((!fdh->delete_me) && fdh->buf_func)
1571 {
1572 fdh->references++;
1573 if (_ecore_call_fd_cb(fdh->buf_func, fdh->buf_data, fdh))
1574 {
1575 ret |= _ecore_call_fd_cb(fdh->func, fdh->data, fdh);
1576 fdh->read_active = EINA_TRUE;
1577 _ecore_try_add_to_call_list(fdh);
1578 }
1579 fdh->references--;
1580 }
1581 else
1582 fd_handlers_with_buffer = eina_list_remove_list(fd_handlers_with_buffer, l);
1583 }
1584 return ret;
1585}
1586
1587#ifndef USE_G_MAIN_LOOP
1588
1589enum {
1590 SPIN_MORE,
1591 SPIN_RESTART,
1592 LOOP_CONTINUE
1593};
1594
1595static int
1596_ecore_main_loop_spin_core(void)
1597{
1598 /* as we are spinning we need to update loop time per spin */
1599 _ecore_time_loop_time = ecore_time_get();
1600 /* call all idlers, which returns false if no more idelrs exist */
1601 if (!_ecore_idler_all_call()) return SPIN_RESTART;
1602 /* sneaky - drop through or if checks - the first one to succeed
1603 * drops through and returns "continue" so further ones dont run */
1604 if ((_ecore_main_select(0.0) > 0) || (_ecore_event_exist()) ||
1605 (_ecore_signal_count_get() > 0) || (do_quit))
1606 return LOOP_CONTINUE;
1607 /* default - spin more */
1608 return SPIN_MORE;
1609}
1610
1611static int
1612_ecore_main_loop_spin_no_timers(void)
1613{
1614 /* if we have idlers we HAVE to spin and handle everything
1615 * in a polling way - spin in a tight polling loop */
1616 for (;; )
1617 {
1618 int action = _ecore_main_loop_spin_core();
1619 if (action != SPIN_MORE) return action;
1620 /* if an idler has added a timer then we need to go through
1621 * the start of the spin cycle again to handle cases properly */
1622 if (_ecore_timers_exists()) return SPIN_RESTART;
1623 }
1624 /* just contiune handling events etc. */
1625 return LOOP_CONTINUE;
1626}
1627
1628static int
1629_ecore_main_loop_spin_timers(void)
1630{
1631 /* if we have idlers we HAVE to spin and handle everything
1632 * in a polling way - spin in a tight polling loop */
1633 for (;; )
1634 {
1635 int action = _ecore_main_loop_spin_core();
1636 if (action != SPIN_MORE) return action;
1637 /* if next timer expires now or in the past - stop spinning and
1638 * continue the mainloop walk as our "select" timeout has
1639 * expired now */
1640 if (_ecore_timer_next_get() <= 0.0) return LOOP_CONTINUE;
1641 }
1642 /* just contiune handling events etc. */
1643 return LOOP_CONTINUE;
1644}
1645
1646static void
1647_ecore_fps_marker_1(void)
1648{
1649 if (!_ecore_fps_debug) return;
1650 t2 = ecore_time_get();
1651 if ((t1 > 0.0) && (t2 > 0.0)) _ecore_fps_debug_runtime_add(t2 - t1);
1652}
1653
1654static void
1655_ecore_fps_marker_2(void)
1656{
1657 if (!_ecore_fps_debug) return;
1658 t1 = ecore_time_get();
1659}
1660
1661static void
1662_ecore_main_loop_iterate_internal(int once_only)
1663{
1664 double next_time = -1.0;
1665
1666 in_main_loop++;
1667 /* expire any timers */
1668 _ecore_timer_expired_timers_call(_ecore_time_loop_time);
1669 _ecore_timer_cleanup();
1670
1671 /* process signals into events .... */
1672 _ecore_signal_received_process();
1673 /* if as a result of timers/animators or signals we have accumulated
1674 * events, then instantly handle them */
1675 if (_ecore_event_exist())
1676 {
1677 /* but first conceptually enter an idle state */
1678 _ecore_idle_enterer_call();
1679 _ecore_throttle();
1680 /* now quickly poll to see which input fd's are active */
1681 _ecore_main_select(0.0);
1682 /* allow newly queued timers to expire from now on */
1683 _ecore_timer_enable_new();
1684 /* go straight to processing the events we had queued */
1685 goto process_all;
1686 }
1687
1688 if (once_only)
1689 {
1690 /* in once_only mode we should quickly poll for inputs, signals
1691 * if we got any events or signals, allow new timers to process.
1692 * use bitwise or to force both conditions to be tested and
1693 * merged together */
1694 if (_ecore_main_select(0.0) | _ecore_signal_count_get())
1695 {
1696 _ecore_timer_enable_new();
1697 goto process_all;
1698 }
1699 }
1700 else
1701 {
1702 /* call idle enterers ... */
1703 _ecore_idle_enterer_call();
1704 _ecore_throttle();
1705 }
1706
1707 /* if these calls caused any buffered events to appear - deal with them */
1708 if (fd_handlers_with_buffer)
1709 _ecore_main_fd_handlers_buf_call();
1710
1711 /* if there are any (buffered fd handling may generate them)
1712 * then jump to processing them */
1713 if (_ecore_event_exist())
1714 {
1715 _ecore_main_select(0.0);
1716 _ecore_timer_enable_new();
1717 goto process_all;
1718 }
1719
1720 if (once_only)
1721 {
1722 /* in once_only mode enter idle here instead and then return */
1723 _ecore_idle_enterer_call();
1724 _ecore_throttle();
1725 _ecore_timer_enable_new();
1726 goto done;
1727 }
1728
1729 _ecore_fps_marker_1();
1730
1731 /* start of the sleeping or looping section */
1732start_loop: /***************************************************************/
1733 /* any timers re-added as a result of these are allowed to go */
1734 _ecore_timer_enable_new();
1735 /* if we have been asked to quit the mainloop then exit at this point */
1736 if (do_quit)
1737 {
1738 _ecore_timer_enable_new();
1739 goto done;
1740 }
1741 if (!_ecore_event_exist())
1742 {
1743 /* init flags */
1744 next_time = _ecore_timer_next_get();
1745 /* no idlers */
1746 if (!_ecore_idler_exist())
1747 {
1748 /* sleep until timeout or forever (-1.0) waiting for on fds */
1749 _ecore_main_select(next_time);
1750 }
1751 else
1752 {
1753 int action = LOOP_CONTINUE;
1754
1755 /* no timers - spin */
1756 if (next_time < 0) action = _ecore_main_loop_spin_no_timers();
1757 /* timers - spin */
1758 else action = _ecore_main_loop_spin_timers();
1759 if (action == SPIN_RESTART) goto start_loop;
1760 }
1761 }
1762 _ecore_fps_marker_2();
1763
1764 /* actually wake up and deal with input, events etc. */
1765process_all: /***********************************************************/
1766
1767 /* we came out of our "wait state" so idle has exited */
1768 if (!once_only) _ecore_idle_exiter_call();
1769 /* call the fd handler per fd that became alive... */
1770 /* this should read or write any data to the monitored fd and then */
1771 /* post events onto the ecore event pipe if necessary */
1772 _ecore_main_fd_handlers_call();
1773 if (fd_handlers_with_buffer) _ecore_main_fd_handlers_buf_call();
1774 /* process signals into events .... */
1775 _ecore_signal_received_process();
1776 /* handle events ... */
1777 _ecore_event_call();
1778 _ecore_main_fd_handlers_cleanup();
1779
1780 if (once_only)
1781 {
1782 /* if in once_only mode handle idle exiting */
1783 _ecore_idle_enterer_call();
1784 _ecore_throttle();
1785 }
1786
1787done: /*******************************************************************/
1788 in_main_loop--;
1789}
1790
1791#endif
1792
1793#ifdef _WIN32
1794static int
1795_ecore_main_win32_select(int nfds __UNUSED__,
1796 fd_set *readfds,
1797 fd_set *writefds,
1798 fd_set *exceptfds,
1799 struct timeval *tv)
1800{
1801 HANDLE objects[MAXIMUM_WAIT_OBJECTS];
1802 int sockets[MAXIMUM_WAIT_OBJECTS];
1803 Ecore_Fd_Handler *fdh;
1804 Ecore_Win32_Handler *wh;
1805 unsigned int objects_nbr = 0;
1806 unsigned int handles_nbr = 0;
1807 unsigned int events_nbr = 0;
1808 DWORD result;
1809 DWORD timeout;
1810 MSG msg;
1811 unsigned int i;
1812 int res;
1813
1814 /* Create an event object per socket */
1815 EINA_INLIST_FOREACH(fd_handlers, fdh)
1816 {
1817 WSAEVENT event;
1818 long network_event;
1819
1820 network_event = 0;
1821 if (FD_ISSET(fdh->fd, readfds))
1822 network_event |= FD_READ;
1823 if (FD_ISSET(fdh->fd, writefds))
1824 network_event |= FD_WRITE;
1825 if (FD_ISSET(fdh->fd, exceptfds))
1826 network_event |= FD_OOB;
1827
1828 if (network_event)
1829 {
1830 event = WSACreateEvent();
1831 WSAEventSelect(fdh->fd, event, network_event);
1832 objects[objects_nbr] = event;
1833 sockets[events_nbr] = fdh->fd;
1834 events_nbr++;
1835 objects_nbr++;
1836 }
1837 }
1838
1839 /* store the HANDLEs in the objects to wait for */
1840 EINA_INLIST_FOREACH(win32_handlers, wh)
1841 {
1842 objects[objects_nbr] = wh->h;
1843 handles_nbr++;
1844 objects_nbr++;
1845 }
1846
1847 /* Empty the queue before waiting */
1848 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
1849 {
1850 TranslateMessage(&msg);
1851 DispatchMessage(&msg);
1852 }
1853
1854 /* Wait for any message sent or posted to this queue */
1855 /* or for one of the passed handles be set to signaled. */
1856 if (!tv)
1857 timeout = INFINITE;
1858 else
1859 timeout = (DWORD)((tv->tv_sec * 1000.0) + (tv->tv_usec / 1000.0));
1860
1861 if (timeout == 0) return 0;
1862
1863 result = MsgWaitForMultipleObjects(objects_nbr, (const HANDLE *)objects, EINA_FALSE,
1864 timeout, QS_ALLINPUT);
1865
1866 FD_ZERO(readfds);
1867 FD_ZERO(writefds);
1868 FD_ZERO(exceptfds);
1869
1870 /* The result tells us the type of event we have. */
1871 if (result == WAIT_FAILED)
1872 {
1873 char *m;
1874
1875 m = evil_last_error_get();
1876 ERR(" * %s\n", m);
1877 free(m);
1878 res = -1;
1879 }
1880 else if (result == WAIT_TIMEOUT)
1881 {
1882 /* ERR("time out\n"); */
1883 res = 0;
1884 }
1885 else if (result == (WAIT_OBJECT_0 + objects_nbr))
1886 {
1887 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
1888 {
1889 TranslateMessage(&msg);
1890 DispatchMessage(&msg);
1891 }
1892
1893 res = 0;
1894 }
1895 else if ((result >= 0) && (result < WAIT_OBJECT_0 + events_nbr))
1896 {
1897 WSANETWORKEVENTS network_event;
1898
1899 WSAEnumNetworkEvents(sockets[result], objects[result], &network_event);
1900
1901 if (network_event.lNetworkEvents & FD_READ)
1902 FD_SET(sockets[result], readfds);
1903 if (network_event.lNetworkEvents & FD_WRITE)
1904 FD_SET(sockets[result], writefds);
1905 if (network_event.lNetworkEvents & FD_OOB)
1906 FD_SET(sockets[result], exceptfds);
1907
1908 res = 1;
1909 }
1910 else if ((result >= (WAIT_OBJECT_0 + events_nbr)) &&
1911 (result < (WAIT_OBJECT_0 + objects_nbr)))
1912 {
1913 if (!win32_handler_current)
1914 {
1915 /* regular main loop, start from head */
1916 win32_handler_current = win32_handlers;
1917 }
1918 else
1919 {
1920 /* recursive main loop, continue from where we were */
1921 win32_handler_current = (Ecore_Win32_Handler *)EINA_INLIST_GET(win32_handler_current)->next;
1922 }
1923
1924 while (win32_handler_current)
1925 {
1926 wh = win32_handler_current;
1927
1928 if (objects[result - WAIT_OBJECT_0] == wh->h)
1929 {
1930 if (!wh->delete_me)
1931 {
1932 wh->references++;
1933 if (!wh->func(wh->data, wh))
1934 {
1935 wh->delete_me = EINA_TRUE;
1936 win32_handlers_delete_me = EINA_TRUE;
1937 }
1938 wh->references--;
1939 }
1940 }
1941 if (win32_handler_current) /* may have changed in recursive main loops */
1942 win32_handler_current = (Ecore_Win32_Handler *)EINA_INLIST_GET(win32_handler_current)->next;
1943 }
1944 res = 1;
1945 }
1946 else
1947 {
1948 ERR("unknown result...\n");
1949 res = -1;
1950 }
1951
1952 /* Remove event objects again */
1953 for (i = 0; i < events_nbr; i++) WSACloseEvent(objects[i]);
1954
1955 return res;
1956}
1957
1958#endif