aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ecore/src/lib/ecore')
-rw-r--r--libraries/ecore/src/lib/ecore/Ecore.h896
-rw-r--r--libraries/ecore/src/lib/ecore/Makefile.am8
-rw-r--r--libraries/ecore/src/lib/ecore/Makefile.in33
-rw-r--r--libraries/ecore/src/lib/ecore/ecore.c6
-rw-r--r--libraries/ecore/src/lib/ecore/ecore_anim.c4
-rw-r--r--libraries/ecore/src/lib/ecore/ecore_events.c158
-rw-r--r--libraries/ecore/src/lib/ecore/ecore_exe.c10
-rw-r--r--libraries/ecore/src/lib/ecore/ecore_getopt.c4
-rw-r--r--libraries/ecore/src/lib/ecore/ecore_main.c185
-rw-r--r--libraries/ecore/src/lib/ecore/ecore_pipe.c17
-rw-r--r--libraries/ecore/src/lib/ecore/ecore_poll.c94
-rw-r--r--libraries/ecore/src/lib/ecore/ecore_private.h6
-rw-r--r--libraries/ecore/src/lib/ecore/ecore_thread.c756
-rw-r--r--libraries/ecore/src/lib/ecore/ecore_time.c6
-rw-r--r--libraries/ecore/src/lib/ecore/ecore_timer.c19
15 files changed, 1121 insertions, 1081 deletions
diff --git a/libraries/ecore/src/lib/ecore/Ecore.h b/libraries/ecore/src/lib/ecore/Ecore.h
index fbe4dda..eace560 100644
--- a/libraries/ecore/src/lib/ecore/Ecore.h
+++ b/libraries/ecore/src/lib/ecore/Ecore.h
@@ -9,7 +9,7 @@
9 @mainpage Ecore 9 @mainpage Ecore
10 10
11 @version 1.1 11 @version 1.1
12 @date 2000-2011 12 @date 2000-2012
13 13
14 Please see the @ref authors page for contact details. 14 Please see the @ref authors page for contact details.
15 15
@@ -22,7 +22,7 @@
22 @li @ref Ecore_Main_Loop_Group 22 @li @ref Ecore_Main_Loop_Group
23 @li @ref Ecore_File_Group 23 @li @ref Ecore_File_Group
24 @li @ref Ecore_Con_Group 24 @li @ref Ecore_Con_Group
25 @li @link Ecore_Evas.h Ecore_Evas - Evas convenience functions. @endlink 25 @li @ref Ecore_Evas_Group
26 @li @ref Ecore_FB_Group 26 @li @ref Ecore_FB_Group
27 @li @link Ecore_Ipc.h Ecore_IPC - Inter Process Communication functions. @endlink 27 @li @link Ecore_Ipc.h Ecore_IPC - Inter Process Communication functions. @endlink
28 @li @link Ecore_X.h Ecore_X - X Windows System wrapper. @endlink 28 @li @link Ecore_X.h Ecore_X - X Windows System wrapper. @endlink
@@ -35,21 +35,31 @@
35 pkgconfig (.pc) files are installed for every ecore module. 35 pkgconfig (.pc) files are installed for every ecore module.
36 Thus, to compile using any of them, you can use something like the following: 36 Thus, to compile using any of them, you can use something like the following:
37 37
38 @verbatim 38@verbatim
39 gcc *.c $(pkg-config ecore ecore-$x ecore-$y [...] --cflags --libs) 39gcc *.c $(pkg-config ecore ecore-$x ecore-$y [...] --cflags --libs)
40 @endverbatim 40@endverbatim
41 41
42 @section install How is it installed? 42 @section install How is it installed?
43 43
44 Suggested configure options for evas for a Linux desktop X display: 44 Suggested configure options for ecore for a Linux desktop X display
45 with OpenGL and Software support, communication (networking) and
46 IPC (inter process communication):
45 47
46 @verbatim 48@verbatim
47 ./configure \ 49./configure \
48 make 50 --enable-ecore-con \
49 su - 51 --enable-ecore-ipc \
50 ... 52 --enable-ecore-file \
51 make install 53 --enable-ecore-input \
52 @endverbatim 54 --enable-ecore-input-evas \
55 --enable-ecore-x \
56 --enable-ecore-evas \
57 --enable-ecore-evas-software-buffer \
58 --enable-ecore-evas-software-x11 \
59 --enable-ecore-evas-opengl-x11
60make
61sudo make install
62@endverbatim
53 63
54 */ 64 */
55 65
@@ -112,140 +122,175 @@
112 */ 122 */
113 123
114/** 124/**
115 @page Ecore_Main_Loop_Page The Ecore Main Loop 125 * @page Ecore_Main_Loop_Page The Ecore Main Loop
116 126 *
117 @section intro What is Ecore? 127 * @section intro What is Ecore?
118 128 *
119 Ecore is a clean and tiny event loop library with many modules to do lots of 129 * Ecore is a clean and tiny event loop library with many modules to do lots of
120 convenient things for a programmer, to save time and effort. 130 * convenient things for a programmer, to save time and effort. It's small and
121 131 * lean, designed to work from embedded systems all the way up to large and
122 It's small and lean, designed to work on embedded systems all the way to 132 * powerful multi-cpu workstations. The main loop has a number of primitives to
123 large and powerful multi-cpu workstations. It serialises all system signals, 133 * be used with its main loop. It serializes all the primitives and allows for
124 events etc. into a single event queue, that is easily processed without 134 * great responsiveness without the need for threads(or any other concurrency).
125 needing to worry about concurrency. A properly written, event-driven program 135 *
126 using this kind of programming doesn't need threads, nor has to worry about 136 * @subsection timers Timers
127 concurrency. It turns a program into a state machine, and makes it very 137 *
128 robust and easy to follow. 138 * Timers serve two main purposes: doing something at a specified time and
129 139 * repeatedly doing something with a set interval.
130 Ecore gives you other handy primitives, such as timers to tick over for you 140 * @see Ecore_Timer_Group
131 and call specified functions at particular times so the programmer can use 141 *
132 this to do things, like animate, or time out on connections or tasks that take 142 * @subsection poolers Poolers
133 too long etc. 143 *
134 144 * Poolers allow for pooling to be centralized into a single place therefore
135 Idle handlers are provided too, as well as calls on entering an idle state 145 * alleviating the need for different parts of the program to wake up at
136 (often a very good time to update the state of the program). All events that 146 * different times to do pooling, thereby making the code simpler and more
137 enter the system are passed to specific callback functions that the program 147 * efficient.
138 sets up to handle those events. Handling them is simple and other Ecore 148 * @see Ecore_Poller_Group
139 modules produce more events on the queue, coming from other sources such as 149 *
140 file descriptors etc. 150 * @subsection idler Idlers
141 151 *
142 Ecore also lets you have functions called when file descriptors become active 152 * There are three types of idlers, enterers, idlers(proper) and exiters, they
143 for reading or writing, allowing for streamlined, non-blocking IO. 153 * are called, respectively, when the program is about to enter an idle state,
144 154 * when the program is idle and when the program is leaving an idle state. Idler
145 Here is an example of a simple program and its basic event loop flow: 155 * enterers are usually a good place to update the program state. Proper idlers
146 156 * are the appropriate place to do heavy computational tasks thereby using what
147 @image html prog_flow.png 157 * would otherwise be wasted CPU cycles. Exiters are the perfect place to do
148 @image latex prog_flow.eps width=\textwidth 158 * anything your program should do just before processing events(also timers,
149 159 * poolers, file descriptor handlers and animators)
150 160 * @see Ecore_Idle_Group
151 161 *
152 @section work How does Ecore work? 162 * @subsection fd_handler File descriptor handlers
153 163 *
154 Ecore is very easy to learn and use. All the function calls are designed to 164 * File descriptor handlers allow you to monitor when there is data available to
155 be easy to remember, explicit in describing what they do, and heavily 165 * read on file descriptors, when writing will not block or if there was an
156 name-spaced. Ecore programs can start and be very simple. 166 * error. Any valid file descriptor can be used with this API, regardless of if
157 167 * was gotten with an OS specific API or from ecore.
158 For example: 168 * @see Ecore_FD_Handler_Group
159 169 *
160 @code 170 * @subsection animators Animators
161 #include <Ecore.h> 171 *
162 172 * Ecore provides a facility called animators, so named since the intended use
163 int 173 * was in animations, that facilitates knowing what percentage of a given
164 main(int argc, const char **argv) 174 * interval has elapsed. This is perfect for performing animations, but is not
165 { 175 * limited to that use, it can, for example, also be used to create a progress
166 ecore_init(); 176 * bar.
167 ecore_app_args_set(argc, argv); 177 * @see Ecore_Animator_Group
168 ecore_main_loop_begin(); 178 *
169 ecore_shutdown(); 179 * @subsection ev_handlers Event handlers
170 return 0; 180 *
171 } 181 * Event handlers are, arguably, the most important feature of the ecore main
172 @endcode 182 * loop, they are what allows the programmer to easily handle user interaction.
173 183 * Events however are not only things the user does, events can represent
174 This program is very simple and doesn't check for errors, but it does start up 184 * anything for which a type is created.
175 and begin a main loop waiting for events or timers to tick off. This program 185 * @see Ecore_Event_Group
176 doesn't set up any, but now we can expand on this simple program a little 186 *
177 more by adding some event handlers and timers. 187 * All of these primitives are discussed in more detail in their respective
178 188 * pages linked above.
179 @code 189 *
180 #include <Ecore.h> 190 * Here is a diagram of the main loop flow of a simple program:
181 191 *
182 Ecore_Timer *timer1 = NULL; 192 * @image html prog_flow.png
183 Ecore_Event_Handler *handler1 = NULL; 193 * @image latex prog_flow.eps width=\textwidth
184 double start_time = 0.0; 194 *
185 195 *
186 int 196 *
187 timer_func(void *data) 197 * @section work How does Ecore work?
188 { 198 *
189 printf("Tick timer. Sec: %3.2f\n", ecore_time_get() - start_time); 199 * Ecore is very easy to learn and use. All the function calls are designed to
190 return 1; 200 * be easy to remember, explicit in describing what they do, and heavily
191 } 201 * name-spaced. Ecore programs can start and be very simple.
192 202 *
193 int 203 * For example:
194 exit_func(void *data, int ev_type, void *ev) 204 *
195 { 205 * @code
196 Ecore_Event_Signal_Exit *e; 206 * #include <Ecore.h>
197 207 *
198 e = (Ecore_Event_Signal_Exit *)ev; 208 * int
199 if (e->interrupt) printf("Exit: interrupt\n"); 209 * main(int argc, const char **argv)
200 else if (e->quit) printf("Exit: quit\n"); 210 * {
201 else if (e->terminate) printf("Exit: terminate\n"); 211 * ecore_init();
202 ecore_main_loop_quit(); 212 * ecore_app_args_set(argc, argv);
203 return 1; 213 * ecore_main_loop_begin();
204 } 214 * ecore_shutdown();
205 215 * return 0;
206 int 216 * }
207 main(int argc, const char **argv) 217 * @endcode
208 { 218 *
209 ecore_init(); 219 * This program is very simple and doesn't check for errors, but it does start up
210 ecore_app_args_set(argc, argv); 220 * and begin a main loop waiting for events or timers to tick off. This program
211 start_time = ecore_time_get(); 221 * doesn't set up any, but now we can expand on this simple program a little
212 handler1 = ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, exit_func, NULL); 222 * more by adding some event handlers and timers.
213 timer1 = ecore_timer_add(0.5, timer_func, NULL); 223 *
214 ecore_main_loop_begin(); 224 * @code
215 ecore_shutdown(); 225 * #include <Ecore.h>
216 return 0; 226 *
217 } 227 * Ecore_Timer *timer1 = NULL;
218 @endcode 228 * Ecore_Event_Handler *handler1 = NULL;
219 229 * double start_time = 0.0;
220 In the previous example, we initialize our application and get the time at 230 *
221 which our program has started so we can calculate an offset. We set 231 * int
222 up a timer to tick off in 0.5 seconds, and since it returns 1, will 232 * timer_func(void *data)
223 keep ticking off every 0.5 seconds until it returns 0, or is deleted 233 * {
224 by hand. An event handler is set up to call a function - 234 * printf("Tick timer. Sec: %3.2f\n", ecore_time_get() - start_time);
225 exit_func(), 235 * return 1;
226 whenever an event of type ECORE_EVENT_SIGNAL_EXIT is received (CTRL-C 236 * }
227 on the command line will cause such an event to happen). If this event 237 *
228 occurs it tells you what kind of exit signal was received, and asks 238 * int
229 the main loop to quit when it is finished by calling 239 * exit_func(void *data, int ev_type, void *ev)
230 ecore_main_loop_quit(). 240 * {
231 241 * Ecore_Event_Signal_Exit *e;
232 The handles returned by ecore_timer_add() and 242 *
233 ecore_event_handler_add() are 243 * e = (Ecore_Event_Signal_Exit *)ev;
234 only stored here as an example. If you don't need to address the timer or 244 * if (e->interrupt) printf("Exit: interrupt\n");
235 event handler again you don't need to store the result, so just call the 245 * else if (e->quit) printf("Exit: quit\n");
236 function, and don't assign the result to any variable. 246 * else if (e->terminate) printf("Exit: terminate\n");
237 247 * ecore_main_loop_quit();
238 This program looks slightly more complex than needed to do these simple 248 * return 1;
239 things, but in principle, programs don't get any more complex. You add more 249 * }
240 event handlers, for more events, will have more timers and such, BUT it all 250 *
241 follows the same principles as shown in this example. 251 * int
242 252 * main(int argc, const char **argv)
253 * {
254 * ecore_init();
255 * ecore_app_args_set(argc, argv);
256 * start_time = ecore_time_get();
257 * handler1 = ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, exit_func, NULL);
258 * timer1 = ecore_timer_add(0.5, timer_func, NULL);
259 * ecore_main_loop_begin();
260 * ecore_shutdown();
261 * return 0;
262 * }
263 * @endcode
264 *
265 * In the previous example, we initialize our application and get the time at
266 * which our program has started so we can calculate an offset. We set
267 * up a timer to tick off in 0.5 seconds, and since it returns 1, will
268 * keep ticking off every 0.5 seconds until it returns 0, or is deleted
269 * by hand. An event handler is set up to call a function -
270 * exit_func(),
271 * whenever an event of type ECORE_EVENT_SIGNAL_EXIT is received (CTRL-C
272 * on the command line will cause such an event to happen). If this event
273 * occurs it tells you what kind of exit signal was received, and asks
274 * the main loop to quit when it is finished by calling
275 * ecore_main_loop_quit().
276 *
277 * The handles returned by ecore_timer_add() and
278 * ecore_event_handler_add() are
279 * only stored here as an example. If you don't need to address the timer or
280 * event handler again you don't need to store the result, so just call the
281 * function, and don't assign the result to any variable.
282 *
283 * This program looks slightly more complex than needed to do these simple
284 * things, but in principle, programs don't get any more complex. You add more
285 * event handlers, for more events, will have more timers and such, BUT it all
286 * follows the same principles as shown in this example.
287 *
243 */ 288 */
244 289
245/* 290/*
246 @page Ecore_Config_Page The Enlightened Property Library 291 @page Ecore_Config_Page The Enlightened Property Library
247 292
248 The Enlightened Property Library (Ecore_Config) is an adbstraction 293 The Enlightened Property Library (Ecore_Config) is an abstraction
249 from the complexities of writing your own configuration. It provides 294 from the complexities of writing your own configuration. It provides
250 many features using the Enlightenment 17 development libraries. 295 many features using the Enlightenment 17 development libraries.
251 296
@@ -310,7 +355,9 @@
310# include <signal.h> 355# include <signal.h>
311#else 356#else
312# include <sys/time.h> 357# include <sys/time.h>
313# include <signal.h> 358# if !defined (EXOTIC_NO_SIGNAL)
359# include <signal.h>
360# endif
314#endif 361#endif
315 362
316#include <sys/types.h> 363#include <sys/types.h>
@@ -333,47 +380,21 @@ EAPI int ecore_shutdown(void);
333 */ 380 */
334 381
335/** 382/**
383 * @defgroup Ecore_Main_Loop_Group Ecore main loop
336 * 384 *
337 * @defgroup Ecore_Main_Loop_Group Ecore main loop functions 385 * This group discusses functions that are acting on Ecore's main loop itself or
338 * 386 * on events and infrastructure directly linked to it. Most programs only need
339 * These are functions acting on Ecore's main loop itself or on 387 * to start and end the main loop, the rest of the function discussed here are
340 * events and infrastructure directly linked to it. This loop is 388 * meant to be used in special situations, and with great care.
341 * designed to work on embedded systems all the way to large and
342 * powerful multi-cpu workstations.
343 * 389 *
344 * It serialises all system signals and events into a single event 390 * For details on the usage of ecore's main loop and how it interacts with other
345 * queue, that can be easily processed without needing to worry 391 * ecore facilities see: @ref Ecore_Main_Loop_Page.
346 * about concurrency. A properly written, event-driven program
347 * using this kind of programming does not need threads. It makes
348 * the program very robust and easy to follow.
349 *
350 * For example, for the main loop to be of any use, you need to be
351 * able to add @b events and event handlers on it. Events for file
352 * descriptor events are covered in @ref Ecore_FD_Handler_Group.
353 *
354 * Timer functions are covered in @ref Ecore_Time_Group.
355 *
356 * There is also provision for callbacks for when the loop enters or
357 * exits an @b idle state. See @ref Ecore_Idle_Group for more
358 * information on it.
359 *
360 * Functions are also provided for spawning child processes using
361 * @c fork(). See @ref Ecore_Exe_Group for more details on it.
362 *
363 * Here is an example of simple program and its basic event loop
364 * flow:
365 *
366 * @image html prog_flow.png
367 * @image latex prog_flow.eps width=\textwidth
368 *
369 * For examples of setting up and using a main loop, see
370 * @ref Ecore_Main_Loop_Page.
371 * 392 *
372 * @{ 393 * @{
373 */ 394 */
374 395
375#define ECORE_VERSION_MAJOR 1 396#define ECORE_VERSION_MAJOR 1
376#define ECORE_VERSION_MINOR 0 397#define ECORE_VERSION_MINOR 2
377 398
378typedef struct _Ecore_Version 399typedef struct _Ecore_Version
379{ 400{
@@ -469,7 +490,7 @@ EAPI void *ecore_main_loop_thread_safe_call_sync(Ecore_Data_Cb callback, void *d
469 * in this thread, if the main loop was suspended correctly. If not, it return @c -1. 490 * in this thread, if the main loop was suspended correctly. If not, it return @c -1.
470 * 491 *
471 * This function suspend the main loop in a know state, this let you 492 * This function suspend the main loop in a know state, this let you
472 * use any EFL call you want after it return. Be carefull, the main loop 493 * use any EFL call you want after it return. Be carefully, the main loop
473 * is blocked until you call ecore_thread_main_loop_end(). This is 494 * is blocked until you call ecore_thread_main_loop_end(). This is
474 * the only sane way to achieve pseudo thread safety. 495 * the only sane way to achieve pseudo thread safety.
475 * 496 *
@@ -489,7 +510,7 @@ EAPI int ecore_thread_main_loop_begin(void);
489 * the main loop is unlocked again. @c -1 will be returned if you are trying to unlock 510 * the main loop is unlocked again. @c -1 will be returned if you are trying to unlock
490 * when there wasn't enough call to ecore_thread_main_loop_begin(). 511 * when there wasn't enough call to ecore_thread_main_loop_begin().
491 * 512 *
492 * After a call to ecore_thread_main_loop_begin(), you need to absolutly 513 * After a call to ecore_thread_main_loop_begin(), you need to absolutely
493 * call ecore_thread_main_loop_end(), or you application will stay frozen. 514 * call ecore_thread_main_loop_end(), or you application will stay frozen.
494 */ 515 */
495EAPI int ecore_thread_main_loop_end(void); 516EAPI int ecore_thread_main_loop_end(void);
@@ -501,34 +522,51 @@ EAPI int ecore_thread_main_loop_end(void);
501/** 522/**
502 * @defgroup Ecore_Event_Group Ecore Event functions 523 * @defgroup Ecore_Event_Group Ecore Event functions
503 * 524 *
504 * Ecore events are used to wake up the Ecore main loop to warn 525 * Ecore events provide two main features that are of use to those using ecore:
505 * about state changes, tasks completed, data available for reading 526 * creating events and being notified of events. Those two will usually be used
506 * or writing, etc. They are the base of the event oriented 527 * in different contexts, creating events is mainly done by libraries wrapping
507 * programming. 528 * some system functionality while being notified of events is mainly a
508 * 529 * necessity of applications.
509 * The idea is to write many functions (callbacks) that will be 530 *
510 * registered to specific events, and called when these events 531 * For a program to be notified of events it's interested in it needs to have a
511 * happen. This way, when the system state changes (a mouse click is 532 * function to process the event and to register that function as the callback
512 * detected, a key is pressed, or the content of a file changes, for 533 * to the event, that's all:
513 * example), the respective callbacks will be called with some 534 * @code
514 * information about that event. Usually the function/callback will 535 * ecore_event_handler_add(EVENT_TYPE, _my_event_handler, some_data);
515 * have a data pointer to the event info (the position in the screen 536 * ...
516 * where the mouse was clicked, the name of the key that was 537 * static Eina_Bool
517 * pressed, or the name of the file that has changed). 538 * _my_event_handler(void *data, int type, void *event)
518 * 539 * {
519 * The basic usage, when one needs to watch for an existing event, 540 * //data is some_data
520 * is to register a callback to it using ecore_event_add(). Of 541 * //event is provided by whoever created the event
521 * course it's necessary to know beforehand what are the types of 542 * //Do really cool stuff with event
522 * events that the system/library will emmit. This should be 543 * }
523 * available with the documentation from that system/library. 544 * @endcode
524 * 545 *
525 * When writing a library or group of functions that need to inform 546 * One very important thing to note here is the @c EVENT_TYPE, to register a
526 * about something, and you already are running on top of a main 547 * handler for an event you must know it's type before hand. This information
527 * loop, it is usually a good approach to use events. This way you 548 * can be found on the documentation of the library emitting the signal, so,
528 * allow others to register as many callbacks as necessary to this 549 * for example, for events related to windowing one would look in @ref
529 * event, and don't have to care about who is registering to it. The 550 * Ecore_Evas_Group.
530 * functions ecore_event_type_new() and ecore_event_add() are 551 *
531 * available for this purpose. 552 * Examples of libraries that integrate into ecore's main loop by providing
553 * events are @ref Ecore_Con_Group, @ref Ecore_Evas_Group and @ref
554 * Ecore_Exe_Group amongst others. This usage can be divided into two parts,
555 * setup and adding events. The setup is very simple, all that needs doing is
556 * getting a type id for the event:
557 * @code
558 * int MY_EV_TYPE = ecore_event_type_new();
559 * @endcode
560 * @note This variable should be declared in the header since it'll be needed by
561 * anyone wishing to register a handler to your event.
562 *
563 * The complexity of adding of an event to the queue depends on whether that
564 * event sends uses @c event, if it doesn't it a one-liner:
565 * @code
566 * ecore_event_add(MY_EV_TYPE, NULL, NULL, NULL);
567 * @endcode
568 * The usage when an @c event is needed is not that much more complex and can be
569 * seen in @ref ecore_event_add.
532 * 570 *
533 * Example that deals with events: 571 * Example that deals with events:
534 * 572 *
@@ -582,7 +620,7 @@ struct _Ecore_Event_Signal_User /** User signal event */
582 int number; /**< The signal number. Either 1 or 2 */ 620 int number; /**< The signal number. Either 1 or 2 */
583 void *ext_data; /**< Extension data - not used */ 621 void *ext_data; /**< Extension data - not used */
584 622
585#if !defined (_WIN32) && !defined (__lv2ppu__) 623#if !defined (_WIN32) && !defined (__lv2ppu__) && !defined (EXOTIC_NO_SIGNAL)
586 siginfo_t data; /**< Signal info */ 624 siginfo_t data; /**< Signal info */
587#endif 625#endif
588}; 626};
@@ -591,7 +629,7 @@ struct _Ecore_Event_Signal_Hup /** Hup signal event */
591{ 629{
592 void *ext_data; /**< Extension data - not used */ 630 void *ext_data; /**< Extension data - not used */
593 631
594#if !defined (_WIN32) && !defined (__lv2ppu__) 632#if !defined (_WIN32) && !defined (__lv2ppu__) && !defined (EXOTIC_NO_SIGNAL)
595 siginfo_t data; /**< Signal info */ 633 siginfo_t data; /**< Signal info */
596#endif 634#endif
597}; 635};
@@ -600,10 +638,10 @@ struct _Ecore_Event_Signal_Exit /** Exit request event */
600{ 638{
601 Eina_Bool interrupt : 1; /**< Set if the exit request was an interrupt signal*/ 639 Eina_Bool interrupt : 1; /**< Set if the exit request was an interrupt signal*/
602 Eina_Bool quit : 1; /**< set if the exit request was a quit signal */ 640 Eina_Bool quit : 1; /**< set if the exit request was a quit signal */
603 Eina_Bool terminate : 1; /**< Set if the exit request was a terminate singal */ 641 Eina_Bool terminate : 1; /**< Set if the exit request was a terminate signal */
604 void *ext_data; /**< Extension data - not used */ 642 void *ext_data; /**< Extension data - not used */
605 643
606#if !defined (_WIN32) && !defined (__lv2ppu__) 644#if !defined (_WIN32) && !defined (__lv2ppu__) && !defined (EXOTIC_NO_SIGNAL)
607 siginfo_t data; /**< Signal info */ 645 siginfo_t data; /**< Signal info */
608#endif 646#endif
609}; 647};
@@ -612,7 +650,7 @@ struct _Ecore_Event_Signal_Power /** Power event */
612{ 650{
613 void *ext_data; /**< Extension data - not used */ 651 void *ext_data; /**< Extension data - not used */
614 652
615#if !defined (_WIN32) && !defined (__lv2ppu__) 653#if !defined (_WIN32) && !defined (__lv2ppu__) && !defined (EXOTIC_NO_SIGNAL)
616 siginfo_t data; /**< Signal info */ 654 siginfo_t data; /**< Signal info */
617#endif 655#endif
618}; 656};
@@ -621,21 +659,161 @@ struct _Ecore_Event_Signal_Realtime /** Realtime event */
621{ 659{
622 int num; /**< The realtime signal's number */ 660 int num; /**< The realtime signal's number */
623 661
624#if !defined (_WIN32) && !defined (__lv2ppu__) 662#if !defined (_WIN32) && !defined (__lv2ppu__) && !defined (EXOTIC_NO_SIGNAL)
625 siginfo_t data; /**< Signal info */ 663 siginfo_t data; /**< Signal info */
626#endif 664#endif
627}; 665};
628 666
667/**
668 * @brief Add an event handler.
669 * @param type The type of the event this handler will get called for
670 * @param func The function to call when the event is found in the queue
671 * @param data A data pointer to pass to the called function @p func
672 * @return A new Event handler, or NULL on failure
673 *
674 * Add an event handler to the list of handlers. This will, on success, return
675 * a handle to the event handler object that was created, that can be used
676 * later to remove the handler using ecore_event_handler_del(). The @p type
677 * parameter is the integer of the event type that will trigger this callback
678 * to be called. The callback @p func is called when this event is processed
679 * and will be passed the event type, a pointer to the private event
680 * structure that is specific to that event type, and a data pointer that is
681 * provided in this call as the @p data parameter.
682 *
683 * When the callback @p func is called, it must return 1 or 0. If it returns
684 * 1 (or ECORE_CALLBACK_PASS_ON), It will keep being called as per normal, for
685 * each handler set up for that event type. If it returns 0 (or
686 * ECORE_CALLBACK_DONE), it will cease processing handlers for that particular
687 * event, so all handler set to handle that event type that have not already
688 * been called, will not be.
689 */
629EAPI Ecore_Event_Handler *ecore_event_handler_add(int type, Ecore_Event_Handler_Cb func, const void *data); 690EAPI Ecore_Event_Handler *ecore_event_handler_add(int type, Ecore_Event_Handler_Cb func, const void *data);
691/**
692 * @brief Delete an event handler.
693 * @param event_handler Event handler handle to delete
694 * @return Data passed to handler
695 *
696 * Delete a specified event handler from the handler list. On success this will
697 * delete the event handler and return the pointer passed as @p data when the
698 * handler was added by ecore_event_handler_add(). On failure NULL will be
699 * returned. Once a handler is deleted it will no longer be called.
700 */
630EAPI void *ecore_event_handler_del(Ecore_Event_Handler *event_handler); 701EAPI void *ecore_event_handler_del(Ecore_Event_Handler *event_handler);
702/**
703 * @brief Add an event to the event queue.
704 * @param type The event type to add to the end of the event queue
705 * @param ev The data structure passed as @c event to event handlers
706 * @param func_free The function to be called to free @a ev
707 * @param data The data pointer to be passed to the free function
708 * @return A Handle for that event on success, otherwise NULL
709 *
710 * If it succeeds, an event of type @a type will be added to the queue for
711 * processing by event handlers added by ecore_event_handler_add(). The @a ev
712 * parameter will be passed as the @c event parameter of the handler. When the
713 * event is no longer needed, @a func_free will be called and passed @a ev for
714 * cleaning up. If @p func_free is NULL, free() will be called with the private
715 * structure pointer.
716 */
631EAPI Ecore_Event *ecore_event_add(int type, void *ev, Ecore_End_Cb func_free, void *data); 717EAPI Ecore_Event *ecore_event_add(int type, void *ev, Ecore_End_Cb func_free, void *data);
718/**
719 * @brief Delete an event from the queue.
720 * @param event The event handle to delete
721 * @return The data pointer originally set for the event free function
722 *
723 * This deletes the event @p event from the event queue, and returns the
724 * @p data parameter originally set when adding it with ecore_event_add(). This
725 * does not immediately call the free function, and it may be called later on
726 * cleanup, and so if the free function depends on the data pointer to work,
727 * you should defer cleaning of this till the free function is called later.
728 */
632EAPI void *ecore_event_del(Ecore_Event *event); 729EAPI void *ecore_event_del(Ecore_Event *event);
730/**
731 * @brief Get the data associated with an #Ecore_Event_Handler
732 * @param eh The event handler
733 * @return The data
734 *
735 * This function returns the data previously associated with @p eh by
736 * ecore_event_handler_add().
737 */
633EAPI void *ecore_event_handler_data_get(Ecore_Event_Handler *eh); 738EAPI void *ecore_event_handler_data_get(Ecore_Event_Handler *eh);
739/**
740 * @brief Set the data associated with an #Ecore_Event_Handler
741 * @param eh The event handler
742 * @param data The data to associate
743 * @return The previous data
744 *
745 * This function sets @p data to @p eh and returns the old data pointer
746 * which was previously associated with @p eh by ecore_event_handler_add().
747 */
634EAPI void *ecore_event_handler_data_set(Ecore_Event_Handler *eh, const void *data); 748EAPI void *ecore_event_handler_data_set(Ecore_Event_Handler *eh, const void *data);
749/**
750 * @brief Allocate a new event type id sensibly and return the new id.
751 * @return A new event type id.
752 *
753 * This function allocates a new event type id and returns it. Once an event
754 * type has been allocated it can never be de-allocated during the life of
755 * the program. There is no guarantee of the contents of this event ID, or how
756 * it is calculated, except that the ID will be unique to the current instance
757 * of the process.
758 */
635EAPI int ecore_event_type_new(void); 759EAPI int ecore_event_type_new(void);
760/**
761 * @brief Add a filter the current event queue.
762 *
763 * @param func_start Function to call just before filtering and return data
764 * @param func_filter Function to call on each event
765 * @param func_end Function to call after the queue has been filtered
766 * @param data Data to pass to the filter functions
767 * @return A filter handle on success, NULL otherwise
768 *
769 * Adds a callback to filter events from the event queue. Filters are called on
770 * the queue just before Event handler processing to try and remove redundant
771 * events. Just as processing is about to start @a func_start is called and
772 * passed the @a data pointer, the return value of this functions is passed to
773 * @a func_filter as loop_data. @a func_filter is also passed @a data and the
774 * event type and event structure. If this @a func_filter returns #EINA_FALSE,
775 * the event is removed from the queue, if it returns #EINA_TRUE, the event is
776 * kept. When processing is finished @p func_end is called and is passed the
777 * loop_data(returned by @c func_start) and @p data pointer to clean up.
778 */
636EAPI Ecore_Event_Filter *ecore_event_filter_add(Ecore_Data_Cb func_start, Ecore_Filter_Cb func_filter, Ecore_End_Cb func_end, const void *data); 779EAPI Ecore_Event_Filter *ecore_event_filter_add(Ecore_Data_Cb func_start, Ecore_Filter_Cb func_filter, Ecore_End_Cb func_end, const void *data);
780/**
781 * @brief Delete an event filter.
782 * @param ef The event filter handle
783 * @return The data set for the filter on success, NULL otherwise
784 *
785 * Delete a filter that has been added by its @p ef handle.
786 */
637EAPI void *ecore_event_filter_del(Ecore_Event_Filter *ef); 787EAPI void *ecore_event_filter_del(Ecore_Event_Filter *ef);
788/**
789 * @brief Return the current event type being handled.
790 * @return The current event type being handled if inside a handler callback,
791 * ECORE_EVENT_NONE otherwise
792 *
793 * If the program is currently inside an Ecore event handler callback this
794 * will return the type of the current event being processed.
795 *
796 * This is useful when certain Ecore modules such as Ecore_Evas "swallow"
797 * events and not all the original information is passed on. In special cases
798 * this extra information may be useful or needed and using this call can let
799 * the program know if the event type being handled is one it wants to get more
800 * information about.
801 */
638EAPI int ecore_event_current_type_get(void); 802EAPI int ecore_event_current_type_get(void);
803/**
804 * @brief Return the current event type pointer handled.
805 * @return The current event pointer being handled if inside a handler callback,
806 * NULL otherwise
807 *
808 * If the program is currently inside an Ecore event handler callback this
809 * will return the pointer of the current event being processed.
810 *
811 * This is useful when certain Ecore modules such as Ecore_Evas "swallow"
812 * events and not all the original information is passed on. In special cases
813 * this extra information may be useful or needed and using this call can let
814 * the program access the event data if the type of the event is handled by
815 * the program.
816 */
639EAPI void *ecore_event_current_event_get(void); 817EAPI void *ecore_event_current_event_get(void);
640 818
641/** 819/**
@@ -652,7 +830,8 @@ EAPI void *ecore_event_current_event_get(void);
652 * @{ 830 * @{
653 */ 831 */
654 832
655 #define ECORE_EXE_PRIORITY_INHERIT 9999 833/** Inherit priority from parent process */
834#define ECORE_EXE_PRIORITY_INHERIT 9999
656 835
657EAPI extern int ECORE_EXE_EVENT_ADD; /**< A child process has been added */ 836EAPI extern int ECORE_EXE_EVENT_ADD; /**< A child process has been added */
658EAPI extern int ECORE_EXE_EVENT_DEL; /**< A child process has been deleted (it exited, naming consistent with the rest of ecore). */ 837EAPI extern int ECORE_EXE_EVENT_DEL; /**< A child process has been deleted (it exited, naming consistent with the rest of ecore). */
@@ -715,7 +894,7 @@ struct _Ecore_Exe_Event_Del /** Process exit event */
715 Eina_Bool exited : 1; /** < set to 1 if the process exited of its own accord */ 894 Eina_Bool exited : 1; /** < set to 1 if the process exited of its own accord */
716 Eina_Bool signalled : 1; /** < set to 1 id the process exited due to uncaught signal */ 895 Eina_Bool signalled : 1; /** < set to 1 id the process exited due to uncaught signal */
717 void *ext_data; /**< Extension data - not used */ 896 void *ext_data; /**< Extension data - not used */
718#if !defined (_WIN32) && !defined (__lv2ppu__) 897#if !defined (_WIN32) && !defined (__lv2ppu__) && !defined (EXOTIC_NO_SIGNAL)
719 siginfo_t data; /**< Signal info */ 898 siginfo_t data; /**< Signal info */
720#endif 899#endif
721}; 900};
@@ -768,24 +947,30 @@ EAPI void ecore_exe_hup(Ecore_Exe *exe);
768/** 947/**
769 * @defgroup Ecore_FD_Handler_Group File Event Handling Functions 948 * @defgroup Ecore_FD_Handler_Group File Event Handling Functions
770 * 949 *
771 * Functions that deal with file descriptor handlers. 950 * @brief Functions that deal with file descriptor handlers.
951 *
952 * File descriptor handlers facilitate reading, writing and checking for errors
953 * without blocking the program or doing expensive pooling. This can be used to
954 * monitor a socket, pipe, or other stream for which an FD can be had.
772 * 955 *
773 * The @ref Ecore_Fd_Handler can be used to watch a file descriptor 956 * @warning This function @b can't be used for monitoring to regular files!
774 * for data available for reading, for the availability to write
775 * without blocking, and for errors on the file descriptor.
776 * 957 *
777 *ecore_main_fd_handler_add() is used to setup a handler for a 958 * One common FD to be monitored is the standard input(stdin), monitoring it for
778 * given file descriptor. This file descriptor can be the standard 959 * reading requires a single call:
779 * input, a network socket, a stream received through some driver 960 * @code
780 * of a hardware decoder, etc. Thus it can contain errors, like a 961 * static Eina_Bool
781 * disconnection, a broken pipe, and so, and that's why it's 962 * _my_cb_func(void *data, Ecore_Fd_Handler *handler)
782 * possible to check for these errors with the @ref ECORE_FD_ERROR 963 * {
783 * flag. 964 * char c;
965 * scanf("%c", &c); //Guaranteed not to block
966 * ... do stuff with c ...
967 * }
968 * ecore_main_fd_handler_add(STDIN_FILENO, ECORE_FD_READ, _my_cb_func, NULL, NULL, NULL);
969 * @endcode
784 * 970 *
785 * An @ref Ecore_Fd_Handler can be used to watch on a file 971 * When using a socket, pipe or other stream it's important to remember that
786 * descriptor without blocking, still being able to receive events, 972 * errors may occur and as such to monitor not only for reading/writing but also
787 * expire timers, and other watch for other things that happen in 973 * for errors using the @ref ECORE_FD_ERROR flag.
788 * the Ecore main loop.
789 * 974 *
790 * Example of use of a file descriptor handler: 975 * Example of use of a file descriptor handler:
791 * @li @ref ecore_fd_handler_example_c 976 * @li @ref ecore_fd_handler_example_c
@@ -823,11 +1008,93 @@ typedef void (*Ecore_Fd_Prep_Cb)(void *data, Ecore_Fd_Handler *fd_handler);
823 */ 1008 */
824typedef Eina_Bool (*Ecore_Win32_Handle_Cb)(void *data, Ecore_Win32_Handler *wh); 1009typedef Eina_Bool (*Ecore_Win32_Handle_Cb)(void *data, Ecore_Win32_Handler *wh);
825 1010
1011/**
1012 * @brief Adds a callback for activity on the given file descriptor.
1013 *
1014 * @param fd The file descriptor to watch.
1015 * @param flags To monitor it for reading use @c ECORE_FD_READ, for writing @c
1016 * ECORE_FD_WRITE, and for error @c ECORE_FD_ERROR. Values bay |(ored).
1017 * @param func The callback function.
1018 * @param data The data to pass to the callback.
1019 * @param buf_func The function to call to check if any data has been buffered
1020 * and already read from the fd. May be @c NULL.
1021 * @param buf_data The data to pass to the @p buf_func function.
1022 * @return A fd handler handle on success, @c NULL otherwise.
1023 *
1024 * @a func will be called during the execution of @ref Ecore_Main_Loop_Page
1025 * when the file descriptor is available for reading, writing, or there has been
1026 * an error(depending on the given @a flags).
1027 *
1028 * When @a func returns ECORE_CALLBACK_CANCEL, it indicates that the
1029 * handler should be marked for deletion (identical to calling @ref
1030 * ecore_main_fd_handler_del).
1031 *
1032 * @warning @a buf_func is meant for @b internal use only and should be @b
1033 * avoided.
1034 *
1035 * The return value of @a buf_func has a different meaning, when it returns
1036 * ECORE_CALLBACK_CANCEL, it indicates that @a func @b shouldn't be called, and
1037 * when it returns ECORE_CALLBACK_RENEW it indicates @a func should be called.
1038 * The return value of @a buf_func will not cause the FD handler to be deleted.
1039 *
1040 * @a buf_func is called during event loop handling to check if data that has
1041 * been read from the file descriptor is in a buffer and is available to read.
1042 * Some systems, notably xlib, handle their own buffering, and would otherwise
1043 * not work with select(). These systems should use a @a buf_func. This is a
1044 * most annoying hack, only ecore_x uses it, so refer to that for an example.
1045 */
826EAPI Ecore_Fd_Handler *ecore_main_fd_handler_add(int fd, Ecore_Fd_Handler_Flags flags, Ecore_Fd_Cb func, const void *data, Ecore_Fd_Cb buf_func, const void *buf_data); 1046EAPI Ecore_Fd_Handler *ecore_main_fd_handler_add(int fd, Ecore_Fd_Handler_Flags flags, Ecore_Fd_Cb func, const void *data, Ecore_Fd_Cb buf_func, const void *buf_data);
1047/**
1048 * @brief Set the prepare callback with data for a given #Ecore_Fd_Handler
1049 *
1050 * @param fd_handler The fd handler
1051 * @param func The prep function
1052 * @param data The data to pass to the prep function
1053 *
1054 * This function will be called prior to any fd handler's callback function
1055 * (even the other fd handlers), before entering the main loop select function.
1056 *
1057 * @note Once a prepare callback is set for a fd handler, it cannot be changed.
1058 * You need to delete the fd handler and create a new one, to set another
1059 * callback.
1060 * @note You probably don't need this function. It is only necessary for very
1061 * uncommon cases that need special behavior.
1062 */
827EAPI void ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Prep_Cb func, const void *data); 1063EAPI void ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Prep_Cb func, const void *data);
1064/**
1065 * @brief Marks an FD handler for deletion.
1066 * @param fd_handler The FD handler.
1067 * @return The data pointer set using @ref ecore_main_fd_handler_add, for @a
1068 * fd_handler on success, @c NULL otherwise.
1069 * This function marks an fd handler to be deleted during an iteration of the
1070 * main loop. It does NOT close the associated fd!
1071 *
1072 * @warning If the underlying fd is already closed ecore may complain if the
1073 * main loop is using epoll internally, and also in some rare cases this may
1074 * cause crashes and instability. Remember to delete your fd handlers before the
1075 * fds they listen to are closed.
1076 */
828EAPI void *ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler); 1077EAPI void *ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler);
1078/**
1079 * @brief Retrieves the file descriptor that the given handler is handling.
1080 * @param fd_handler The given FD handler.
1081 * @return The file descriptor the handler is watching.
1082 */
829EAPI int ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler); 1083EAPI int ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler);
1084/**
1085 * @brief Gets which flags are active on an FD handler.
1086 * @param fd_handler The given FD handler.
1087 * @param flags The flags, @c ECORE_FD_READ, @c ECORE_FD_WRITE or @c
1088 * ECORE_FD_ERROR to query.
1089 * @return #EINA_TRUE if any of the given flags are active, #EINA_FALSE
1090 * otherwise.
1091 */
830EAPI Eina_Bool ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags); 1092EAPI Eina_Bool ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags);
1093/**
1094 * @brief Set what active streams the given FD handler should be monitoring.
1095 * @param fd_handler The given FD handler.
1096 * @param flags The flags to be watching.
1097 */
831EAPI void ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags); 1098EAPI void ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags);
832 1099
833EAPI Ecore_Win32_Handler *ecore_main_win32_handler_add(void *h, Ecore_Win32_Handle_Cb func, const void *data); 1100EAPI Ecore_Win32_Handler *ecore_main_win32_handler_add(void *h, Ecore_Win32_Handle_Cb func, const void *data);
@@ -840,13 +1107,30 @@ EAPI void *ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler);
840/** 1107/**
841 * @defgroup Ecore_Poller_Group Ecore Poll functions 1108 * @defgroup Ecore_Poller_Group Ecore Poll functions
842 * 1109 *
843 * These functions are for the need to poll information, but provide 1110 * Ecore poller provides infrastructure for the creation of pollers. Pollers
844 * a shared abstracted API to pool such polling to minimise wakeup 1111 * are, in essence, callbacks that share a single timer per type. Because not
845 * and ensure all the polling happens in as few spots as possible 1112 * all pollers need to be called at the same frequency the user may specify the
846 * areound a core poll interval. For now only 1 core poller type is 1113 * frequency in ticks(each expiration of the shared timer is called a tick, in
847 * supprted: ECORE_POLLER_CORE 1114 * ecore poller parlance) for each added poller. Ecore pollers should only be
1115 * used when the poller doesn't have specific requirements on the exact times
1116 * to poll.
848 * 1117 *
849 * Example of @ref Ecore_Poller : 1118 * This architecture means that the main loop is only woken up once to handle
1119 * all pollers of that type, this will save power as the CPU has more of a
1120 * chance to go into a low power state the longer it is asleep for, so this
1121 * should be used in situations where power usage is a concern.
1122 *
1123 * For now only 1 core poller type is supported: ECORE_POLLER_CORE, the default
1124 * interval for ECORE_POLLER_CORE is 0.125(or 1/8th) second.
1125 *
1126 * The creation of a poller is extremely simple and only required one line:
1127 * @code
1128 * ecore_poller_add(ECORE_POLLER_CORE, 1, my_poller_function, NULL);
1129 * @endcode
1130 * This sample creates a poller to call @c my_poller_function at every tick with
1131 * @c NULL as data.
1132 *
1133 * Example:
850 * @li @ref ecore_poller_example_c 1134 * @li @ref ecore_poller_example_c
851 * 1135 *
852 * @ingroup Ecore_Main_Loop_Group 1136 * @ingroup Ecore_Main_Loop_Group
@@ -862,11 +1146,76 @@ typedef enum _Ecore_Poller_Type Ecore_Poller_Type;
862 1146
863typedef struct _Ecore_Poller Ecore_Poller; /**< A handle for pollers */ 1147typedef struct _Ecore_Poller Ecore_Poller; /**< A handle for pollers */
864 1148
1149/**
1150 * @brief Sets the time(in seconds) between ticks for the given poller type.
1151 * @param type The poller type to adjust.
1152 * @param poll_time The time(in seconds) between ticks of the timer.
1153 *
1154 * This will adjust the time between ticks of the given timer type defined by
1155 * @p type to the time period defined by @p poll_time.
1156 */
865EAPI void ecore_poller_poll_interval_set(Ecore_Poller_Type type, double poll_time); 1157EAPI void ecore_poller_poll_interval_set(Ecore_Poller_Type type, double poll_time);
1158/**
1159 * @brief Gets the time(in seconds) between ticks for the given poller type.
1160 * @param type The poller type to query.
1161 * @return The time in seconds between ticks of the poller timer.
1162 *
1163 * This will get the time between ticks of the specified poller timer.
1164 */
866EAPI double ecore_poller_poll_interval_get(Ecore_Poller_Type type); 1165EAPI double ecore_poller_poll_interval_get(Ecore_Poller_Type type);
1166/**
1167 * @brief Changes the polling interval rate of @p poller.
1168 * @param poller The Ecore_Poller to change the interval of.
1169 * @param interval The tick interval to set; must be a power of 2 and <= 32768.
1170 * @return Returns true on success, false on failure.
1171 *
1172 * This allows the changing of a poller's polling interval. It is useful when
1173 * you want to alter a poll rate without deleting and re-creating a poller.
1174 */
867EAPI Eina_Bool ecore_poller_poller_interval_set(Ecore_Poller *poller, int interval); 1175EAPI Eina_Bool ecore_poller_poller_interval_set(Ecore_Poller *poller, int interval);
1176/**
1177 * @brief Gets the polling interval rate of @p poller.
1178 * @param poller The Ecore_Poller to change the interval of.
1179 * @return Returns the interval, in ticks, that @p poller polls at.
1180 *
1181 * This returns a poller's polling interval, or 0 on error.
1182 */
868EAPI int ecore_poller_poller_interval_get(Ecore_Poller *poller); 1183EAPI int ecore_poller_poller_interval_get(Ecore_Poller *poller);
1184/**
1185 * @brief Creates a poller to call the given function at a particular tick interval.
1186 * @param type The ticker type to attach the poller to. Must be ECORE_POLLER_CORE.
1187 * @param interval The poll interval.
1188 * @param func The poller function.
1189 * @param data Data to pass to @a func when it is called.
1190 * @return A poller object on success, @c NULL otherwise.
1191 *
1192 * This function adds @a func as a poller callback that will be called every @a
1193 * interval ticks together with other pollers of type @a type. @a func will be
1194 * passed the @p data pointer as a parameter.
1195 *
1196 * The @p interval must be between 1 and 32768 inclusive, and must be a power of
1197 * 2 (i.e. 1, 2, 4, 8, 16, ... 16384, 32768). The exact tick in which @a func
1198 * will be called is undefined, as only the interval between calls can be
1199 * defined. Ecore will endeavor to keep pollers synchronized and to call as
1200 * many in 1 wakeup event as possible. If @a interval is not a power of two, the
1201 * closest power of 2 greater than @a interval will be used.
1202 *
1203 * When the poller @p func is called, it must return a value of either
1204 * ECORE_CALLBACK_RENEW(or 1) or ECORE_CALLBACK_CANCEL(or 0). If it
1205 * returns 1, it will be called again at the next tick, or if it returns
1206 * 0 it will be deleted automatically making any references/handles for it
1207 * invalid.
1208 */
869EAPI Ecore_Poller *ecore_poller_add(Ecore_Poller_Type type, int interval, Ecore_Task_Cb func, const void *data); 1209EAPI Ecore_Poller *ecore_poller_add(Ecore_Poller_Type type, int interval, Ecore_Task_Cb func, const void *data);
1210/**
1211 * @brief Delete the specified poller from the timer list.
1212 * @param poller The poller to delete.
1213 * @return The data pointer set for the timer when @ref ecore_poller_add was
1214 * called on success, @c NULL otherwise.
1215 *
1216 * @note @a poller must be a valid handle. If the poller function has already
1217 * returned 0, the handle is no longer valid (and does not need to be deleted).
1218 */
870EAPI void *ecore_poller_del(Ecore_Poller *poller); 1219EAPI void *ecore_poller_del(Ecore_Poller *poller);
871 1220
872/** 1221/**
@@ -941,7 +1290,7 @@ typedef enum _Ecore_Animator_Source Ecore_Animator_Source;
941typedef Eina_Bool (*Ecore_Timeline_Cb)(void *data, double pos); 1290typedef Eina_Bool (*Ecore_Timeline_Cb)(void *data, double pos);
942 1291
943/** 1292/**
944 * @brief Add an animator to call @p func at every animaton tick during main 1293 * @brief Add an animator to call @p func at every animation tick during main
945 * loop execution. 1294 * loop execution.
946 * 1295 *
947 * @param func The function to call when it ticks off 1296 * @param func The function to call when it ticks off
@@ -1011,7 +1360,7 @@ EAPI void *ecore_animator_del(Ecore_Animator *animator);
1011 * 1360 *
1012 * @param animator The animator to delete 1361 * @param animator The animator to delete
1013 * 1362 *
1014 * The specified @p animator will be temporarly removed from the set of 1363 * The specified @p animator will be temporarily removed from the set of
1015 * animators that are executed during main loop. 1364 * animators that are executed during main loop.
1016 * 1365 *
1017 * @warning Freezing an animator doesn't freeze accounting of how long that 1366 * @warning Freezing an animator doesn't freeze accounting of how long that
@@ -1069,7 +1418,7 @@ EAPI double ecore_animator_frametime_get(void);
1069 * has "overshot" the mark) using some interpolation (mapping) algorithm. 1418 * has "overshot" the mark) using some interpolation (mapping) algorithm.
1070 * 1419 *
1071 * This function useful to create non-linear animations. It offers a variety 1420 * This function useful to create non-linear animations. It offers a variety
1072 * of possible animaton curves to be used: 1421 * of possible animation curves to be used:
1073 * @li ECORE_POS_MAP_LINEAR - Linear, returns @p pos 1422 * @li ECORE_POS_MAP_LINEAR - Linear, returns @p pos
1074 * @li ECORE_POS_MAP_ACCELERATE - Start slow then speed up 1423 * @li ECORE_POS_MAP_ACCELERATE - Start slow then speed up
1075 * @li ECORE_POS_MAP_DECELERATE - Start fast then slow down 1424 * @li ECORE_POS_MAP_DECELERATE - Start fast then slow down
@@ -1107,7 +1456,7 @@ EAPI double ecore_animator_frametime_get(void);
1107 * y = (y1 * out) + (y2 * (1.0 - out)); 1456 * y = (y1 * out) + (y2 * (1.0 - out));
1108 * move_my_object_to(myobject, x, y); 1457 * move_my_object_to(myobject, x, y);
1109 * @endcode 1458 * @endcode
1110 * This will make an animaton that bounces 7 each times diminishing by a 1459 * This will make an animation that bounces 7 each times diminishing by a
1111 * factor of 1.8. 1460 * factor of 1.8.
1112 * 1461 *
1113 * @see _Ecore_Pos_Map 1462 * @see _Ecore_Pos_Map
@@ -1205,16 +1554,39 @@ EAPI void ecore_animator_custom_tick(void);
1205 */ 1554 */
1206 1555
1207/** 1556/**
1208 * @defgroup Ecore_Time_Group Ecore Time functions 1557 * @defgroup Ecore_Time_Group Ecore time functions
1209 *
1210 * Functions that deal with time. These functions include those
1211 * that simply retrieve it in a given format, and those that create
1212 * events based on it.
1213 * 1558 *
1214 * The timer allows callbacks to be called at specific intervals. 1559 * These are function to retrieve time in a given format.
1215 * 1560 *
1216 * Examples with functions that deal with time: 1561 * Examples:
1217 * @li @ref ecore_time_functions_example_c 1562 * @li @ref ecore_time_functions_example_c
1563 * @{
1564 */
1565EAPI double ecore_time_get(void);
1566EAPI double ecore_time_unix_get(void);
1567EAPI double ecore_loop_time_get(void);
1568
1569/**
1570 * @}
1571 */
1572
1573/**
1574 * @defgroup Ecore_Timer_Group Ecore Timer functions
1575 *
1576 * Ecore provides very flexible timer functionality. The basic usage of timers,
1577 * to call a certain function at a certain interval can be achieved with a
1578 * single line:
1579 * @code
1580 * Eina_Bool my_func(void *data) {
1581 * do_funky_stuff_with_data(data);
1582 * return EINA_TRUE;
1583 * }
1584 * ecore_timer_add(interval_in_seconds, my_func, data_given_to_function);
1585 * @endcode
1586 * @note If the function was to be executed only once simply return EINA_FALSE
1587 * instead.
1588 *
1589 * An example that shows the usage of a lot of these:
1218 * @li @ref ecore_timer_example_c 1590 * @li @ref ecore_timer_example_c
1219 * 1591 *
1220 * @ingroup Ecore_Main_Loop_Group 1592 * @ingroup Ecore_Main_Loop_Group
@@ -1224,10 +1596,6 @@ EAPI void ecore_animator_custom_tick(void);
1224 1596
1225typedef struct _Ecore_Timer Ecore_Timer; /**< A handle for timers */ 1597typedef struct _Ecore_Timer Ecore_Timer; /**< A handle for timers */
1226 1598
1227EAPI double ecore_time_get(void);
1228EAPI double ecore_time_unix_get(void);
1229EAPI double ecore_loop_time_get(void);
1230
1231EAPI Ecore_Timer *ecore_timer_add(double in, Ecore_Task_Cb func, const void *data); 1599EAPI Ecore_Timer *ecore_timer_add(double in, Ecore_Task_Cb func, const void *data);
1232EAPI Ecore_Timer *ecore_timer_loop_add(double in, Ecore_Task_Cb func, const void *data); 1600EAPI Ecore_Timer *ecore_timer_loop_add(double in, Ecore_Task_Cb func, const void *data);
1233EAPI void *ecore_timer_del(Ecore_Timer *timer); 1601EAPI void *ecore_timer_del(Ecore_Timer *timer);
@@ -1249,14 +1617,15 @@ EAPI char *ecore_timer_dump(void);
1249/** 1617/**
1250 * @defgroup Ecore_Idle_Group Ecore Idle functions 1618 * @defgroup Ecore_Idle_Group Ecore Idle functions
1251 * 1619 *
1252 * Callbacks that are called when the program enters or exits an 1620 * The idler functionality in Ecore allows for callbacks to be called when the
1253 * idle state. 1621 * program isn't handling @ref Ecore_Event_Group "events", @ref Ecore_Timer_Group
1622 * "timers" or @ref Ecore_FD_Handler_Group "fd handlers".
1254 * 1623 *
1255 * The ecore main loop enters an idle state when it is waiting for 1624 * There are three types of idlers: Enterers, Idlers(proper) and Exiters. They
1256 * timers to time out, data to come in on a file descriptor or any 1625 * are called, respectively, when the program is about to enter an idle state,
1257 * other event to occur. You can set callbacks to be called when 1626 * when the program is in an idle state and when the program has just left an
1258 * the main loop enters an idle state, during an idle state or just 1627 * idle state and will begin processing @ref Ecore_Event_Group "events", @ref
1259 * after the program wakes up. 1628 * Ecore_Timer_Group "timers" or @ref Ecore_FD_Handler_Group "fd handlers".
1260 * 1629 *
1261 * Enterer callbacks are good for updating your program's state, if 1630 * Enterer callbacks are good for updating your program's state, if
1262 * it has a state engine. Once all of the enterer handlers are 1631 * it has a state engine. Once all of the enterer handlers are
@@ -1266,14 +1635,13 @@ EAPI char *ecore_timer_dump(void);
1266 * enterer handlers. They are useful for interfaces that require 1635 * enterer handlers. They are useful for interfaces that require
1267 * polling and timers would be too slow to use. 1636 * polling and timers would be too slow to use.
1268 * 1637 *
1638 * Exiter callbacks are called when the main loop wakes up from an idle state.
1639 *
1269 * If no idler callbacks are specified, then the process literally 1640 * If no idler callbacks are specified, then the process literally
1270 * goes to sleep. Otherwise, the idler callbacks are called 1641 * goes to sleep. Otherwise, the idler callbacks are called
1271 * continuously while the loop is "idle", using as much CPU as is 1642 * continuously while the loop is "idle", using as much CPU as is
1272 * available to the process. 1643 * available to the process.
1273 * 1644 *
1274 * Exiter callbacks are called when the main loop wakes up from an
1275 * idle state.
1276 *
1277 * @note Idle state doesn't mean that the @b program is idle, but 1645 * @note Idle state doesn't mean that the @b program is idle, but
1278 * that the <b>main loop</b> is idle. It doesn't have any timers, 1646 * that the <b>main loop</b> is idle. It doesn't have any timers,
1279 * events, fd handlers or anything else to process (which in most 1647 * events, fd handlers or anything else to process (which in most
@@ -1343,7 +1711,7 @@ EAPI void *ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter);
1343 * thread, the one running the main loop. This problem can be solved 1711 * thread, the one running the main loop. This problem can be solved
1344 * by running a thread that sends messages to the main one using an 1712 * by running a thread that sends messages to the main one using an
1345 * @ref Ecore_Pipe_Group "Ecore_Pipe", but when you need to handle other 1713 * @ref Ecore_Pipe_Group "Ecore_Pipe", but when you need to handle other
1346 * things like cancelling the thread, your code grows in coplexity and gets 1714 * things like cancelling the thread, your code grows in complexity and gets
1347 * much harder to maintain. 1715 * much harder to maintain.
1348 * 1716 *
1349 * Ecore Thread is here to solve that problem. It is @b not a simple wrapper 1717 * Ecore Thread is here to solve that problem. It is @b not a simple wrapper
@@ -1514,7 +1882,7 @@ EAPI Ecore_Thread *ecore_thread_run(Ecore_Thread_Cb func_blocking, Ecore_Thread_
1514 * with ecore_thread_feedback(). 1882 * with ecore_thread_feedback().
1515 * 1883 *
1516 * Like with ecore_thread_run(), a new thread will be launched to run 1884 * Like with ecore_thread_run(), a new thread will be launched to run
1517 * @p func_heavy unless the maximum number of simultaneous threadas has been 1885 * @p func_heavy unless the maximum number of simultaneous threads has been
1518 * reached, in which case the function will be scheduled to run whenever a 1886 * reached, in which case the function will be scheduled to run whenever a
1519 * running task ends and a thread becomes free. But if @p try_no_queue is 1887 * running task ends and a thread becomes free. But if @p try_no_queue is
1520 * set, Ecore will first try to launch a thread outside of the pool to run 1888 * set, Ecore will first try to launch a thread outside of the pool to run
@@ -2076,7 +2444,7 @@ EAPI int ecore_pipe_wait(Ecore_Pipe *p, int message_count, double wait);
2076 * also will be executed in the order in which they were added. 2444 * also will be executed in the order in which they were added.
2077 * 2445 *
2078 * A good use for them is when you don't want to execute an action 2446 * A good use for them is when you don't want to execute an action
2079 * immeditately, but want to give the control back to the main loop 2447 * immediately, but want to give the control back to the main loop
2080 * so that it will call your job callback when jobs start being 2448 * so that it will call your job callback when jobs start being
2081 * processed (and if there are other jobs added before yours, they 2449 * processed (and if there are other jobs added before yours, they
2082 * will be processed first). This also gives the chance to other 2450 * will be processed first). This also gives the chance to other
diff --git a/libraries/ecore/src/lib/ecore/Makefile.am b/libraries/ecore/src/lib/ecore/Makefile.am
index ec3d99f..6f14387 100644
--- a/libraries/ecore/src/lib/ecore/Makefile.am
+++ b/libraries/ecore/src/lib/ecore/Makefile.am
@@ -47,6 +47,12 @@ libecore_la_SOURCES += ecore_exe_ps3.c
47 47
48else 48else
49 49
50if ECORE_HAVE_EXOTIC
51
52libecore_la_SOURCES +=
53
54else
55
50libecore_la_SOURCES += ecore_signal.c ecore_exe.c 56libecore_la_SOURCES += ecore_signal.c ecore_exe.c
51 57
52endif 58endif
@@ -55,6 +61,8 @@ endif
55 61
56endif 62endif
57 63
64endif
65
58libecore_la_LIBADD = @dlopen_libs@ @EINA_LIBS@ @EVIL_LIBS@ @GLIB_LIBS@ @WIN32_LIBS@ @LTLIBINTL@ @EFL_PTHREAD_LIBS@ @rt_libs@ -lm 66libecore_la_LIBADD = @dlopen_libs@ @EINA_LIBS@ @EVIL_LIBS@ @GLIB_LIBS@ @WIN32_LIBS@ @LTLIBINTL@ @EFL_PTHREAD_LIBS@ @rt_libs@ -lm
59libecore_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@ @EFL_PTHREAD_LIBS@ 67libecore_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@ @EFL_PTHREAD_LIBS@
60 68
diff --git a/libraries/ecore/src/lib/ecore/Makefile.in b/libraries/ecore/src/lib/ecore/Makefile.in
index 66a25cd..71e2ac4 100644
--- a/libraries/ecore/src/lib/ecore/Makefile.in
+++ b/libraries/ecore/src/lib/ecore/Makefile.in
@@ -38,7 +38,8 @@ host_triplet = @host@
38@ECORE_HAVE_WIN32_TRUE@am__append_1 = ecore_exe_win32.c 38@ECORE_HAVE_WIN32_TRUE@am__append_1 = ecore_exe_win32.c
39@ECORE_HAVE_WIN32_FALSE@@ECORE_HAVE_WINCE_TRUE@am__append_2 = ecore_exe_wince.c 39@ECORE_HAVE_WIN32_FALSE@@ECORE_HAVE_WINCE_TRUE@am__append_2 = ecore_exe_wince.c
40@ECORE_HAVE_PS3_TRUE@@ECORE_HAVE_WIN32_FALSE@@ECORE_HAVE_WINCE_FALSE@am__append_3 = ecore_exe_ps3.c 40@ECORE_HAVE_PS3_TRUE@@ECORE_HAVE_WIN32_FALSE@@ECORE_HAVE_WINCE_FALSE@am__append_3 = ecore_exe_ps3.c
41@ECORE_HAVE_PS3_FALSE@@ECORE_HAVE_WIN32_FALSE@@ECORE_HAVE_WINCE_FALSE@am__append_4 = ecore_signal.c ecore_exe.c 41@ECORE_HAVE_EXOTIC_TRUE@@ECORE_HAVE_PS3_FALSE@@ECORE_HAVE_WIN32_FALSE@@ECORE_HAVE_WINCE_FALSE@am__append_4 =
42@ECORE_HAVE_EXOTIC_FALSE@@ECORE_HAVE_PS3_FALSE@@ECORE_HAVE_WIN32_FALSE@@ECORE_HAVE_WINCE_FALSE@am__append_5 = ecore_signal.c ecore_exe.c
42subdir = src/lib/ecore 43subdir = src/lib/ecore
43DIST_COMMON = $(includes_HEADERS) $(srcdir)/Makefile.am \ 44DIST_COMMON = $(includes_HEADERS) $(srcdir)/Makefile.am \
44 $(srcdir)/Makefile.in 45 $(srcdir)/Makefile.in
@@ -54,16 +55,15 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ac_attribute.m4 \
54 $(top_srcdir)/m4/efl_path_max.m4 $(top_srcdir)/m4/efl_tests.m4 \ 55 $(top_srcdir)/m4/efl_path_max.m4 $(top_srcdir)/m4/efl_tests.m4 \
55 $(top_srcdir)/m4/efl_threads.m4 $(top_srcdir)/m4/gettext.m4 \ 56 $(top_srcdir)/m4/efl_threads.m4 $(top_srcdir)/m4/gettext.m4 \
56 $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ 57 $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
57 $(top_srcdir)/m4/isc-posix.m4 $(top_srcdir)/m4/lib-ld.m4 \ 58 $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
58 $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ 59 $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \
59 $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ 60 $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
60 $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ 61 $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
61 $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ 62 $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
62 $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ 63 $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/configure.ac
63 $(top_srcdir)/configure.ac
64am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ 64am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
65 $(ACLOCAL_M4) 65 $(ACLOCAL_M4)
66mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs 66mkinstalldirs = $(install_sh) -d
67CONFIG_HEADER = $(top_builddir)/config.h 67CONFIG_HEADER = $(top_builddir)/config.h
68CONFIG_CLEAN_FILES = 68CONFIG_CLEAN_FILES =
69CONFIG_CLEAN_VPATH_FILES = 69CONFIG_CLEAN_VPATH_FILES =
@@ -100,15 +100,16 @@ am__libecore_la_SOURCES_DIST = ecore.c ecore_alloc.c ecore_anim.c \
100@ECORE_HAVE_WIN32_TRUE@am__objects_1 = ecore_exe_win32.lo 100@ECORE_HAVE_WIN32_TRUE@am__objects_1 = ecore_exe_win32.lo
101@ECORE_HAVE_WIN32_FALSE@@ECORE_HAVE_WINCE_TRUE@am__objects_2 = ecore_exe_wince.lo 101@ECORE_HAVE_WIN32_FALSE@@ECORE_HAVE_WINCE_TRUE@am__objects_2 = ecore_exe_wince.lo
102@ECORE_HAVE_PS3_TRUE@@ECORE_HAVE_WIN32_FALSE@@ECORE_HAVE_WINCE_FALSE@am__objects_3 = ecore_exe_ps3.lo 102@ECORE_HAVE_PS3_TRUE@@ECORE_HAVE_WIN32_FALSE@@ECORE_HAVE_WINCE_FALSE@am__objects_3 = ecore_exe_ps3.lo
103@ECORE_HAVE_PS3_FALSE@@ECORE_HAVE_WIN32_FALSE@@ECORE_HAVE_WINCE_FALSE@am__objects_4 = ecore_signal.lo \ 103am__objects_4 =
104@ECORE_HAVE_PS3_FALSE@@ECORE_HAVE_WIN32_FALSE@@ECORE_HAVE_WINCE_FALSE@ ecore_exe.lo 104@ECORE_HAVE_EXOTIC_FALSE@@ECORE_HAVE_PS3_FALSE@@ECORE_HAVE_WIN32_FALSE@@ECORE_HAVE_WINCE_FALSE@am__objects_5 = ecore_signal.lo \
105@ECORE_HAVE_EXOTIC_FALSE@@ECORE_HAVE_PS3_FALSE@@ECORE_HAVE_WIN32_FALSE@@ECORE_HAVE_WINCE_FALSE@ ecore_exe.lo
105am_libecore_la_OBJECTS = ecore.lo ecore_alloc.lo ecore_anim.lo \ 106am_libecore_la_OBJECTS = ecore.lo ecore_alloc.lo ecore_anim.lo \
106 ecore_app.lo ecore_events.lo ecore_getopt.lo \ 107 ecore_app.lo ecore_events.lo ecore_getopt.lo \
107 ecore_idle_enterer.lo ecore_idle_exiter.lo ecore_idler.lo \ 108 ecore_idle_enterer.lo ecore_idle_exiter.lo ecore_idler.lo \
108 ecore_job.lo ecore_main.lo ecore_pipe.lo ecore_poll.lo \ 109 ecore_job.lo ecore_main.lo ecore_pipe.lo ecore_poll.lo \
109 ecore_time.lo ecore_timer.lo ecore_thread.lo ecore_glib.lo \ 110 ecore_time.lo ecore_timer.lo ecore_thread.lo ecore_glib.lo \
110 ecore_throttle.lo $(am__objects_1) $(am__objects_2) \ 111 ecore_throttle.lo $(am__objects_1) $(am__objects_2) \
111 $(am__objects_3) $(am__objects_4) 112 $(am__objects_3) $(am__objects_4) $(am__objects_5)
112libecore_la_OBJECTS = $(am_libecore_la_OBJECTS) 113libecore_la_OBJECTS = $(am_libecore_la_OBJECTS)
113AM_V_lt = $(am__v_lt_$(V)) 114AM_V_lt = $(am__v_lt_$(V))
114am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) 115am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
@@ -211,6 +212,8 @@ EVAS_LIBS = @EVAS_LIBS@
211EVIL_CFLAGS = @EVIL_CFLAGS@ 212EVIL_CFLAGS = @EVIL_CFLAGS@
212EVIL_LIBS = @EVIL_LIBS@ 213EVIL_LIBS = @EVIL_LIBS@
213EXEEXT = @EXEEXT@ 214EXEEXT = @EXEEXT@
215EXOTIC_CFLAGS = @EXOTIC_CFLAGS@
216EXOTIC_LIBS = @EXOTIC_LIBS@
214FGREP = @FGREP@ 217FGREP = @FGREP@
215GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ 218GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
216GLIB_CFLAGS = @GLIB_CFLAGS@ 219GLIB_CFLAGS = @GLIB_CFLAGS@
@@ -266,6 +269,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
266PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ 269PIXMAN_CFLAGS = @PIXMAN_CFLAGS@
267PIXMAN_LIBS = @PIXMAN_LIBS@ 270PIXMAN_LIBS = @PIXMAN_LIBS@
268PKG_CONFIG = @PKG_CONFIG@ 271PKG_CONFIG = @PKG_CONFIG@
272PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
273PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
269POSUB = @POSUB@ 274POSUB = @POSUB@
270RANLIB = @RANLIB@ 275RANLIB = @RANLIB@
271SCIM_CFLAGS = @SCIM_CFLAGS@ 276SCIM_CFLAGS = @SCIM_CFLAGS@
@@ -276,6 +281,7 @@ SDL_LIBS = @SDL_LIBS@
276SED = @SED@ 281SED = @SED@
277SET_MAKE = @SET_MAKE@ 282SET_MAKE = @SET_MAKE@
278SHELL = @SHELL@ 283SHELL = @SHELL@
284SHM_OPEN_LIBS = @SHM_OPEN_LIBS@
279SSL_CFLAGS = @SSL_CFLAGS@ 285SSL_CFLAGS = @SSL_CFLAGS@
280SSL_LIBS = @SSL_LIBS@ 286SSL_LIBS = @SSL_LIBS@
281STRIP = @STRIP@ 287STRIP = @STRIP@
@@ -503,7 +509,8 @@ libecore_la_SOURCES = ecore.c ecore_alloc.c ecore_anim.c ecore_app.c \
503 ecore_idle_exiter.c ecore_idler.c ecore_job.c ecore_main.c \ 509 ecore_idle_exiter.c ecore_idler.c ecore_job.c ecore_main.c \
504 ecore_pipe.c ecore_poll.c ecore_time.c ecore_timer.c \ 510 ecore_pipe.c ecore_poll.c ecore_time.c ecore_timer.c \
505 ecore_thread.c ecore_glib.c ecore_throttle.c $(am__append_1) \ 511 ecore_thread.c ecore_glib.c ecore_throttle.c $(am__append_1) \
506 $(am__append_2) $(am__append_3) $(am__append_4) 512 $(am__append_2) $(am__append_3) $(am__append_4) \
513 $(am__append_5)
507libecore_la_LIBADD = @dlopen_libs@ @EINA_LIBS@ @EVIL_LIBS@ @GLIB_LIBS@ @WIN32_LIBS@ @LTLIBINTL@ @EFL_PTHREAD_LIBS@ @rt_libs@ -lm 514libecore_la_LIBADD = @dlopen_libs@ @EINA_LIBS@ @EVIL_LIBS@ @GLIB_LIBS@ @WIN32_LIBS@ @LTLIBINTL@ @EFL_PTHREAD_LIBS@ @rt_libs@ -lm
508libecore_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@ @EFL_PTHREAD_LIBS@ 515libecore_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@ @EFL_PTHREAD_LIBS@
509EXTRA_DIST = ecore_private.h 516EXTRA_DIST = ecore_private.h
diff --git a/libraries/ecore/src/lib/ecore/ecore.c b/libraries/ecore/src/lib/ecore/ecore.c
index 7e0f973..d8b8723 100644
--- a/libraries/ecore/src/lib/ecore/ecore.c
+++ b/libraries/ecore/src/lib/ecore/ecore.c
@@ -163,8 +163,10 @@ ecore_init(void)
163 if (!ecore_mempool_init()) goto shutdown_mempool; 163 if (!ecore_mempool_init()) goto shutdown_mempool;
164 _ecore_main_loop_init(); 164 _ecore_main_loop_init();
165 _ecore_signal_init(); 165 _ecore_signal_init();
166 _ecore_thread_init(); 166#ifndef HAVE_EXOTIC
167 _ecore_exe_init(); 167 _ecore_exe_init();
168#endif
169 _ecore_thread_init();
168 _ecore_glib_init(); 170 _ecore_glib_init();
169 _ecore_job_init(); 171 _ecore_job_init();
170 _ecore_time_init(); 172 _ecore_time_init();
@@ -252,7 +254,9 @@ ecore_shutdown(void)
252 _ecore_glib_shutdown(); 254 _ecore_glib_shutdown();
253 _ecore_job_shutdown(); 255 _ecore_job_shutdown();
254 _ecore_thread_shutdown(); 256 _ecore_thread_shutdown();
257#ifndef HAVE_EXOTIC
255 _ecore_exe_shutdown(); 258 _ecore_exe_shutdown();
259#endif
256 _ecore_idle_enterer_shutdown(); 260 _ecore_idle_enterer_shutdown();
257 _ecore_idle_exiter_shutdown(); 261 _ecore_idle_exiter_shutdown();
258 _ecore_idler_shutdown(); 262 _ecore_idler_shutdown();
diff --git a/libraries/ecore/src/lib/ecore/ecore_anim.c b/libraries/ecore/src/lib/ecore/ecore_anim.c
index 78abad7..22c1f8c 100644
--- a/libraries/ecore/src/lib/ecore/ecore_anim.c
+++ b/libraries/ecore/src/lib/ecore/ecore_anim.c
@@ -272,11 +272,11 @@ ecore_animator_pos_map(double pos,
272 return pos; 272 return pos;
273 273
274 case ECORE_POS_MAP_ACCELERATE: 274 case ECORE_POS_MAP_ACCELERATE:
275 pos = 1.0 - _pos_map_sin((M_PI / 2.0) + ((pos * M_PI) / 2.0)); 275 pos = 1.0 - _pos_map_sin(M_PI_2 + pos * M_PI_2);
276 return pos; 276 return pos;
277 277
278 case ECORE_POS_MAP_DECELERATE: 278 case ECORE_POS_MAP_DECELERATE:
279 pos = _pos_map_sin((pos * M_PI) / 2.0); 279 pos = _pos_map_sin(pos * M_PI_2);
280 return pos; 280 return pos;
281 281
282 case ECORE_POS_MAP_SINUSOIDAL: 282 case ECORE_POS_MAP_SINUSOIDAL:
diff --git a/libraries/ecore/src/lib/ecore/ecore_events.c b/libraries/ecore/src/lib/ecore/ecore_events.c
index 0550224..500cf74 100644
--- a/libraries/ecore/src/lib/ecore/ecore_events.c
+++ b/libraries/ecore/src/lib/ecore/ecore_events.c
@@ -72,35 +72,6 @@ static void *ecore_raw_event_event = NULL;
72static void _ecore_event_purge_deleted(void); 72static void _ecore_event_purge_deleted(void);
73static void *_ecore_event_del(Ecore_Event *event); 73static void *_ecore_event_del(Ecore_Event *event);
74 74
75/**
76 * @addtogroup Ecore_Event_Group
77 *
78 * @{
79 */
80
81/**
82 * Add an event handler.
83 * @param type The type of the event this handler will get called for
84 * @param func The function to call when the event is found in the queue
85 * @param data A data pointer to pass to the called function @p func
86 * @return A new Event handler, or NULL on failure
87 *
88 * Add an event handler to the list of handlers. This will, on success, return
89 * a handle to the event handler object that was created, that can be used
90 * later to remove the handler using ecore_event_handler_del(). The @p type
91 * parameter is the integer of the event type that will trigger this callback
92 * to be called. The callback @p func is called when this event is processed
93 * and will be passed the event type, a pointer to the private event
94 * structure that is specific to that event type, and a data pointer that is
95 * provided in this call as the @p data parameter.
96 *
97 * When the callback @p func is called, it must return 1 or 0. If it returns
98 * 1 (or ECORE_CALLBACK_PASS_ON), It will keep being called as per normal, for
99 * each handler set up for that event type. If it returns 0 (or
100 * ECORE_CALLBACK_DONE), it will cease processing handlers for that particular
101 * event, so all handler set to handle that event type that have not already
102 * been called, will not be.
103 */
104EAPI Ecore_Event_Handler * 75EAPI Ecore_Event_Handler *
105ecore_event_handler_add(int type, 76ecore_event_handler_add(int type,
106 Ecore_Event_Handler_Cb func, 77 Ecore_Event_Handler_Cb func,
@@ -151,16 +122,6 @@ unlock:
151 return eh; 122 return eh;
152} 123}
153 124
154/**
155 * Delete an event handler.
156 * @param event_handler Event handler handle to delete
157 * @return Data passed to handler
158 *
159 * Delete a specified event handler from the handler list. On success this will
160 * delete the event handler and return the pointer passed as @p data when the
161 * handler was added by ecore_event_handler_add(). On failure NULL will be
162 * returned. Once a handler is deleted it will no longer be called.
163 */
164EAPI void * 125EAPI void *
165ecore_event_handler_del(Ecore_Event_Handler *event_handler) 126ecore_event_handler_del(Ecore_Event_Handler *event_handler)
166{ 127{
@@ -180,14 +141,6 @@ unlock:
180 return data; 141 return data;
181} 142}
182 143
183/**
184 * @brief Get the data associated with an #Ecore_Event_Handler
185 * @param eh The event handler
186 * @return The data
187 *
188 * This function returns the data previously associated with @p eh by
189 * ecore_event_handler_add().
190 */
191EAPI void * 144EAPI void *
192ecore_event_handler_data_get(Ecore_Event_Handler *eh) 145ecore_event_handler_data_get(Ecore_Event_Handler *eh)
193{ 146{
@@ -205,15 +158,6 @@ unlock:
205 return data; 158 return data;
206} 159}
207 160
208/**
209 * @brief Set the data associated with an #Ecore_Event_Handler
210 * @param eh The event handler
211 * @param data The data to associate
212 * @return The previous data
213 *
214 * This function sets @p data to @p eh and returns the old data pointer
215 * which was previously associated with @p eh by ecore_event_handler_add().
216 */
217EAPI void * 161EAPI void *
218ecore_event_handler_data_set(Ecore_Event_Handler *eh, 162ecore_event_handler_data_set(Ecore_Event_Handler *eh,
219 const void *data) 163 const void *data)
@@ -238,27 +182,9 @@ static void
238_ecore_event_generic_free(void *data __UNUSED__, 182_ecore_event_generic_free(void *data __UNUSED__,
239 void *event) 183 void *event)
240{ /* DO NOT MEMPOOL FREE THIS */ 184{ /* DO NOT MEMPOOL FREE THIS */
241 free (event); 185 free(event);
242} 186}
243 187
244/**
245 * Add an event to the event queue.
246 * @param type The event type to add to the end of the event queue
247 * @param ev The private data structure for this event type
248 * @param func_free The function to be called to free this private structure
249 * @param data The data pointer to be passed to the free function
250 * @return A Handle for that event
251 *
252 * On success this function returns a handle to an event on the event queue, or
253 * NULL if it fails. If it succeeds, an event of type @p type will be added
254 * to the queue for processing by event handlers added by
255 * ecore_event_handler_add(). The @p ev parameter will be a pointer to the event
256 * private data that is specific to that event type. When the event is no
257 * longer needed, @p func_free will be called and passed the private structure
258 * pointer for cleaning up. If @p func_free is NULL, free() will be called
259 * with the private structure pointer.
260 * func_free is passed @p data as its data parameter.
261 */
262EAPI Ecore_Event * 188EAPI Ecore_Event *
263ecore_event_add(int type, 189ecore_event_add(int type,
264 void *ev, 190 void *ev,
@@ -279,17 +205,6 @@ unlock:
279 return event; 205 return event;
280} 206}
281 207
282/**
283 * Delete an event from the queue.
284 * @param event The event handle to delete
285 * @return The data pointer originally set for the event free function
286 *
287 * This deletes the event @p event from the event queue, and returns the
288 * @p data parameer originally set when adding it with ecore_event_add(). This
289 * does not immediately call the free function, and it may be called later on
290 * cleanup, and so if the free function depends on the data pointer to work,
291 * you should defer cleaning of this till the free function is called later.
292 */
293EAPI void * 208EAPI void *
294ecore_event_del(Ecore_Event *event) 209ecore_event_del(Ecore_Event *event)
295{ 210{
@@ -309,16 +224,6 @@ unlock:
309 return data; 224 return data;
310} 225}
311 226
312/**
313 * Allocate a new event type id sensibly and return the new id.
314 * @return A new event type id.
315 *
316 * This function allocates a new event type id and returns it. Once an event
317 * type has been allocated it can never be de-allocated during the life of
318 * the program. There is no guarantee of the contents of this event ID, or how
319 * it is calculated, except that the ID will be unique to the current instance
320 * of the process.
321 */
322EAPI int 227EAPI int
323ecore_event_type_new(void) 228ecore_event_type_new(void)
324{ 229{
@@ -331,26 +236,6 @@ ecore_event_type_new(void)
331 return id; 236 return id;
332} 237}
333 238
334/**
335 * Add a filter the current event queue.
336 * @param func_start Function to call just before filtering and return data
337 * @param func_filter Function to call on each event
338 * @param func_end Function to call after the queu has been filtered
339 * @param data Data to pass to the filter functions
340 * @return A filter handle
341 *
342 * This adds a filter to call callbacks to loop through the event queue and
343 * filter events out of the queue. On failure NULL is returned. On success a
344 * Filter handle is returned. Filters are called on the queue just before
345 * Event handler processing to try and remove redundant events. Just as
346 * processing starts @p func_start is called and passed the @p data pointer.
347 * This function returns a pointer that is used as loop_data that is now passed to
348 * @p func_filter as loop_data. @p func_filter is also passed @p data and the
349 * event type and private event structure. If this callback returns 0, the
350 * event is removed from the queue. If it returns 1, the event is kept. When
351 * processing is finished @p func_end is called and is passed the loop_data
352 * and @p data pointer to clean up.
353 */
354EAPI Ecore_Event_Filter * 239EAPI Ecore_Event_Filter *
355ecore_event_filter_add(Ecore_Data_Cb func_start, 240ecore_event_filter_add(Ecore_Data_Cb func_start,
356 Ecore_Filter_Cb func_filter, 241 Ecore_Filter_Cb func_filter,
@@ -374,15 +259,6 @@ unlock:
374 return ef; 259 return ef;
375} 260}
376 261
377/**
378 * Delete an event filter.
379 * @param ef The event filter handle
380 * @return The data set for the filter
381 *
382 * Delete a filter that has been added by its @p ef handle. On success this
383 * will return the data pointer set when this filter was added. On failure
384 * NULL is returned.
385 */
386EAPI void * 262EAPI void *
387ecore_event_filter_del(Ecore_Event_Filter *ef) 263ecore_event_filter_del(Ecore_Event_Filter *ef)
388{ 264{
@@ -404,50 +280,18 @@ unlock:
404 return data; 280 return data;
405} 281}
406 282
407/**
408 * Return the current event type being handled.
409 * @return The current event type being handled if inside a handler callback
410 *
411 * If the program is currently inside an Ecore event handler callback this
412 * will return the type of the current event being processed. If Ecore is
413 * not inside an event handler, ECORE_EVENT_NONE is returned.
414 *
415 * This is useful when certain Ecore modules such as Ecore_Evas "swallow"
416 * events and not all the original information is passed on. In special cases
417 * this extra information may be useful or needed and using this call can let
418 * the program know if the event type being handled is one it wants to get more
419 * information about.
420 */
421EAPI int 283EAPI int
422ecore_event_current_type_get(void) 284ecore_event_current_type_get(void)
423{ 285{
424 return ecore_raw_event_type; 286 return ecore_raw_event_type;
425} 287}
426 288
427/**
428 * Return the current event type pointer handled.
429 * @return The current event pointer being handled if inside a handler callback
430 *
431 * If the program is currently inside an Ecore event handler callback this
432 * will return the pointer of the current event being processed. If Ecore is
433 * not inside an event handler, NULL will be returned.
434 *
435 * This is useful when certain Ecore modules such as Ecore_Evas "swallow"
436 * events and not all the original information is passed on. In special cases
437 * this extra information may be useful or needed and using this call can let
438 * the program access the event data if the type of the event is handled by
439 * the program.
440 */
441EAPI void * 289EAPI void *
442ecore_event_current_event_get(void) 290ecore_event_current_event_get(void)
443{ 291{
444 return ecore_raw_event_event; 292 return ecore_raw_event_event;
445} 293}
446 294
447/**
448 * @}
449 */
450
451EAPI void * 295EAPI void *
452_ecore_event_handler_del(Ecore_Event_Handler *event_handler) 296_ecore_event_handler_del(Ecore_Event_Handler *event_handler)
453{ 297{
diff --git a/libraries/ecore/src/lib/ecore/ecore_exe.c b/libraries/ecore/src/lib/ecore/ecore_exe.c
index d5465fc..47f8dc9 100644
--- a/libraries/ecore/src/lib/ecore/ecore_exe.c
+++ b/libraries/ecore/src/lib/ecore/ecore_exe.c
@@ -331,15 +331,15 @@ static int run_pri = ECORE_EXE_PRIORITY_INHERIT;
331 * This sets the priority of processes run by ecore_exe_run() and 331 * This sets the priority of processes run by ecore_exe_run() and
332 * ecore_exe_pipe_run(). 332 * ecore_exe_pipe_run().
333 * @li On Windows, the child process is created by default with the 333 * @li On Windows, the child process is created by default with the
334 * #ECORE_EXE_WIN32_PRIORITY_NORMAL priority, unless the calling 334 * @ref ECORE_EXE_WIN32_PRIORITY_NORMAL priority, unless the calling
335 * process is in #ECORE_EXE_WIN32_PRIORITY_IDLE or 335 * process is in @ref ECORE_EXE_WIN32_PRIORITY_IDLE or
336 * #ECORE_EXE_WIN32_PRIORITY_BELOW_NORMAL priority. In that case, the 336 * @ref ECORE_EXE_WIN32_PRIORITY_BELOW_NORMAL priority. In that case, the
337 * child process inherits this priority. 337 * child process inherits this priority.
338 * @li On other platforms, if set to #ECORE_EXE_PRIORITY_INHERIT child 338 * @li On other platforms, if set to @ref ECORE_EXE_PRIORITY_INHERIT child
339 * processes inherits the priority of their parent. This is the default. 339 * processes inherits the priority of their parent. This is the default.
340 * 340 *
341 * @param pri value a Ecore_Exe_Win32_Priority value on Windows, -20 341 * @param pri value a Ecore_Exe_Win32_Priority value on Windows, -20
342 * to 19 or ECORE_EXE_PRIORITY_INHERIT on other OS. 342 * to 19 or @ref ECORE_EXE_PRIORITY_INHERIT on other OS.
343 */ 343 */
344EAPI void 344EAPI void
345ecore_exe_run_priority_set(int pri) 345ecore_exe_run_priority_set(int pri)
diff --git a/libraries/ecore/src/lib/ecore/ecore_getopt.c b/libraries/ecore/src/lib/ecore/ecore_getopt.c
index 76272d3..cd68189 100644
--- a/libraries/ecore/src/lib/ecore/ecore_getopt.c
+++ b/libraries/ecore/src/lib/ecore/ecore_getopt.c
@@ -38,6 +38,10 @@ void *alloca(size_t);
38# include <Evil.h> 38# include <Evil.h>
39#endif 39#endif
40 40
41#ifdef HAVE_EXOTIC
42# include <Exotic.h>
43#endif
44
41#include "Ecore.h" 45#include "Ecore.h"
42#include "Ecore_Getopt.h" 46#include "Ecore_Getopt.h"
43 47
diff --git a/libraries/ecore/src/lib/ecore/ecore_main.c b/libraries/ecore/src/lib/ecore/ecore_main.c
index 76aced6..587c83b 100644
--- a/libraries/ecore/src/lib/ecore/ecore_main.c
+++ b/libraries/ecore/src/lib/ecore/ecore_main.c
@@ -229,10 +229,14 @@ static Eina_Bool win32_handlers_delete_me = EINA_FALSE;
229#ifdef _WIN32 229#ifdef _WIN32
230Ecore_Select_Function main_loop_select = _ecore_main_win32_select; 230Ecore_Select_Function main_loop_select = _ecore_main_win32_select;
231#else 231#else
232# ifdef HAVE_SYS_SELECT_H 232# if !defined EXOTIC_NO_SELECT
233# include <sys/select.h> 233# ifdef HAVE_SYS_SELECT_H
234# endif 234# include <sys/select.h>
235# endif
235Ecore_Select_Function main_loop_select = select; 236Ecore_Select_Function main_loop_select = select;
237# else
238Ecore_Select_Function main_loop_select = NULL;
239# endif
236#endif 240#endif
237 241
238#ifndef USE_G_MAIN_LOOP 242#ifndef USE_G_MAIN_LOOP
@@ -848,6 +852,21 @@ _ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler)
848 * DO NOT use this function unless you are the person God comes to ask for 852 * DO NOT use this function unless you are the person God comes to ask for
849 * advice when He has trouble managing the Universe. 853 * advice when He has trouble managing the Universe.
850 */ 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}
851EAPI void 870EAPI void
852ecore_main_loop_iterate(void) 871ecore_main_loop_iterate(void)
853{ 872{
@@ -945,39 +964,6 @@ ecore_main_loop_select_func_get(void)
945 return main_loop_select; 964 return main_loop_select;
946} 965}
947 966
948/**
949 * Adds a callback for activity on the given file descriptor.
950 *
951 * @p func will be called during the execution of @ref ecore_main_loop_begin
952 * when the file descriptor is available for reading, or writing, or both.
953 *
954 * Normally when @p func returns ECORE_CALLBACK_CANCEL, it indicates that the
955 * handler should be marked for deletion (identical to calling @ref ecore_main_fd_handler_del).
956 * However, if the @p buf_func is supplied, then the return value from the @p func indicates that
957 * @p func should be called repeatedly until it returns ECORE_CALLBACK_CANCEL.
958 *
959 * @p buf_func is called during event loop handling to check if data that has
960 * been read from the file descriptor is in a buffer and is available to
961 * read. Some systems (notably xlib) handle their own buffering, and would
962 * otherwise not work with select(). These systems should use a @p buf_func.
963 * This is a most annoying hack, only ecore_x uses it, so refer to that for
964 * an example. NOTE - @p func should probably return ECORE_CALLBACK_RENEW always if
965 * @p buf_func is used, to avoid confusion with the other return value
966 * semantics.
967 *
968 * @param fd The file descriptor to watch.
969 * @param flags To watch it for read (@c ECORE_FD_READ) and/or
970 * (@c ECORE_FD_WRITE) write ability. @c ECORE_FD_ERROR
971 *
972 * @param func The callback function.
973 * @param data The data to pass to the callback.
974 * @param buf_func The function to call to check if any data has been
975 * buffered and already read from the fd. Can be @c NULL.
976 * @param buf_data The data to pass to the @p buf_func function.
977 * @return A fd handler handle if successful. @c NULL otherwise.
978 * @note This function CANNOT be used for reading/writing to regular files!
979 * @ingroup Ecore_FD_Handler_Group
980 */
981EAPI Ecore_Fd_Handler * 967EAPI Ecore_Fd_Handler *
982ecore_main_fd_handler_add(int fd, 968ecore_main_fd_handler_add(int fd,
983 Ecore_Fd_Handler_Flags flags, 969 Ecore_Fd_Handler_Flags flags,
@@ -1059,20 +1045,6 @@ ecore_main_win32_handler_add(void *h __UNUSED__,
1059 1045
1060#endif 1046#endif
1061 1047
1062/**
1063 * Marks an FD handler for deletion.
1064 * @param fd_handler The FD handler.
1065 * @return The data pointer set using @ref ecore_main_fd_handler_add,
1066 * for @p fd_handler on success. @c NULL otherwise.
1067 * @ingroup Ecore_FD_Handler_Group
1068 * This function marks an fd handler to be deleted during an iteration of the main loop.
1069 * It does NOT close the associated fd!
1070 *
1071 * @note If the underlying fd is already closed ecore may complain if the main loop
1072 * is using epoll internally, and also in some rare cases this may cause
1073 * crashes and instability. Remember to delete your fd handlers before the
1074 * fds they listen to are closed.
1075 */
1076EAPI void * 1048EAPI void *
1077ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler) 1049ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler)
1078{ 1050{
@@ -1116,24 +1088,6 @@ ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler __UNUSED__)
1116 1088
1117#endif 1089#endif
1118 1090
1119/**
1120 * @brief Set the prepare callback with data for a given #Ecore_Fd_Handler
1121 *
1122 * @param fd_handler The fd handler
1123 * @param func The prep function
1124 * @param data The data to pass to the prep function
1125 *
1126 * This function will be called prior to any fd handler's callback function
1127 * (even the other fd handlers), before entering the main loop select function.
1128 *
1129 * @note Once a prepare callback is set for a fd handler, it cannot be changed.
1130 * You need to delete the fd handler and create a new one, to set another
1131 * callback.
1132 * @note You probably don't need this function. It is only necessary for very
1133 * uncommon cases that need special behavior.
1134 *
1135 * @ingroup Ecore_FD_Handler_Group
1136 */
1137EAPI void 1091EAPI void
1138ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, 1092ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler,
1139 Ecore_Fd_Prep_Cb func, 1093 Ecore_Fd_Prep_Cb func,
@@ -1157,12 +1111,6 @@ unlock:
1157 _ecore_unlock(); 1111 _ecore_unlock();
1158} 1112}
1159 1113
1160/**
1161 * Retrieves the file descriptor that the given handler is handling.
1162 * @param fd_handler The given FD handler.
1163 * @return The file descriptor the handler is watching.
1164 * @ingroup Ecore_FD_Handler_Group
1165 */
1166EAPI int 1114EAPI int
1167ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler) 1115ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler)
1168{ 1116{
@@ -1182,15 +1130,6 @@ unlock:
1182 return fd; 1130 return fd;
1183} 1131}
1184 1132
1185/**
1186 * Return if read, write or error, or a combination thereof, is active on the
1187 * file descriptor of the given FD handler.
1188 * @param fd_handler The given FD handler.
1189 * @param flags The flags, @c ECORE_FD_READ, @c ECORE_FD_WRITE or
1190 * @c ECORE_FD_ERROR to query.
1191 * @return #EINA_TRUE if any of the given flags are active. #EINA_FALSE otherwise.
1192 * @ingroup Ecore_FD_Handler_Group
1193 */
1194EAPI Eina_Bool 1133EAPI Eina_Bool
1195ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, 1134ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler,
1196 Ecore_Fd_Handler_Flags flags) 1135 Ecore_Fd_Handler_Flags flags)
@@ -1213,12 +1152,6 @@ unlock:
1213 return ret; 1152 return ret;
1214} 1153}
1215 1154
1216/**
1217 * Set what active streams the given FD handler should be monitoring.
1218 * @param fd_handler The given FD handler.
1219 * @param flags The flags to be watching.
1220 * @ingroup Ecore_FD_Handler_Group
1221 */
1222EAPI void 1155EAPI void
1223ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, 1156ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler,
1224 Ecore_Fd_Handler_Flags flags) 1157 Ecore_Fd_Handler_Flags flags)
@@ -1742,14 +1675,14 @@ _ecore_main_loop_iterate_internal(int once_only)
1742 if (_ecore_event_exist()) 1675 if (_ecore_event_exist())
1743 { 1676 {
1744 /* but first conceptually enter an idle state */ 1677 /* but first conceptually enter an idle state */
1745 _ecore_idle_enterer_call(); 1678 _ecore_idle_enterer_call();
1746 _ecore_throttle(); 1679 _ecore_throttle();
1747 /* now quickly poll to see which input fd's are active */ 1680 /* now quickly poll to see which input fd's are active */
1748 _ecore_main_select(0.0); 1681 _ecore_main_select(0.0);
1749 /* allow newly queued timers to expire from now on */ 1682 /* allow newly queued timers to expire from now on */
1750 _ecore_timer_enable_new(); 1683 _ecore_timer_enable_new();
1751 /* go straight to processing the events we had queued */ 1684 /* go straight to processing the events we had queued */
1752 goto process_all; 1685 goto process_all;
1753 } 1686 }
1754 1687
1755 if (once_only) 1688 if (once_only)
@@ -1758,17 +1691,17 @@ _ecore_main_loop_iterate_internal(int once_only)
1758 * if we got any events or signals, allow new timers to process. 1691 * if we got any events or signals, allow new timers to process.
1759 * use bitwise or to force both conditions to be tested and 1692 * use bitwise or to force both conditions to be tested and
1760 * merged together */ 1693 * merged together */
1761 if (_ecore_main_select(0.0) | _ecore_signal_count_get()) 1694 if (_ecore_main_select(0.0) | _ecore_signal_count_get())
1762 { 1695 {
1763 _ecore_timer_enable_new(); 1696 _ecore_timer_enable_new();
1764 goto process_all; 1697 goto process_all;
1765 } 1698 }
1766 } 1699 }
1767 else 1700 else
1768 { 1701 {
1769 /* call idle enterers ... */ 1702 /* call idle enterers ... */
1770 _ecore_idle_enterer_call(); 1703 _ecore_idle_enterer_call();
1771 _ecore_throttle(); 1704 _ecore_throttle();
1772 } 1705 }
1773 1706
1774 /* if these calls caused any buffered events to appear - deal with them */ 1707 /* if these calls caused any buffered events to appear - deal with them */
@@ -1787,10 +1720,10 @@ _ecore_main_loop_iterate_internal(int once_only)
1787 if (once_only) 1720 if (once_only)
1788 { 1721 {
1789 /* in once_only mode enter idle here instead and then return */ 1722 /* in once_only mode enter idle here instead and then return */
1790 _ecore_idle_enterer_call(); 1723 _ecore_idle_enterer_call();
1791 _ecore_throttle(); 1724 _ecore_throttle();
1792 _ecore_timer_enable_new(); 1725 _ecore_timer_enable_new();
1793 goto done; 1726 goto done;
1794 } 1727 }
1795 1728
1796 _ecore_fps_marker_1(); 1729 _ecore_fps_marker_1();
@@ -1808,23 +1741,23 @@ start_loop: /***************************************************************/
1808 if (!_ecore_event_exist()) 1741 if (!_ecore_event_exist())
1809 { 1742 {
1810 /* init flags */ 1743 /* init flags */
1811 next_time = _ecore_timer_next_get(); 1744 next_time = _ecore_timer_next_get();
1812 /* no idlers */ 1745 /* no idlers */
1813 if (!_ecore_idler_exist()) 1746 if (!_ecore_idler_exist())
1814 { 1747 {
1815 /* sleep until timeout or forever (-1.0) waiting for on fds */ 1748 /* sleep until timeout or forever (-1.0) waiting for on fds */
1816 _ecore_main_select(next_time); 1749 _ecore_main_select(next_time);
1817 } 1750 }
1818 else 1751 else
1819 { 1752 {
1820 int action = LOOP_CONTINUE; 1753 int action = LOOP_CONTINUE;
1821 1754
1822 /* no timers - spin */ 1755 /* no timers - spin */
1823 if (next_time < 0) action = _ecore_main_loop_spin_no_timers(); 1756 if (next_time < 0) action = _ecore_main_loop_spin_no_timers();
1824 /* timers - spin */ 1757 /* timers - spin */
1825 else action = _ecore_main_loop_spin_timers(); 1758 else action = _ecore_main_loop_spin_timers();
1826 if (action == SPIN_RESTART) goto start_loop; 1759 if (action == SPIN_RESTART) goto start_loop;
1827 } 1760 }
1828 } 1761 }
1829 _ecore_fps_marker_2(); 1762 _ecore_fps_marker_2();
1830 1763
@@ -1847,8 +1780,8 @@ process_all: /***********************************************************/
1847 if (once_only) 1780 if (once_only)
1848 { 1781 {
1849 /* if in once_only mode handle idle exiting */ 1782 /* if in once_only mode handle idle exiting */
1850 _ecore_idle_enterer_call(); 1783 _ecore_idle_enterer_call();
1851 _ecore_throttle(); 1784 _ecore_throttle();
1852 } 1785 }
1853 1786
1854done: /*******************************************************************/ 1787done: /*******************************************************************/
diff --git a/libraries/ecore/src/lib/ecore/ecore_pipe.c b/libraries/ecore/src/lib/ecore/ecore_pipe.c
index aa640cd..ea7453e 100644
--- a/libraries/ecore/src/lib/ecore/ecore_pipe.c
+++ b/libraries/ecore/src/lib/ecore/ecore_pipe.c
@@ -36,15 +36,13 @@
36# include <Escape.h> 36# include <Escape.h>
37#endif 37#endif
38 38
39#ifdef HAVE_EXOTIC
40# include <Exotic.h>
41#endif
42
39#include "Ecore.h" 43#include "Ecore.h"
40#include "ecore_private.h" 44#include "ecore_private.h"
41 45
42#ifdef _WIN32
43# define FMT_SSIZE_T "%Id"
44#else
45# define FMT_SSIZE_T "%zd"
46#endif
47
48/* How of then we should retry to write to the pipe */ 46/* How of then we should retry to write to the pipe */
49#define ECORE_PIPE_WRITE_RETRY 6 47#define ECORE_PIPE_WRITE_RETRY 6
50 48
@@ -80,6 +78,9 @@
80 78
81#endif /* ! _WIN32 */ 79#endif /* ! _WIN32 */
82 80
81#include <Ecore.h>
82#include "ecore_private.h"
83
83struct _Ecore_Pipe 84struct _Ecore_Pipe
84{ 85{
85 ECORE_MAGIC; 86 ECORE_MAGIC;
@@ -414,7 +415,7 @@ ecore_pipe_write(Ecore_Pipe *p,
414 ; 415 ;
415 else 416 else
416 { 417 {
417 ERR("An unhandled error (ret: " FMT_SSIZE_T " errno: %d)" 418 ERR("An unhandled error (ret: %zd errno: %d)"
418 "occurred while writing to the pipe the length", 419 "occurred while writing to the pipe the length",
419 ret, errno); 420 ret, errno);
420 } 421 }
@@ -448,7 +449,7 @@ ecore_pipe_write(Ecore_Pipe *p,
448 ; 449 ;
449 else 450 else
450 { 451 {
451 ERR("An unhandled error (ret: " FMT_SSIZE_T " errno: %d)" 452 ERR("An unhandled error (ret: %zd errno: %d)"
452 "occurred while writing to the pipe the length", 453 "occurred while writing to the pipe the length",
453 ret, errno); 454 ret, errno);
454 } 455 }
diff --git a/libraries/ecore/src/lib/ecore/ecore_poll.c b/libraries/ecore/src/lib/ecore/ecore_poll.c
index 732850b..bf4da6a 100644
--- a/libraries/ecore/src/lib/ecore/ecore_poll.c
+++ b/libraries/ecore/src/lib/ecore/ecore_poll.c
@@ -189,20 +189,6 @@ _ecore_poller_cb_timer(void *data __UNUSED__)
189 return ECORE_CALLBACK_RENEW; 189 return ECORE_CALLBACK_RENEW;
190} 190}
191 191
192/**
193 * @addtogroup Ecore_Poller_Group
194 *
195 * @{
196 */
197
198/**
199 * Sets the time between ticks (in seconds) for the given ticker clock.
200 * @param type The ticker type to adjust
201 * @param poll_time The time (in seconds) between ticks of the clock
202 *
203 * This will adjust the time between ticks of the given ticker type defined
204 * by @p type to the time period defined by @p poll_time.
205 */
206EAPI void 192EAPI void
207ecore_poller_poll_interval_set(Ecore_Poller_Type type __UNUSED__, 193ecore_poller_poll_interval_set(Ecore_Poller_Type type __UNUSED__,
208 double poll_time) 194 double poll_time)
@@ -211,65 +197,12 @@ ecore_poller_poll_interval_set(Ecore_Poller_Type type __UNUSED__,
211 _ecore_poller_next_tick_eval(); 197 _ecore_poller_next_tick_eval();
212} 198}
213 199
214/**
215 * Gets the time between ticks (in seconds) for the given ticker clock.
216 * @param type The ticker type to query
217 * @return The time in seconds between ticks of the ticker clock
218 *
219 * This will get the time between ticks of the specified ticker clock.
220 */
221EAPI double 200EAPI double
222ecore_poller_poll_interval_get(Ecore_Poller_Type type __UNUSED__) 201ecore_poller_poll_interval_get(Ecore_Poller_Type type __UNUSED__)
223{ 202{
224 return poll_interval; 203 return poll_interval;
225} 204}
226 205
227/**
228 * Creates a poller to call the given function at a particular tick interval.
229 * @param type The ticker type to attach the poller to
230 * @param interval The poll interval
231 * @param func The given function. If @p func returns 1, the poller is
232 * rescheduled for the next tick interval.
233 * @param data Data to pass to @p func when it is called.
234 * @return A poller object on success. @c NULL on failure.
235 *
236 * This function adds a poller callback that is to be called regularly
237 * along with all other poller callbacks so the pollers are synchronized with
238 * all other pollers running off the same poller type and at the same tick
239 * interval. This should be used for polling things when polling is desired
240 * or required, and you do not have specific requirements on the exact times
241 * to poll and want to avoid extra process wakeups for polling. This will
242 * save power as the CPU has more of a chance to go into a low power state
243 * the longer it is asleep for, so this should be used if you are at all
244 * power conscious.
245 *
246 * The @p type parameter defines the poller tick type (there is a virtual
247 * clock ticking all the time - though ecore avoids making it tick when
248 * there will not be any work to do at that tick point). There is only one
249 * ticker at the moment - that is ECORE_POLLER_CORE. This is here for future
250 * expansion if multiple clocks with different frequencies are really required.
251 * The default time between ticks for the ECORE_POLLER_CORE ticker is 0.125
252 * seconds.
253 *
254 * The @p interval is the number of ticker ticks that will pass by in between
255 * invocations of the @p func callback. This must be between 1 and 32768
256 * inclusive, and must be a power of 2 (i.e. 1, 2, 4, 8, 16, ... 16384, 32768).
257 * If it is 1, then the function will be called every tick. if it is 2, then it
258 * will be called every 2nd tick, if it is 8, then every 8th tick etc. Exactly
259 * which tick is undefined, as only the interval between calls can be defined.
260 * Ecore will endeavour to keep pollers synchronised and to call as many in
261 * 1 wakeup event as possible.
262 *
263 * This function adds a poller and returns its handle on success and NULL on
264 * failure. The function @p func will be called at tick intervals described
265 * above. The function will be passed the @p data pointer as its parameter.
266 *
267 * When the poller @p func is called, it must return a value of either
268 * 1 (or ECORE_CALLBACK_RENEW) or 0 (or ECORE_CALLBACK_CANCEL). If it
269 * returns 1, it will be called again at the next tick, or if it returns
270 * 0 it will be deleted automatically making any references/handles for it
271 * invalid.
272 */
273EAPI Ecore_Poller * 206EAPI Ecore_Poller *
274ecore_poller_add(Ecore_Poller_Type type __UNUSED__, 207ecore_poller_add(Ecore_Poller_Type type __UNUSED__,
275 int interval, 208 int interval,
@@ -307,16 +240,6 @@ ecore_poller_add(Ecore_Poller_Type type __UNUSED__,
307 return poller; 240 return poller;
308} 241}
309 242
310/**
311 * Changes the polling interval rate of @p poller.
312 *
313 * @param poller The Ecore_Poller to change the interval of
314 * @param interval The tick interval to set; must be a power of 2 but <= 32768
315 * @return Returns true on success, false on failure
316 *
317 * This allows the changing of a poller's polling interval. It is useful when you want to alter
318 * a poll rate without deleting and re-creating a poller.
319 */
320EAPI Eina_Bool 243EAPI Eina_Bool
321ecore_poller_poller_interval_set(Ecore_Poller *poller, 244ecore_poller_poller_interval_set(Ecore_Poller *poller,
322 int interval) 245 int interval)
@@ -353,14 +276,6 @@ ecore_poller_poller_interval_set(Ecore_Poller *poller,
353 return EINA_TRUE; 276 return EINA_TRUE;
354} 277}
355 278
356/**
357 * Gets the polling interval rate of @p poller.
358 *
359 * @param poller The Ecore_Poller to change the interval of
360 * @return Returns the interval, in ticks, that @p poller polls at
361 *
362 * This returns a poller's polling interval, or 0 on error.
363 */
364EAPI int 279EAPI int
365ecore_poller_poller_interval_get(Ecore_Poller *poller) 280ecore_poller_poller_interval_get(Ecore_Poller *poller)
366{ 281{
@@ -382,15 +297,6 @@ ecore_poller_poller_interval_get(Ecore_Poller *poller)
382 return interval; 297 return interval;
383} 298}
384 299
385/**
386 * Delete the specified poller from the timer list.
387 * @param poller The poller to delete.
388 * @return The data pointer set for the timer when @ref ecore_poller_add was
389 * called. @c NULL is returned if the function is unsuccessful.
390 *
391 * Note: @p poller must be a valid handle. If the poller function has already
392 * returned 0, the handle is no longer valid (and does not need to be delete).
393 */
394EAPI void * 300EAPI void *
395ecore_poller_del(Ecore_Poller *poller) 301ecore_poller_del(Ecore_Poller *poller)
396{ 302{
diff --git a/libraries/ecore/src/lib/ecore/ecore_private.h b/libraries/ecore/src/lib/ecore/ecore_private.h
index 50d502c..f0c5d6b 100644
--- a/libraries/ecore/src/lib/ecore/ecore_private.h
+++ b/libraries/ecore/src/lib/ecore/ecore_private.h
@@ -174,7 +174,7 @@ void *_ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler);
174 174
175void _ecore_main_shutdown(void); 175void _ecore_main_shutdown(void);
176 176
177#if defined (_WIN32) || defined (__lv2ppu__) 177#if defined (_WIN32) || defined (__lv2ppu__) || defined (HAVE_EXOTIC)
178static inline void _ecore_signal_shutdown(void) { } 178static inline void _ecore_signal_shutdown(void) { }
179 179
180static inline void _ecore_signal_init(void) { } 180static inline void _ecore_signal_init(void) { }
@@ -237,14 +237,14 @@ _ecore_lock(void)
237 EINA_MAIN_LOOP_CHECK_RETURN; 237 EINA_MAIN_LOOP_CHECK_RETURN;
238#endif 238#endif
239 _ecore_main_lock_count++; 239 _ecore_main_lock_count++;
240 assert(_ecore_main_lock_count == 1); 240 /* assert(_ecore_main_lock_count == 1); */
241} 241}
242 242
243static inline void 243static inline void
244_ecore_unlock(void) 244_ecore_unlock(void)
245{ 245{
246 _ecore_main_lock_count--; 246 _ecore_main_lock_count--;
247 assert(_ecore_main_lock_count == 0); 247 /* assert(_ecore_main_lock_count == 0); */
248#ifdef HAVE_THREAD_SAFETY 248#ifdef HAVE_THREAD_SAFETY
249 eina_lock_release(&_ecore_main_loop_lock); 249 eina_lock_release(&_ecore_main_loop_lock);
250#endif 250#endif
diff --git a/libraries/ecore/src/lib/ecore/ecore_thread.c b/libraries/ecore/src/lib/ecore/ecore_thread.c
index 4444ad4..85fbe64 100644
--- a/libraries/ecore/src/lib/ecore/ecore_thread.c
+++ b/libraries/ecore/src/lib/ecore/ecore_thread.c
@@ -17,6 +17,25 @@
17 17
18#ifdef EFL_HAVE_THREADS 18#ifdef EFL_HAVE_THREADS
19 19
20# define LK(x) Eina_Lock x
21# define LKI(x) eina_lock_new(&(x))
22# define LKD(x) eina_lock_free(&(x))
23# define LKL(x) eina_lock_take(&(x))
24# define LKU(x) eina_lock_release(&(x))
25
26# define CD(x) Eina_Condition x
27# define CDI(x, m) eina_condition_new(&(x), &(m))
28# define CDD(x) eina_condition_free(&(x))
29# define CDB(x) eina_condition_broadcast(&(x))
30# define CDW(x, t) eina_condition_timedwait(&(x), t)
31
32# define LRWK(x) Eina_RWLock x
33# define LRWKI(x) eina_rwlock_new(&(x));
34# define LRWKD(x) eina_rwlock_free(&(x));
35# define LRWKWL(x) eina_rwlock_take_write(&(x));
36# define LRWKRL(x) eina_rwlock_take_read(&(x));
37# define LRWKU(x) eina_rwlock_release(&(x));
38
20# ifdef EFL_HAVE_POSIX_THREADS 39# ifdef EFL_HAVE_POSIX_THREADS
21# include <pthread.h> 40# include <pthread.h>
22# ifdef __linux__ 41# ifdef __linux__
@@ -31,28 +50,9 @@
31# define PHE(x, y) pthread_equal(x, y) 50# define PHE(x, y) pthread_equal(x, y)
32# define PHS() pthread_self() 51# define PHS() pthread_self()
33# define PHC(x, f, d) pthread_create(&(x), NULL, (void *)f, d) 52# define PHC(x, f, d) pthread_create(&(x), NULL, (void *)f, d)
34# define PHJ(x, p) pthread_join(x, (void **)(&(p))) 53# define PHJ(x) pthread_join(x, NULL)
35# define PHA(x) pthread_cancel(x) 54# define PHA(x) pthread_cancel(x)
36 55
37# define CD(x) pthread_cond_t x
38# define CDI(x) pthread_cond_init(&(x), NULL);
39# define CDD(x) pthread_cond_destroy(&(x));
40# define CDB(x) pthread_cond_broadcast(&(x));
41# define CDW(x, y, t) pthread_cond_timedwait(&(x), &(y), t);
42
43# define LK(x) pthread_mutex_t x
44# define LKI(x) pthread_mutex_init(&(x), NULL);
45# define LKD(x) pthread_mutex_destroy(&(x));
46# define LKL(x) pthread_mutex_lock(&(x));
47# define LKU(x) pthread_mutex_unlock(&(x));
48
49# define LRWK(x) pthread_rwlock_t x
50# define LRWKI(x) pthread_rwlock_init(&(x), NULL);
51# define LRWKD(x) pthread_rwlock_destroy(&(x));
52# define LRWKWL(x) pthread_rwlock_wrlock(&(x));
53# define LRWKRL(x) pthread_rwlock_rdlock(&(x));
54# define LRWKU(x) pthread_rwlock_unlock(&(x));
55
56# else /* EFL_HAVE_WIN32_THREADS */ 56# else /* EFL_HAVE_WIN32_THREADS */
57 57
58# define WIN32_LEAN_AND_MEAN 58# define WIN32_LEAN_AND_MEAN
@@ -108,209 +108,9 @@ _ecore_thread_win32_join(win32_thread *x,
108 return 0; 108 return 0;
109} 109}
110 110
111# define PHJ(x, p) _ecore_thread_win32_join(x, (void **)(&(p))) 111# define PHJ(x) _ecore_thread_win32_join(x, NULL)
112# define PHA(x) TerminateThread(x->thread, 0) 112# define PHA(x) TerminateThread(x->thread, 0)
113 113
114# define LK(x) HANDLE x
115# define LKI(x) x = CreateMutex(NULL, FALSE, NULL)
116# define LKD(x) CloseHandle(x)
117# define LKL(x) WaitForSingleObject(x, INFINITE)
118# define LKU(x) ReleaseMutex(x)
119
120typedef struct
121{
122 HANDLE semaphore;
123 LONG threads_count;
124 CRITICAL_SECTION threads_count_lock;
125} win32_cond;
126
127# define CD(x) win32_cond * x
128
129# define CDI(x) \
130 do { \
131 x = (win32_cond *)calloc(1, sizeof(win32_cond)); \
132 if (x) \
133 { \
134 x->semaphore = CreateSemaphore(NULL, 0, 0x7fffffff, NULL); \
135 if (x->semaphore) \
136 InitializeCriticalSection(&x->threads_count_lock); \
137 else \
138 { \
139 free(x); \
140 x = NULL; \
141 } \
142 } \
143 } while (0)
144
145# define CDD(x) \
146 do { \
147 CloseHandle(x->semaphore); \
148 free(x); \
149 x = NULL; \
150 } while (0)
151
152# define CDB(x) \
153 do { \
154 EnterCriticalSection(&x->threads_count_lock); \
155 if (x->threads_count > 0) \
156 ReleaseSemaphore(x->semaphore, x->threads_count, NULL); \
157 LeaveCriticalSection (&x->threads_count_lock); \
158 } while (0)
159
160int
161_ecore_thread_win32_cond_timedwait(win32_cond *c,
162 HANDLE *external_mutex,
163 struct timeval *t)
164{
165 DWORD res;
166 DWORD val = t->tv_sec * 1000 + (t->tv_usec / 1000);
167 LKL(external_mutex);
168 EnterCriticalSection (&c->threads_count_lock);
169 c->threads_count++;
170 LeaveCriticalSection (&c->threads_count_lock);
171 LKU(external_mutex);
172 res = WaitForSingleObject(c->semaphore, val);
173 if (res == WAIT_OBJECT_0)
174 return 0;
175 else
176 return -1;
177}
178
179# define CDW(x, y, t) _ecore_thread_win32_cond_timedwait(x, y, t)
180
181typedef struct
182{
183 LONG readers_count;
184 LONG writers_count;
185 int readers;
186 int writers;
187 LK(mutex);
188 CD(cond_read);
189 CD(cond_write);
190} win32_rwl;
191
192# define LRWK(x) win32_rwl * x
193# define LRWKI(x) \
194 do { \
195 x = (win32_rwl *)calloc(1, sizeof(win32_rwl)); \
196 if (x) \
197 { \
198 LKI(x->mutex); \
199 if (x->mutex) \
200 { \
201 CDI(x->cond_read); \
202 if (x->cond_read) \
203 { \
204 CDI(x->cond_write); \
205 if (!x->cond_write) \
206 { \
207 CDD(x->cond_read); \
208 LKD(x->mutex); \
209 free(x); \
210 x = NULL; \
211 } \
212 } \
213 else \
214 { \
215 LKD(x->mutex); \
216 free(x); \
217 x = NULL; \
218 } \
219 } \
220 else \
221 { \
222 free(x); \
223 x = NULL; \
224 } \
225 } \
226 } while (0)
227
228# define LRWKD(x) \
229 do { \
230 LKU(x->mutex); \
231 LKD(x->mutex); \
232 CDD(x->cond_write); \
233 CDD(x->cond_read); \
234 free(x); \
235 } while (0)
236# define LRWKWL(x) \
237 do { \
238 DWORD res; \
239 LKU(x->mutex); \
240 if (x->writers || x->readers > 0) \
241 { \
242 x->writers_count++; \
243 while (x->writers || x->readers > 0) \
244 { \
245 EnterCriticalSection(&x->cond_write->threads_count_lock); \
246 x->cond_read->threads_count++; \
247 LeaveCriticalSection(&x->cond_write->threads_count_lock); \
248 res = WaitForSingleObject(x->cond_write->semaphore, INFINITE); \
249 if (res != WAIT_OBJECT_0) break; \
250 } \
251 x->writers_count--; \
252 } \
253 if (res == 0) x->writers_count = 1; \
254 LKU(x->mutex); \
255 } while (0)
256# define LRWKRL(x) \
257 do { \
258 DWORD res; \
259 LKL(x->mutex); \
260 if (x->writers) \
261 { \
262 x->readers_count++; \
263 while (x->writers) \
264 { \
265 EnterCriticalSection(&x->cond_write->threads_count_lock); \
266 x->cond_read->threads_count++; \
267 LeaveCriticalSection(&x->cond_write->threads_count_lock); \
268 res = WaitForSingleObject(x->cond_write->semaphore, INFINITE); \
269 if (res != WAIT_OBJECT_0) break; \
270 } \
271 x->readers_count--; \
272 } \
273 if (res == 0) \
274 x->readers++; \
275 LKU(x->mutex); \
276 } while (0)
277# define LRWKU(x) \
278 do { \
279 LKL(x->mutex); \
280 if (x->writers) \
281 { \
282 x->writers = 0; \
283 if (x->readers_count == 1) \
284 { \
285 EnterCriticalSection(&x->cond_read->threads_count_lock); \
286 if (x->cond_read->threads_count > 0) \
287 ReleaseSemaphore(x->cond_read->semaphore, 1, 0); \
288 LeaveCriticalSection(&x->cond_read->threads_count_lock); \
289 } \
290 else if (x->readers_count > 0) \
291 CDB(x->cond_read); \
292 else if (x->writers_count > 0) \
293 { \
294 EnterCriticalSection (&x->cond_write->threads_count_lock); \
295 if (x->cond_write->threads_count > 0) \
296 ReleaseSemaphore(x->cond_write->semaphore, 1, 0); \
297 LeaveCriticalSection (&x->cond_write->threads_count_lock); \
298 } \
299 } \
300 else if (x->readers > 0) \
301 { \
302 x->readers--; \
303 if (x->readers == 0 && x->writers_count > 0) \
304 { \
305 EnterCriticalSection (&x->cond_write->threads_count_lock); \
306 if (x->cond_write->threads_count > 0) \
307 ReleaseSemaphore(x->cond_write->semaphore, 1, 0); \
308 LeaveCriticalSection (&x->cond_write->threads_count_lock); \
309 } \
310 } \
311 LKU(x->mutex); \
312 } while (0)
313
314# endif 114# endif
315 115
316#endif 116#endif
@@ -336,14 +136,24 @@ struct _Ecore_Pthread_Worker
336 { 136 {
337 Ecore_Thread_Cb func_heavy; 137 Ecore_Thread_Cb func_heavy;
338 Ecore_Thread_Notify_Cb func_notify; 138 Ecore_Thread_Notify_Cb func_notify;
339 Ecore_Pipe *notify;
340 139
341 Ecore_Pipe *direct_pipe;
342 Ecore_Pthread_Worker *direct_worker; 140 Ecore_Pthread_Worker *direct_worker;
343 141
344 int send; 142 int send;
345 int received; 143 int received;
346 } feedback_run; 144 } feedback_run;
145 struct {
146 Ecore_Thread_Cb func_main;
147 Ecore_Thread_Notify_Cb func_notify;
148
149 Ecore_Pipe *send;
150 Ecore_Pthread_Worker *direct_worker;
151
152 struct {
153 int send;
154 int received;
155 } from, to;
156 } message_run;
347 } u; 157 } u;
348 158
349 Ecore_Thread_Cb func_cancel; 159 Ecore_Thread_Cb func_cancel;
@@ -357,47 +167,63 @@ struct _Ecore_Pthread_Worker
357 167
358 const void *data; 168 const void *data;
359 169
360 Eina_Bool cancel : 1; 170 volatile int cancel;
361 Eina_Bool feedback_run : 1; 171
362 Eina_Bool kill : 1; 172#ifdef EFL_HAVE_THREADS
363 Eina_Bool reschedule : 1; 173 LK(cancel_mutex);
364 Eina_Bool no_queue : 1; 174#endif
175
176 Eina_Bool message_run : 1;
177 Eina_Bool feedback_run : 1;
178 Eina_Bool kill : 1;
179 Eina_Bool reschedule : 1;
180 Eina_Bool no_queue : 1;
365}; 181};
366 182
367#ifdef EFL_HAVE_THREADS 183#ifdef EFL_HAVE_THREADS
368typedef struct _Ecore_Pthread_Data Ecore_Pthread_Data; 184typedef struct _Ecore_Pthread_Data Ecore_Pthread_Data;
369
370struct _Ecore_Pthread_Data 185struct _Ecore_Pthread_Data
371{ 186{
372 Ecore_Pthread_Worker *death_job; 187 Ecore_Pthread_Worker *death_job;
373 Ecore_Pipe *p;
374 void *data; 188 void *data;
375 PH(thread); 189 PH(thread);
376}; 190};
191
192typedef struct _Ecore_Pthread_Notify Ecore_Pthread_Notify;
193struct _Ecore_Pthread_Notify
194{
195 Ecore_Pthread_Worker *work;
196 const void *user_data;
197};
198
199typedef void *(*Ecore_Thread_Sync_Cb)(void* data, Ecore_Thread *thread);
200
201typedef struct _Ecore_Pthread_Message Ecore_Pthread_Message;
202struct _Ecore_Pthread_Message
203{
204 union {
205 Ecore_Thread_Cb async;
206 Ecore_Thread_Sync_Cb sync;
207 } u;
208
209 const void *data;
210
211 int code;
212
213 Eina_Bool callback : 1;
214 Eina_Bool sync : 1;
215};
216
377#endif 217#endif
378 218
379static int _ecore_thread_count_max = 0; 219static int _ecore_thread_count_max = 0;
380static int ECORE_THREAD_PIPE_DEL = 0;
381static Eina_Array *_ecore_thread_pipe = NULL;
382 220
383#ifdef EFL_HAVE_THREADS 221#ifdef EFL_HAVE_THREADS
384 222
385static void _ecore_thread_handler(void *data __UNUSED__, 223static void _ecore_thread_handler(void *data);
386 void *buffer,
387 unsigned int nbyte);
388
389static Ecore_Pipe *
390_ecore_thread_pipe_get(void)
391{
392 if (eina_array_count(_ecore_thread_pipe) > 0)
393 return eina_array_pop(_ecore_thread_pipe);
394
395 return ecore_pipe_add(_ecore_thread_handler, NULL);
396}
397 224
398static int _ecore_thread_count = 0; 225static int _ecore_thread_count = 0;
399 226
400static Ecore_Event_Handler *del_handler = NULL;
401static Eina_List *_ecore_active_job_threads = NULL; 227static Eina_List *_ecore_active_job_threads = NULL;
402static Eina_List *_ecore_pending_job_threads = NULL; 228static Eina_List *_ecore_pending_job_threads = NULL;
403static Eina_List *_ecore_pending_job_threads_feedback = NULL; 229static Eina_List *_ecore_pending_job_threads_feedback = NULL;
@@ -435,6 +261,10 @@ static PH(get_main_loop_thread) (void)
435static void 261static void
436_ecore_thread_worker_free(Ecore_Pthread_Worker *worker) 262_ecore_thread_worker_free(Ecore_Pthread_Worker *worker)
437{ 263{
264 LKD(worker->cancel_mutex);
265 CDD(worker->cond);
266 LKD(worker->mutex);
267
438 if (_ecore_thread_worker_count > (_ecore_thread_count_max + 1) * 16) 268 if (_ecore_thread_worker_count > (_ecore_thread_count_max + 1) * 16)
439 { 269 {
440 free(worker); 270 free(worker);
@@ -454,38 +284,15 @@ _ecore_thread_data_free(void *data)
454} 284}
455 285
456static void 286static void
457_ecore_thread_pipe_free(void *data __UNUSED__,
458 void *event)
459{
460 Ecore_Pipe *p = event;
461
462 if (eina_array_count(_ecore_thread_pipe) < 50)
463 eina_array_push(_ecore_thread_pipe, p);
464 else
465 ecore_pipe_del(p);
466 eina_threads_shutdown();
467}
468
469static Eina_Bool
470_ecore_thread_pipe_del(void *data __UNUSED__,
471 int type __UNUSED__,
472 void *event __UNUSED__)
473{
474 /* This is a hack to delay pipe destruction until we are out of its internal loop. */
475 return ECORE_CALLBACK_CANCEL;
476}
477
478static void
479_ecore_thread_end(Ecore_Pthread_Data *pth, 287_ecore_thread_end(Ecore_Pthread_Data *pth,
480 Ecore_Thread *work) 288 Ecore_Thread *work)
481{ 289{
482 Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)work; 290 Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)work;
483 Ecore_Pipe *p;
484 291
485 if (!worker->feedback_run || (worker->feedback_run && !worker->no_queue)) 292 if (!worker->message_run || !worker->feedback_run || (worker->feedback_run && !worker->no_queue))
486 _ecore_thread_count--; 293 _ecore_thread_count--;
487 294
488 if (PHJ(pth->thread, p) != 0) 295 if (PHJ(pth->thread) != 0)
489 return; 296 return;
490 297
491 if (eina_list_count(_ecore_pending_job_threads) > 0 298 if (eina_list_count(_ecore_pending_job_threads) > 0
@@ -496,7 +303,7 @@ _ecore_thread_end(Ecore_Pthread_Data *pth,
496 INF("spawning threads because of still pending jobs."); 303 INF("spawning threads because of still pending jobs.");
497 304
498 pth->death_job = _ecore_thread_worker_new(); 305 pth->death_job = _ecore_thread_worker_new();
499 if (!pth->p || !pth->death_job) goto end; 306 if (!pth->death_job) goto end;
500 307
501 eina_threads_init(); 308 eina_threads_init();
502 309
@@ -514,7 +321,6 @@ end:
514 321
515 _ecore_active_job_threads = eina_list_remove(_ecore_active_job_threads, pth); 322 _ecore_active_job_threads = eina_list_remove(_ecore_active_job_threads, pth);
516 323
517 ecore_event_add(ECORE_THREAD_PIPE_DEL, pth->p, _ecore_thread_pipe_free, NULL);
518 free(pth); 324 free(pth);
519} 325}
520 326
@@ -534,30 +340,18 @@ _ecore_thread_kill(Ecore_Pthread_Worker *work)
534 340
535 if (work->feedback_run) 341 if (work->feedback_run)
536 { 342 {
537 ecore_pipe_del(work->u.feedback_run.notify);
538
539 if (work->u.feedback_run.direct_pipe)
540 eina_array_push(_ecore_thread_pipe, work->u.feedback_run.direct_pipe);
541 if (work->u.feedback_run.direct_worker) 343 if (work->u.feedback_run.direct_worker)
542 _ecore_thread_worker_free(work->u.feedback_run.direct_worker); 344 _ecore_thread_worker_free(work->u.feedback_run.direct_worker);
543 } 345 }
544 CDD(work->cond);
545 LKD(work->mutex);
546 if (work->hash) 346 if (work->hash)
547 eina_hash_free(work->hash); 347 eina_hash_free(work->hash);
548 _ecore_thread_worker_free(work); 348 _ecore_thread_worker_free(work);
549} 349}
550 350
551static void 351static void
552_ecore_thread_handler(void *data __UNUSED__, 352_ecore_thread_handler(void *data)
553 void *buffer,
554 unsigned int nbyte)
555{ 353{
556 Ecore_Pthread_Worker *work; 354 Ecore_Pthread_Worker *work = data;
557
558 if (nbyte != sizeof (Ecore_Pthread_Worker *)) return;
559
560 work = *(Ecore_Pthread_Worker **)buffer;
561 355
562 if (work->feedback_run) 356 if (work->feedback_run)
563 { 357 {
@@ -571,17 +365,20 @@ _ecore_thread_handler(void *data __UNUSED__,
571 _ecore_thread_kill(work); 365 _ecore_thread_kill(work);
572} 366}
573 367
368#if 0
574static void 369static void
575_ecore_notify_handler(void *data, 370_ecore_nothing_handler(void *data __UNUSED__, void *buffer __UNUSED__, unsigned int nbyte __UNUSED__)
576 void *buffer,
577 unsigned int nbyte)
578{ 371{
579 Ecore_Pthread_Worker *work = data; 372}
580 void *user_data; 373#endif
581 374
582 if (nbyte != sizeof (Ecore_Pthread_Worker *)) return; 375static void
376_ecore_notify_handler(void *data)
377{
378 Ecore_Pthread_Notify *notify = data;
379 Ecore_Pthread_Worker *work = notify->work;
380 void *user_data = (void*) notify->user_data;
583 381
584 user_data = *(void **)buffer;
585 work->u.feedback_run.received++; 382 work->u.feedback_run.received++;
586 383
587 if (work->u.feedback_run.func_notify) 384 if (work->u.feedback_run.func_notify)
@@ -592,16 +389,64 @@ _ecore_notify_handler(void *data,
592 { 389 {
593 _ecore_thread_kill(work); 390 _ecore_thread_kill(work);
594 } 391 }
392
393 free(notify);
394}
395
396static void
397_ecore_message_notify_handler(void *data)
398{
399 Ecore_Pthread_Notify *notify = data;
400 Ecore_Pthread_Worker *work = notify->work;
401 Ecore_Pthread_Message *user_data = (void *) notify->user_data;
402 Eina_Bool delete = EINA_TRUE;
403
404 work->u.message_run.from.received++;
405
406 if (!user_data->callback)
407 {
408 if (work->u.message_run.func_notify)
409 work->u.message_run.func_notify((void *) work->data, (Ecore_Thread *) work, (void *) user_data->data);
410 }
411 else
412 {
413 if (user_data->sync)
414 {
415 user_data->data = user_data->u.sync((void*) user_data->data, (Ecore_Thread *) work);
416 user_data->callback = EINA_FALSE;
417 user_data->code = INT_MAX;
418 ecore_pipe_write(work->u.message_run.send, &user_data, sizeof (Ecore_Pthread_Message *));
419
420 delete = EINA_FALSE;
421 }
422 else
423 {
424 user_data->u.async((void*) user_data->data, (Ecore_Thread *) work);
425 }
426 }
427
428 if (delete)
429 {
430 free(user_data);
431 }
432
433 /* Force reading all notify event before killing the thread */
434 if (work->kill && work->u.message_run.from.send == work->u.message_run.from.received)
435 {
436 _ecore_thread_kill(work);
437 }
438 free(notify);
595} 439}
596 440
597static void 441static void
598_ecore_short_job(Ecore_Pipe *end_pipe, 442_ecore_short_job(PH(thread))
599 PH(thread))
600{ 443{
601 Ecore_Pthread_Worker *work; 444 Ecore_Pthread_Worker *work;
602 445
603 while (_ecore_pending_job_threads) 446 while (_ecore_pending_job_threads)
604 { 447 {
448 int cancel;
449
605 LKL(_ecore_pending_job_threads_mutex); 450 LKL(_ecore_pending_job_threads_mutex);
606 451
607 if (!_ecore_pending_job_threads) 452 if (!_ecore_pending_job_threads)
@@ -616,9 +461,12 @@ _ecore_short_job(Ecore_Pipe *end_pipe,
616 461
617 LKU(_ecore_pending_job_threads_mutex); 462 LKU(_ecore_pending_job_threads_mutex);
618 463
464 LKL(work->cancel_mutex);
465 cancel = work->cancel;
466 LKU(work->cancel_mutex);
619 work->self = thread; 467 work->self = thread;
620 if (!work->cancel) 468 if (!cancel)
621 work->u.short_run.func_blocking((void *)work->data, (Ecore_Thread *)work); 469 work->u.short_run.func_blocking((void *) work->data, (Ecore_Thread*) work);
622 470
623 if (work->reschedule) 471 if (work->reschedule)
624 { 472 {
@@ -630,19 +478,20 @@ _ecore_short_job(Ecore_Pipe *end_pipe,
630 } 478 }
631 else 479 else
632 { 480 {
633 ecore_pipe_write(end_pipe, &work, sizeof (Ecore_Pthread_Worker *)); 481 ecore_main_loop_thread_safe_call_async(_ecore_thread_handler, work);
634 } 482 }
635 } 483 }
636} 484}
637 485
638static void 486static void
639_ecore_feedback_job(Ecore_Pipe *end_pipe, 487_ecore_feedback_job(PH(thread))
640 PH(thread))
641{ 488{
642 Ecore_Pthread_Worker *work; 489 Ecore_Pthread_Worker *work;
643 490
644 while (_ecore_pending_job_threads_feedback) 491 while (_ecore_pending_job_threads_feedback)
645 { 492 {
493 int cancel;
494
646 LKL(_ecore_pending_job_threads_mutex); 495 LKL(_ecore_pending_job_threads_mutex);
647 496
648 if (!_ecore_pending_job_threads_feedback) 497 if (!_ecore_pending_job_threads_feedback)
@@ -657,9 +506,12 @@ _ecore_feedback_job(Ecore_Pipe *end_pipe,
657 506
658 LKU(_ecore_pending_job_threads_mutex); 507 LKU(_ecore_pending_job_threads_mutex);
659 508
509 LKL(work->cancel_mutex);
510 cancel = work->cancel;
511 LKU(work->cancel_mutex);
660 work->self = thread; 512 work->self = thread;
661 if (!work->cancel) 513 if (!cancel)
662 work->u.feedback_run.func_heavy((void *)work->data, (Ecore_Thread *)work); 514 work->u.feedback_run.func_heavy((void *) work->data, (Ecore_Thread *) work);
663 515
664 if (work->reschedule) 516 if (work->reschedule)
665 { 517 {
@@ -671,7 +523,7 @@ _ecore_feedback_job(Ecore_Pipe *end_pipe,
671 } 523 }
672 else 524 else
673 { 525 {
674 ecore_pipe_write(end_pipe, &work, sizeof (Ecore_Pthread_Worker *)); 526 ecore_main_loop_thread_safe_call_async(_ecore_thread_handler, work);
675 } 527 }
676 } 528 }
677} 529}
@@ -679,6 +531,7 @@ _ecore_feedback_job(Ecore_Pipe *end_pipe,
679static void * 531static void *
680_ecore_direct_worker(Ecore_Pthread_Worker *work) 532_ecore_direct_worker(Ecore_Pthread_Worker *work)
681{ 533{
534 Ecore_Pthread_Worker *end;
682 Ecore_Pthread_Data *pth; 535 Ecore_Pthread_Data *pth;
683 536
684#ifdef EFL_POSIX_THREADS 537#ifdef EFL_POSIX_THREADS
@@ -691,40 +544,49 @@ _ecore_direct_worker(Ecore_Pthread_Worker *work)
691 pth = malloc(sizeof (Ecore_Pthread_Data)); 544 pth = malloc(sizeof (Ecore_Pthread_Data));
692 if (!pth) return NULL; 545 if (!pth) return NULL;
693 546
694 pth->p = work->u.feedback_run.direct_pipe;
695 if (!pth->p)
696 {
697 free(pth);
698 return NULL;
699 }
700 pth->thread = PHS(); 547 pth->thread = PHS();
701 548
702 work->self = pth->thread; 549 work->self = pth->thread;
703 work->u.feedback_run.func_heavy((void *)work->data, (Ecore_Thread *)work); 550 if (work->message_run)
551 work->u.message_run.func_main((void *) work->data, (Ecore_Thread *) work);
552 else
553 work->u.feedback_run.func_heavy((void *) work->data, (Ecore_Thread *) work);
704 554
705 ecore_pipe_write(pth->p, &work, sizeof (Ecore_Pthread_Worker *)); 555 if (work->message_run)
556 {
557 end = work->u.message_run.direct_worker;
558 work->u.message_run.direct_worker = NULL;
559 }
560 else
561 {
562 end = work->u.feedback_run.direct_worker;
563 work->u.feedback_run.direct_worker = NULL;
564 }
706 565
707 work = work->u.feedback_run.direct_worker; 566 ecore_main_loop_thread_safe_call_async(_ecore_thread_handler, work);
708 if (!work) 567
568 if (!end)
709 { 569 {
710 free(pth); 570 free(pth);
711 return NULL; 571 return NULL;
712 } 572 }
713 573
714 work->data = pth; 574 end->data = pth;
715 work->u.short_run.func_blocking = NULL; 575 end->u.short_run.func_blocking = NULL;
716 work->func_end = (void *)_ecore_thread_end; 576 end->func_end = (void *)_ecore_thread_end;
717 work->func_cancel = NULL; 577 end->func_cancel = NULL;
718 work->cancel = EINA_FALSE; 578 end->cancel = EINA_FALSE;
719 work->feedback_run = EINA_FALSE; 579 end->feedback_run = EINA_FALSE;
720 work->kill = EINA_FALSE; 580 end->message_run = EINA_FALSE;
721 work->hash = NULL; 581 end->no_queue = EINA_FALSE;
722 CDI(work->cond); 582 end->kill = EINA_FALSE;
723 LKI(work->mutex); 583 end->hash = NULL;
724 584 LKI(end->mutex);
725 ecore_pipe_write(pth->p, &work, sizeof (Ecore_Pthread_Worker *)); 585 CDI(end->cond, end->mutex);
586
587 ecore_main_loop_thread_safe_call_async(_ecore_thread_handler, end);
726 588
727 return pth->p; 589 return NULL;
728} 590}
729 591
730static void * 592static void *
@@ -740,8 +602,8 @@ _ecore_thread_worker(Ecore_Pthread_Data *pth)
740 eina_sched_prio_drop(); 602 eina_sched_prio_drop();
741 603
742restart: 604restart:
743 if (_ecore_pending_job_threads) _ecore_short_job(pth->p, pth->thread); 605 if (_ecore_pending_job_threads) _ecore_short_job(pth->thread);
744 if (_ecore_pending_job_threads_feedback) _ecore_feedback_job(pth->p, pth->thread); 606 if (_ecore_pending_job_threads_feedback) _ecore_feedback_job(pth->thread);
745 607
746 /* FIXME: Check if there is feedback running task todo, and switch to feedback run handler. */ 608 /* FIXME: Check if there is feedback running task todo, and switch to feedback run handler. */
747 609
@@ -777,14 +639,14 @@ restart:
777 work->func_cancel = NULL; 639 work->func_cancel = NULL;
778 work->cancel = EINA_FALSE; 640 work->cancel = EINA_FALSE;
779 work->feedback_run = EINA_FALSE; 641 work->feedback_run = EINA_FALSE;
642 work->message_run = EINA_FALSE;
780 work->kill = EINA_FALSE; 643 work->kill = EINA_FALSE;
644 work->no_queue = EINA_FALSE;
781 work->hash = NULL; 645 work->hash = NULL;
782 CDI(work->cond);
783 LKI(work->mutex);
784 646
785 ecore_pipe_write(pth->p, &work, sizeof (Ecore_Pthread_Worker *)); 647 ecore_main_loop_thread_safe_call_async(_ecore_thread_handler, work);
786 648
787 return pth->p; 649 return NULL;
788} 650}
789 651
790#endif 652#endif
@@ -800,6 +662,10 @@ _ecore_thread_worker_new(void)
800 if (!result) result = malloc(sizeof (Ecore_Pthread_Worker)); 662 if (!result) result = malloc(sizeof (Ecore_Pthread_Worker));
801 else _ecore_thread_worker_count--; 663 else _ecore_thread_worker_count--;
802 664
665 LKI(result->cancel_mutex);
666 LKI(result->mutex);
667 CDI(result->cond, result->mutex);
668
803 return result; 669 return result;
804#else 670#else
805 return malloc(sizeof (Ecore_Pthread_Worker)); 671 return malloc(sizeof (Ecore_Pthread_Worker));
@@ -813,16 +679,11 @@ _ecore_thread_init(void)
813 if (_ecore_thread_count_max <= 0) 679 if (_ecore_thread_count_max <= 0)
814 _ecore_thread_count_max = 1; 680 _ecore_thread_count_max = 1;
815 681
816 ECORE_THREAD_PIPE_DEL = ecore_event_type_new();
817 _ecore_thread_pipe = eina_array_new(8);
818
819#ifdef EFL_HAVE_THREADS 682#ifdef EFL_HAVE_THREADS
820 del_handler = ecore_event_handler_add(ECORE_THREAD_PIPE_DEL, _ecore_thread_pipe_del, NULL);
821
822 LKI(_ecore_pending_job_threads_mutex); 683 LKI(_ecore_pending_job_threads_mutex);
823 LRWKI(_ecore_thread_global_hash_lock); 684 LRWKI(_ecore_thread_global_hash_lock);
824 LKI(_ecore_thread_global_hash_mutex); 685 LKI(_ecore_thread_global_hash_mutex);
825 CDI(_ecore_thread_global_hash_cond); 686 CDI(_ecore_thread_global_hash_cond, _ecore_thread_global_hash_mutex);
826#endif 687#endif
827} 688}
828 689
@@ -830,10 +691,6 @@ void
830_ecore_thread_shutdown(void) 691_ecore_thread_shutdown(void)
831{ 692{
832 /* FIXME: If function are still running in the background, should we kill them ? */ 693 /* FIXME: If function are still running in the background, should we kill them ? */
833 Ecore_Pipe *p;
834 Eina_Array_Iterator it;
835 unsigned int i;
836
837#ifdef EFL_HAVE_THREADS 694#ifdef EFL_HAVE_THREADS
838 Ecore_Pthread_Worker *work; 695 Ecore_Pthread_Worker *work;
839 Ecore_Pthread_Data *pth; 696 Ecore_Pthread_Data *pth;
@@ -843,46 +700,39 @@ _ecore_thread_shutdown(void)
843 EINA_LIST_FREE(_ecore_pending_job_threads, work) 700 EINA_LIST_FREE(_ecore_pending_job_threads, work)
844 { 701 {
845 if (work->func_cancel) 702 if (work->func_cancel)
846 work->func_cancel((void *)work->data, (Ecore_Thread *)work); 703 work->func_cancel((void *)work->data, (Ecore_Thread *) work);
847 free(work); 704 free(work);
848 } 705 }
849 706
850 EINA_LIST_FREE(_ecore_pending_job_threads_feedback, work) 707 EINA_LIST_FREE(_ecore_pending_job_threads_feedback, work)
851 { 708 {
852 if (work->func_cancel) 709 if (work->func_cancel)
853 work->func_cancel((void *)work->data, (Ecore_Thread *)work); 710 work->func_cancel((void *)work->data, (Ecore_Thread *) work);
854 free(work); 711 free(work);
855 } 712 }
856 713
857 LKU(_ecore_pending_job_threads_mutex); 714 LKU(_ecore_pending_job_threads_mutex);
858 715
859 /* Improve emergency shutdown */ 716 /* FIXME: Improve emergency shutdown, now that we use async call, we can do something */
860 EINA_LIST_FREE(_ecore_active_job_threads, pth) 717 EINA_LIST_FREE(_ecore_active_job_threads, pth)
861 { 718 {
862 Ecore_Pipe *ep;
863
864 PHA(pth->thread); 719 PHA(pth->thread);
865 PHJ(pth->thread, ep); 720 PHJ(pth->thread);
866
867 ecore_pipe_del(pth->p);
868 } 721 }
869 if (_ecore_thread_global_hash) 722 if (_ecore_thread_global_hash)
870 eina_hash_free(_ecore_thread_global_hash); 723 eina_hash_free(_ecore_thread_global_hash);
871 _ecore_event_handler_del(del_handler);
872 have_main_loop_thread = 0; 724 have_main_loop_thread = 0;
873 del_handler = NULL; 725
726 while ((work = eina_trash_pop(&_ecore_thread_worker_trash)))
727 {
728 free(work);
729 }
874 730
875 LKD(_ecore_pending_job_threads_mutex); 731 LKD(_ecore_pending_job_threads_mutex);
876 LRWKD(_ecore_thread_global_hash_lock); 732 LRWKD(_ecore_thread_global_hash_lock);
877 LKD(_ecore_thread_global_hash_mutex); 733 LKD(_ecore_thread_global_hash_mutex);
878 CDD(_ecore_thread_global_hash_cond); 734 CDD(_ecore_thread_global_hash_cond);
879#endif 735#endif
880
881 EINA_ARRAY_ITER_NEXT(_ecore_thread_pipe, i, p, it)
882 ecore_pipe_del(p);
883
884 eina_array_free(_ecore_thread_pipe);
885 _ecore_thread_pipe = NULL;
886} 736}
887 737
888void 738void
@@ -927,15 +777,15 @@ ecore_thread_run(Ecore_Thread_Cb func_blocking,
927 work->func_cancel = func_cancel; 777 work->func_cancel = func_cancel;
928 work->cancel = EINA_FALSE; 778 work->cancel = EINA_FALSE;
929 work->feedback_run = EINA_FALSE; 779 work->feedback_run = EINA_FALSE;
780 work->message_run = EINA_FALSE;
930 work->kill = EINA_FALSE; 781 work->kill = EINA_FALSE;
931 work->reschedule = EINA_FALSE; 782 work->reschedule = EINA_FALSE;
783 work->no_queue = EINA_FALSE;
932 work->data = data; 784 work->data = data;
933 785
934#ifdef EFL_HAVE_THREADS 786#ifdef EFL_HAVE_THREADS
935 work->self = 0; 787 work->self = 0;
936 work->hash = NULL; 788 work->hash = NULL;
937 CDI(work->cond);
938 LKI(work->mutex);
939 789
940 LKL(_ecore_pending_job_threads_mutex); 790 LKL(_ecore_pending_job_threads_mutex);
941 _ecore_pending_job_threads = eina_list_append(_ecore_pending_job_threads, work); 791 _ecore_pending_job_threads = eina_list_append(_ecore_pending_job_threads, work);
@@ -952,9 +802,8 @@ ecore_thread_run(Ecore_Thread_Cb func_blocking,
952 pth = malloc(sizeof (Ecore_Pthread_Data)); 802 pth = malloc(sizeof (Ecore_Pthread_Data));
953 if (!pth) goto on_error; 803 if (!pth) goto on_error;
954 804
955 pth->p = _ecore_thread_pipe_get();
956 pth->death_job = _ecore_thread_worker_new(); 805 pth->death_job = _ecore_thread_worker_new();
957 if (!pth->p || !pth->death_job) goto on_error; 806 if (!pth->death_job) goto on_error;
958 807
959 eina_threads_init(); 808 eina_threads_init();
960 809
@@ -969,7 +818,6 @@ ecore_thread_run(Ecore_Thread_Cb func_blocking,
969on_error: 818on_error:
970 if (pth) 819 if (pth)
971 { 820 {
972 if (pth->p) eina_array_push(_ecore_thread_pipe, pth->p);
973 if (pth->death_job) _ecore_thread_worker_free(pth->death_job); 821 if (pth->death_job) _ecore_thread_worker_free(pth->death_job);
974 free(pth); 822 free(pth);
975 } 823 }
@@ -981,7 +829,11 @@ on_error:
981 LKU(_ecore_pending_job_threads_mutex); 829 LKU(_ecore_pending_job_threads_mutex);
982 830
983 if (work->func_cancel) 831 if (work->func_cancel)
984 work->func_cancel((void *)work->data, (Ecore_Thread *)work); 832 work->func_cancel((void *) work->data, (Ecore_Thread *) work);
833
834 CDD(work->cond);
835 LKD(work->mutex);
836 LKD(work->cancel_mutex);
985 free(work); 837 free(work);
986 work = NULL; 838 work = NULL;
987 } 839 }
@@ -1013,12 +865,16 @@ EAPI Eina_Bool
1013ecore_thread_cancel(Ecore_Thread *thread) 865ecore_thread_cancel(Ecore_Thread *thread)
1014{ 866{
1015#ifdef EFL_HAVE_THREADS 867#ifdef EFL_HAVE_THREADS
1016 Ecore_Pthread_Worker *work = (Ecore_Pthread_Worker *)thread; 868 Ecore_Pthread_Worker *volatile work = (Ecore_Pthread_Worker *)thread;
1017 Eina_List *l; 869 Eina_List *l;
870 int cancel;
1018 871
1019 if (!work) 872 if (!work)
1020 return EINA_TRUE; 873 return EINA_TRUE;
1021 if (work->cancel) 874 LKL(work->cancel_mutex);
875 cancel = work->cancel;
876 LKU(work->cancel_mutex);
877 if (cancel)
1022 return EINA_FALSE; 878 return EINA_FALSE;
1023 879
1024 if (work->feedback_run) 880 if (work->feedback_run)
@@ -1070,9 +926,14 @@ ecore_thread_cancel(Ecore_Thread *thread)
1070 926
1071 LKU(_ecore_pending_job_threads_mutex); 927 LKU(_ecore_pending_job_threads_mutex);
1072 928
929 work = (Ecore_Pthread_Worker *)thread;
930
1073 /* Delay the destruction */ 931 /* Delay the destruction */
1074on_exit: 932 on_exit:
1075 ((Ecore_Pthread_Worker *)thread)->cancel = EINA_TRUE; 933 LKL(work->cancel_mutex);
934 work->cancel = EINA_TRUE;
935 LKU(work->cancel_mutex);
936
1076 return EINA_FALSE; 937 return EINA_FALSE;
1077#else 938#else
1078 (void) thread; 939 (void) thread;
@@ -1083,10 +944,23 @@ on_exit:
1083EAPI Eina_Bool 944EAPI Eina_Bool
1084ecore_thread_check(Ecore_Thread *thread) 945ecore_thread_check(Ecore_Thread *thread)
1085{ 946{
1086 Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)thread; 947 Ecore_Pthread_Worker *volatile worker = (Ecore_Pthread_Worker *) thread;
948 int cancel;
1087 949
1088 if (!worker) return EINA_TRUE; 950 if (!worker) return EINA_TRUE;
1089 return worker->cancel; 951#ifdef EFL_HAVE_THREADS
952 LKL(worker->cancel_mutex);
953#endif
954 cancel = worker->cancel;
955 /* FIXME: there is an insane bug driving me nuts here. I don't know if
956 it's a race condition, some cache issue or some alien attack on our software.
957 But ecore_thread_check will only work correctly with a printf, all the volatile,
958 lock and even usleep don't help here... */
959 /* fprintf(stderr, "wc: %i\n", cancel); */
960#ifdef EFL_HAVE_THREADS
961 LKU(worker->cancel_mutex);
962#endif
963 return cancel;
1090} 964}
1091 965
1092EAPI Ecore_Thread * 966EAPI Ecore_Thread *
@@ -1109,12 +983,11 @@ ecore_thread_feedback_run(Ecore_Thread_Cb func_heavy,
1109 worker->u.feedback_run.func_heavy = func_heavy; 983 worker->u.feedback_run.func_heavy = func_heavy;
1110 worker->u.feedback_run.func_notify = func_notify; 984 worker->u.feedback_run.func_notify = func_notify;
1111 worker->hash = NULL; 985 worker->hash = NULL;
1112 CDI(worker->cond);
1113 LKI(worker->mutex);
1114 worker->func_cancel = func_cancel; 986 worker->func_cancel = func_cancel;
1115 worker->func_end = func_end; 987 worker->func_end = func_end;
1116 worker->data = data; 988 worker->data = data;
1117 worker->cancel = EINA_FALSE; 989 worker->cancel = EINA_FALSE;
990 worker->message_run = EINA_FALSE;
1118 worker->feedback_run = EINA_TRUE; 991 worker->feedback_run = EINA_TRUE;
1119 worker->kill = EINA_FALSE; 992 worker->kill = EINA_FALSE;
1120 worker->reschedule = EINA_FALSE; 993 worker->reschedule = EINA_FALSE;
@@ -1123,15 +996,12 @@ ecore_thread_feedback_run(Ecore_Thread_Cb func_heavy,
1123 worker->u.feedback_run.send = 0; 996 worker->u.feedback_run.send = 0;
1124 worker->u.feedback_run.received = 0; 997 worker->u.feedback_run.received = 0;
1125 998
1126 worker->u.feedback_run.notify = ecore_pipe_add(_ecore_notify_handler, worker);
1127 worker->u.feedback_run.direct_pipe = NULL;
1128 worker->u.feedback_run.direct_worker = NULL; 999 worker->u.feedback_run.direct_worker = NULL;
1129 1000
1130 if (!try_no_queue) 1001 if (try_no_queue)
1131 { 1002 {
1132 PH(t); 1003 PH(t);
1133 1004
1134 worker->u.feedback_run.direct_pipe = _ecore_thread_pipe_get();
1135 worker->u.feedback_run.direct_worker = _ecore_thread_worker_new(); 1005 worker->u.feedback_run.direct_worker = _ecore_thread_worker_new();
1136 worker->no_queue = EINA_TRUE; 1006 worker->no_queue = EINA_TRUE;
1137 1007
@@ -1140,6 +1010,12 @@ ecore_thread_feedback_run(Ecore_Thread_Cb func_heavy,
1140 if (PHC(t, _ecore_direct_worker, worker) == 0) 1010 if (PHC(t, _ecore_direct_worker, worker) == 0)
1141 return (Ecore_Thread *)worker; 1011 return (Ecore_Thread *)worker;
1142 1012
1013 if (worker->u.feedback_run.direct_worker)
1014 {
1015 _ecore_thread_worker_free(worker->u.feedback_run.direct_worker);
1016 worker->u.feedback_run.direct_worker = NULL;
1017 }
1018
1143 eina_threads_shutdown(); 1019 eina_threads_shutdown();
1144 } 1020 }
1145 1021
@@ -1160,9 +1036,8 @@ ecore_thread_feedback_run(Ecore_Thread_Cb func_heavy,
1160 pth = malloc(sizeof (Ecore_Pthread_Data)); 1036 pth = malloc(sizeof (Ecore_Pthread_Data));
1161 if (!pth) goto on_error; 1037 if (!pth) goto on_error;
1162 1038
1163 pth->p = _ecore_thread_pipe_get();
1164 pth->death_job = _ecore_thread_worker_new(); 1039 pth->death_job = _ecore_thread_worker_new();
1165 if (!pth->p || !pth->death_job) goto on_error; 1040 if (!pth->death_job) goto on_error;
1166 1041
1167 eina_threads_init(); 1042 eina_threads_init();
1168 1043
@@ -1177,7 +1052,6 @@ ecore_thread_feedback_run(Ecore_Thread_Cb func_heavy,
1177on_error: 1052on_error:
1178 if (pth) 1053 if (pth)
1179 { 1054 {
1180 if (pth->p) eina_array_push(_ecore_thread_pipe, pth->p);
1181 if (pth->death_job) _ecore_thread_worker_free(pth->death_job); 1055 if (pth->death_job) _ecore_thread_worker_free(pth->death_job);
1182 free(pth); 1056 free(pth);
1183 } 1057 }
@@ -1193,7 +1067,8 @@ on_error:
1193 1067
1194 if (worker) 1068 if (worker)
1195 { 1069 {
1196 ecore_pipe_del(worker->u.feedback_run.notify); 1070 CDD(worker->cond);
1071 LKD(worker->mutex);
1197 free(worker); 1072 free(worker);
1198 worker = NULL; 1073 worker = NULL;
1199 } 1074 }
@@ -1211,7 +1086,6 @@ on_error:
1211 */ 1086 */
1212 worker.u.feedback_run.func_heavy = func_heavy; 1087 worker.u.feedback_run.func_heavy = func_heavy;
1213 worker.u.feedback_run.func_notify = func_notify; 1088 worker.u.feedback_run.func_notify = func_notify;
1214 worker.u.feedback_run.notify = NULL;
1215 worker.u.feedback_run.send = 0; 1089 worker.u.feedback_run.send = 0;
1216 worker.u.feedback_run.received = 0; 1090 worker.u.feedback_run.received = 0;
1217 worker.func_cancel = func_cancel; 1091 worker.func_cancel = func_cancel;
@@ -1219,6 +1093,7 @@ on_error:
1219 worker.data = data; 1093 worker.data = data;
1220 worker.cancel = EINA_FALSE; 1094 worker.cancel = EINA_FALSE;
1221 worker.feedback_run = EINA_TRUE; 1095 worker.feedback_run = EINA_TRUE;
1096 worker.message_run = EINA_FALSE;
1222 worker.kill = EINA_FALSE; 1097 worker.kill = EINA_FALSE;
1223 1098
1224 do { 1099 do {
@@ -1241,13 +1116,48 @@ ecore_thread_feedback(Ecore_Thread *thread,
1241 Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)thread; 1116 Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)thread;
1242 1117
1243 if (!worker) return EINA_FALSE; 1118 if (!worker) return EINA_FALSE;
1244 if (!worker->feedback_run) return EINA_FALSE;
1245 1119
1246#ifdef EFL_HAVE_THREADS 1120#ifdef EFL_HAVE_THREADS
1247 if (!PHE(worker->self, PHS())) return EINA_FALSE; 1121 if (!PHE(worker->self, PHS())) return EINA_FALSE;
1248 1122
1249 worker->u.feedback_run.send++; 1123 if (worker->feedback_run)
1250 ecore_pipe_write(worker->u.feedback_run.notify, &data, sizeof (void *)); 1124 {
1125 Ecore_Pthread_Notify *notify;
1126
1127 notify = malloc(sizeof (Ecore_Pthread_Notify));
1128 if (!notify) return EINA_FALSE;
1129
1130 notify->user_data = data;
1131 notify->work = worker;
1132 worker->u.feedback_run.send++;
1133
1134 ecore_main_loop_thread_safe_call_async(_ecore_notify_handler, notify);
1135 }
1136 else if (worker->message_run)
1137 {
1138 Ecore_Pthread_Message *msg;
1139 Ecore_Pthread_Notify *notify;
1140
1141 msg = malloc(sizeof (Ecore_Pthread_Message*));
1142 if (!msg) return EINA_FALSE;
1143 msg->data = data;
1144 msg->callback = EINA_FALSE;
1145 msg->sync = EINA_FALSE;
1146
1147 notify = malloc(sizeof (Ecore_Pthread_Notify));
1148 if (!notify)
1149 {
1150 free(msg);
1151 return EINA_FALSE;
1152 }
1153 notify->work = worker;
1154 notify->user_data = msg;
1155
1156 worker->u.message_run.from.send++;
1157 ecore_main_loop_thread_safe_call_async(_ecore_message_notify_handler, notify);
1158 }
1159 else
1160 return EINA_FALSE;
1251 1161
1252 return EINA_TRUE; 1162 return EINA_TRUE;
1253#else 1163#else
@@ -1257,6 +1167,71 @@ ecore_thread_feedback(Ecore_Thread *thread,
1257#endif 1167#endif
1258} 1168}
1259 1169
1170#if 0
1171EAPI Ecore_Thread *
1172ecore_thread_message_run(Ecore_Thread_Cb func_main,
1173 Ecore_Thread_Notify_Cb func_notify,
1174 Ecore_Thread_Cb func_end,
1175 Ecore_Thread_Cb func_cancel,
1176 const void *data)
1177{
1178#ifdef EFL_HAVE_THREADS
1179 Ecore_Pthread_Worker *worker;
1180 PH(t);
1181
1182 if (!func_main) return NULL;
1183
1184 worker = _ecore_thread_worker_new();
1185 if (!worker) return NULL;
1186
1187 worker->u.message_run.func_main = func_main;
1188 worker->u.message_run.func_notify = func_notify;
1189 worker->u.message_run.direct_worker = _ecore_thread_worker_new();
1190 worker->u.message_run.send = ecore_pipe_add(_ecore_nothing_handler, worker);
1191 worker->u.message_run.from.send = 0;
1192 worker->u.message_run.from.received = 0;
1193 worker->u.message_run.to.send = 0;
1194 worker->u.message_run.to.received = 0;
1195
1196 ecore_pipe_freeze(worker->u.message_run.send);
1197
1198 worker->func_cancel = func_cancel;
1199 worker->func_end = func_end;
1200 worker->hash = NULL;
1201 worker->data = data;
1202
1203 worker->cancel = EINA_FALSE;
1204 worker->message_run = EINA_TRUE;
1205 worker->feedback_run = EINA_FALSE;
1206 worker->kill = EINA_FALSE;
1207 worker->reschedule = EINA_FALSE;
1208 worker->no_queue = EINA_FALSE;
1209 worker->self = 0;
1210
1211 eina_threads_init();
1212
1213 if (PHC(t, _ecore_direct_worker, worker) == 0)
1214 return (Ecore_Thread*) worker;
1215
1216 eina_threads_shutdown();
1217
1218 if (worker->u.message_run.direct_worker) _ecore_thread_worker_free(worker->u.message_run.direct_worker);
1219 if (worker->u.message_run.send) ecore_pipe_del(worker->u.message_run.send);
1220
1221 CDD(worker->cond);
1222 LKD(worker->mutex);
1223#else
1224 /* Note: This type of thread can't and never will work without thread support */
1225 WRN("ecore_thread_message_run called, but threads disable in Ecore, things will go wrong. Starting now !");
1226# warning "You disabled threads support in ecore, I hope you know what you are doing !"
1227#endif
1228
1229 func_cancel((void *) data, NULL);
1230
1231 return NULL;
1232}
1233#endif
1234
1260EAPI Eina_Bool 1235EAPI Eina_Bool
1261ecore_thread_reschedule(Ecore_Thread *thread) 1236ecore_thread_reschedule(Ecore_Thread *thread)
1262{ 1237{
@@ -1641,24 +1616,13 @@ ecore_thread_global_data_wait(const char *key,
1641 1616
1642 while (1) 1617 while (1)
1643 { 1618 {
1644#ifndef _WIN32
1645 struct timespec t = { 0, 0 };
1646
1647 t.tv_sec = (long int)tm;
1648 t.tv_nsec = (long int)((tm - (double)t.tv_sec) * 1000000000);
1649#else
1650 struct timeval t = { 0, 0 };
1651
1652 t.tv_sec = (long int)tm;
1653 t.tv_usec = (long int)((tm - (double)t.tv_sec) * 1000000);
1654#endif
1655 LRWKRL(_ecore_thread_global_hash_lock); 1619 LRWKRL(_ecore_thread_global_hash_lock);
1656 ret = eina_hash_find(_ecore_thread_global_hash, key); 1620 ret = eina_hash_find(_ecore_thread_global_hash, key);
1657 LRWKU(_ecore_thread_global_hash_lock); 1621 LRWKU(_ecore_thread_global_hash_lock);
1658 if ((ret) || (!seconds) || ((seconds > 0) && (tm <= ecore_time_get()))) 1622 if ((ret) || (!seconds) || ((seconds > 0) && (tm <= ecore_time_get())))
1659 break; 1623 break;
1660 LKL(_ecore_thread_global_hash_mutex); 1624 LKL(_ecore_thread_global_hash_mutex);
1661 CDW(_ecore_thread_global_hash_cond, _ecore_thread_global_hash_mutex, &t); 1625 CDW(_ecore_thread_global_hash_cond, tm);
1662 LKU(_ecore_thread_global_hash_mutex); 1626 LKU(_ecore_thread_global_hash_mutex);
1663 } 1627 }
1664 if (ret) return ret->data; 1628 if (ret) return ret->data;
diff --git a/libraries/ecore/src/lib/ecore/ecore_time.c b/libraries/ecore/src/lib/ecore/ecore_time.c
index 8e7611b..0eeb1d6 100644
--- a/libraries/ecore/src/lib/ecore/ecore_time.c
+++ b/libraries/ecore/src/lib/ecore/ecore_time.c
@@ -21,7 +21,7 @@
21 21
22#include <time.h> 22#include <time.h>
23 23
24#ifdef HAVE_CLOCK_GETTIME 24#if defined (HAVE_CLOCK_GETTIME) || defined (EXOTIC_PROVIDE_CLOCK_GETTIME)
25static clockid_t _ecore_time_clock_id = -1; 25static clockid_t _ecore_time_clock_id = -1;
26#elif defined(__APPLE__) && defined(__MACH__) 26#elif defined(__APPLE__) && defined(__MACH__)
27static double _ecore_time_clock_conversion = 1e-9; 27static double _ecore_time_clock_conversion = 1e-9;
@@ -52,7 +52,7 @@ double _ecore_time_loop_time = -1.0;
52EAPI double 52EAPI double
53ecore_time_get(void) 53ecore_time_get(void)
54{ 54{
55#ifdef HAVE_CLOCK_GETTIME 55#if defined (HAVE_CLOCK_GETTIME) || defined (EXOTIC_PROVIDE_CLOCK_GETTIME)
56 struct timespec t; 56 struct timespec t;
57 57
58 if (EINA_UNLIKELY(_ecore_time_clock_id < 0)) 58 if (EINA_UNLIKELY(_ecore_time_clock_id < 0))
@@ -136,7 +136,7 @@ ecore_loop_time_get(void)
136void 136void
137_ecore_time_init(void) 137_ecore_time_init(void)
138{ 138{
139#ifdef HAVE_CLOCK_GETTIME 139#if defined (HAVE_CLOCK_GETTIME) || defined (EXOTIC_PROVIDE_CLOCK_GETTIME)
140 struct timespec t; 140 struct timespec t;
141 141
142 if (_ecore_time_clock_id != -1) return; 142 if (_ecore_time_clock_id != -1) return;
diff --git a/libraries/ecore/src/lib/ecore/ecore_timer.c b/libraries/ecore/src/lib/ecore/ecore_timer.c
index cc19e3f..d76733b 100644
--- a/libraries/ecore/src/lib/ecore/ecore_timer.c
+++ b/libraries/ecore/src/lib/ecore/ecore_timer.c
@@ -56,7 +56,7 @@ static double last_check = 0.0;
56static double precision = 10.0 / 1000000.0; 56static double precision = 10.0 / 1000000.0;
57 57
58/** 58/**
59 * @addtogroup Ecore_Time_Group 59 * @addtogroup Ecore_Timer_Group
60 * 60 *
61 * @{ 61 * @{
62 */ 62 */
@@ -73,12 +73,15 @@ ecore_timer_precision_get(void)
73} 73}
74 74
75/** 75/**
76 * Sets the precision to be used by timer infrastructure. 76 * @brief Sets the precision to be used by timer infrastructure.
77 * 77 *
78 * When system calculates time to expire the next timer we'll be able 78 * @param value allowed introduced timeout delay, in seconds.
79 * to delay the timer by the given amount so more timers will fit in 79 *
80 * the same dispatch, waking up the system less often and thus being 80 * This sets the precision for @b all timers. The precision determines how much
81 * able to save power. 81 * of an difference from the requested interval is acceptable. One common reason
82 * to use this function is to @b increase the allowed timeout and thus @b
83 * decrease precision of the timers, this is because less precise the timers
84 * result in the system waking up less often and thus consuming less resources.
82 * 85 *
83 * Be aware that kernel may delay delivery even further, these delays 86 * Be aware that kernel may delay delivery even further, these delays
84 * are always possible due other tasks having higher priorities or 87 * are always possible due other tasks having higher priorities or
@@ -93,8 +96,6 @@ ecore_timer_precision_get(void)
93 * @note Ecore is smart enough to see if there are timers in the 96 * @note Ecore is smart enough to see if there are timers in the
94 * precision range, if it does not, in our example if no second timer 97 * precision range, if it does not, in our example if no second timer
95 * in (T + precision) existed, then it would use the minimum timeout. 98 * in (T + precision) existed, then it would use the minimum timeout.
96 *
97 * @param value allowed introduced timeout delay, in seconds.
98 */ 99 */
99EAPI void 100EAPI void
100ecore_timer_precision_set(double value) 101ecore_timer_precision_set(double value)
@@ -322,7 +323,7 @@ ecore_timer_reset(Ecore_Timer *timer)
322 * Get the pending time regarding a timer. 323 * Get the pending time regarding a timer.
323 * 324 *
324 * @param timer The timer to learn from. 325 * @param timer The timer to learn from.
325 * @ingroup Ecore_Time_Group 326 * @ingroup Ecore_Timer_Group
326 */ 327 */
327EAPI double 328EAPI double
328ecore_timer_pending_get(Ecore_Timer *timer) 329ecore_timer_pending_get(Ecore_Timer *timer)