diff options
Diffstat (limited to 'libraries/ecore/src/lib/ecore')
-rw-r--r-- | libraries/ecore/src/lib/ecore/Ecore.h | 896 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore/Makefile.am | 8 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore/Makefile.in | 33 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore/ecore.c | 6 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore/ecore_anim.c | 4 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore/ecore_events.c | 158 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore/ecore_exe.c | 10 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore/ecore_getopt.c | 4 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore/ecore_main.c | 185 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore/ecore_pipe.c | 17 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore/ecore_poll.c | 94 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore/ecore_private.h | 6 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore/ecore_thread.c | 756 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore/ecore_time.c | 6 | ||||
-rw-r--r-- | libraries/ecore/src/lib/ecore/ecore_timer.c | 19 |
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) | 39 | gcc *.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 | ||
60 | make | ||
61 | sudo 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 | ||
378 | typedef struct _Ecore_Version | 399 | typedef 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 | */ |
495 | EAPI int ecore_thread_main_loop_end(void); | 516 | EAPI 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 | */ | ||
629 | EAPI Ecore_Event_Handler *ecore_event_handler_add(int type, Ecore_Event_Handler_Cb func, const void *data); | 690 | EAPI 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 | */ | ||
630 | EAPI void *ecore_event_handler_del(Ecore_Event_Handler *event_handler); | 701 | EAPI 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 | */ | ||
631 | EAPI Ecore_Event *ecore_event_add(int type, void *ev, Ecore_End_Cb func_free, void *data); | 717 | EAPI 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 | */ | ||
632 | EAPI void *ecore_event_del(Ecore_Event *event); | 729 | EAPI 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 | */ | ||
633 | EAPI void *ecore_event_handler_data_get(Ecore_Event_Handler *eh); | 738 | EAPI 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 | */ | ||
634 | EAPI void *ecore_event_handler_data_set(Ecore_Event_Handler *eh, const void *data); | 748 | EAPI 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 | */ | ||
635 | EAPI int ecore_event_type_new(void); | 759 | EAPI 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 | */ | ||
636 | EAPI 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); | 779 | EAPI 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 | */ | ||
637 | EAPI void *ecore_event_filter_del(Ecore_Event_Filter *ef); | 787 | EAPI 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 | */ | ||
638 | EAPI int ecore_event_current_type_get(void); | 802 | EAPI 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 | */ | ||
639 | EAPI void *ecore_event_current_event_get(void); | 817 | EAPI 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 | ||
657 | EAPI extern int ECORE_EXE_EVENT_ADD; /**< A child process has been added */ | 836 | EAPI extern int ECORE_EXE_EVENT_ADD; /**< A child process has been added */ |
658 | EAPI extern int ECORE_EXE_EVENT_DEL; /**< A child process has been deleted (it exited, naming consistent with the rest of ecore). */ | 837 | EAPI 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 | */ |
824 | typedef Eina_Bool (*Ecore_Win32_Handle_Cb)(void *data, Ecore_Win32_Handler *wh); | 1009 | typedef 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 | */ | ||
826 | EAPI 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); | 1046 | EAPI 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 | */ | ||
827 | EAPI void ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Prep_Cb func, const void *data); | 1063 | EAPI 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 | */ | ||
828 | EAPI void *ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler); | 1077 | EAPI 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 | */ | ||
829 | EAPI int ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler); | 1083 | EAPI 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 | */ | ||
830 | EAPI Eina_Bool ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags); | 1092 | EAPI 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 | */ | ||
831 | EAPI void ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags); | 1098 | EAPI void ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags); |
832 | 1099 | ||
833 | EAPI Ecore_Win32_Handler *ecore_main_win32_handler_add(void *h, Ecore_Win32_Handle_Cb func, const void *data); | 1100 | EAPI 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 | ||
863 | typedef struct _Ecore_Poller Ecore_Poller; /**< A handle for pollers */ | 1147 | typedef 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 | */ | ||
865 | EAPI void ecore_poller_poll_interval_set(Ecore_Poller_Type type, double poll_time); | 1157 | EAPI 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 | */ | ||
866 | EAPI double ecore_poller_poll_interval_get(Ecore_Poller_Type type); | 1165 | EAPI 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 | */ | ||
867 | EAPI Eina_Bool ecore_poller_poller_interval_set(Ecore_Poller *poller, int interval); | 1175 | EAPI 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 | */ | ||
868 | EAPI int ecore_poller_poller_interval_get(Ecore_Poller *poller); | 1183 | EAPI 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 | */ | ||
869 | EAPI Ecore_Poller *ecore_poller_add(Ecore_Poller_Type type, int interval, Ecore_Task_Cb func, const void *data); | 1209 | EAPI 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 | */ | ||
870 | EAPI void *ecore_poller_del(Ecore_Poller *poller); | 1219 | EAPI void *ecore_poller_del(Ecore_Poller *poller); |
871 | 1220 | ||
872 | /** | 1221 | /** |
@@ -941,7 +1290,7 @@ typedef enum _Ecore_Animator_Source Ecore_Animator_Source; | |||
941 | typedef Eina_Bool (*Ecore_Timeline_Cb)(void *data, double pos); | 1290 | typedef 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 | */ | ||
1565 | EAPI double ecore_time_get(void); | ||
1566 | EAPI double ecore_time_unix_get(void); | ||
1567 | EAPI 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 | ||
1225 | typedef struct _Ecore_Timer Ecore_Timer; /**< A handle for timers */ | 1597 | typedef struct _Ecore_Timer Ecore_Timer; /**< A handle for timers */ |
1226 | 1598 | ||
1227 | EAPI double ecore_time_get(void); | ||
1228 | EAPI double ecore_time_unix_get(void); | ||
1229 | EAPI double ecore_loop_time_get(void); | ||
1230 | |||
1231 | EAPI Ecore_Timer *ecore_timer_add(double in, Ecore_Task_Cb func, const void *data); | 1599 | EAPI Ecore_Timer *ecore_timer_add(double in, Ecore_Task_Cb func, const void *data); |
1232 | EAPI Ecore_Timer *ecore_timer_loop_add(double in, Ecore_Task_Cb func, const void *data); | 1600 | EAPI Ecore_Timer *ecore_timer_loop_add(double in, Ecore_Task_Cb func, const void *data); |
1233 | EAPI void *ecore_timer_del(Ecore_Timer *timer); | 1601 | EAPI 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 | ||
48 | else | 48 | else |
49 | 49 | ||
50 | if ECORE_HAVE_EXOTIC | ||
51 | |||
52 | libecore_la_SOURCES += | ||
53 | |||
54 | else | ||
55 | |||
50 | libecore_la_SOURCES += ecore_signal.c ecore_exe.c | 56 | libecore_la_SOURCES += ecore_signal.c ecore_exe.c |
51 | 57 | ||
52 | endif | 58 | endif |
@@ -55,6 +61,8 @@ endif | |||
55 | 61 | ||
56 | endif | 62 | endif |
57 | 63 | ||
64 | endif | ||
65 | |||
58 | libecore_la_LIBADD = @dlopen_libs@ @EINA_LIBS@ @EVIL_LIBS@ @GLIB_LIBS@ @WIN32_LIBS@ @LTLIBINTL@ @EFL_PTHREAD_LIBS@ @rt_libs@ -lm | 66 | libecore_la_LIBADD = @dlopen_libs@ @EINA_LIBS@ @EVIL_LIBS@ @GLIB_LIBS@ @WIN32_LIBS@ @LTLIBINTL@ @EFL_PTHREAD_LIBS@ @rt_libs@ -lm |
59 | libecore_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@ @EFL_PTHREAD_LIBS@ | 67 | libecore_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 | ||
42 | subdir = src/lib/ecore | 43 | subdir = src/lib/ecore |
43 | DIST_COMMON = $(includes_HEADERS) $(srcdir)/Makefile.am \ | 44 | DIST_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 | ||
64 | am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ | 64 | am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ |
65 | $(ACLOCAL_M4) | 65 | $(ACLOCAL_M4) |
66 | mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs | 66 | mkinstalldirs = $(install_sh) -d |
67 | CONFIG_HEADER = $(top_builddir)/config.h | 67 | CONFIG_HEADER = $(top_builddir)/config.h |
68 | CONFIG_CLEAN_FILES = | 68 | CONFIG_CLEAN_FILES = |
69 | CONFIG_CLEAN_VPATH_FILES = | 69 | CONFIG_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 \ | 103 | am__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 | ||
105 | am_libecore_la_OBJECTS = ecore.lo ecore_alloc.lo ecore_anim.lo \ | 106 | am_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) |
112 | libecore_la_OBJECTS = $(am_libecore_la_OBJECTS) | 113 | libecore_la_OBJECTS = $(am_libecore_la_OBJECTS) |
113 | AM_V_lt = $(am__v_lt_$(V)) | 114 | AM_V_lt = $(am__v_lt_$(V)) |
114 | am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) | 115 | am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) |
@@ -211,6 +212,8 @@ EVAS_LIBS = @EVAS_LIBS@ | |||
211 | EVIL_CFLAGS = @EVIL_CFLAGS@ | 212 | EVIL_CFLAGS = @EVIL_CFLAGS@ |
212 | EVIL_LIBS = @EVIL_LIBS@ | 213 | EVIL_LIBS = @EVIL_LIBS@ |
213 | EXEEXT = @EXEEXT@ | 214 | EXEEXT = @EXEEXT@ |
215 | EXOTIC_CFLAGS = @EXOTIC_CFLAGS@ | ||
216 | EXOTIC_LIBS = @EXOTIC_LIBS@ | ||
214 | FGREP = @FGREP@ | 217 | FGREP = @FGREP@ |
215 | GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ | 218 | GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ |
216 | GLIB_CFLAGS = @GLIB_CFLAGS@ | 219 | GLIB_CFLAGS = @GLIB_CFLAGS@ |
@@ -266,6 +269,8 @@ PATH_SEPARATOR = @PATH_SEPARATOR@ | |||
266 | PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ | 269 | PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ |
267 | PIXMAN_LIBS = @PIXMAN_LIBS@ | 270 | PIXMAN_LIBS = @PIXMAN_LIBS@ |
268 | PKG_CONFIG = @PKG_CONFIG@ | 271 | PKG_CONFIG = @PKG_CONFIG@ |
272 | PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ | ||
273 | PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ | ||
269 | POSUB = @POSUB@ | 274 | POSUB = @POSUB@ |
270 | RANLIB = @RANLIB@ | 275 | RANLIB = @RANLIB@ |
271 | SCIM_CFLAGS = @SCIM_CFLAGS@ | 276 | SCIM_CFLAGS = @SCIM_CFLAGS@ |
@@ -276,6 +281,7 @@ SDL_LIBS = @SDL_LIBS@ | |||
276 | SED = @SED@ | 281 | SED = @SED@ |
277 | SET_MAKE = @SET_MAKE@ | 282 | SET_MAKE = @SET_MAKE@ |
278 | SHELL = @SHELL@ | 283 | SHELL = @SHELL@ |
284 | SHM_OPEN_LIBS = @SHM_OPEN_LIBS@ | ||
279 | SSL_CFLAGS = @SSL_CFLAGS@ | 285 | SSL_CFLAGS = @SSL_CFLAGS@ |
280 | SSL_LIBS = @SSL_LIBS@ | 286 | SSL_LIBS = @SSL_LIBS@ |
281 | STRIP = @STRIP@ | 287 | STRIP = @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) | ||
507 | libecore_la_LIBADD = @dlopen_libs@ @EINA_LIBS@ @EVIL_LIBS@ @GLIB_LIBS@ @WIN32_LIBS@ @LTLIBINTL@ @EFL_PTHREAD_LIBS@ @rt_libs@ -lm | 514 | libecore_la_LIBADD = @dlopen_libs@ @EINA_LIBS@ @EVIL_LIBS@ @GLIB_LIBS@ @WIN32_LIBS@ @LTLIBINTL@ @EFL_PTHREAD_LIBS@ @rt_libs@ -lm |
508 | libecore_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@ @EFL_PTHREAD_LIBS@ | 515 | libecore_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@ @EFL_PTHREAD_LIBS@ |
509 | EXTRA_DIST = ecore_private.h | 516 | EXTRA_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; | |||
72 | static void _ecore_event_purge_deleted(void); | 72 | static void _ecore_event_purge_deleted(void); |
73 | static void *_ecore_event_del(Ecore_Event *event); | 73 | static 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 | */ | ||
104 | EAPI Ecore_Event_Handler * | 75 | EAPI Ecore_Event_Handler * |
105 | ecore_event_handler_add(int type, | 76 | ecore_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 | */ | ||
164 | EAPI void * | 125 | EAPI void * |
165 | ecore_event_handler_del(Ecore_Event_Handler *event_handler) | 126 | ecore_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 | */ | ||
191 | EAPI void * | 144 | EAPI void * |
192 | ecore_event_handler_data_get(Ecore_Event_Handler *eh) | 145 | ecore_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 | */ | ||
217 | EAPI void * | 161 | EAPI void * |
218 | ecore_event_handler_data_set(Ecore_Event_Handler *eh, | 162 | ecore_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 | */ | ||
262 | EAPI Ecore_Event * | 188 | EAPI Ecore_Event * |
263 | ecore_event_add(int type, | 189 | ecore_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 | */ | ||
293 | EAPI void * | 208 | EAPI void * |
294 | ecore_event_del(Ecore_Event *event) | 209 | ecore_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 | */ | ||
322 | EAPI int | 227 | EAPI int |
323 | ecore_event_type_new(void) | 228 | ecore_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 | */ | ||
354 | EAPI Ecore_Event_Filter * | 239 | EAPI Ecore_Event_Filter * |
355 | ecore_event_filter_add(Ecore_Data_Cb func_start, | 240 | ecore_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 | */ | ||
386 | EAPI void * | 262 | EAPI void * |
387 | ecore_event_filter_del(Ecore_Event_Filter *ef) | 263 | ecore_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 | */ | ||
421 | EAPI int | 283 | EAPI int |
422 | ecore_event_current_type_get(void) | 284 | ecore_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 | */ | ||
441 | EAPI void * | 289 | EAPI void * |
442 | ecore_event_current_event_get(void) | 290 | ecore_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 | |||
451 | EAPI void * | 295 | EAPI 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 | */ |
344 | EAPI void | 344 | EAPI void |
345 | ecore_exe_run_priority_set(int pri) | 345 | ecore_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 |
230 | Ecore_Select_Function main_loop_select = _ecore_main_win32_select; | 230 | Ecore_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 | ||
235 | Ecore_Select_Function main_loop_select = select; | 236 | Ecore_Select_Function main_loop_select = select; |
237 | # else | ||
238 | Ecore_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 | |||
856 | EAPI int | ||
857 | ecore_main_loop_iterate_may_block(int may_block) | ||
858 | { | ||
859 | #ifndef USE_G_MAIN_LOOP | ||
860 | _ecore_lock(); | ||
861 | in_main_loop++; | ||
862 | _ecore_main_loop_iterate_internal(!may_block); | ||
863 | in_main_loop--; | ||
864 | _ecore_unlock(); | ||
865 | return _ecore_event_exist(); | ||
866 | #else | ||
867 | return g_main_context_iteration(NULL, may_block); | ||
868 | #endif | ||
869 | } | ||
851 | EAPI void | 870 | EAPI void |
852 | ecore_main_loop_iterate(void) | 871 | ecore_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 | */ | ||
981 | EAPI Ecore_Fd_Handler * | 967 | EAPI Ecore_Fd_Handler * |
982 | ecore_main_fd_handler_add(int fd, | 968 | ecore_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 | */ | ||
1076 | EAPI void * | 1048 | EAPI void * |
1077 | ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler) | 1049 | ecore_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 | */ | ||
1137 | EAPI void | 1091 | EAPI void |
1138 | ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, | 1092 | ecore_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 | */ | ||
1166 | EAPI int | 1114 | EAPI int |
1167 | ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler) | 1115 | ecore_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 | */ | ||
1194 | EAPI Eina_Bool | 1133 | EAPI Eina_Bool |
1195 | ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, | 1134 | ecore_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 | */ | ||
1222 | EAPI void | 1155 | EAPI void |
1223 | ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, | 1156 | ecore_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 | ||
1854 | done: /*******************************************************************/ | 1787 | done: /*******************************************************************/ |
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 | |||
83 | struct _Ecore_Pipe | 84 | struct _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 | */ | ||
206 | EAPI void | 192 | EAPI void |
207 | ecore_poller_poll_interval_set(Ecore_Poller_Type type __UNUSED__, | 193 | ecore_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 | */ | ||
221 | EAPI double | 200 | EAPI double |
222 | ecore_poller_poll_interval_get(Ecore_Poller_Type type __UNUSED__) | 201 | ecore_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 | */ | ||
273 | EAPI Ecore_Poller * | 206 | EAPI Ecore_Poller * |
274 | ecore_poller_add(Ecore_Poller_Type type __UNUSED__, | 207 | ecore_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 | */ | ||
320 | EAPI Eina_Bool | 243 | EAPI Eina_Bool |
321 | ecore_poller_poller_interval_set(Ecore_Poller *poller, | 244 | ecore_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 | */ | ||
364 | EAPI int | 279 | EAPI int |
365 | ecore_poller_poller_interval_get(Ecore_Poller *poller) | 280 | ecore_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 | */ | ||
394 | EAPI void * | 300 | EAPI void * |
395 | ecore_poller_del(Ecore_Poller *poller) | 301 | ecore_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 | ||
175 | void _ecore_main_shutdown(void); | 175 | void _ecore_main_shutdown(void); |
176 | 176 | ||
177 | #if defined (_WIN32) || defined (__lv2ppu__) | 177 | #if defined (_WIN32) || defined (__lv2ppu__) || defined (HAVE_EXOTIC) |
178 | static inline void _ecore_signal_shutdown(void) { } | 178 | static inline void _ecore_signal_shutdown(void) { } |
179 | 179 | ||
180 | static inline void _ecore_signal_init(void) { } | 180 | static 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 | ||
243 | static inline void | 243 | static 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 | |||
120 | typedef 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 | |||
160 | int | ||
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 | |||
181 | typedef 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 |
368 | typedef struct _Ecore_Pthread_Data Ecore_Pthread_Data; | 184 | typedef struct _Ecore_Pthread_Data Ecore_Pthread_Data; |
369 | |||
370 | struct _Ecore_Pthread_Data | 185 | struct _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 | |||
192 | typedef struct _Ecore_Pthread_Notify Ecore_Pthread_Notify; | ||
193 | struct _Ecore_Pthread_Notify | ||
194 | { | ||
195 | Ecore_Pthread_Worker *work; | ||
196 | const void *user_data; | ||
197 | }; | ||
198 | |||
199 | typedef void *(*Ecore_Thread_Sync_Cb)(void* data, Ecore_Thread *thread); | ||
200 | |||
201 | typedef struct _Ecore_Pthread_Message Ecore_Pthread_Message; | ||
202 | struct _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 | ||
379 | static int _ecore_thread_count_max = 0; | 219 | static int _ecore_thread_count_max = 0; |
380 | static int ECORE_THREAD_PIPE_DEL = 0; | ||
381 | static Eina_Array *_ecore_thread_pipe = NULL; | ||
382 | 220 | ||
383 | #ifdef EFL_HAVE_THREADS | 221 | #ifdef EFL_HAVE_THREADS |
384 | 222 | ||
385 | static void _ecore_thread_handler(void *data __UNUSED__, | 223 | static void _ecore_thread_handler(void *data); |
386 | void *buffer, | ||
387 | unsigned int nbyte); | ||
388 | |||
389 | static 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 | ||
398 | static int _ecore_thread_count = 0; | 225 | static int _ecore_thread_count = 0; |
399 | 226 | ||
400 | static Ecore_Event_Handler *del_handler = NULL; | ||
401 | static Eina_List *_ecore_active_job_threads = NULL; | 227 | static Eina_List *_ecore_active_job_threads = NULL; |
402 | static Eina_List *_ecore_pending_job_threads = NULL; | 228 | static Eina_List *_ecore_pending_job_threads = NULL; |
403 | static Eina_List *_ecore_pending_job_threads_feedback = NULL; | 229 | static Eina_List *_ecore_pending_job_threads_feedback = NULL; |
@@ -435,6 +261,10 @@ static PH(get_main_loop_thread) (void) | |||
435 | static void | 261 | static 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 | ||
456 | static void | 286 | static 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 | |||
469 | static 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 | |||
478 | static 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 | ||
551 | static void | 351 | static 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 | ||
574 | static void | 369 | static 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; | 375 | static 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 | |||
396 | static 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 | ||
597 | static void | 441 | static 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 | ||
638 | static void | 486 | static 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, | |||
679 | static void * | 531 | static 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 | ||
730 | static void * | 592 | static void * |
@@ -740,8 +602,8 @@ _ecore_thread_worker(Ecore_Pthread_Data *pth) | |||
740 | eina_sched_prio_drop(); | 602 | eina_sched_prio_drop(); |
741 | 603 | ||
742 | restart: | 604 | restart: |
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 | ||
888 | void | 738 | void |
@@ -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, | |||
969 | on_error: | 818 | on_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 | |||
1013 | ecore_thread_cancel(Ecore_Thread *thread) | 865 | ecore_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 */ |
1074 | on_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: | |||
1083 | EAPI Eina_Bool | 944 | EAPI Eina_Bool |
1084 | ecore_thread_check(Ecore_Thread *thread) | 945 | ecore_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 | ||
1092 | EAPI Ecore_Thread * | 966 | EAPI 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, | |||
1177 | on_error: | 1052 | on_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 | ||
1171 | EAPI Ecore_Thread * | ||
1172 | ecore_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 | |||
1260 | EAPI Eina_Bool | 1235 | EAPI Eina_Bool |
1261 | ecore_thread_reschedule(Ecore_Thread *thread) | 1236 | ecore_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) |
25 | static clockid_t _ecore_time_clock_id = -1; | 25 | static clockid_t _ecore_time_clock_id = -1; |
26 | #elif defined(__APPLE__) && defined(__MACH__) | 26 | #elif defined(__APPLE__) && defined(__MACH__) |
27 | static double _ecore_time_clock_conversion = 1e-9; | 27 | static double _ecore_time_clock_conversion = 1e-9; |
@@ -52,7 +52,7 @@ double _ecore_time_loop_time = -1.0; | |||
52 | EAPI double | 52 | EAPI double |
53 | ecore_time_get(void) | 53 | ecore_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) | |||
136 | void | 136 | void |
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; | |||
56 | static double precision = 10.0 / 1000000.0; | 56 | static 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 | */ |
99 | EAPI void | 100 | EAPI void |
100 | ecore_timer_precision_set(double value) | 101 | ecore_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 | */ |
327 | EAPI double | 328 | EAPI double |
328 | ecore_timer_pending_get(Ecore_Timer *timer) | 329 | ecore_timer_pending_get(Ecore_Timer *timer) |