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