-/**
-@brief Ecore Library Public API Calls
-
-These routines are used for Ecore Library interaction
-*/
-
-/**
-
-@mainpage Ecore
-
-@version 1.1
-@date 2000-2011
-
-Please see the @ref authors page for contact details.
-
-@section intro Introduction
-
-Ecore is a library of convenience functions. A brief explanation of how to use
-it can be found in @ref Ecore_Main_Loop_Page.
-
-The Ecore library provides the following modules:
-@li @ref Ecore_Main_Loop_Group
-@li @ref Ecore_File_Group
-@li @ref Ecore_Con_Group
-@li @link Ecore_Evas.h Ecore_Evas - Evas convenience functions. @endlink
-@li @ref Ecore_FB_Group
-@li @link Ecore_Ipc.h Ecore_IPC - Inter Process Communication functions. @endlink
-@li @link Ecore_X.h Ecore_X - X Windows System wrapper. @endlink
-@li @ref Ecore_Win32_Group
-@li @ref Ecore_WinCE_Group
-
-For more info on Ecore usage, there are these @ref Examples.
-
-@section compiling How to compile using Ecore?
-pkgconfig (.pc) files are installed for every ecore module.
-Thus, to compile using any of them, you can use something like the following:
-
-@verbatim
-gcc *.c $(pkg-config ecore ecore-$x ecore-$y [...] --cflags --libs)
-@endverbatim
-
-@section install How is it installed?
-
-Suggested configure options for evas for a Linux desktop X display:
-
-@verbatim
-./configure \
-make
-su -
-...
-make install
-@endverbatim
-
-*/
-
-/**
-@page authors Authors
-@author Carsten Haitzler <raster@rasterman.com>
-@author Tom Gilbert <tom@linuxbrit.co.uk>
-@author Burra <burra@colorado.edu>
-@author Chris Ross <chris@darkrock.co.uk>
-@author Term <term@twistedpath.org>
-@author Tilman Sauerbeck <tilman@code-monkey.de>
-@author Ibukun Olumuyiwa <ibukun@computer.org>
-@author Yuri <da2001@hotmail.ru>
-@author Nicholas Curran <quasar@bigblue.net.au>
-@author Howell Tam <pigeon@pigeond.net>
-@author Nathan Ingersoll <rbdpngn@users.sourceforge.net>
-@author Andrew Elcock <andy@elcock.org>
-@author Kim Woelders <kim@woelders.dk>
-@author Sebastian Dransfeld <sebastid@tango.flipp.net>
-@author Simon Poole <simon.armlinux@themalago.net>
-@author Jorge Luis Zapata Muga <jorgeluis.zapata@gmail.com>
-@author dan sinclair <zero@everburning.com>
-@author Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de>
-@author David 'onefang' Seikel <onefang@gmail.com>
-@author Hisham 'CodeWarrior' Mardam Bey <hisham@hisham.cc>
-@author Brian 'rephorm' Mattern <rephorm@rephorm.com>
-@author Tim Horton <hortont424@gmail.com>
-@author Arnaud de Turckheim 'quarium' <quarium@gmail.com>
-@author Matt Barclay <mbarclay@gmail.com>
-@author Peter Wehrfritz <peter.wehrfritz@web.de>
-@author Albin "Lutin" Tonnerre <albin.tonnerre@gmail.com>
-@author Vincent Torri <vincent.torri@gmail.com>
-@author Lars Munch <lars@segv.dk>
-@author Andre Dieb <andre.dieb@gmail.com>
-@author Mathieu Taillefumier <mathieu.taillefumier@free.fr>
-@author Rui Miguel Silva Seabra <rms@1407.org>
-@author Samsung Electronics
-@author Samsung SAIT
-@author Nicolas Aguirre <aguirre.nicolas@gmail.com>
-@author Brett Nash <nash@nash.id.au>
-@author Mike Blumenkrantz <mike@zentific.com>
-@author Leif Middelschulte <leif.middelschulte@gmail.com>
-@author Mike McCormack <mj.mccormack@samsung.com>
-@author Sangho Park <gouache95@gmail.com>
-@author Jihoon Kim <jihoon48.kim@samsung.com> <imfine98@gmail.com>
-@author Daniel Juyung Seo <seojuyung2@gmail.com> <juyung.seo@samsung.com>
-
-Please contact <enlightenment-devel@lists.sourceforge.net> to get in
-contact with the developers and maintainers.
-*/
-
-/*
-@page Ecore_Main_Loop_Page The Ecore Main Loop
-
-@section intro What is Ecore?
-
-Ecore is a clean and tiny event loop library with many modules to do lots of
-convenient things for a programmer, to save time and effort.
-
-It's small and lean, designed to work on embedded systems all the way to
-large and powerful multi-cpu workstations. It serialises all system signals,
-events etc. into a single event queue, that is easily processed without
-needing to worry about concurrency. A properly written, event-driven program
-using this kind of programming doesn't need threads, nor has to worry about
-concurrency. It turns a program into a state machine, and makes it very
-robust and easy to follow.
-
-Ecore gives you other handy primitives, such as timers to tick over for you
-and call specified functions at particular times so the programmer can use
-this to do things, like animate, or time out on connections or tasks that take
-too long etc.
+/**
+ @brief Ecore Library Public API Calls
-Idle handlers are provided too, as well as calls on entering an idle state
-(often a very good time to update the state of the program). All events that
-enter the system are passed to specific callback functions that the program
-sets up to handle those events. Handling them is simple and other Ecore
-modules produce more events on the queue, coming from other sources such as
-file descriptors etc.
+ These routines are used for Ecore Library interaction
+ */
-Ecore also lets you have functions called when file descriptors become active
-for reading or writing, allowing for streamlined, non-blocking IO.
+/**
-Here is an example of a simple program and its basic event loop flow:
+ @mainpage Ecore
-@image html prog_flow.png
-@image latex prog_flow.eps width=\textwidth
+ @version 1.1
+ @date 2000-2011
+ Please see the @ref authors page for contact details.
+ @section intro Introduction
-@section work How does Ecore work?
+ Ecore is a library of convenience functions. A brief explanation of how to use
+ it can be found in @ref Ecore_Main_Loop_Page.
-Ecore is very easy to learn and use. All the function calls are designed to
-be easy to remember, explicit in describing what they do, and heavily
-name-spaced. Ecore programs can start and be very simple.
+ The Ecore library provides the following modules:
+ @li @ref Ecore_Main_Loop_Group
+ @li @ref Ecore_File_Group
+ @li @ref Ecore_Con_Group
+ @li @link Ecore_Evas.h Ecore_Evas - Evas convenience functions. @endlink
+ @li @ref Ecore_FB_Group
+ @li @link Ecore_Ipc.h Ecore_IPC - Inter Process Communication functions. @endlink
+ @li @link Ecore_X.h Ecore_X - X Windows System wrapper. @endlink
+ @li @ref Ecore_Win32_Group
+ @li @ref Ecore_WinCE_Group
-For example:
+ For more info on Ecore usage, there are these @ref Examples.
-@code
-#include <Ecore.h>
+ @section compiling How to compile using Ecore?
+ pkgconfig (.pc) files are installed for every ecore module.
+ Thus, to compile using any of them, you can use something like the following:
-int main(int argc, const char **argv)
-{
- ecore_init();
- ecore_app_args_set(argc, argv);
- ecore_main_loop_begin();
- ecore_shutdown();
- return 0;
-}
-@endcode
+ @verbatim
+ gcc *.c $(pkg-config ecore ecore-$x ecore-$y [...] --cflags --libs)
+ @endverbatim
-This program is very simple and doesn't check for errors, but it does start up
-and begin a main loop waiting for events or timers to tick off. This program
-doesn't set up any, but now we can expand on this simple program a little
-more by adding some event handlers and timers.
+ @section install How is it installed?
-@code
-#include <Ecore.h>
+ Suggested configure options for evas for a Linux desktop X display:
-Ecore_Timer *timer1 = NULL;
-Ecore_Event_Handler *handler1 = NULL;
-double start_time = 0.0;
+ @verbatim
+ ./configure \
+ make
+ su -
+ ...
+ make install
+ @endverbatim
-int timer_func(void *data)
-{
- printf("Tick timer. Sec: %3.2f\n", ecore_time_get() - start_time);
- return 1;
-}
+ */
-int exit_func(void *data, int ev_type, void *ev)
-{
- Ecore_Event_Signal_Exit *e;
-
- e = (Ecore_Event_Signal_Exit *)ev;
- if (e->interrupt) printf("Exit: interrupt\n");
- else if (e->quit) printf("Exit: quit\n");
- else if (e->terminate) printf("Exit: terminate\n");
- ecore_main_loop_quit();
- return 1;
-}
+/**
+ @page authors Authors
+ @author Carsten Haitzler <raster@rasterman.com>
+ @author Tom Gilbert <tom@linuxbrit.co.uk>
+ @author Burra <burra@colorado.edu>
+ @author Chris Ross <chris@darkrock.co.uk>
+ @author Term <term@twistedpath.org>
+ @author Tilman Sauerbeck <tilman@code-monkey.de>
+ @author Ibukun Olumuyiwa <ibukun@computer.org>
+ @author Yuri <da2001@hotmail.ru>
+ @author Nicholas Curran <quasar@bigblue.net.au>
+ @author Howell Tam <pigeon@pigeond.net>
+ @author Nathan Ingersoll <rbdpngn@users.sourceforge.net>
+ @author Andrew Elcock <andy@elcock.org>
+ @author Kim Woelders <kim@woelders.dk>
+ @author Sebastian Dransfeld <sebastid@tango.flipp.net>
+ @author Simon Poole <simon.armlinux@themalago.net>
+ @author Jorge Luis Zapata Muga <jorgeluis.zapata@gmail.com>
+ @author dan sinclair <zero@everburning.com>
+ @author Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de>
+ @author David 'onefang' Seikel <onefang@gmail.com>
+ @author Hisham 'CodeWarrior' Mardam Bey <hisham@hisham.cc>
+ @author Brian 'rephorm' Mattern <rephorm@rephorm.com>
+ @author Tim Horton <hortont424@gmail.com>
+ @author Arnaud de Turckheim 'quarium' <quarium@gmail.com>
+ @author Matt Barclay <mbarclay@gmail.com>
+ @author Peter Wehrfritz <peter.wehrfritz@web.de>
+ @author Albin "Lutin" Tonnerre <albin.tonnerre@gmail.com>
+ @author Vincent Torri <vincent.torri@gmail.com>
+ @author Lars Munch <lars@segv.dk>
+ @author Andre Dieb <andre.dieb@gmail.com>
+ @author Mathieu Taillefumier <mathieu.taillefumier@free.fr>
+ @author Rui Miguel Silva Seabra <rms@1407.org>
+ @author Samsung Electronics
+ @author Samsung SAIT
+ @author Nicolas Aguirre <aguirre.nicolas@gmail.com>
+ @author Brett Nash <nash@nash.id.au>
+ @author Mike Blumenkrantz <mike@zentific.com>
+ @author Leif Middelschulte <leif.middelschulte@gmail.com>
+ @author Mike McCormack <mj.mccormack@samsung.com>
+ @author Sangho Park <gouache95@gmail.com>
+ @author Jihoon Kim <jihoon48.kim@samsung.com> <imfine98@gmail.com>
+ @author Daniel Juyung Seo <seojuyung2@gmail.com> <juyung.seo@samsung.com>
+
+ Please contact <enlightenment-devel@lists.sourceforge.net> to get in
+ contact with the developers and maintainers.
+ */
-int main(int argc, const char **argv)
-{
- ecore_init();
- ecore_app_args_set(argc, argv);
- start_time = ecore_time_get();
- handler1 = ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, exit_func, NULL);
- timer1 = ecore_timer_add(0.5, timer_func, NULL);
- ecore_main_loop_begin();
- ecore_shutdown();
- return 0;
-}
-@endcode
-
-In the previous example, we initialize our application and get the time at
-which our program has started so we can calculate an offset. We set
-up a timer to tick off in 0.5 seconds, and since it returns 1, will
-keep ticking off every 0.5 seconds until it returns 0, or is deleted
-by hand. An event handler is set up to call a function - exit_func(),
-whenever an event of type ECORE_EVENT_SIGNAL_EXIT is received (CTRL-C
-on the command line will cause such an event to happen). If this event
-occurs it tells you what kind of exit signal was received, and asks
-the main loop to quit when it is finished by calling
-ecore_main_loop_quit().
-
-The handles returned by ecore_timer_add() and ecore_event_handler_add() are
-only stored here as an example. If you don't need to address the timer or
-event handler again you don't need to store the result, so just call the
-function, and don't assign the result to any variable.
-
-This program looks slightly more complex than needed to do these simple
-things, but in principle, programs don't get any more complex. You add more
-event handlers, for more events, will have more timers and such, BUT it all
-follows the same principles as shown in this example.
-
-*/
+/*
+ @page Ecore_Main_Loop_Page The Ecore Main Loop
+
+ @section intro What is Ecore?
+
+ Ecore is a clean and tiny event loop library with many modules to do lots of
+ convenient things for a programmer, to save time and effort.
+
+ It's small and lean, designed to work on embedded systems all the way to
+ large and powerful multi-cpu workstations. It serialises all system signals,
+ events etc. into a single event queue, that is easily processed without
+ needing to worry about concurrency. A properly written, event-driven program
+ using this kind of programming doesn't need threads, nor has to worry about
+ concurrency. It turns a program into a state machine, and makes it very
+ robust and easy to follow.
+
+ Ecore gives you other handy primitives, such as timers to tick over for you
+ and call specified functions at particular times so the programmer can use
+ this to do things, like animate, or time out on connections or tasks that take
+ too long etc.
+
+ Idle handlers are provided too, as well as calls on entering an idle state
+ (often a very good time to update the state of the program). All events that
+ enter the system are passed to specific callback functions that the program
+ sets up to handle those events. Handling them is simple and other Ecore
+ modules produce more events on the queue, coming from other sources such as
+ file descriptors etc.
+
+ Ecore also lets you have functions called when file descriptors become active
+ for reading or writing, allowing for streamlined, non-blocking IO.
+
+ Here is an example of a simple program and its basic event loop flow:
+
+ @image html prog_flow.png
+ @image latex prog_flow.eps width=\textwidth
+
+
+
+ @section work How does Ecore work?
+
+ Ecore is very easy to learn and use. All the function calls are designed to
+ be easy to remember, explicit in describing what they do, and heavily
+ name-spaced. Ecore programs can start and be very simple.
+
+ For example:
+
+ @code
+ #include <Ecore.h>
+
+ int
+ main(int argc, const char **argv)
+ {
+ ecore_init();
+ ecore_app_args_set(argc, argv);
+ ecore_main_loop_begin();
+ ecore_shutdown();
+ return 0;
+ }
+ @endcode
+
+ This program is very simple and doesn't check for errors, but it does start up
+ and begin a main loop waiting for events or timers to tick off. This program
+ doesn't set up any, but now we can expand on this simple program a little
+ more by adding some event handlers and timers.
+
+ @code
+ #include <Ecore.h>
+
+ Ecore_Timer *timer1 = NULL;
+ Ecore_Event_Handler *handler1 = NULL;
+ double start_time = 0.0;
+
+ int
+ timer_func(void *data)
+ {
+ printf("Tick timer. Sec: %3.2f\n", ecore_time_get() - start_time);
+ return 1;
+ }
+
+ int
+ exit_func(void *data, int ev_type, void *ev)
+ {
+ Ecore_Event_Signal_Exit *e;
+
+ e = (Ecore_Event_Signal_Exit *)ev;
+ if (e->interrupt) printf("Exit: interrupt\n");
+ else if (e->quit) printf("Exit: quit\n");
+ else if (e->terminate) printf("Exit: terminate\n");
+ ecore_main_loop_quit();
+ return 1;
+ }
+
+ int
+ main(int argc, const char **argv)
+ {
+ ecore_init();
+ ecore_app_args_set(argc, argv);
+ start_time = ecore_time_get();
+ handler1 = ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, exit_func, NULL);
+ timer1 = ecore_timer_add(0.5, timer_func, NULL);
+ ecore_main_loop_begin();
+ ecore_shutdown();
+ return 0;
+ }
+ @endcode
+
+ In the previous example, we initialize our application and get the time at
+ which our program has started so we can calculate an offset. We set
+ up a timer to tick off in 0.5 seconds, and since it returns 1, will
+ keep ticking off every 0.5 seconds until it returns 0, or is deleted
+ by hand. An event handler is set up to call a function -
+ exit_func(),
+ whenever an event of type ECORE_EVENT_SIGNAL_EXIT is received (CTRL-C
+ on the command line will cause such an event to happen). If this event
+ occurs it tells you what kind of exit signal was received, and asks
+ the main loop to quit when it is finished by calling
+ ecore_main_loop_quit().
+
+ The handles returned by ecore_timer_add() and
+ ecore_event_handler_add() are
+ only stored here as an example. If you don't need to address the timer or
+ event handler again you don't need to store the result, so just call the
+ function, and don't assign the result to any variable.
+
+ This program looks slightly more complex than needed to do these simple
+ things, but in principle, programs don't get any more complex. You add more
+ event handlers, for more events, will have more timers and such, BUT it all
+ follows the same principles as shown in this example.
+
+ */
/*
-@page Ecore_Config_Page The Enlightened Property Library
+ @page Ecore_Config_Page The Enlightened Property Library
-The Enlightened Property Library (Ecore_Config) is an adbstraction
-from the complexities of writing your own configuration. It provides
-many features using the Enlightenment 17 development libraries.
+ The Enlightened Property Library (Ecore_Config) is an adbstraction
+ from the complexities of writing your own configuration. It provides
+ many features using the Enlightenment 17 development libraries.
-To use the library, you:
-@li Set the default values of your properties.
-@li Load the configuration from a file. You must set the default values
+ To use the library, you:
+ @li Set the default values of your properties.
+ @li Load the configuration from a file. You must set the default values
first, so that the library knows the correct type of each argument.
-The following examples show how to use the Enlightened Property Library:
-@li @link config_basic_example.c config_basic_example.c @endlink
-@li @link config_listener_example.c config_listener_example.c @endlink
+ The following examples show how to use the Enlightened Property Library:
+ @li @link config_basic_example.c config_basic_example.c @endlink
+ @li @link config_listener_example.c config_listener_example.c @endlink
-*/
+ */
/**
-@page X_Window_System_Page X Window System
+ @page X_Window_System_Page X Window System
-The Ecore library includes a wrapper for handling the X window system.
-This page briefly explains what the X window system is and various terms
-that are used.
-*/
+ The Ecore library includes a wrapper for handling the X window system.
+ This page briefly explains what the X window system is and various terms
+ that are used.
+ */
#ifndef _ECORE_H
#define _ECORE_H
extern "C" {
#endif
- /**
- * @defgroup Ecore_Init_Group Ecore initialization and shutdown functions.
- *
- * @{
- */
-
- EAPI int ecore_init(void);
- EAPI int ecore_shutdown(void);
-
- /**
- * @}
- */
-
- /**
- *
- * @defgroup Ecore_Main_Loop_Group Ecore main loop functions
- *
- * These are functions acting on Ecore's main loop itself or on
- * events and infrastructure directly linked to it. This loop is
- * designed to work on embedded systems all the way to large and
- * powerful multi-cpu workstations.
- *
- * It serialises all system signals and events into a single event
- * queue, that can be easily processed without needing to worry
- * about concurrency. A properly written, event-driven program
- * using this kind of programming does not need threads. It makes
- * the program very robust and easy to follow.
- *
- * For example, for the main loop to be of any use, you need to be
- * able to add @b events and event handlers on it. Events for file
- * descriptor events are covered in @ref Ecore_FD_Handler_Group.
- *
- * Timer functions are covered in @ref Ecore_Time_Group.
- *
- * There is also provision for callbacks for when the loop enters or
- * exits an @b idle state. See @ref Ecore_Idle_Group for more
- * information on it.
- *
- * Functions are also provided for spawning child processes using
- * @c fork(). See @ref Ecore_Exe_Group for more details on it.
- *
- * Here is an example of simple program and its basic event loop
- * flow:
- *
- * @image html prog_flow.png
- * @image latex prog_flow.eps width=\textwidth
- *
- * For examples of setting up and using a main loop, see
- * @ref Ecore_Main_Loop_Page.
- *
- * @{
- */
+/**
+ * @defgroup Ecore_Init_Group Ecore initialization and shutdown functions.
+ *
+ * @{
+ */
+
+EAPI int
+ ecore_init(void);
+EAPI int
+ ecore_shutdown(void);
+
+/**
+ * @}
+ */
+
+/**
+ *
+ * @defgroup Ecore_Main_Loop_Group Ecore main loop functions
+ *
+ * These are functions acting on Ecore's main loop itself or on
+ * events and infrastructure directly linked to it. This loop is
+ * designed to work on embedded systems all the way to large and
+ * powerful multi-cpu workstations.
+ *
+ * It serialises all system signals and events into a single event
+ * queue, that can be easily processed without needing to worry
+ * about concurrency. A properly written, event-driven program
+ * using this kind of programming does not need threads. It makes
+ * the program very robust and easy to follow.
+ *
+ * For example, for the main loop to be of any use, you need to be
+ * able to add @b events and event handlers on it. Events for file
+ * descriptor events are covered in @ref Ecore_FD_Handler_Group.
+ *
+ * Timer functions are covered in @ref Ecore_Time_Group.
+ *
+ * There is also provision for callbacks for when the loop enters or
+ * exits an @b idle state. See @ref Ecore_Idle_Group for more
+ * information on it.
+ *
+ * Functions are also provided for spawning child processes using
+ * @c fork(). See @ref Ecore_Exe_Group for more details on it.
+ *
+ * Here is an example of simple program and its basic event loop
+ * flow:
+ *
+ * @image html prog_flow.png
+ * @image latex prog_flow.eps width=\textwidth
+ *
+ * For examples of setting up and using a main loop, see
+ * @ref Ecore_Main_Loop_Page.
+ *
+ * @{
+ */
#define ECORE_VERSION_MAJOR 1
#define ECORE_VERSION_MINOR 0
- typedef struct _Ecore_Version
- {
- int major;
- int minor;
- int micro;
- int revision;
- } Ecore_Version;
+typedef struct _Ecore_Version
+{
+ int major;
+ int minor;
+ int micro;
+ int revision;
+} Ecore_Version;
- EAPI extern Ecore_Version *ecore_version;
+EAPI extern Ecore_Version *ecore_version;
-#define ECORE_CALLBACK_CANCEL EINA_FALSE /**< Return value to remove a callback */
-#define ECORE_CALLBACK_RENEW EINA_TRUE /**< Return value to keep a callback */
+#define ECORE_CALLBACK_CANCEL EINA_FALSE /**< Return value to remove a callback */
+#define ECORE_CALLBACK_RENEW EINA_TRUE /**< Return value to keep a callback */
#define ECORE_CALLBACK_PASS_ON EINA_TRUE /**< Return value to pass event to next handler */
-#define ECORE_CALLBACK_DONE EINA_FALSE /**< Return value to stop event handling */
-
- /**
- * @typedef Ecore_Task_Cb Ecore_Task_Cb
- * A callback run for a task (timer, idler, poller, animator, etc)
- */
- typedef Eina_Bool (*Ecore_Task_Cb) (void *data);
-
- /**
- * @typedef Ecore_Eselect_Function Ecore_Eselect_Function
- * A function which can be used to replace select() in the main loop
- */
- typedef int (*Ecore_Select_Function)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
-
- EAPI void ecore_main_loop_iterate(void);
-
- EAPI void ecore_main_loop_select_func_set(Ecore_Select_Function func);
- EAPI Ecore_Select_Function ecore_main_loop_select_func_get(void);
-
- EAPI Eina_Bool ecore_main_loop_glib_integrate(void);
- EAPI void ecore_main_loop_glib_always_integrate_disable(void);
-
- EAPI void ecore_main_loop_begin(void);
- EAPI void ecore_main_loop_quit(void);
-
- /**
- * @typedef Ecore_Cb Ecore_Cb
- * A generic callback called as a hook when a certain point in
- * execution is reached.
- */
- typedef void (*Ecore_Cb) (void *data);
-
- /**
- * @typedef Ecore_Data_Cb Ecore_Data_Cb
- * A callback which is used to return data to the main function
- */
- typedef void *(*Ecore_Data_Cb) (void *data);
-
- /**
- * @brief Call callback asynchronously in the main loop.
- * @since 1.1.0
- *
- * @param callback The callback to call in the main loop
- * @param data The data to give to that call back
- *
- * For all calls that need to happen in the main loop (most EFL functions do),
- * this helper function provides the infrastructure needed to do it safely
- * by avoiding dead lock, race condition and properly wake up the main loop.
- *
- * Remember after that function call, you should never touch again the @p data
- * in the thread, it is owned by the main loop and your callback should take
- * care of freeing it if necessary.
- */
- EAPI void ecore_main_loop_thread_safe_call_async(Ecore_Cb callback, void *data);
-
- /**
- * @brief Call callback synchronously in the main loop.
- * @since 1.1.0
- *
- * @param callback The callback to call in the main loop
- * @param data The data to give to that call back
- * @return the value returned by the callback in the main loop
- *
- * For all calls that need to happen in the main loop (most EFL functions do),
- * this helper function provides the infrastructure needed to do it safely
- * by avoiding dead lock, race condition and properly wake up the main loop.
- *
- * Remember this function will block until the callback is executed in the
- * main loop. It can take time and you have no guaranty about the timeline.
- */
- EAPI void *ecore_main_loop_thread_safe_call_sync(Ecore_Data_Cb callback, void *data);
-
- /**
- * @brief This function suspend the main loop in a know state
- * @since 1.1.0
- *
- * @result the number of time ecore_thread_main_loop_begin() has been called
- * in this thread, if the main loop was suspended correctly. If not, it return @c -1.
- *
- * This function suspend the main loop in a know state, this let you
- * use any EFL call you want after it return. Be carefull, the main loop
- * is blocked until you call ecore_thread_main_loop_end(). This is
- * the only sane way to achieve pseudo thread safety.
- *
- * Notice that until the main loop is blocked, the thread is blocked
- * and their is noway around that.
- *
- * We still advise you, when possible, to use ecore_main_loop_thread_safe_call_async()
- * as it will not block the thread nor the main loop.
- */
- EAPI int ecore_thread_main_loop_begin(void);
-
- /**
- * @brief Unlock the main loop.
- * @since 1.1.0
- *
- * @result the number of time ecore_thread_main_loop_end() need to be called before
- * the main loop is unlocked again. @c -1 will be returned if you are trying to unlock
- * when there wasn't enough call to ecore_thread_main_loop_begin().
- *
- * After a call to ecore_thread_main_loop_begin(), you need to absolutly
- * call ecore_thread_main_loop_end(), or you application will stay frozen.
- */
- EAPI int ecore_thread_main_loop_end(void);
-
- /**
- * @}
- */
-
- /**
- * @defgroup Ecore_Event_Group Ecore Event functions
- *
- * Ecore events are used to wake up the Ecore main loop to warn
- * about state changes, tasks completed, data available for reading
- * or writing, etc. They are the base of the event oriented
- * programming.
- *
- * The idea is to write many functions (callbacks) that will be
- * registered to specific events, and called when these events
- * happen. This way, when the system state changes (a mouse click is
- * detected, a key is pressed, or the content of a file changes, for
- * example), the respective callbacks will be called with some
- * information about that event. Usually the function/callback will
- * have a data pointer to the event info (the position in the screen
- * where the mouse was clicked, the name of the key that was
- * pressed, or the name of the file that has changed).
- *
- * The basic usage, when one needs to watch for an existing event,
- * is to register a callback to it using ecore_event_add(). Of
- * course it's necessary to know beforehand what are the types of
- * events that the system/library will emmit. This should be
- * available with the documentation from that system/library.
- *
- * When writing a library or group of functions that need to inform
- * about something, and you already are running on top of a main
- * loop, it is usually a good approach to use events. This way you
- * allow others to register as many callbacks as necessary to this
- * event, and don't have to care about who is registering to it. The
- * functions ecore_event_type_new() and ecore_event_add() are
- * available for this purpose.
- *
- * Example that deals with events:
- *
- * @li @ref ecore_event_example_c
- *
- * @ingroup Ecore_Main_Loop_Group
- *
- * @{
- */
+#define ECORE_CALLBACK_DONE EINA_FALSE /**< Return value to stop event handling */
+
+/**
+ * @typedef Ecore_Task_Cb Ecore_Task_Cb
+ * A callback run for a task (timer, idler, poller, animator, etc)
+ */
+typedef Eina_Bool (*Ecore_Task_Cb)(void *data);
+
+/**
+ * @typedef Ecore_Eselect_Function Ecore_Eselect_Function
+ * A function which can be used to replace select() in the main loop
+ */
+typedef int (*Ecore_Select_Function)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
+
+EAPI void
+ecore_main_loop_iterate(void);
+
+EAPI void
+ ecore_main_loop_select_func_set(Ecore_Select_Function func);
+EAPI Ecore_Select_Function
+ ecore_main_loop_select_func_get(void);
+
+EAPI Eina_Bool
+ ecore_main_loop_glib_integrate(void);
+EAPI void
+ ecore_main_loop_glib_always_integrate_disable(void);
+
+EAPI void
+ ecore_main_loop_begin(void);
+EAPI void
+ ecore_main_loop_quit(void);
+
+/**
+ * @typedef Ecore_Cb Ecore_Cb
+ * A generic callback called as a hook when a certain point in
+ * execution is reached.
+ */
+typedef void (*Ecore_Cb)(void *data);
+
+/**
+ * @typedef Ecore_Data_Cb Ecore_Data_Cb
+ * A callback which is used to return data to the main function
+ */
+typedef void *(*Ecore_Data_Cb)(void *data);
+
+/**
+ * @brief Call callback asynchronously in the main loop.
+ * @since 1.1.0
+ *
+ * @param callback The callback to call in the main loop
+ * @param data The data to give to that call back
+ *
+ * For all calls that need to happen in the main loop (most EFL functions do),
+ * this helper function provides the infrastructure needed to do it safely
+ * by avoiding dead lock, race condition and properly wake up the main loop.
+ *
+ * Remember after that function call, you should never touch again the @p data
+ * in the thread, it is owned by the main loop and your callback should take
+ * care of freeing it if necessary.
+ */
+EAPI void
+ecore_main_loop_thread_safe_call_async(Ecore_Cb callback,
+ void *data);
+
+/**
+ * @brief Call callback synchronously in the main loop.
+ * @since 1.1.0
+ *
+ * @param callback The callback to call in the main loop
+ * @param data The data to give to that call back
+ * @return the value returned by the callback in the main loop
+ *
+ * For all calls that need to happen in the main loop (most EFL functions do),
+ * this helper function provides the infrastructure needed to do it safely
+ * by avoiding dead lock, race condition and properly wake up the main loop.
+ *
+ * Remember this function will block until the callback is executed in the
+ * main loop. It can take time and you have no guaranty about the timeline.
+ */
+EAPI void *
+ecore_main_loop_thread_safe_call_sync(Ecore_Data_Cb callback,
+ void *data);
+
+/**
+ * @brief This function suspend the main loop in a know state
+ * @since 1.1.0
+ *
+ * @result the number of time ecore_thread_main_loop_begin() has been called
+ * in this thread, if the main loop was suspended correctly. If not, it return @c -1.
+ *
+ * This function suspend the main loop in a know state, this let you
+ * use any EFL call you want after it return. Be carefull, the main loop
+ * is blocked until you call ecore_thread_main_loop_end(). This is
+ * the only sane way to achieve pseudo thread safety.
+ *
+ * Notice that until the main loop is blocked, the thread is blocked
+ * and their is noway around that.
+ *
+ * We still advise you, when possible, to use ecore_main_loop_thread_safe_call_async()
+ * as it will not block the thread nor the main loop.
+ */
+EAPI int
+ecore_thread_main_loop_begin(void);
+
+/**
+ * @brief Unlock the main loop.
+ * @since 1.1.0
+ *
+ * @result the number of time ecore_thread_main_loop_end() need to be called before
+ * the main loop is unlocked again. @c -1 will be returned if you are trying to unlock
+ * when there wasn't enough call to ecore_thread_main_loop_begin().
+ *
+ * After a call to ecore_thread_main_loop_begin(), you need to absolutly
+ * call ecore_thread_main_loop_end(), or you application will stay frozen.
+ */
+EAPI int
+ecore_thread_main_loop_end(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Ecore_Event_Group Ecore Event functions
+ *
+ * Ecore events are used to wake up the Ecore main loop to warn
+ * about state changes, tasks completed, data available for reading
+ * or writing, etc. They are the base of the event oriented
+ * programming.
+ *
+ * The idea is to write many functions (callbacks) that will be
+ * registered to specific events, and called when these events
+ * happen. This way, when the system state changes (a mouse click is
+ * detected, a key is pressed, or the content of a file changes, for
+ * example), the respective callbacks will be called with some
+ * information about that event. Usually the function/callback will
+ * have a data pointer to the event info (the position in the screen
+ * where the mouse was clicked, the name of the key that was
+ * pressed, or the name of the file that has changed).
+ *
+ * The basic usage, when one needs to watch for an existing event,
+ * is to register a callback to it using ecore_event_add(). Of
+ * course it's necessary to know beforehand what are the types of
+ * events that the system/library will emmit. This should be
+ * available with the documentation from that system/library.
+ *
+ * When writing a library or group of functions that need to inform
+ * about something, and you already are running on top of a main
+ * loop, it is usually a good approach to use events. This way you
+ * allow others to register as many callbacks as necessary to this
+ * event, and don't have to care about who is registering to it. The
+ * functions ecore_event_type_new() and ecore_event_add() are
+ * available for this purpose.
+ *
+ * Example that deals with events:
+ *
+ * @li @ref ecore_event_example_c
+ *
+ * @ingroup Ecore_Main_Loop_Group
+ *
+ * @{
+ */
#define ECORE_EVENT_NONE 0
#define ECORE_EVENT_SIGNAL_USER 1 /**< User signal event */
#define ECORE_EVENT_SIGNAL_REALTIME 5 /**< Realtime signal event */
#define ECORE_EVENT_COUNT 6
- typedef struct _Ecore_Win32_Handler Ecore_Win32_Handler; /**< A handle for HANDLE handlers on Windows */
- typedef struct _Ecore_Event_Handler Ecore_Event_Handler; /**< A handle for an event handler */
- typedef struct _Ecore_Event_Filter Ecore_Event_Filter; /**< A handle for an event filter */
- typedef struct _Ecore_Event Ecore_Event; /**< A handle for an event */
- typedef struct _Ecore_Event_Signal_User Ecore_Event_Signal_User; /**< User signal event */
- typedef struct _Ecore_Event_Signal_Hup Ecore_Event_Signal_Hup; /**< Hup signal event */
- typedef struct _Ecore_Event_Signal_Exit Ecore_Event_Signal_Exit; /**< Exit signal event */
- typedef struct _Ecore_Event_Signal_Power Ecore_Event_Signal_Power; /**< Power signal event */
- typedef struct _Ecore_Event_Signal_Realtime Ecore_Event_Signal_Realtime; /**< Realtime signal event */
-
- /**
- * @typedef Ecore_Filter_Cb
- * A callback used for filtering events from the main loop.
- */
- typedef Eina_Bool (*Ecore_Filter_Cb) (void *data, void *loop_data, int type, void *event);
-
- /**
- * @typedef Ecore_End_Cb Ecore_End_Cb
- * This is the callback which is called at the end of a function,
- * usually for cleanup purposes.
- */
- typedef void (*Ecore_End_Cb) (void *user_data, void *func_data);
-
- /**
- * @typedef Ecore_Event_Handler_Cb Ecore_Event_Handler_Cb
- * A callback used by the main loop to handle events of a specified
- * type.
- */
- typedef Eina_Bool (*Ecore_Event_Handler_Cb) (void *data, int type, void *event);
-
- struct _Ecore_Event_Signal_User /** User signal event */
- {
- int number; /**< The signal number. Either 1 or 2 */
- void *ext_data; /**< Extension data - not used */
+typedef struct _Ecore_Win32_Handler Ecore_Win32_Handler; /**< A handle for HANDLE handlers on Windows */
+typedef struct _Ecore_Event_Handler Ecore_Event_Handler; /**< A handle for an event handler */
+typedef struct _Ecore_Event_Filter Ecore_Event_Filter; /**< A handle for an event filter */
+typedef struct _Ecore_Event Ecore_Event; /**< A handle for an event */
+typedef struct _Ecore_Event_Signal_User Ecore_Event_Signal_User; /**< User signal event */
+typedef struct _Ecore_Event_Signal_Hup Ecore_Event_Signal_Hup; /**< Hup signal event */
+typedef struct _Ecore_Event_Signal_Exit Ecore_Event_Signal_Exit; /**< Exit signal event */
+typedef struct _Ecore_Event_Signal_Power Ecore_Event_Signal_Power; /**< Power signal event */
+typedef struct _Ecore_Event_Signal_Realtime Ecore_Event_Signal_Realtime; /**< Realtime signal event */
+
+/**
+ * @typedef Ecore_Filter_Cb
+ * A callback used for filtering events from the main loop.
+ */
+typedef Eina_Bool (*Ecore_Filter_Cb)(void *data, void *loop_data, int type, void *event);
+
+/**
+ * @typedef Ecore_End_Cb Ecore_End_Cb
+ * This is the callback which is called at the end of a function,
+ * usually for cleanup purposes.
+ */
+typedef void (*Ecore_End_Cb)(void *user_data, void *func_data);
+
+/**
+ * @typedef Ecore_Event_Handler_Cb Ecore_Event_Handler_Cb
+ * A callback used by the main loop to handle events of a specified
+ * type.
+ */
+typedef Eina_Bool (*Ecore_Event_Handler_Cb)(void *data, int type, void *event);
+
+struct _Ecore_Event_Signal_User /** User signal event */
+{
+ int number; /**< The signal number. Either 1 or 2 */
+ void *ext_data; /**< Extension data - not used */
#if !defined (_WIN32) && !defined (__lv2ppu__)
- siginfo_t data; /**< Signal info */
+ siginfo_t data; /**< Signal info */
#endif
- };
+};
- struct _Ecore_Event_Signal_Hup /** Hup signal event */
- {
- void *ext_data; /**< Extension data - not used */
+struct _Ecore_Event_Signal_Hup /** Hup signal event */
+{
+ void *ext_data; /**< Extension data - not used */
#if !defined (_WIN32) && !defined (__lv2ppu__)
- siginfo_t data; /**< Signal info */
+ siginfo_t data; /**< Signal info */
#endif
- };
+};
- struct _Ecore_Event_Signal_Exit /** Exit request event */
- {
- Eina_Bool interrupt : 1; /**< Set if the exit request was an interrupt signal*/
- Eina_Bool quit : 1; /**< set if the exit request was a quit signal */
- Eina_Bool terminate : 1; /**< Set if the exit request was a terminate singal */
- void *ext_data; /**< Extension data - not used */
+struct _Ecore_Event_Signal_Exit /** Exit request event */
+{
+ Eina_Bool interrupt : 1; /**< Set if the exit request was an interrupt signal*/
+ Eina_Bool quit : 1; /**< set if the exit request was a quit signal */
+ Eina_Bool terminate : 1; /**< Set if the exit request was a terminate singal */
+ void *ext_data; /**< Extension data - not used */
#if !defined (_WIN32) && !defined (__lv2ppu__)
- siginfo_t data; /**< Signal info */
+ siginfo_t data; /**< Signal info */
#endif
- };
+};
- struct _Ecore_Event_Signal_Power /** Power event */
- {
- void *ext_data; /**< Extension data - not used */
+struct _Ecore_Event_Signal_Power /** Power event */
+{
+ void *ext_data; /**< Extension data - not used */
#if !defined (_WIN32) && !defined (__lv2ppu__)
- siginfo_t data; /**< Signal info */
+ siginfo_t data; /**< Signal info */
#endif
- };
+};
- struct _Ecore_Event_Signal_Realtime /** Realtime event */
- {
- int num; /**< The realtime signal's number */
+struct _Ecore_Event_Signal_Realtime /** Realtime event */
+{
+ int num; /**< The realtime signal's number */
#if !defined (_WIN32) && !defined (__lv2ppu__)
- siginfo_t data; /**< Signal info */
+ siginfo_t data; /**< Signal info */
#endif
- };
-
- EAPI Ecore_Event_Handler *ecore_event_handler_add(int type, Ecore_Event_Handler_Cb func, const void *data);
- EAPI void *ecore_event_handler_del(Ecore_Event_Handler *event_handler);
- EAPI Ecore_Event *ecore_event_add(int type, void *ev, Ecore_End_Cb func_free, void *data);
- EAPI void *ecore_event_del(Ecore_Event *event);
- EAPI void *ecore_event_handler_data_get(Ecore_Event_Handler *eh);
- EAPI void *ecore_event_handler_data_set(Ecore_Event_Handler *eh, const void *data);
- EAPI int ecore_event_type_new(void);
- 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);
- EAPI void *ecore_event_filter_del(Ecore_Event_Filter *ef);
- EAPI int ecore_event_current_type_get(void);
- EAPI void *ecore_event_current_event_get(void);
-
- /**
- * @}
- */
-
- /**
- * @defgroup Ecore_Exe_Group Process Spawning Functions
- *
- * Functions that deal with and send signals to spawned processes.
- *
- * @ingroup Ecore_Main_Loop_Group
- *
- * @{
- */
+};
+
+EAPI Ecore_Event_Handler *
+ecore_event_handler_add(int type,
+ Ecore_Event_Handler_Cb func,
+ const void *data);
+EAPI void *
+ ecore_event_handler_del(Ecore_Event_Handler *event_handler);
+EAPI Ecore_Event *
+ ecore_event_add(int type,
+ void *ev,
+ Ecore_End_Cb func_free,
+ void *data);
+EAPI void *
+ ecore_event_del(Ecore_Event *event);
+EAPI void *
+ ecore_event_handler_data_get(Ecore_Event_Handler *eh);
+EAPI void *
+ ecore_event_handler_data_set(Ecore_Event_Handler *eh,
+ const void *data);
+EAPI int
+ ecore_event_type_new(void);
+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);
+EAPI void *
+ ecore_event_filter_del(Ecore_Event_Filter *ef);
+EAPI int
+ ecore_event_current_type_get(void);
+EAPI void *
+ ecore_event_current_event_get(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Ecore_Exe_Group Process Spawning Functions
+ *
+ * Functions that deal with and send signals to spawned processes.
+ *
+ * @ingroup Ecore_Main_Loop_Group
+ *
+ * @{
+ */
#define ECORE_EXE_PRIORITY_INHERIT 9999
- EAPI extern int ECORE_EXE_EVENT_ADD; /**< A child process has been added */
- EAPI extern int ECORE_EXE_EVENT_DEL; /**< A child process has been deleted (it exited, naming consistent with the rest of ecore). */
- EAPI extern int ECORE_EXE_EVENT_DATA; /**< Data from a child process. */
- EAPI extern int ECORE_EXE_EVENT_ERROR; /**< Errors from a child process. */
-
- enum _Ecore_Exe_Flags /* flags for executing a child with its stdin and/or stdout piped back */
- {
- ECORE_EXE_NONE = 0, /**< No exe flags at all */
- ECORE_EXE_PIPE_READ = 1, /**< Exe Pipe Read mask */
- ECORE_EXE_PIPE_WRITE = 2, /**< Exe Pipe Write mask */
- ECORE_EXE_PIPE_ERROR = 4, /**< Exe Pipe error mask */
- ECORE_EXE_PIPE_READ_LINE_BUFFERED = 8, /**< Reads are buffered until a newline and split 1 line per Ecore_Exe_Event_Data_Line */
- ECORE_EXE_PIPE_ERROR_LINE_BUFFERED = 16, /**< Errors are buffered until a newline and split 1 line per Ecore_Exe_Event_Data_Line */
- ECORE_EXE_PIPE_AUTO = 32, /**< stdout and stderr are buffered automatically */
- ECORE_EXE_RESPAWN = 64, /**< FIXME: Exe is restarted if it dies */
- ECORE_EXE_USE_SH = 128, /**< Use /bin/sh to run the command. */
- ECORE_EXE_NOT_LEADER = 256, /**< Do not use setsid() to have the executed process be its own session leader */
- ECORE_EXE_TERM_WITH_PARENT = 512 /**< Makes child receive SIGTERM when parent dies. */
- };
- typedef enum _Ecore_Exe_Flags Ecore_Exe_Flags;
-
- enum _Ecore_Exe_Win32_Priority
- {
- ECORE_EXE_WIN32_PRIORITY_IDLE, /**< Idle priority, for monitoring the system */
- ECORE_EXE_WIN32_PRIORITY_BELOW_NORMAL, /**< Below default priority */
- ECORE_EXE_WIN32_PRIORITY_NORMAL, /**< Default priority */
- ECORE_EXE_WIN32_PRIORITY_ABOVE_NORMAL, /**< Above default priority */
- ECORE_EXE_WIN32_PRIORITY_HIGH, /**< High priority, use with care as other threads in the system will not get processor time */
- ECORE_EXE_WIN32_PRIORITY_REALTIME /**< Realtime priority, should be almost never used as it can interrupt system threads that manage mouse input, keyboard input, and background disk flushing */
- };
- typedef enum _Ecore_Exe_Win32_Priority Ecore_Exe_Win32_Priority;
-
- typedef struct _Ecore_Exe Ecore_Exe; /**< A handle for spawned processes */
-
- /**
- * @typedef Ecore_Exe_Cb Ecore_Exe_Cb
- * A callback to run with the associated @ref Ecore_Exe, usually
- * for cleanup purposes.
- */
- typedef void (*Ecore_Exe_Cb)(void *data, const Ecore_Exe *exe);
-
- typedef struct _Ecore_Exe_Event_Add Ecore_Exe_Event_Add; /**< Spawned Exe add event */
- typedef struct _Ecore_Exe_Event_Del Ecore_Exe_Event_Del; /**< Spawned Exe exit event */
- typedef struct _Ecore_Exe_Event_Data_Line Ecore_Exe_Event_Data_Line; /**< Lines from a child process */
- typedef struct _Ecore_Exe_Event_Data Ecore_Exe_Event_Data; /**< Data from a child process */
-
- struct _Ecore_Exe_Event_Add /** Process add event */
- {
- Ecore_Exe *exe; /**< The handle to the added process */
- void *ext_data; /**< Extension data - not used */
- };
-
- struct _Ecore_Exe_Event_Del /** Process exit event */
- {
- pid_t pid; /**< The process ID of the process that exited */
- int exit_code; /**< The exit code of the process */
- Ecore_Exe *exe; /**< The handle to the exited process, or NULL if not found */
- int exit_signal; /** < The signal that caused the process to exit */
- Eina_Bool exited : 1; /** < set to 1 if the process exited of its own accord */
- Eina_Bool signalled : 1; /** < set to 1 id the process exited due to uncaught signal */
- void *ext_data; /**< Extension data - not used */
+EAPI extern int ECORE_EXE_EVENT_ADD; /**< A child process has been added */
+EAPI extern int ECORE_EXE_EVENT_DEL; /**< A child process has been deleted (it exited, naming consistent with the rest of ecore). */
+EAPI extern int ECORE_EXE_EVENT_DATA; /**< Data from a child process. */
+EAPI extern int ECORE_EXE_EVENT_ERROR; /**< Errors from a child process. */
+
+enum _Ecore_Exe_Flags /* flags for executing a child with its stdin and/or stdout piped back */
+{
+ ECORE_EXE_NONE = 0, /**< No exe flags at all */
+ ECORE_EXE_PIPE_READ = 1, /**< Exe Pipe Read mask */
+ ECORE_EXE_PIPE_WRITE = 2, /**< Exe Pipe Write mask */
+ ECORE_EXE_PIPE_ERROR = 4, /**< Exe Pipe error mask */
+ ECORE_EXE_PIPE_READ_LINE_BUFFERED = 8, /**< Reads are buffered until a newline and split 1 line per Ecore_Exe_Event_Data_Line */
+ ECORE_EXE_PIPE_ERROR_LINE_BUFFERED = 16, /**< Errors are buffered until a newline and split 1 line per Ecore_Exe_Event_Data_Line */
+ ECORE_EXE_PIPE_AUTO = 32, /**< stdout and stderr are buffered automatically */
+ ECORE_EXE_RESPAWN = 64, /**< FIXME: Exe is restarted if it dies */
+ ECORE_EXE_USE_SH = 128, /**< Use /bin/sh to run the command. */
+ ECORE_EXE_NOT_LEADER = 256, /**< Do not use setsid() to have the executed process be its own session leader */
+ ECORE_EXE_TERM_WITH_PARENT = 512 /**< Makes child receive SIGTERM when parent dies. */
+};
+typedef enum _Ecore_Exe_Flags Ecore_Exe_Flags;
+
+enum _Ecore_Exe_Win32_Priority
+{
+ ECORE_EXE_WIN32_PRIORITY_IDLE, /**< Idle priority, for monitoring the system */
+ ECORE_EXE_WIN32_PRIORITY_BELOW_NORMAL, /**< Below default priority */
+ ECORE_EXE_WIN32_PRIORITY_NORMAL, /**< Default priority */
+ ECORE_EXE_WIN32_PRIORITY_ABOVE_NORMAL, /**< Above default priority */
+ ECORE_EXE_WIN32_PRIORITY_HIGH, /**< High priority, use with care as other threads in the system will not get processor time */
+ ECORE_EXE_WIN32_PRIORITY_REALTIME /**< Realtime priority, should be almost never used as it can interrupt system threads that manage mouse input, keyboard input, and background disk flushing */
+};
+typedef enum _Ecore_Exe_Win32_Priority Ecore_Exe_Win32_Priority;
+
+typedef struct _Ecore_Exe Ecore_Exe; /**< A handle for spawned processes */
+
+/**
+ * @typedef Ecore_Exe_Cb Ecore_Exe_Cb
+ * A callback to run with the associated @ref Ecore_Exe, usually
+ * for cleanup purposes.
+ */
+typedef void (*Ecore_Exe_Cb)(void *data, const Ecore_Exe *exe);
+
+typedef struct _Ecore_Exe_Event_Add Ecore_Exe_Event_Add; /**< Spawned Exe add event */
+typedef struct _Ecore_Exe_Event_Del Ecore_Exe_Event_Del; /**< Spawned Exe exit event */
+typedef struct _Ecore_Exe_Event_Data_Line Ecore_Exe_Event_Data_Line; /**< Lines from a child process */
+typedef struct _Ecore_Exe_Event_Data Ecore_Exe_Event_Data; /**< Data from a child process */
+
+struct _Ecore_Exe_Event_Add /** Process add event */
+{
+ Ecore_Exe *exe; /**< The handle to the added process */
+ void *ext_data; /**< Extension data - not used */
+};
+
+struct _Ecore_Exe_Event_Del /** Process exit event */
+{
+ pid_t pid; /**< The process ID of the process that exited */
+ int exit_code; /**< The exit code of the process */
+ Ecore_Exe *exe; /**< The handle to the exited process, or NULL if not found */
+ int exit_signal; /** < The signal that caused the process to exit */
+ Eina_Bool exited : 1; /** < set to 1 if the process exited of its own accord */
+ Eina_Bool signalled : 1; /** < set to 1 id the process exited due to uncaught signal */
+ void *ext_data; /**< Extension data - not used */
#if !defined (_WIN32) && !defined (__lv2ppu__)
- siginfo_t data; /**< Signal info */
+ siginfo_t data; /**< Signal info */
#endif
- };
-
- struct _Ecore_Exe_Event_Data_Line /**< Lines from a child process */
- {
- char *line;
- int size;
- };
-
- struct _Ecore_Exe_Event_Data /** Data from a child process event */
- {
- Ecore_Exe *exe; /**< The handle to the process */
- void *data; /**< the raw binary data from the child process that was received */
- int size; /**< the size of this data in bytes */
- Ecore_Exe_Event_Data_Line *lines; /**< an array of line data if line buffered, the last one has it's line member set to NULL */
- };
-
- EAPI void ecore_exe_run_priority_set(int pri);
- EAPI int ecore_exe_run_priority_get(void);
- EAPI Ecore_Exe *ecore_exe_run(const char *exe_cmd, const void *data);
- EAPI Ecore_Exe *ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, const void *data);
- EAPI void ecore_exe_callback_pre_free_set(Ecore_Exe *exe, Ecore_Exe_Cb func);
- EAPI Eina_Bool ecore_exe_send(Ecore_Exe *exe, const void *data, int size);
- EAPI void ecore_exe_close_stdin(Ecore_Exe *exe);
- EAPI void ecore_exe_auto_limits_set(Ecore_Exe *exe, int start_bytes, int end_bytes, int start_lines, int end_lines);
- EAPI Ecore_Exe_Event_Data *ecore_exe_event_data_get(Ecore_Exe *exe, Ecore_Exe_Flags flags);
- EAPI void ecore_exe_event_data_free(Ecore_Exe_Event_Data *data);
- EAPI void *ecore_exe_free(Ecore_Exe *exe);
- EAPI pid_t ecore_exe_pid_get(const Ecore_Exe *exe);
- EAPI void ecore_exe_tag_set(Ecore_Exe *exe, const char *tag);
- EAPI const char *ecore_exe_tag_get(const Ecore_Exe *exe);
- EAPI const char *ecore_exe_cmd_get(const Ecore_Exe *exe);
- EAPI void *ecore_exe_data_get(const Ecore_Exe *exe);
- EAPI void *ecore_exe_data_set(Ecore_Exe *exe, void *data);
- EAPI Ecore_Exe_Flags ecore_exe_flags_get(const Ecore_Exe *exe);
- EAPI void ecore_exe_pause(Ecore_Exe *exe);
- EAPI void ecore_exe_continue(Ecore_Exe *exe);
- EAPI void ecore_exe_interrupt(Ecore_Exe *exe);
- EAPI void ecore_exe_quit(Ecore_Exe *exe);
- EAPI void ecore_exe_terminate(Ecore_Exe *exe);
- EAPI void ecore_exe_kill(Ecore_Exe *exe);
- EAPI void ecore_exe_signal(Ecore_Exe *exe, int num);
- EAPI void ecore_exe_hup(Ecore_Exe *exe);
-
- /**
- * @}
- */
-
- /**
- * @defgroup Ecore_FD_Handler_Group File Event Handling Functions
- *
- * Functions that deal with file descriptor handlers.
- *
- * The @ref Ecore_Fd_Handler can be used to watch a file descriptor
- * for data available for reading, for the availability to write
- * without blocking, and for errors on the file descriptor.
- *
- * ecore_main_fd_handler_add() is used to setup a handler for a
- * given file descriptor. This file descriptor can be the standard
- * input, a network socket, a stream received through some driver
- * of a hardware decoder, etc. Thus it can contain errors, like a
- * disconnection, a broken pipe, and so, and that's why it's
- * possible to check for these errors with the @ref ECORE_FD_ERROR
- * flag.
- *
- * An @ref Ecore_Fd_Handler can be used to watch on a file
- * descriptor without blocking, still being able to receive events,
- * expire timers, and other watch for other things that happen in
- * the Ecore main loop.
- *
- * Example of use of a file descriptor handler:
- * @li @ref ecore_fd_handler_example_c
- *
- * @ingroup Ecore_Main_Loop_Group
- *
- * @{
- */
-
- typedef struct _Ecore_Fd_Handler Ecore_Fd_Handler; /**< A handle for Fd handlers */
-
- enum _Ecore_Fd_Handler_Flags
- {
- ECORE_FD_READ = 1, /**< Fd Read mask */
- ECORE_FD_WRITE = 2, /**< Fd Write mask */
- ECORE_FD_ERROR = 4 /**< Fd Error mask */
- };
- typedef enum _Ecore_Fd_Handler_Flags Ecore_Fd_Handler_Flags;
-
- /**
- * @typedef Ecore_Fd_Cb Ecore_Fd_Cb
- * A callback used by an @ref Ecore_Fd_Handler.
- */
- typedef Eina_Bool (*Ecore_Fd_Cb) (void *data, Ecore_Fd_Handler *fd_handler);
-
- /**
- * @typedef Ecore_Fd_Prep_Cb Ecore_Fd_Prep_Cb
- * A callback used by an @ref Ecore_Fd_Handler.
- */
- typedef void (*Ecore_Fd_Prep_Cb) (void *data, Ecore_Fd_Handler *fd_handler);
-
- /**
- * @typedef Ecore_Win32_Handle_Cb Ecore_Win32_Handle_Cb
- * A callback used by an @ref Ecore_Win32_Handler.
- */
- typedef Eina_Bool (*Ecore_Win32_Handle_Cb) (void *data, Ecore_Win32_Handler *wh);
-
- 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);
- EAPI void ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Prep_Cb func, const void *data);
- EAPI void *ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler);
- EAPI int ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler);
- EAPI Eina_Bool ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags);
- EAPI void ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags);
-
- EAPI Ecore_Win32_Handler *ecore_main_win32_handler_add(void *h, Ecore_Win32_Handle_Cb func, const void *data);
- EAPI void *ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler);
-
- /**
- * @}
- */
-
- /**
- * @defgroup Ecore_Poller_Group Ecore Poll functions
- *
- * These functions are for the need to poll information, but provide
- * a shared abstracted API to pool such polling to minimise wakeup
- * and ensure all the polling happens in as few spots as possible
- * areound a core poll interval. For now only 1 core poller type is
- * supprted: ECORE_POLLER_CORE
- *
- * Example of @ref Ecore_Poller:
- * @li @ref ecore_poller_example_c
- *
- * @ingroup Ecore_Main_Loop_Group
- *
- * @{
- */
-
- enum _Ecore_Poller_Type /* Poller types */
- {
- ECORE_POLLER_CORE = 0 /**< The core poller interval */
- };
- typedef enum _Ecore_Poller_Type Ecore_Poller_Type;
-
- typedef struct _Ecore_Poller Ecore_Poller; /**< A handle for pollers */
-
- EAPI void ecore_poller_poll_interval_set(Ecore_Poller_Type type, double poll_time);
- EAPI double ecore_poller_poll_interval_get(Ecore_Poller_Type type);
- EAPI Eina_Bool ecore_poller_poller_interval_set(Ecore_Poller *poller, int interval);
- EAPI int ecore_poller_poller_interval_get(Ecore_Poller *poller);
- EAPI Ecore_Poller *ecore_poller_add(Ecore_Poller_Type type, int interval, Ecore_Task_Cb func, const void *data);
- EAPI void *ecore_poller_del(Ecore_Poller *poller);
-
- /**
- * @}
- */
-
- /**
- * @defgroup Ecore_Animator_Group Ecore Animator functions
- *
- * @brief Ecore animators are a helper to simplify creating
- * animations.
- *
- * Creating an animation is as simple as saying for how long it
- * should be run and having a callback that does the animation,
- * something like this:
- * @code
- * static Eina_Bool
- * _do_animation(void *data, double pos)
- * {
- * evas_object_move(data, 100 * pos, 100 * pos);
- * ... do some more animating ...
- * }
- * ...
- * ecore_animator_timeline_add(2, _do_animation, my_evas_object);
- * @endcode
- * In the sample above we create an animation to move
- * @c my_evas_object from position (0,0) to (100,100) in 2 seconds.
- *
- * If your animation will run for an unspecified amount of time you
- * can use ecore_animator_add(), which is like using
- * ecore_timer_add() with the interval being the
- * @ref ecore_animator_frametime_set "framerate". Note that this has
- * tangible benefits to creating a timer for each animation in terms
- * of performance.
- *
- * For a more detailed example that show several animation see
- * @ref tutorial_ecore_animator.
- *
- * @ingroup Ecore_Main_Loop_Group
- *
- * @{
- */
-
- typedef struct _Ecore_Animator Ecore_Animator; /**< A handle for animators */
-
- enum _Ecore_Pos_Map /* Position mappings */
- {
- ECORE_POS_MAP_LINEAR, /**< Linear 0.0 -> 1.0 */
- ECORE_POS_MAP_ACCELERATE, /**< Start slow then speed up */
- ECORE_POS_MAP_DECELERATE, /**< Start fast then slow down */
- ECORE_POS_MAP_SINUSOIDAL, /**< Start slow, speed up then slow down at end */
- ECORE_POS_MAP_ACCELERATE_FACTOR, /**< Start slow then speed up, v1 being a power factor, 0.0 being linear, 1.0 being normal accelerate, 2.0 being much more pronounced accelerate (squared), 3.0 being cubed, etc. */
- ECORE_POS_MAP_DECELERATE_FACTOR, /**< Start fast then slow down, v1 being a power factor, 0.0 being linear, 1.0 being normal decelerate, 2.0 being much more pronounced decelerate (squared), 3.0 being cubed, etc. */
- ECORE_POS_MAP_SINUSOIDAL_FACTOR, /**< Start slow, speed up then slow down at end, v1 being a power factor, 0.0 being linear, 1.0 being normal sinusoidal, 2.0 being much more pronounced sinusoidal (squared), 3.0 being cubed, etc. */
- ECORE_POS_MAP_DIVISOR_INTERP, /**< Start at gradient * v1, interpolated via power of v2 curve */
- ECORE_POS_MAP_BOUNCE, /**< Start at 0.0 then "drop" like a ball bouncing to the ground at 1.0, and bounce v2 times, with decay factor of v1 */
- ECORE_POS_MAP_SPRING /**< Start at 0.0 then "wobble" like a spring rest position 1.0, and wobble v2 times, with decay factor of v1 */
- };
- typedef enum _Ecore_Pos_Map Ecore_Pos_Map;
-
- enum _Ecore_Animator_Source /* Timing sources for animators */
- {
- ECORE_ANIMATOR_SOURCE_TIMER, /**< The default system clock/timer based animator that ticks every "frametime" seconds */
- ECORE_ANIMATOR_SOURCE_CUSTOM /**< A custom animator trigger that you need to call ecore_animator_trigger() to make it tick */
- };
- typedef enum _Ecore_Animator_Source Ecore_Animator_Source;
-
- /**
- * @typedef Ecore_Timeline_Cb Ecore_Timeline_Cb
- * A callback run for a task (animators with runtimes)
- */
- typedef Eina_Bool (*Ecore_Timeline_Cb) (void *data, double pos);
-
- /**
- * @brief Add an animator to call @p func at every animaton tick during main
- * loop execution.
- *
- * @param func The function to call when it ticks off
- * @param data The data to pass to the function
- * @return A handle to the new animator
- *
- * This function adds a animator and returns its handle on success and NULL on
- * failure. The function @p func will be called every N seconds where N is the
- * @p frametime interval set by ecore_animator_frametime_set(). The function
- * will be passed the @p data pointer as its parameter.
- *
- * When the animator @p func is called, it must return a value of either 1 or
- * 0. If it returns 1 (or ECORE_CALLBACK_RENEW), it will be called again at
- * the next tick, or if it returns 0 (or ECORE_CALLBACK_CANCEL) it will be
- * deleted automatically making any references/handles for it invalid.
- *
- * @note The default @p frametime value is 1/30th of a second.
- *
- * @see ecore_animator_timeline_add()
- * @see ecore_animator_frametime_set()
- */
- EAPI Ecore_Animator *ecore_animator_add(Ecore_Task_Cb func, const void *data);
- /**
- * @brief Add a animator that runs for a limited time
- *
- * @param runtime The time to run in seconds
- * @param func The function to call when it ticks off
- * @param data The data to pass to the function
- * @return A handle to the new animator
- *
- * This function is just like ecore_animator_add() except the animator only
- * runs for a limited time specified in seconds by @p runtime. Once the
- * runtime the animator has elapsed (animator finished) it will automatically
- * be deleted. The callback function @p func can return ECORE_CALLBACK_RENEW
- * to keep the animator running or ECORE_CALLBACK_CANCEL ro stop it and have
- * it be deleted automatically at any time.
- *
- * The @p func will ALSO be passed a position parameter that will be in value
- * from 0.0 to 1.0 to indicate where along the timeline (0.0 start, 1.0 end)
- * the animator run is at. If the callback wishes not to have a linear
- * transition it can "map" this value to one of several curves and mappings
- * via ecore_animator_pos_map().
- *
- * @note The default @p frametime value is 1/30th of a second.
- *
- * @see ecore_animator_add()
- * @see ecore_animator_pos_map()
- * @since 1.1.0
- */
- EAPI Ecore_Animator *ecore_animator_timeline_add(double runtime, Ecore_Timeline_Cb func, const void *data);
- /**
- * @brief Delete the specified animator from the animator list.
- *
- * @param animator The animator to delete
- * @return The data pointer set for the animator on add
- *
- * Delete the specified @p animator from the set of animators that are
- * executed during main loop execution. This function returns the data
- * parameter that was being passed to the callback on success, or NULL on
- * failure. After this call returns the specified animator object @p animator
- * is invalid and should not be used again. It will not get called again after
- * deletion.
- */
- EAPI void *ecore_animator_del(Ecore_Animator *animator);
- /**
- * @brief Suspend the specified animator.
- *
- * @param animator The animator to delete
- *
- * The specified @p animator will be temporarly removed from the set of
- * animators that are executed during main loop.
- *
- * @warning Freezing an animator doesn't freeze accounting of how long that
- * animator has been running. Therefore if the animator was created with
- * ecore_animator_timeline_add() the @p pos argument given to the callback
- * will increase as if the animator hadn't been frozen and the animator may
- * have it's execution halted if @p runtime elapsed.
- */
- EAPI void ecore_animator_freeze(Ecore_Animator *animator);
- /**
- * @brief Restore execution of the specified animator.
- *
- * @param animator The animator to delete
- *
- * The specified @p animator will be put back in the set of animators that are
- * executed during main loop.
- */
- EAPI void ecore_animator_thaw(Ecore_Animator *animator);
- /**
- * @brief Set the animator call interval in seconds.
- *
- * @param frametime The time in seconds in between animator ticks.
- *
- * This function sets the time interval (in seconds) between animator ticks.
- * At every tick the callback of every existing animator will be called.
- *
- * @warning Too small a value may cause performance issues and too high a
- * value may cause your animation to seem "jerky".
- *
- * @note The default @p frametime value is 1/30th of a second.
- */
- EAPI void ecore_animator_frametime_set(double frametime);
- /**
- * @brief Get the animator call interval in seconds.
- *
- * @return The time in second in between animator ticks.
- *
- * This function retrieves the time in seconds between animator ticks.
- *
- * @see ecore_animator_frametime_set()
- */
- EAPI double ecore_animator_frametime_get(void);
- /**
- * @brief Maps an input position from 0.0 to 1.0 along a timeline to a
- * position in a different curve.
- *
- * @param pos The input position to map
- * @param map The mapping to use
- * @param v1 A parameter use by the mapping (pass 0.0 if not used)
- * @param v2 A parameter use by the mapping (pass 0.0 if not used)
- * @return The mapped value
- *
- * Takes an input position (0.0 to 1.0) and maps to a new position (normally
- * between 0.0 and 1.0, but it may go above/below 0.0 or 1.0 to show that it
- * has "overshot" the mark) using some interpolation (mapping) algorithm.
- *
- * This function useful to create non-linear animations. It offers a variety
- * of possible animaton curves to be used:
- * @li ECORE_POS_MAP_LINEAR - Linear, returns @p pos
- * @li ECORE_POS_MAP_ACCELERATE - Start slow then speed up
- * @li ECORE_POS_MAP_DECELERATE - Start fast then slow down
- * @li ECORE_POS_MAP_SINUSOIDAL - Start slow, speed up then slow down at end
- * @li ECORE_POS_MAP_ACCELERATE_FACTOR - Start slow then speed up, v1 being a
- * power factor, 0.0 being linear, 1.0 being ECORE_POS_MAP_ACCELERATE, 2.0
- * being much more pronounced accelerate (squared), 3.0 being cubed, etc.
- * @li ECORE_POS_MAP_DECELERATE_FACTOR - Start fast then slow down, v1 being a
- * power factor, 0.0 being linear, 1.0 being ECORE_POS_MAP_DECELERATE, 2.0
- * being much more pronounced decelerate (squared), 3.0 being cubed, etc.
- * @li ECORE_POS_MAP_SINUSOIDAL_FACTOR - Start slow, speed up then slow down
- * at end, v1 being a power factor, 0.0 being linear, 1.0 being
- * ECORE_POS_MAP_SINUSOIDAL, 2.0 being much more pronounced sinusoidal
- * (squared), 3.0 being cubed, etc.
- * @li ECORE_POS_MAP_DIVISOR_INTERP - Start at gradient * v1, interpolated via
- * power of v2 curve
- * @li ECORE_POS_MAP_BOUNCE - Start at 0.0 then "drop" like a ball bouncing to
- * the ground at 1.0, and bounce v2 times, with decay factor of v1
- * @li ECORE_POS_MAP_SPRING - Start at 0.0 then "wobble" like a spring rest
- * position 1.0, and wobble v2 times, with decay factor of v1
- * @note When not listed v1 and v2 have no effect.
- *
- * @image html ecore-pos-map.png
- * @image latex ecore-pos-map.eps width=\textwidth
- *
- * One way to use this would be:
- * @code
- * double pos; // input position in a timeline from 0.0 to 1.0
- * double out; // output position after mapping
- * int x1, y1, x2, y2; // x1 & y1 are start position, x2 & y2 are end position
- * int x, y; // x & y are the calculated position
- *
- * out = ecore_animator_pos_map(pos, ECORE_POS_MAP_BOUNCE, 1.8, 7);
- * x = (x1 * out) + (x2 * (1.0 - out));
- * y = (y1 * out) + (y2 * (1.0 - out));
- * move_my_object_to(myobject, x, y);
- * @endcode
- * This will make an animaton that bounces 7 each times diminishing by a
- * factor of 1.8.
- *
- * @see _Ecore_Pos_Map
- *
- * @since 1.1.0
- */
- EAPI double ecore_animator_pos_map(double pos, Ecore_Pos_Map map, double v1, double v2);
- /**
- * @brief Set the source of animator ticks for the mainloop
- *
- * @param source The source of animator ticks to use
- *
- * This sets the source of animator ticks. When an animator is active the
- * mainloop will "tick" over frame by frame calling all animators that are
- * registered until none are. The mainloop will tick at a given rate based
- * on the animator source. The default source is the system clock timer
- * source - ECORE_ANIMATOR_SOURCE_TIMER. This source uses the system clock
- * to tick over every N seconds (specified by ecore_animator_frametime_set(),
- * with the default being 1/30th of a second unless set otherwise). You can
- * set a custom tick source by setting the source to
- * ECORE_ANIMATOR_SOURCE_CUSTOM and then drive it yourself based on some input
- * tick source (like another application via ipc, some vertical blanking
- * interrupt interrupt etc.) using
- * ecore_animator_custom_source_tick_begin_callback_set() and
- * ecore_animator_custom_source_tick_end_callback_set() to set the functions
- * that will be called to start and stop the ticking source, which when it
- * gets a "tick" should call ecore_animator_custom_tick() to make the "tick" over 1
- * frame.
- */
- EAPI void ecore_animator_source_set(Ecore_Animator_Source source);
- /**
- * @brief Get the animator source currently set.
- *
- * @return The current animator source
- *
- * This gets the current animator source.
- *
- * @see ecore_animator_source_set()
- */
- EAPI Ecore_Animator_Source ecore_animator_source_get(void);
- /**
- * @brief Set the function that begins a custom animator tick source
- *
- * @param func The function to call when ticking is to begin
- * @param data The data passed to the tick begin function as its parameter
- *
- * The Ecore Animator infrastructure handles tracking if animators are needed
- * or not and which ones need to be called and when, but when the tick source
- * is custom, you have to provide a tick source by calling
- * ecore_animator_custom_tick() to indicate a frame tick happened. In order
- * to allow the source of ticks to be dynamically enabled or disabled as
- * needed, the @p func when set is called to enable the tick source to
- * produce tick events that call ecore_animator_custom_tick(). If @p func
- * is NULL then no function is called to begin custom ticking.
- *
- * @see ecore_animator_source_set()
- * @see ecore_animator_custom_source_tick_end_callback_set()
- * @see ecore_animator_custom_tick()
- */
- EAPI void ecore_animator_custom_source_tick_begin_callback_set(Ecore_Cb func, const void *data);
- /**
- * @brief Set the function that ends a custom animator tick source
- *
- * @param func The function to call when ticking is to end
- * @param data The data passed to the tick end function as its parameter
- *
- * This function is a matching pair to the function set by
- * ecore_animator_custom_source_tick_begin_callback_set() and is called
- * when ticking is to stop. If @p func is NULL then no function will be
- * called to stop ticking. For more information please see
- * ecore_animator_custom_source_tick_begin_callback_set().
- *
- * @see ecore_animator_source_set()
- * @see ecore_animator_custom_source_tick_begin_callback_set()
- * @see ecore_animator_custom_tick()
- */
- EAPI void ecore_animator_custom_source_tick_end_callback_set(Ecore_Cb func, const void *data);
- /**
- * @brief Trigger a custom animator tick
- *
- * When animator source is set to ECORE_ANIMATOR_SOURCE_CUSTOM, then calling
- * this function triggers a run of all animators currently registered with
- * Ecore as this indicates a "frame tick" happened. This will do nothing if
- * the animator source(set by ecore_animator_source_set()) is not set to
- * ECORE_ANIMATOR_SOURCE_CUSTOM.
- *
- * @see ecore_animator_source_set()
- * @see ecore_animator_custom_source_tick_begin_callback_set
- * @see ecore_animator_custom_source_tick_end_callback_set()()
- */
- EAPI void ecore_animator_custom_tick(void);
-
- /**
- * @}
- */
-
- /**
- * @defgroup Ecore_Time_Group Ecore Time functions
- *
- * Functions that deal with time. These functions include those
- * that simply retrieve it in a given format, and those that create
- * events based on it.
- *
- * The timer allows callbacks to be called at specific intervals.
- *
- * Examples with functions that deal with time:
- * @li @ref ecore_time_functions_example_c
- * @li @ref ecore_timer_example_c
- *
- * @ingroup Ecore_Main_Loop_Group
- *
- * @{
- */
-
- typedef struct _Ecore_Timer Ecore_Timer; /**< A handle for timers */
-
- EAPI double ecore_time_get(void);
- EAPI double ecore_time_unix_get(void);
- EAPI double ecore_loop_time_get(void);
-
- EAPI Ecore_Timer *ecore_timer_add(double in, Ecore_Task_Cb func, const void *data);
- EAPI Ecore_Timer *ecore_timer_loop_add(double in, Ecore_Task_Cb func, const void *data);
- EAPI void *ecore_timer_del(Ecore_Timer *timer);
- EAPI void ecore_timer_interval_set(Ecore_Timer *timer, double in);
- EAPI double ecore_timer_interval_get(Ecore_Timer *timer);
- EAPI void ecore_timer_freeze(Ecore_Timer *timer);
- EAPI void ecore_timer_thaw(Ecore_Timer *timer);
- EAPI void ecore_timer_delay(Ecore_Timer *timer, double add);
- EAPI double ecore_timer_pending_get(Ecore_Timer *timer);
- EAPI double ecore_timer_precision_get(void);
- EAPI void ecore_timer_precision_set(double precision);
- EAPI char *ecore_timer_dump(void);
-
- /**
- * @}
- */
-
- /**
- * @defgroup Ecore_Idle_Group Ecore Idle functions
- *
- * Callbacks that are called when the program enters or exits an
- * idle state.
- *
- * The ecore main loop enters an idle state when it is waiting for
- * timers to time out, data to come in on a file descriptor or any
- * other event to occur. You can set callbacks to be called when
- * the main loop enters an idle state, during an idle state or just
- * after the program wakes up.
- *
- * Enterer callbacks are good for updating your program's state, if
- * it has a state engine. Once all of the enterer handlers are
- * called, the program will enter a "sleeping" state.
- *
- * Idler callbacks are called when the main loop has called all
- * enterer handlers. They are useful for interfaces that require
- * polling and timers would be too slow to use.
- *
- * If no idler callbacks are specified, then the process literally
- * goes to sleep. Otherwise, the idler callbacks are called
- * continuously while the loop is "idle", using as much CPU as is
- * available to the process.
- *
- * Exiter callbacks are called when the main loop wakes up from an
- * idle state.
- *
- * @note Idle state doesn't mean that the @b program is idle, but
- * that the <b>main loop</b> is idle. It doesn't have any timers,
- * events, fd handlers or anything else to process (which in most
- * <em>event driven</em> programs also means that the @b program is
- * idle too, but it's not a rule). The program itself may be doing
- * a lot of processing in the idler, or in another thread, for
- * example.
- *
- * Example with functions that deal with idle state:
- *
- * @li @ref ecore_idler_example_c
- *
- * @ingroup Ecore_Main_Loop_Group
- *
- * @{
- */
-
- typedef struct _Ecore_Idler Ecore_Idler; /**< A handle for idlers */
- typedef struct _Ecore_Idle_Enterer Ecore_Idle_Enterer; /**< A handle for idle enterers */
- typedef struct _Ecore_Idle_Exiter Ecore_Idle_Exiter; /**< A handle for idle exiters */
-
- /**
- * Add an idler handler.
- * @param func The function to call when idling.
- * @param data The data to be passed to this @p func call.
- * @return A idler handle if successfully added. NULL otherwise.
- *
- * Add an idler handle to the event loop, returning a handle on
- * success and NULL otherwise. The function @p func will be called
- * repeatedly while no other events are ready to be processed, as
- * long as it returns 1 (or ECORE_CALLBACK_RENEW). A return of 0
- * (or ECORE_CALLBACK_CANCEL) deletes the idler.
- *
- * Idlers are useful for progressively prossessing data without blocking.
- */
- EAPI Ecore_Idler *ecore_idler_add(Ecore_Task_Cb func, const void *data);
-
- /**
- * Delete an idler callback from the list to be executed.
- * @param idler The handle of the idler callback to delete
- * @return The data pointer passed to the idler callback on success. NULL
- * otherwise.
- */
- EAPI void *ecore_idler_del(Ecore_Idler *idler);
-
- EAPI Ecore_Idle_Enterer *ecore_idle_enterer_add(Ecore_Task_Cb func, const void *data);
- EAPI Ecore_Idle_Enterer *ecore_idle_enterer_before_add(Ecore_Task_Cb func, const void *data);
- EAPI void *ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer);
-
- EAPI Ecore_Idle_Exiter *ecore_idle_exiter_add(Ecore_Task_Cb func, const void *data);
- EAPI void *ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter);
-
- /**
- * @}
- */
-
- /**
- * @defgroup Ecore_Thread_Group Ecore Thread functions
- *
- * Facilities to run heavy tasks in different threads to avoid blocking
- * the main loop.
- *
- * The EFL is, for the most part, not thread safe. This means that if you
- * have some task running in another thread and you have, for example, an
- * Evas object to show the status progress of this task, you cannot update
- * the object from within the thread. This can only be done from the main
- * thread, the one running the main loop. This problem can be solved
- * by running a thread that sends messages to the main one using an
- * @ref Ecore_Pipe_Group "Ecore_Pipe", but when you need to handle other
- * things like cancelling the thread, your code grows in coplexity and gets
- * much harder to maintain.
- *
- * Ecore Thread is here to solve that problem. It is @b not a simple wrapper
- * around standard POSIX threads (or the equivalent in other systems) and
- * it's not meant to be used to run parallel tasks throughout the entire
- * duration of the program, especially when these tasks are performance
- * critical, as Ecore manages these tasks using a pool of threads based on
- * system configuration.
- *
- * What Ecore Thread does, is make it a lot easier to dispatch a worker
- * function to perform some heavy task and then get the result once it
- * completes, without blocking the application's UI. In addition, cancelling
- * and rescheduling comes practically for free and the developer needs not
- * worry about how many threads are launched, since Ecore will schedule
- * them according to the number of processors the system has and maximum
- * amount of concurrent threads set for the application.
- *
- * At the system level, Ecore will start a new thread on an as-needed basis
- * until the maximum set is reached. When no more threads can be launched,
- * new worker functions will be queued in a waiting list until a thread
- * becomes available. This way, system threads will be shared throughout
- * different worker functions, but running only one at a time. At the same
- * time, a worker function that is rescheduled may be run on a different
- * thread the next time.
- *
- * The ::Ecore_Thread handler has two meanings, depending on what context
- * it is on. The one returned when starting a worker with any of the
- * functions ecore_thread_run() or ecore_thread_feedback_run() is an
- * identifier of that specific instance of the function and can be used from
- * the main loop with the ecore_thread_cancel() and ecore_thread_check()
- * functions. This handler must not be shared with the worker function
- * function running in the thread. This same handler will be the one received
- * on the @c end, @c cancel and @c feedback callbacks.
- *
- * The worker function, that's the one running in the thread, also receives
- * an ::Ecore_Thread handler that can be used with ecore_thread_cancel() and
- * ecore_thread_check(), sharing the flag with the main loop. But this
- * handler is also associated with the thread where the function is running.
- * This has strong implications when working with thread local data.
- *
- * There are two kinds of worker threads Ecore handles: simple, or short,
- * workers and feedback workers.
- *
- * The first kind is for simple functions that perform a
- * usually small but time consuming task. Ecore will run this function in
- * a thread as soon as one becomes available and notify the calling user of
- * its completion once the task is done.
- *
- * The following image shows the flow of a program running four tasks on
- * a pool of two threads.
- *
- * @image html ecore_thread.png
- * @image rtf ecore_thread.png
- * @image latex ecore_thread.eps width=\textwidth
- *
- * For larger tasks that may require continuous communication with the main
- * program, the feedback workers provide the same functionality plus a way
- * for the function running in the thread to send messages to the main
- * thread.
- *
- * The next diagram omits some details shown in the previous one regarding
- * how threads are spawned and tasks are queued, but illustrates how feedback
- * jobs communicate with the main loop and the special case of threads
- * running out of pool.
- *
- * @image html ecore_thread_feedback.png
- * @image rtf ecore_thread_feedback.png
- * @image latex ecore_thread_feedback.eps width=\textwidth
- *
- * See an overview example in @ref ecore_thread_example_c.
- *
- * @ingroup Ecore_Main_Loop_Group
- *
- * @{
- */
-
- typedef struct _Ecore_Thread Ecore_Thread; /**< A handle for threaded jobs */
-
- /**
- * @typedef Ecore_Thread_Cb Ecore_Thread_Cb
- * A callback used by Ecore_Thread helper.
- */
- typedef void (*Ecore_Thread_Cb) (void *data, Ecore_Thread *thread);
- /**
- * @typedef Ecore_Thread_Notify_Cb Ecore_Thread_Notify_Cb
- * A callback used by the main loop to receive data sent by an
- * @ref Ecore_Thread_Group.
- */
- typedef void (*Ecore_Thread_Notify_Cb) (void *data, Ecore_Thread *thread, void *msg_data);
-
- /**
- * Schedule a task to run in a parallel thread to avoid locking the main loop
- *
- * @param func_blocking The function that should run in another thread.
- * @param func_end Function to call from main loop when @p func_blocking
- * completes its task successfully (may be NULL)
- * @param func_cancel Function to call from main loop if the thread running
- * @p func_blocking is cancelled or fails to start (may be NULL)
- * @param data User context data to pass to all callbacks.
- * @return A new thread handler, or NULL on failure
- *
- * This function will try to create a new thread to run @p func_blocking in,
- * or if the maximum number of concurrent threads has been reached, will
- * add it to the pending list, where it will wait until a thread becomes
- * available. The return value will be an ::Ecore_Thread handle that can
- * be used to cancel the thread before its completion.
- *
- * @note This function should always return immediately, but in the rare
- * case that Ecore is built with no thread support, @p func_blocking will
- * be called here, actually blocking the main loop.
- *
- * Once a thread becomes available, @p func_blocking will be run in it until
- * it finishes, then @p func_end is called from the thread containing the
- * main loop to inform the user of its completion. While in @p func_blocking,
- * no functions from the EFL can be used, except for those from Eina that are
- * marked to be thread-safe. Even for the latter, caution needs to be taken
- * if the data is shared across several threads.
- *
- * @p func_end will be called from the main thread when @p func_blocking ends,
- * so here it's safe to use anything from the EFL freely.
- *
- * The thread can also be cancelled before its completion calling
- * ecore_thread_cancel(), either from the main thread or @p func_blocking.
- * In this case, @p func_cancel will be called, also from the main thread
- * to inform of this happening. If the thread could not be created, this
- * function will be called and it's @c thread parameter will be NULL. It's
- * also safe to call any EFL function here, as it will be running in the
- * main thread.
- *
- * Inside @p func_blocking, it's possible to call ecore_thread_reschedule()
- * to tell Ecore that this function should be called again.
- *
- * Be aware that no assumptions can be made about the order in which the
- * @p func_end callbacks for each task will be called. Once the function is
- * running in a different thread, it's the OS that will handle its running
- * schedule, and different functions may take longer to finish than others.
- * Also remember that just starting several tasks together doesn't mean they
- * will be running at the same time. Ecore will schedule them based on the
- * number of threads available for the particular system it's running in,
- * so some of the jobs started may be waiting until another one finishes
- * before it can execute its own @p func_blocking.
- *
- * @see ecore_thread_feedback_run()
- * @see ecore_thread_cancel()
- * @see ecore_thread_reschedule()
- * @see ecore_thread_max_set()
- */
- EAPI Ecore_Thread *ecore_thread_run(Ecore_Thread_Cb func_blocking,
- Ecore_Thread_Cb func_end,
- Ecore_Thread_Cb func_cancel,
- const void *data);
- /**
- * Launch a thread to run a task than can talk back to the main thread
- *
- * @param func_heavy The function that should run in another thread.
- * @param func_notify Function that receives the data sent from the thread
- * @param func_end Function to call from main loop when @p func_heavy
- * completes its task successfully
- * @param func_cancel Function to call from main loop if the thread running
- * @p func_heavy is cancelled or fails to start
- * @param data User context data to pass to all callback.
- * @param try_no_queue If you want to run outside of the thread pool.
- * @return A new thread handler, or NULL on failure
- *
- * See ecore_thread_run() for a general description of this function.
- *
- * The difference with the above is that ecore_thread_run() is meant for
- * tasks that don't need to communicate anything until they finish, while
- * this function is provided with a new callback, @p func_notify, that will
- * be called from the main thread for every message sent from @p func_heavy
- * with ecore_thread_feedback().
- *
- * Like with ecore_thread_run(), a new thread will be launched to run
- * @p func_heavy unless the maximum number of simultaneous threadas has been
- * reached, in which case the function will be scheduled to run whenever a
- * running task ends and a thread becomes free. But if @p try_no_queue is
- * set, Ecore will first try to launch a thread outside of the pool to run
- * the task. If it fails, it will revert to the normal behaviour of using a
- * thread from the pool as if @p try_no_queue had not been set.
- *
- * Keep in mind that Ecore handles the thread pool based on the number of
- * CPUs available, but running a thread outside of the pool doesn't count for
- * this, so having too many of them may have drastic effects over the
- * program's performance.
- *
- * @see ecore_thread_feedback()
- * @see ecore_thread_run()
- * @see ecore_thread_cancel()
- * @see ecore_thread_reschedule()
- * @see ecore_thread_max_set()
- */
- EAPI Ecore_Thread *ecore_thread_feedback_run(Ecore_Thread_Cb func_heavy,
- Ecore_Thread_Notify_Cb func_notify,
- Ecore_Thread_Cb func_end,
- Ecore_Thread_Cb func_cancel,
- const void *data,
- Eina_Bool try_no_queue);
- /**
- * Cancel a running thread.
- *
- * @param thread The thread to cancel.
- * @return Will return EINA_TRUE if the thread has been cancelled,
- * EINA_FALSE if it is pending.
- *
- * This function can be called both in the main loop or in the running thread.
- *
- * This function cancels a running thread. If @p thread can be immediately
- * cancelled (it's still pending execution after creation or rescheduling),
- * then the @c cancel callback will be called, @p thread will be freed and
- * the function will return EINA_TRUE.
- *
- * If the thread is already running, then this function returns EINA_FALSE
- * after marking the @p thread as pending cancellation. For the thread to
- * actually be terminated, it needs to return from the user function back
- * into Ecore control. This can happen in several ways:
- * @li The function ends and returns normally. If it hadn't been cancelled,
- * @c func_end would be called here, but instead @c func_cancel will happen.
- * @li The function returns after requesting to be rescheduled with
- * ecore_thread_reschedule().
- * @li The function is prepared to leave early by checking if
- * ecore_thread_check() returns EINA_TRUE.
- *
- * The user function can cancel itself by calling ecore_thread_cancel(), but
- * it should always use the ::Ecore_Thread handle passed to it and never
- * share it with the main loop thread by means of shared user data or any
- * other way.
- *
- * @p thread will be freed and should not be used again if this function
- * returns EINA_TRUE or after the @c func_cancel callback returns.
- *
- * @see ecore_thread_check()
- */
- EAPI Eina_Bool ecore_thread_cancel(Ecore_Thread *thread);
- /**
- * Checks if a thread is pending cancellation
- *
- * @param thread The thread to test.
- * @return EINA_TRUE if the thread is pending cancellation,
- * EINA_FALSE if it is not.
- *
- * This function can be called both in the main loop or in the running thread.
- *
- * When ecore_thread_cancel() is called on an already running task, the
- * thread is marked as pending cancellation. This function returns EINA_TRUE
- * if this mark is set for the given @p thread and can be used from the
- * main loop thread to check if a still active thread has been cancelled,
- * or from the user function running in the thread to check if it should
- * stop doing what it's doing and return early, effectively cancelling the
- * task.
- *
- * @see ecore_thread_cancel()
- */
- EAPI Eina_Bool ecore_thread_check(Ecore_Thread *thread);
- /**
- * Sends data from the worker thread to the main loop
- *
- * @param thread The current ::Ecore_Thread context to send data from
- * @param msg_data Data to be transmitted to the main loop
- * @return EINA_TRUE if @p msg_data was successfully sent to main loop,
- * EINA_FALSE if anything goes wrong.
- *
- * You should use this function only in the @c func_heavy call.
- *
- * Only the address to @p msg_data will be sent and once this function
- * returns EINA_TRUE, the job running in the thread should never touch the
- * contents of it again. The data sent should be malloc()'ed or something
- * similar, as long as it's not memory local to the thread that risks being
- * overwritten or deleted once it goes out of scope or the thread finishes.
- *
- * Care must be taken that @p msg_data is properly freed in the @c func_notify
- * callback set when creating the thread.
- *
- * @see ecore_thread_feedback_run()
- */
- EAPI Eina_Bool ecore_thread_feedback(Ecore_Thread *thread, const void *msg_data);
- /**
- * Asks for the function in the thread to be called again at a later time
- *
- * @param thread The current ::Ecore_Thread context to rescheduled
- * @return EINA_TRUE if the task was successfully rescheduled,
- * EINA_FALSE if anything goes wrong.
- *
- * This function should be called only from the same function represented
- * by @pthread.
- *
- * Calling this function will mark the thread for a reschedule, so as soon
- * as it returns, it will be added to the end of the list of pending tasks.
- * If no other tasks are waiting or there are sufficient threads available,
- * the rescheduled task will be launched again immediately.
- *
- * This should never return EINA_FALSE, unless it was called from the wrong
- * thread or with the wrong arguments.
- *
- * The @c func_end callback set when the thread is created will not be
- * called until the function in the thread returns without being rescheduled.
- * Similarly, if the @p thread is cancelled, the reschedule will not take
- * effect.
- */
- EAPI Eina_Bool ecore_thread_reschedule(Ecore_Thread *thread);
- /**
- * Gets the number of active threads running jobs
- *
- * @return Number of active threads running jobs
- *
- * This returns the number of threads currently running jobs of any type
- * through the Ecore_Thread API.
- *
- * @note Jobs started through the ecore_thread_feedback_run() function with
- * the @c try_no_queue parameter set to EINA_TRUE will not be accounted for
- * in the return of this function unless the thread creation fails and it
- * falls back to using one from the pool.
- */
- EAPI int ecore_thread_active_get(void);
- /**
- * Gets the number of short jobs waiting for a thread to run
- *
- * @return Number of pending threads running "short" jobs
- *
- * This returns the number of tasks started with ecore_thread_run() that are
- * pending, waiting for a thread to become available to run them.
- */
- EAPI int ecore_thread_pending_get(void);
- /**
- * Gets the number of feedback jobs waiting for a thread to run
- *
- * @return Number of pending threads running "feedback" jobs
- *
- * This returns the number of tasks started with ecore_thread_feedback_run()
- * that are pending, waiting for a thread to become available to run them.
- */
- EAPI int ecore_thread_pending_feedback_get(void);
- /**
- * Gets the total number of pending jobs
- *
- * @return Number of pending threads running jobs
- *
- * Same as the sum of ecore_thread_pending_get() and
- * ecore_thread_pending_feedback_get().
- */
- EAPI int ecore_thread_pending_total_get(void);
- /**
- * Gets the maximum number of threads that can run simultaneously
- *
- * @return Max possible number of Ecore_Thread's running concurrently
- *
- * This returns the maximum number of Ecore_Thread's that may be running at
- * the same time. If this number is reached, new jobs started by either
- * ecore_thread_run() or ecore_thread_feedback_run() will be added to the
- * respective pending queue until one of the running threads finishes its
- * task and becomes available to run a new one.
- *
- * By default, this will be the number of available CPUs for the
- * running program (as returned by eina_cpu_count()), or 1 if this value
- * could not be fetched.
- *
- * @see ecore_thread_max_set()
- * @see ecore_thread_max_reset()
- */
- EAPI int ecore_thread_max_get(void);
- /**
- * Sets the maximum number of threads allowed to run simultaneously
- *
- * @param num The new maximum
- *
- * This sets a new value for the maximum number of concurrently running
- * Ecore_Thread's. It @b must an integer between 1 and (2 * @c x), where @c x
- * is the number for CPUs available.
- *
- * @see ecore_thread_max_get()
- * @see ecore_thread_max_reset()
- */
- EAPI void ecore_thread_max_set(int num);
- /**
- * Resets the maximum number of concurrently running threads to the default
- *
- * This resets the value returned by ecore_thread_max_get() back to its
- * default.
- *
- * @see ecore_thread_max_get()
- * @see ecore_thread_max_set()
- */
- EAPI void ecore_thread_max_reset(void);
- /**
- * Gets the number of threads available for running tasks
- *
- * @return The number of available threads
- *
- * Same as doing ecore_thread_max_get() - ecore_thread_active_get().
- *
- * This function may return a negative number only in the case the user
- * changed the maximum number of running threads while other tasks are
- * running.
- */
- EAPI int ecore_thread_available_get(void);
- /**
- * Adds some data to a hash local to the thread
- *
- * @param thread The thread context the data belongs to
- * @param key The name under which the data will be stored
- * @param value The data to add
- * @param cb Function to free the data when removed from the hash
- * @param direct If true, this will not copy the key string (like
- * eina_hash_direct_add())
- * @return EINA_TRUE on success, EINA_FALSE on failure
- *
- * Ecore Thread has a mechanism to share data across several worker functions
- * that run on the same system thread. That is, the data is stored per
- * thread and for a worker function to have access to it, it must be run
- * by the same thread that stored the data.
- *
- * When there are no more workers pending, the thread will be destroyed
- * along with the internal hash and any data left in it will be freed with
- * the @p cb function given.
- *
- * This set of functions is useful to share things around several instances
- * of a function when that thing is costly to create and can be reused, but
- * may only be used by one function at a time.
- *
- * For example, if you have a program doing requisitions to a database,
- * these requisitions can be done in threads so that waiting for the
- * database to respond doesn't block the UI. Each of these threads will
- * run a function, and each function will be dependent on a connection to
- * the database, which may not be able to handle more than one request at
- * a time so for each running function you will need one connection handle.
- * The options then are:
- * @li Each function opens a connection when it's called, does the work and
- * closes the connection when it finishes. This may be costly, wasting a lot
- * of time on resolving hostnames, negotiating permissions and allocating
- * memory.
- * @li Open the connections in the main loop and pass it to the threads
- * using the data pointer. Even worse, it's just as costly as before and now
- * it may even be kept with connections open doing nothing until a thread
- * becomes available to run the function.
- * @li Have a way to share connection handles, so that each instance of the
- * function can check if an available connection exists, and if it doesn't,
- * create one and add it to the pool. When no more connections are needed,
- * they are all closed.
- *
- * The last option is the most efficient, but it requires a lot of work to
- * implement properly. Using thread local data helps to achieve the same
- * result while avoiding doing all the tracking work on your code. The way
- * to use it would be, at the worker function, to ask for the connection
- * with ecore_thread_local_data_find() and if it doesn't exist, then open
- * a new one and save it with ecore_thread_local_data_add(). Do the work and
- * forget about the connection handle, when everything is done the function
- * just ends. The next worker to run on that thread will check if a
- * connection exists and find that it does, so the process of opening a
- * new one has been spared. When no more workers exist, the thread is
- * destroyed and the callback used when saving the connection will be called
- * to close it.
- *
- * This function adds the data @p value to the thread data under the given
- * @p key.
- * No other value in the hash may have the same @p key. If you need to
- * change the value under a @p key, or you don't know if one exists already,
- * you can use ecore_thread_local_data_set().
- *
- * Neither @p key nor @p value may be NULL and @p key will be copied in the
- * hash, unless @p direct is set, in which case the string used should not
- * be freed until the data is removed from the hash.
- *
- * The @p cb function will be called when the data in the hash needs to be
- * freed, be it because it got deleted with ecore_thread_local_data_del() or
- * because @p thread was terminated and the hash destroyed. This parameter
- * may be NULL, in which case @p value needs to be manually freed after
- * removing it from the hash with either ecore_thread_local_data_del() or
- * ecore_thread_local_data_set(), but it's very unlikely that this is what
- * you want.
- *
- * This function, and all of the others in the @c ecore_thread_local_data
- * family of functions, can only be called within the worker function running
- * in the thread. Do not call them from the main loop or from a thread
- * other than the one represented by @p thread.
- *
- * @see ecore_thread_local_data_set()
- * @see ecore_thread_local_data_find()
- * @see ecore_thread_local_data_del()
- */
- EAPI Eina_Bool ecore_thread_local_data_add(Ecore_Thread *thread, const char *key, void *value, Eina_Free_Cb cb, Eina_Bool direct);
- /**
- * Sets some data in the hash local to the given thread
- *
- * @param thread The thread context the data belongs to
- * @param key The name under which the data will be stored
- * @param value The data to add
- * @param cb Function to free the data when removed from the hash
- *
- * If no data exists in the hash under the @p key, this function adds
- * @p value in the hash under the given @p key and returns NULL.
- * The key itself is copied.
- *
- * If the hash already contains something under @p key, the data will be
- * replaced by @p value and the old value will be returned.
- *
- * NULL will also be returned if either @p key or @p value are NULL, or if
- * an error occurred.
- *
- * This function, and all of the others in the @c ecore_thread_local_data
- * family of functions, can only be called within the worker function running
- * in the thread. Do not call them from the main loop or from a thread
- * other than the one represented by @p thread.
- *
- * @see ecore_thread_local_data_add()
- * @see ecore_thread_local_data_del()
- * @see ecore_thread_local_data_find()
- */
- EAPI void *ecore_thread_local_data_set(Ecore_Thread *thread, const char *key, void *value, Eina_Free_Cb cb);
- /**
- * Gets data stored in the hash local to the given thread
- *
- * @param thread The thread context the data belongs to
- * @param key The name under which the data is stored
- * @return The value under the given key, or NULL on error
- *
- * Finds and return the data stored in the shared hash under the key @p key.
- *
- * This function, and all of the others in the @c ecore_thread_local_data
- * family of functions, can only be called within the worker function running
- * in the thread. Do not call them from the main loop or from a thread
- * other than the one represented by @p thread.
- *
- * @see ecore_thread_local_data_add()
- * @see ecore_thread_local_data_wait()
- */
- EAPI void *ecore_thread_local_data_find(Ecore_Thread *thread, const char *key);
- /**
- * Deletes from the thread's hash the data corresponding to the given key
- *
- * @param thread The thread context the data belongs to
- * @param key The name under which the data is stored
- * @return EINA_TRUE on success, EINA_FALSE on failure
- *
- * If there's any data stored associated with @p key in the global hash,
- * this function will remove it from it and return EINA_TRUE. If no data
- * exists or an error occurs, it returns EINA_FALSE.
- *
- * If the data was added to the hash with a free function, then it will
- * also be freed after removing it from the hash, otherwise it requires
- * to be manually freed by the user, which means that if no other reference
- * to it exists before calling this function, it will result in a memory
- * leak.
- *
- * This function, and all of the others in the @c ecore_thread_local_data
- * family of functions, can only be called within the worker function running
- * in the thread. Do not call them from the main loop or from a thread
- * other than the one represented by @p thread.
- *
- * @see ecore_thread_local_data_add()
- */
- EAPI Eina_Bool ecore_thread_local_data_del(Ecore_Thread *thread, const char *key);
-
- /**
- * Adds some data to a hash shared by all threads
- *
- * @param key The name under which the data will be stored
- * @param value The data to add
- * @param cb Function to free the data when removed from the hash
- * @param direct If true, this will not copy the key string (like
- * eina_hash_direct_add())
- * @return EINA_TRUE on success, EINA_FALSE on failure
- *
- * Ecore Thread keeps a hash that can be used to share data across several
- * threads, including the main loop one, without having to manually handle
- * mutexes to do so safely.
- *
- * This function adds the data @p value to this hash under the given @p key.
- * No other value in the hash may have the same @p key. If you need to
- * change the value under a @p key, or you don't know if one exists already,
- * you can use ecore_thread_global_data_set().
- *
- * Neither @p key nor @p value may be NULL and @p key will be copied in the
- * hash, unless @p direct is set, in which case the string used should not
- * be freed until the data is removed from the hash.
- *
- * The @p cb function will be called when the data in the hash needs to be
- * freed, be it because it got deleted with ecore_thread_global_data_del() or
- * because Ecore Thread was shut down and the hash destroyed. This parameter
- * may be NULL, in which case @p value needs to be manually freed after
- * removing it from the hash with either ecore_thread_global_data_del() or
- * ecore_thread_global_data_set().
- *
- * Manually freeing any data that was added to the hash with a @p cb function
- * is likely to produce a segmentation fault, or any other strange
- * happenings, later on in the program.
- *
- * @see ecore_thread_global_data_del()
- * @see ecore_thread_global_data_set()
- * @see ecore_thread_global_data_find()
- */
- EAPI Eina_Bool ecore_thread_global_data_add(const char *key, void *value, Eina_Free_Cb cb, Eina_Bool direct);
- /**
- * Sets some data in the hash shared by all threads
- *
- * @param key The name under which the data will be stored
- * @param value The data to add
- * @param cb Function to free the data when removed from the hash
- *
- * If no data exists in the hash under the @p key, this function adds
- * @p value in the hash under the given @p key and returns NULL.
- * The key itself is copied.
- *
- * If the hash already contains something under @p key, the data will be
- * replaced by @p value and the old value will be returned.
- *
- * NULL will also be returned if either @p key or @p value are NULL, or if
- * an error occurred.
- *
- * @see ecore_thread_global_data_add()
- * @see ecore_thread_global_data_del()
- * @see ecore_thread_global_data_find()
- */
- EAPI void *ecore_thread_global_data_set(const char *key, void *value, Eina_Free_Cb cb);
- /**
- * Gets data stored in the hash shared by all threads
- *
- * @param key The name under which the data is stored
- * @return The value under the given key, or NULL on error
- *
- * Finds and return the data stored in the shared hash under the key @p key.
- *
- * Keep in mind that the data returned may be used by more than one thread
- * at the same time and no reference counting is done on it by Ecore.
- * Freeing the data or modifying its contents may require additional
- * precautions to be considered, depending on the application's design.
- *
- * @see ecore_thread_global_data_add()
- * @see ecore_thread_global_data_wait()
- */
- EAPI void *ecore_thread_global_data_find(const char *key);
- /**
- * Deletes from the shared hash the data corresponding to the given key
- *
- * @param key The name under which the data is stored
- * @return EINA_TRUE on success, EINA_FALSE on failure
- *
- * If there's any data stored associated with @p key in the global hash,
- * this function will remove it from it and return EINA_TRUE. If no data
- * exists or an error occurs, it returns EINA_FALSE.
- *
- * If the data was added to the hash with a free function, then it will
- * also be freed after removing it from the hash, otherwise it requires
- * to be manually freed by the user, which means that if no other reference
- * to it exists before calling this function, it will result in a memory
- * leak.
- *
- * Note, also, that freeing data that other threads may be using will result
- * in a crash, so appropriate care must be taken by the application when
- * that possibility exists.
- *
- * @see ecore_thread_global_data_add()
- */
- EAPI Eina_Bool ecore_thread_global_data_del(const char *key);
- /**
- * Gets data stored in the shared hash, or wait for it if it doesn't exist
- *
- * @param key The name under which the data is stored
- * @param seconds The amount of time in seconds to wait for the data.
- * @return The value under the given key, or NULL on error
- *
- * Finds and return the data stored in the shared hash under the key @p key.
- *
- * If there's nothing in the hash under the given @p key, the function
- * will block and wait up to @p seconds seconds for some other thread to
- * add it with either ecore_thread_global_data_add() or
- * ecore_thread_global_data_set(). If after waiting there's still no data
- * to get, NULL will be returned.
- *
- * If @p seconds is 0, then no waiting will happen and this function works
- * like ecore_thread_global_data_find(). If @p seconds is less than 0, then
- * the function will wait indefinitely.
- *
- * Keep in mind that the data returned may be used by more than one thread
- * at the same time and no reference counting is done on it by Ecore.
- * Freeing the data or modifying its contents may require additional
- * precautions to be considered, depending on the application's design.
- *
- * @see ecore_thread_global_data_add()
- * @see ecore_thread_global_data_find()
- */
- EAPI void *ecore_thread_global_data_wait(const char *key, double seconds);
-
- /**
- * @}
- */
-
- /**
- * @defgroup Ecore_Pipe_Group Pipe wrapper
- *
- * These functions wrap the pipe / write / read functions to easily
- * integrate its use into ecore's main loop.
- *
- * The ecore_pipe_add() function creates file descriptors (sockets
- * on Windows) and attach a handle to the ecore main loop. That
- * handle is called when data is read in the pipe. To write data in
- * the pipe, just call ecore_pipe_write(). When you are done, just
- * call ecore_pipe_del().
- *
- * For examples see here:
- * @li @ref tutorial_ecore_pipe_gstreamer_example
- * @li @ref tutorial_ecore_pipe_simple_example
- *
- * @ingroup Ecore_Main_Loop_Group
- *
- * @{
- */
-
- typedef struct _Ecore_Pipe Ecore_Pipe; /**< A handle for pipes */
-
- /**
- * @typedef Ecore_Pipe_Cb Ecore_Pipe_Cb
- * The callback that data written to the pipe is sent to.
- */
- typedef void (*Ecore_Pipe_Cb) (void *data, void *buffer, unsigned int nbyte);
-
- EAPI Ecore_Pipe *ecore_pipe_add(Ecore_Pipe_Cb handler, const void *data);
- EAPI void *ecore_pipe_del(Ecore_Pipe *p);
- EAPI Eina_Bool ecore_pipe_write(Ecore_Pipe *p, const void *buffer, unsigned int nbytes);
- EAPI void ecore_pipe_write_close(Ecore_Pipe *p);
- EAPI void ecore_pipe_read_close(Ecore_Pipe *p);
- EAPI void ecore_pipe_thaw(Ecore_Pipe *p);
- EAPI void ecore_pipe_freeze(Ecore_Pipe *p);
- EAPI int ecore_pipe_wait(Ecore_Pipe *p, int message_count, double wait);
-
- /**
- * @}
- */
-
- /**
- * @defgroup Ecore_Job_Group Ecore Job functions
- *
- * You can queue jobs that are to be done by the main loop when the
- * current event is dealt with.
- *
- * Jobs are processed by the main loop similarly to events. They
- * also will be executed in the order in which they were added.
- *
- * A good use for them is when you don't want to execute an action
- * immeditately, but want to give the control back to the main loop
- * so that it will call your job callback when jobs start being
- * processed (and if there are other jobs added before yours, they
- * will be processed first). This also gives the chance to other
- * actions in your program to cancel the job before it is started.
- *
- * Examples of using @ref Ecore_Job:
- * @li @ref ecore_job_example_c
- *
- * @ingroup Ecore_Main_Loop_Group
- *
- * @{
- */
-
- typedef struct _Ecore_Job Ecore_Job; /**< A job handle */
-
- EAPI Ecore_Job *ecore_job_add(Ecore_Cb func, const void *data);
- EAPI void *ecore_job_del(Ecore_Job *job);
-
- /**
- * @}
- */
-
- /**
- * @defgroup Ecore_Application_Group Ecore Application functions
- *
- * @{
- */
-
- EAPI void ecore_app_args_set(int argc, const char **argv);
- EAPI void ecore_app_args_get(int *argc, char ***argv);
- EAPI void ecore_app_restart(void);
-
- /**
- * @}
- */
-
- /**
- * @defgroup Ecore_Throttle_Group Ecore Throttle functions
- *
- * @ingroup Ecore_Main_Loop_Group
- *
- * @{
- */
-
- EAPI void ecore_throttle_adjust(double amount );
- EAPI double ecore_throttle_get(void);
-
- /**
- * @}
- */
+};
+
+struct _Ecore_Exe_Event_Data_Line /**< Lines from a child process */
+{
+ char *line;
+ int size;
+};
+
+struct _Ecore_Exe_Event_Data /** Data from a child process event */
+{
+ Ecore_Exe *exe; /**< The handle to the process */
+ void *data; /**< the raw binary data from the child process that was received */
+ int size; /**< the size of this data in bytes */
+ Ecore_Exe_Event_Data_Line *lines; /**< an array of line data if line buffered, the last one has it's line member set to NULL */
+};
+
+EAPI void
+ ecore_exe_run_priority_set(int pri);
+EAPI int
+ ecore_exe_run_priority_get(void);
+EAPI Ecore_Exe *
+ ecore_exe_run(const char *exe_cmd,
+ const void *data);
+EAPI Ecore_Exe *
+ecore_exe_pipe_run(const char *exe_cmd,
+ Ecore_Exe_Flags flags,
+ const void *data);
+EAPI void
+ecore_exe_callback_pre_free_set(Ecore_Exe *exe,
+ Ecore_Exe_Cb func);
+EAPI Eina_Bool
+ecore_exe_send(Ecore_Exe *exe,
+ const void *data,
+ int size);
+EAPI void
+ ecore_exe_close_stdin(Ecore_Exe *exe);
+EAPI void
+ ecore_exe_auto_limits_set(Ecore_Exe *exe,
+ int start_bytes,
+ int end_bytes,
+ int start_lines,
+ int end_lines);
+EAPI Ecore_Exe_Event_Data *
+ecore_exe_event_data_get(Ecore_Exe *exe,
+ Ecore_Exe_Flags flags);
+EAPI void
+ ecore_exe_event_data_free(Ecore_Exe_Event_Data *data);
+EAPI void *
+ ecore_exe_free(Ecore_Exe *exe);
+EAPI pid_t
+ ecore_exe_pid_get(const Ecore_Exe *exe);
+EAPI void
+ ecore_exe_tag_set(Ecore_Exe *exe,
+ const char *tag);
+EAPI const char *
+ ecore_exe_tag_get(const Ecore_Exe *exe);
+EAPI const char *
+ ecore_exe_cmd_get(const Ecore_Exe *exe);
+EAPI void *
+ ecore_exe_data_get(const Ecore_Exe *exe);
+EAPI void *
+ ecore_exe_data_set(Ecore_Exe *exe,
+ void *data);
+EAPI Ecore_Exe_Flags
+ ecore_exe_flags_get(const Ecore_Exe *exe);
+EAPI void
+ ecore_exe_pause(Ecore_Exe *exe);
+EAPI void
+ ecore_exe_continue(Ecore_Exe *exe);
+EAPI void
+ ecore_exe_interrupt(Ecore_Exe *exe);
+EAPI void
+ ecore_exe_quit(Ecore_Exe *exe);
+EAPI void
+ ecore_exe_terminate(Ecore_Exe *exe);
+EAPI void
+ ecore_exe_kill(Ecore_Exe *exe);
+EAPI void
+ ecore_exe_signal(Ecore_Exe *exe,
+ int num);
+EAPI void
+ecore_exe_hup(Ecore_Exe *exe);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Ecore_FD_Handler_Group File Event Handling Functions
+ *
+ * Functions that deal with file descriptor handlers.
+ *
+ * The @ref Ecore_Fd_Handler can be used to watch a file descriptor
+ * for data available for reading, for the availability to write
+ * without blocking, and for errors on the file descriptor.
+ *
+ * ecore_main_fd_handler_add() is used to setup a handler for a
+ * given file descriptor. This file descriptor can be the standard
+ * input, a network socket, a stream received through some driver
+ * of a hardware decoder, etc. Thus it can contain errors, like a
+ * disconnection, a broken pipe, and so, and that's why it's
+ * possible to check for these errors with the @ref ECORE_FD_ERROR
+ * flag.
+ *
+ * An @ref Ecore_Fd_Handler can be used to watch on a file
+ * descriptor without blocking, still being able to receive events,
+ * expire timers, and other watch for other things that happen in
+ * the Ecore main loop.
+ *
+ * Example of use of a file descriptor handler:
+ * @li @ref ecore_fd_handler_example_c
+ *
+ * @ingroup Ecore_Main_Loop_Group
+ *
+ * @{
+ */
+
+typedef struct _Ecore_Fd_Handler Ecore_Fd_Handler; /**< A handle for Fd handlers */
+
+enum _Ecore_Fd_Handler_Flags
+{
+ ECORE_FD_READ = 1, /**< Fd Read mask */
+ ECORE_FD_WRITE = 2, /**< Fd Write mask */
+ ECORE_FD_ERROR = 4 /**< Fd Error mask */
+};
+typedef enum _Ecore_Fd_Handler_Flags Ecore_Fd_Handler_Flags;
+
+/**
+ * @typedef Ecore_Fd_Cb Ecore_Fd_Cb
+ * A callback used by an @ref Ecore_Fd_Handler.
+ */
+typedef Eina_Bool (*Ecore_Fd_Cb)(void *data, Ecore_Fd_Handler *fd_handler);
+
+/**
+ * @typedef Ecore_Fd_Prep_Cb Ecore_Fd_Prep_Cb
+ * A callback used by an @ref Ecore_Fd_Handler.
+ */
+typedef void (*Ecore_Fd_Prep_Cb)(void *data, Ecore_Fd_Handler *fd_handler);
+
+/**
+ * @typedef Ecore_Win32_Handle_Cb Ecore_Win32_Handle_Cb
+ * A callback used by an @ref Ecore_Win32_Handler.
+ */
+typedef Eina_Bool (*Ecore_Win32_Handle_Cb)(void *data, Ecore_Win32_Handler *wh);
+
+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);
+EAPI void
+ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler,
+ Ecore_Fd_Prep_Cb func,
+ const void *data);
+EAPI void *
+ ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler);
+EAPI int
+ ecore_main_fd_handler_fd_get(Ecore_Fd_Handler *fd_handler);
+EAPI Eina_Bool
+ ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler,
+ Ecore_Fd_Handler_Flags flags);
+EAPI void
+ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler,
+ Ecore_Fd_Handler_Flags flags);
+
+EAPI Ecore_Win32_Handler *
+ecore_main_win32_handler_add(void *h,
+ Ecore_Win32_Handle_Cb func,
+ const void *data);
+EAPI void *
+ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Ecore_Poller_Group Ecore Poll functions
+ *
+ * These functions are for the need to poll information, but provide
+ * a shared abstracted API to pool such polling to minimise wakeup
+ * and ensure all the polling happens in as few spots as possible
+ * areound a core poll interval. For now only 1 core poller type is
+ * supprted: ECORE_POLLER_CORE
+ *
+ * Example of @ref Ecore_Poller:
+ * @li @ref ecore_poller_example_c
+ *
+ * @ingroup Ecore_Main_Loop_Group
+ *
+ * @{
+ */
+
+enum _Ecore_Poller_Type /* Poller types */
+{
+ ECORE_POLLER_CORE = 0 /**< The core poller interval */
+};
+typedef enum _Ecore_Poller_Type Ecore_Poller_Type;
+
+typedef struct _Ecore_Poller Ecore_Poller; /**< A handle for pollers */
+
+EAPI void
+ecore_poller_poll_interval_set(Ecore_Poller_Type type,
+ double poll_time);
+EAPI double
+ ecore_poller_poll_interval_get(Ecore_Poller_Type type);
+EAPI Eina_Bool
+ ecore_poller_poller_interval_set(Ecore_Poller *poller,
+ int interval);
+EAPI int
+ ecore_poller_poller_interval_get(Ecore_Poller *poller);
+EAPI Ecore_Poller *
+ ecore_poller_add(Ecore_Poller_Type type,
+ int interval,
+ Ecore_Task_Cb func,
+ const void *data);
+EAPI void *ecore_poller_del(Ecore_Poller *poller);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Ecore_Animator_Group Ecore Animator functions
+ *
+ * @brief Ecore animators are a helper to simplify creating
+ * animations.
+ *
+ * Creating an animation is as simple as saying for how long it
+ * should be run and having a callback that does the animation,
+ * something like this:
+ * @code
+ * static Eina_Bool
+ * _do_animation(void *data, double pos)
+ * {
+ * evas_object_move(data, 100 * pos, 100 * pos);
+ * ... do some more animating ...
+ * }
+ * ...
+ * ecore_animator_timeline_add(2, _do_animation, my_evas_object);
+ * @endcode
+ * In the sample above we create an animation to move
+ * @c my_evas_object from position (0,0) to (100,100) in 2 seconds.
+ *
+ * If your animation will run for an unspecified amount of time you
+ * can use ecore_animator_add(), which is like using
+ * ecore_timer_add() with the interval being the
+ * @ref ecore_animator_frametime_set "framerate". Note that this has
+ * tangible benefits to creating a timer for each animation in terms
+ * of performance.
+ *
+ * For a more detailed example that show several animation see
+ * @ref tutorial_ecore_animator.
+ *
+ * @ingroup Ecore_Main_Loop_Group
+ *
+ * @{
+ */
+
+typedef struct _Ecore_Animator Ecore_Animator; /**< A handle for animators */
+
+enum _Ecore_Pos_Map /* Position mappings */
+{
+ ECORE_POS_MAP_LINEAR, /**< Linear 0.0 -> 1.0 */
+ ECORE_POS_MAP_ACCELERATE, /**< Start slow then speed up */
+ ECORE_POS_MAP_DECELERATE, /**< Start fast then slow down */
+ ECORE_POS_MAP_SINUSOIDAL, /**< Start slow, speed up then slow down at end */
+ ECORE_POS_MAP_ACCELERATE_FACTOR, /**< Start slow then speed up, v1 being a power factor, 0.0 being linear, 1.0 being normal accelerate, 2.0 being much more pronounced accelerate (squared), 3.0 being cubed, etc. */
+ ECORE_POS_MAP_DECELERATE_FACTOR, /**< Start fast then slow down, v1 being a power factor, 0.0 being linear, 1.0 being normal decelerate, 2.0 being much more pronounced decelerate (squared), 3.0 being cubed, etc. */
+ ECORE_POS_MAP_SINUSOIDAL_FACTOR, /**< Start slow, speed up then slow down at end, v1 being a power factor, 0.0 being linear, 1.0 being normal sinusoidal, 2.0 being much more pronounced sinusoidal (squared), 3.0 being cubed, etc. */
+ ECORE_POS_MAP_DIVISOR_INTERP, /**< Start at gradient * v1, interpolated via power of v2 curve */
+ ECORE_POS_MAP_BOUNCE, /**< Start at 0.0 then "drop" like a ball bouncing to the ground at 1.0, and bounce v2 times, with decay factor of v1 */
+ ECORE_POS_MAP_SPRING /**< Start at 0.0 then "wobble" like a spring rest position 1.0, and wobble v2 times, with decay factor of v1 */
+};
+typedef enum _Ecore_Pos_Map Ecore_Pos_Map;
+
+enum _Ecore_Animator_Source /* Timing sources for animators */
+{
+ ECORE_ANIMATOR_SOURCE_TIMER, /**< The default system clock/timer based animator that ticks every "frametime" seconds */
+ ECORE_ANIMATOR_SOURCE_CUSTOM /**< A custom animator trigger that you need to call ecore_animator_trigger() to make it tick */
+};
+typedef enum _Ecore_Animator_Source Ecore_Animator_Source;
+
+/**
+ * @typedef Ecore_Timeline_Cb Ecore_Timeline_Cb
+ * A callback run for a task (animators with runtimes)
+ */
+typedef Eina_Bool (*Ecore_Timeline_Cb)(void *data, double pos);
+
+/**
+ * @brief Add an animator to call @p func at every animaton tick during main
+ * loop execution.
+ *
+ * @param func The function to call when it ticks off
+ * @param data The data to pass to the function
+ * @return A handle to the new animator
+ *
+ * This function adds a animator and returns its handle on success and NULL on
+ * failure. The function @p func will be called every N seconds where N is the
+ * @p frametime interval set by ecore_animator_frametime_set(). The function
+ * will be passed the @p data pointer as its parameter.
+ *
+ * When the animator @p func is called, it must return a value of either 1 or
+ * 0. If it returns 1 (or ECORE_CALLBACK_RENEW), it will be called again at
+ * the next tick, or if it returns 0 (or ECORE_CALLBACK_CANCEL) it will be
+ * deleted automatically making any references/handles for it invalid.
+ *
+ * @note The default @p frametime value is 1/30th of a second.
+ *
+ * @see ecore_animator_timeline_add()
+ * @see ecore_animator_frametime_set()
+ */
+EAPI Ecore_Animator *ecore_animator_add(Ecore_Task_Cb func,
+ const void *data);
+/**
+ * @brief Add a animator that runs for a limited time
+ *
+ * @param runtime The time to run in seconds
+ * @param func The function to call when it ticks off
+ * @param data The data to pass to the function
+ * @return A handle to the new animator
+ *
+ * This function is just like ecore_animator_add() except the animator only
+ * runs for a limited time specified in seconds by @p runtime. Once the
+ * runtime the animator has elapsed (animator finished) it will automatically
+ * be deleted. The callback function @p func can return ECORE_CALLBACK_RENEW
+ * to keep the animator running or ECORE_CALLBACK_CANCEL ro stop it and have
+ * it be deleted automatically at any time.
+ *
+ * The @p func will ALSO be passed a position parameter that will be in value
+ * from 0.0 to 1.0 to indicate where along the timeline (0.0 start, 1.0 end)
+ * the animator run is at. If the callback wishes not to have a linear
+ * transition it can "map" this value to one of several curves and mappings
+ * via ecore_animator_pos_map().
+ *
+ * @note The default @p frametime value is 1/30th of a second.
+ *
+ * @see ecore_animator_add()
+ * @see ecore_animator_pos_map()
+ * @since 1.1.0
+ */
+EAPI Ecore_Animator *
+ecore_animator_timeline_add(double runtime,
+ Ecore_Timeline_Cb func,
+ const void *data);
+/**
+ * @brief Delete the specified animator from the animator list.
+ *
+ * @param animator The animator to delete
+ * @return The data pointer set for the animator on add
+ *
+ * Delete the specified @p animator from the set of animators that are
+ * executed during main loop execution. This function returns the data
+ * parameter that was being passed to the callback on success, or NULL on
+ * failure. After this call returns the specified animator object @p animator
+ * is invalid and should not be used again. It will not get called again after
+ * deletion.
+ */
+EAPI void *
+ecore_animator_del(Ecore_Animator *animator);
+/**
+ * @brief Suspend the specified animator.
+ *
+ * @param animator The animator to delete
+ *
+ * The specified @p animator will be temporarly removed from the set of
+ * animators that are executed during main loop.
+ *
+ * @warning Freezing an animator doesn't freeze accounting of how long that
+ * animator has been running. Therefore if the animator was created with
+ * ecore_animator_timeline_add() the @p pos argument given to the callback
+ * will increase as if the animator hadn't been frozen and the animator may
+ * have it's execution halted if @p runtime elapsed.
+ */
+EAPI void
+ecore_animator_freeze(Ecore_Animator *animator);
+/**
+ * @brief Restore execution of the specified animator.
+ *
+ * @param animator The animator to delete
+ *
+ * The specified @p animator will be put back in the set of animators that are
+ * executed during main loop.
+ */
+EAPI void
+ecore_animator_thaw(Ecore_Animator *animator);
+/**
+ * @brief Set the animator call interval in seconds.
+ *
+ * @param frametime The time in seconds in between animator ticks.
+ *
+ * This function sets the time interval (in seconds) between animator ticks.
+ * At every tick the callback of every existing animator will be called.
+ *
+ * @warning Too small a value may cause performance issues and too high a
+ * value may cause your animation to seem "jerky".
+ *
+ * @note The default @p frametime value is 1/30th of a second.
+ */
+EAPI void
+ecore_animator_frametime_set(double frametime);
+/**
+ * @brief Get the animator call interval in seconds.
+ *
+ * @return The time in second in between animator ticks.
+ *
+ * This function retrieves the time in seconds between animator ticks.
+ *
+ * @see ecore_animator_frametime_set()
+ */
+EAPI double
+ecore_animator_frametime_get(void);
+/**
+ * @brief Maps an input position from 0.0 to 1.0 along a timeline to a
+ * position in a different curve.
+ *
+ * @param pos The input position to map
+ * @param map The mapping to use
+ * @param v1 A parameter use by the mapping (pass 0.0 if not used)
+ * @param v2 A parameter use by the mapping (pass 0.0 if not used)
+ * @return The mapped value
+ *
+ * Takes an input position (0.0 to 1.0) and maps to a new position (normally
+ * between 0.0 and 1.0, but it may go above/below 0.0 or 1.0 to show that it
+ * has "overshot" the mark) using some interpolation (mapping) algorithm.
+ *
+ * This function useful to create non-linear animations. It offers a variety
+ * of possible animaton curves to be used:
+ * @li ECORE_POS_MAP_LINEAR - Linear, returns @p pos
+ * @li ECORE_POS_MAP_ACCELERATE - Start slow then speed up
+ * @li ECORE_POS_MAP_DECELERATE - Start fast then slow down
+ * @li ECORE_POS_MAP_SINUSOIDAL - Start slow, speed up then slow down at end
+ * @li ECORE_POS_MAP_ACCELERATE_FACTOR - Start slow then speed up, v1 being a
+ * power factor, 0.0 being linear, 1.0 being ECORE_POS_MAP_ACCELERATE, 2.0
+ * being much more pronounced accelerate (squared), 3.0 being cubed, etc.
+ * @li ECORE_POS_MAP_DECELERATE_FACTOR - Start fast then slow down, v1 being a
+ * power factor, 0.0 being linear, 1.0 being ECORE_POS_MAP_DECELERATE, 2.0
+ * being much more pronounced decelerate (squared), 3.0 being cubed, etc.
+ * @li ECORE_POS_MAP_SINUSOIDAL_FACTOR - Start slow, speed up then slow down
+ * at end, v1 being a power factor, 0.0 being linear, 1.0 being
+ * ECORE_POS_MAP_SINUSOIDAL, 2.0 being much more pronounced sinusoidal
+ * (squared), 3.0 being cubed, etc.
+ * @li ECORE_POS_MAP_DIVISOR_INTERP - Start at gradient * v1, interpolated via
+ * power of v2 curve
+ * @li ECORE_POS_MAP_BOUNCE - Start at 0.0 then "drop" like a ball bouncing to
+ * the ground at 1.0, and bounce v2 times, with decay factor of v1
+ * @li ECORE_POS_MAP_SPRING - Start at 0.0 then "wobble" like a spring rest
+ * position 1.0, and wobble v2 times, with decay factor of v1
+ * @note When not listed v1 and v2 have no effect.
+ *
+ * @image html ecore-pos-map.png
+ * @image latex ecore-pos-map.eps width=\textwidth
+ *
+ * One way to use this would be:
+ * @code
+ * double pos; // input position in a timeline from 0.0 to 1.0
+ * double out; // output position after mapping
+ * int x1, y1, x2, y2; // x1 & y1 are start position, x2 & y2 are end position
+ * int x, y; // x & y are the calculated position
+ *
+ * out = ecore_animator_pos_map(pos, ECORE_POS_MAP_BOUNCE, 1.8, 7);
+ * x = (x1 * out) + (x2 * (1.0 - out));
+ * y = (y1 * out) + (y2 * (1.0 - out));
+ * move_my_object_to(myobject, x, y);
+ * @endcode
+ * This will make an animaton that bounces 7 each times diminishing by a
+ * factor of 1.8.
+ *
+ * @see _Ecore_Pos_Map
+ *
+ * @since 1.1.0
+ */
+EAPI double
+ecore_animator_pos_map(double pos,
+ Ecore_Pos_Map map,
+ double v1,
+ double v2);
+/**
+ * @brief Set the source of animator ticks for the mainloop
+ *
+ * @param source The source of animator ticks to use
+ *
+ * This sets the source of animator ticks. When an animator is active the
+ * mainloop will "tick" over frame by frame calling all animators that are
+ * registered until none are. The mainloop will tick at a given rate based
+ * on the animator source. The default source is the system clock timer
+ * source - ECORE_ANIMATOR_SOURCE_TIMER. This source uses the system clock
+ * to tick over every N seconds (specified by ecore_animator_frametime_set(),
+ * with the default being 1/30th of a second unless set otherwise). You can
+ * set a custom tick source by setting the source to
+ * ECORE_ANIMATOR_SOURCE_CUSTOM and then drive it yourself based on some input
+ * tick source (like another application via ipc, some vertical blanking
+ * interrupt interrupt etc.) using
+ * ecore_animator_custom_source_tick_begin_callback_set() and
+ * ecore_animator_custom_source_tick_end_callback_set() to set the functions
+ * that will be called to start and stop the ticking source, which when it
+ * gets a "tick" should call ecore_animator_custom_tick() to make the "tick" over 1
+ * frame.
+ */
+EAPI void
+ecore_animator_source_set(Ecore_Animator_Source source);
+/**
+ * @brief Get the animator source currently set.
+ *
+ * @return The current animator source
+ *
+ * This gets the current animator source.
+ *
+ * @see ecore_animator_source_set()
+ */
+EAPI Ecore_Animator_Source
+ecore_animator_source_get(void);
+/**
+ * @brief Set the function that begins a custom animator tick source
+ *
+ * @param func The function to call when ticking is to begin
+ * @param data The data passed to the tick begin function as its parameter
+ *
+ * The Ecore Animator infrastructure handles tracking if animators are needed
+ * or not and which ones need to be called and when, but when the tick source
+ * is custom, you have to provide a tick source by calling
+ * ecore_animator_custom_tick() to indicate a frame tick happened. In order
+ * to allow the source of ticks to be dynamically enabled or disabled as
+ * needed, the @p func when set is called to enable the tick source to
+ * produce tick events that call ecore_animator_custom_tick(). If @p func
+ * is NULL then no function is called to begin custom ticking.
+ *
+ * @see ecore_animator_source_set()
+ * @see ecore_animator_custom_source_tick_end_callback_set()
+ * @see ecore_animator_custom_tick()
+ */
+EAPI void
+ecore_animator_custom_source_tick_begin_callback_set(Ecore_Cb func,
+ const void *data);
+/**
+ * @brief Set the function that ends a custom animator tick source
+ *
+ * @param func The function to call when ticking is to end
+ * @param data The data passed to the tick end function as its parameter
+ *
+ * This function is a matching pair to the function set by
+ * ecore_animator_custom_source_tick_begin_callback_set() and is called
+ * when ticking is to stop. If @p func is NULL then no function will be
+ * called to stop ticking. For more information please see
+ * ecore_animator_custom_source_tick_begin_callback_set().
+ *
+ * @see ecore_animator_source_set()
+ * @see ecore_animator_custom_source_tick_begin_callback_set()
+ * @see ecore_animator_custom_tick()
+ */
+EAPI void
+ecore_animator_custom_source_tick_end_callback_set(Ecore_Cb func,
+ const void *data);
+/**
+ * @brief Trigger a custom animator tick
+ *
+ * When animator source is set to ECORE_ANIMATOR_SOURCE_CUSTOM, then calling
+ * this function triggers a run of all animators currently registered with
+ * Ecore as this indicates a "frame tick" happened. This will do nothing if
+ * the animator source(set by ecore_animator_source_set()) is not set to
+ * ECORE_ANIMATOR_SOURCE_CUSTOM.
+ *
+ * @see ecore_animator_source_set()
+ * @see ecore_animator_custom_source_tick_begin_callback_set
+ * @see ecore_animator_custom_source_tick_end_callback_set()()
+ */
+EAPI void
+ecore_animator_custom_tick(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Ecore_Time_Group Ecore Time functions
+ *
+ * Functions that deal with time. These functions include those
+ * that simply retrieve it in a given format, and those that create
+ * events based on it.
+ *
+ * The timer allows callbacks to be called at specific intervals.
+ *
+ * Examples with functions that deal with time:
+ * @li @ref ecore_time_functions_example_c
+ * @li @ref ecore_timer_example_c
+ *
+ * @ingroup Ecore_Main_Loop_Group
+ *
+ * @{
+ */
+
+typedef struct _Ecore_Timer Ecore_Timer; /**< A handle for timers */
+
+EAPI double
+ ecore_time_get(void);
+EAPI double
+ ecore_time_unix_get(void);
+EAPI double
+ ecore_loop_time_get(void);
+
+EAPI Ecore_Timer *
+ecore_timer_add(double in,
+ Ecore_Task_Cb func,
+ const void *data);
+EAPI Ecore_Timer *
+ecore_timer_loop_add(double in,
+ Ecore_Task_Cb func,
+ const void *data);
+EAPI void *
+ ecore_timer_del(Ecore_Timer *timer);
+EAPI void
+ ecore_timer_interval_set(Ecore_Timer *timer,
+ double in);
+EAPI double
+ ecore_timer_interval_get(Ecore_Timer *timer);
+EAPI void
+ ecore_timer_freeze(Ecore_Timer *timer);
+EAPI void
+ ecore_timer_thaw(Ecore_Timer *timer);
+EAPI void
+ ecore_timer_delay(Ecore_Timer *timer,
+ double add);
+EAPI double
+ ecore_timer_pending_get(Ecore_Timer *timer);
+EAPI double
+ ecore_timer_precision_get(void);
+EAPI void
+ ecore_timer_precision_set(double precision);
+EAPI char *
+ ecore_timer_dump(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Ecore_Idle_Group Ecore Idle functions
+ *
+ * Callbacks that are called when the program enters or exits an
+ * idle state.
+ *
+ * The ecore main loop enters an idle state when it is waiting for
+ * timers to time out, data to come in on a file descriptor or any
+ * other event to occur. You can set callbacks to be called when
+ * the main loop enters an idle state, during an idle state or just
+ * after the program wakes up.
+ *
+ * Enterer callbacks are good for updating your program's state, if
+ * it has a state engine. Once all of the enterer handlers are
+ * called, the program will enter a "sleeping" state.
+ *
+ * Idler callbacks are called when the main loop has called all
+ * enterer handlers. They are useful for interfaces that require
+ * polling and timers would be too slow to use.
+ *
+ * If no idler callbacks are specified, then the process literally
+ * goes to sleep. Otherwise, the idler callbacks are called
+ * continuously while the loop is "idle", using as much CPU as is
+ * available to the process.
+ *
+ * Exiter callbacks are called when the main loop wakes up from an
+ * idle state.
+ *
+ * @note Idle state doesn't mean that the @b program is idle, but
+ * that the <b>main loop</b> is idle. It doesn't have any timers,
+ * events, fd handlers or anything else to process (which in most
+ * <em>event driven</em> programs also means that the @b program is
+ * idle too, but it's not a rule). The program itself may be doing
+ * a lot of processing in the idler, or in another thread, for
+ * example.
+ *
+ * Example with functions that deal with idle state:
+ *
+ * @li @ref ecore_idler_example_c
+ *
+ * @ingroup Ecore_Main_Loop_Group
+ *
+ * @{
+ */
+
+typedef struct _Ecore_Idler Ecore_Idler; /**< A handle for idlers */
+typedef struct _Ecore_Idle_Enterer Ecore_Idle_Enterer; /**< A handle for idle enterers */
+typedef struct _Ecore_Idle_Exiter Ecore_Idle_Exiter; /**< A handle for idle exiters */
+
+/**
+ * Add an idler handler.
+ * @param func The function to call when idling.
+ * @param data The data to be passed to this @p func call.
+ * @return A idler handle if successfully added. NULL otherwise.
+ *
+ * Add an idler handle to the event loop, returning a handle on
+ * success and NULL otherwise. The function @p func will be called
+ * repeatedly while no other events are ready to be processed, as
+ * long as it returns 1 (or ECORE_CALLBACK_RENEW). A return of 0
+ * (or ECORE_CALLBACK_CANCEL) deletes the idler.
+ *
+ * Idlers are useful for progressively prossessing data without blocking.
+ */
+EAPI Ecore_Idler *
+ecore_idler_add(Ecore_Task_Cb func,
+ const void *data);
+
+/**
+ * Delete an idler callback from the list to be executed.
+ * @param idler The handle of the idler callback to delete
+ * @return The data pointer passed to the idler callback on success. NULL
+ * otherwise.
+ */
+EAPI void *
+ecore_idler_del(Ecore_Idler *idler);
+
+EAPI Ecore_Idle_Enterer *
+ecore_idle_enterer_add(Ecore_Task_Cb func,
+ const void *data);
+EAPI Ecore_Idle_Enterer *
+ecore_idle_enterer_before_add(Ecore_Task_Cb func,
+ const void *data);
+EAPI void *
+ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer);
+
+EAPI Ecore_Idle_Exiter *
+ecore_idle_exiter_add(Ecore_Task_Cb func,
+ const void *data);
+EAPI void *
+ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Ecore_Thread_Group Ecore Thread functions
+ *
+ * Facilities to run heavy tasks in different threads to avoid blocking
+ * the main loop.
+ *
+ * The EFL is, for the most part, not thread safe. This means that if you
+ * have some task running in another thread and you have, for example, an
+ * Evas object to show the status progress of this task, you cannot update
+ * the object from within the thread. This can only be done from the main
+ * thread, the one running the main loop. This problem can be solved
+ * by running a thread that sends messages to the main one using an
+ * @ref Ecore_Pipe_Group "Ecore_Pipe", but when you need to handle other
+ * things like cancelling the thread, your code grows in coplexity and gets
+ * much harder to maintain.
+ *
+ * Ecore Thread is here to solve that problem. It is @b not a simple wrapper
+ * around standard POSIX threads (or the equivalent in other systems) and
+ * it's not meant to be used to run parallel tasks throughout the entire
+ * duration of the program, especially when these tasks are performance
+ * critical, as Ecore manages these tasks using a pool of threads based on
+ * system configuration.
+ *
+ * What Ecore Thread does, is make it a lot easier to dispatch a worker
+ * function to perform some heavy task and then get the result once it
+ * completes, without blocking the application's UI. In addition, cancelling
+ * and rescheduling comes practically for free and the developer needs not
+ * worry about how many threads are launched, since Ecore will schedule
+ * them according to the number of processors the system has and maximum
+ * amount of concurrent threads set for the application.
+ *
+ * At the system level, Ecore will start a new thread on an as-needed basis
+ * until the maximum set is reached. When no more threads can be launched,
+ * new worker functions will be queued in a waiting list until a thread
+ * becomes available. This way, system threads will be shared throughout
+ * different worker functions, but running only one at a time. At the same
+ * time, a worker function that is rescheduled may be run on a different
+ * thread the next time.
+ *
+ * The ::Ecore_Thread handler has two meanings, depending on what context
+ * it is on. The one returned when starting a worker with any of the
+ * functions ecore_thread_run() or ecore_thread_feedback_run() is an
+ * identifier of that specific instance of the function and can be used from
+ * the main loop with the ecore_thread_cancel() and ecore_thread_check()
+ * functions. This handler must not be shared with the worker function
+ * function running in the thread. This same handler will be the one received
+ * on the @c end, @c cancel and @c feedback callbacks.
+ *
+ * The worker function, that's the one running in the thread, also receives
+ * an ::Ecore_Thread handler that can be used with ecore_thread_cancel() and
+ * ecore_thread_check(), sharing the flag with the main loop. But this
+ * handler is also associated with the thread where the function is running.
+ * This has strong implications when working with thread local data.
+ *
+ * There are two kinds of worker threads Ecore handles: simple, or short,
+ * workers and feedback workers.
+ *
+ * The first kind is for simple functions that perform a
+ * usually small but time consuming task. Ecore will run this function in
+ * a thread as soon as one becomes available and notify the calling user of
+ * its completion once the task is done.
+ *
+ * The following image shows the flow of a program running four tasks on
+ * a pool of two threads.
+ *
+ * @image html ecore_thread.png
+ * @image rtf ecore_thread.png
+ * @image latex ecore_thread.eps width=\textwidth
+ *
+ * For larger tasks that may require continuous communication with the main
+ * program, the feedback workers provide the same functionality plus a way
+ * for the function running in the thread to send messages to the main
+ * thread.
+ *
+ * The next diagram omits some details shown in the previous one regarding
+ * how threads are spawned and tasks are queued, but illustrates how feedback
+ * jobs communicate with the main loop and the special case of threads
+ * running out of pool.
+ *
+ * @image html ecore_thread_feedback.png
+ * @image rtf ecore_thread_feedback.png
+ * @image latex ecore_thread_feedback.eps width=\textwidth
+ *
+ * See an overview example in @ref ecore_thread_example_c.
+ *
+ * @ingroup Ecore_Main_Loop_Group
+ *
+ * @{
+ */
+
+typedef struct _Ecore_Thread Ecore_Thread; /**< A handle for threaded jobs */
+
+/**
+ * @typedef Ecore_Thread_Cb Ecore_Thread_Cb
+ * A callback used by Ecore_Thread helper.
+ */
+typedef void (*Ecore_Thread_Cb)(void *data, Ecore_Thread *thread);
+/**
+ * @typedef Ecore_Thread_Notify_Cb Ecore_Thread_Notify_Cb
+ * A callback used by the main loop to receive data sent by an
+ * @ref Ecore_Thread_Group.
+ */
+typedef void (*Ecore_Thread_Notify_Cb)(void *data, Ecore_Thread *thread, void *msg_data);
+
+/**
+ * Schedule a task to run in a parallel thread to avoid locking the main loop
+ *
+ * @param func_blocking The function that should run in another thread.
+ * @param func_end Function to call from main loop when @p func_blocking
+ * completes its task successfully (may be NULL)
+ * @param func_cancel Function to call from main loop if the thread running
+ * @p func_blocking is cancelled or fails to start (may be NULL)
+ * @param data User context data to pass to all callbacks.
+ * @return A new thread handler, or NULL on failure
+ *
+ * This function will try to create a new thread to run @p func_blocking in,
+ * or if the maximum number of concurrent threads has been reached, will
+ * add it to the pending list, where it will wait until a thread becomes
+ * available. The return value will be an ::Ecore_Thread handle that can
+ * be used to cancel the thread before its completion.
+ *
+ * @note This function should always return immediately, but in the rare
+ * case that Ecore is built with no thread support, @p func_blocking will
+ * be called here, actually blocking the main loop.
+ *
+ * Once a thread becomes available, @p func_blocking will be run in it until
+ * it finishes, then @p func_end is called from the thread containing the
+ * main loop to inform the user of its completion. While in @p func_blocking,
+ * no functions from the EFL can be used, except for those from Eina that are
+ * marked to be thread-safe. Even for the latter, caution needs to be taken
+ * if the data is shared across several threads.
+ *
+ * @p func_end will be called from the main thread when @p func_blocking ends,
+ * so here it's safe to use anything from the EFL freely.
+ *
+ * The thread can also be cancelled before its completion calling
+ * ecore_thread_cancel(), either from the main thread or @p func_blocking.
+ * In this case, @p func_cancel will be called, also from the main thread
+ * to inform of this happening. If the thread could not be created, this
+ * function will be called and it's @c thread parameter will be NULL. It's
+ * also safe to call any EFL function here, as it will be running in the
+ * main thread.
+ *
+ * Inside @p func_blocking, it's possible to call ecore_thread_reschedule()
+ * to tell Ecore that this function should be called again.
+ *
+ * Be aware that no assumptions can be made about the order in which the
+ * @p func_end callbacks for each task will be called. Once the function is
+ * running in a different thread, it's the OS that will handle its running
+ * schedule, and different functions may take longer to finish than others.
+ * Also remember that just starting several tasks together doesn't mean they
+ * will be running at the same time. Ecore will schedule them based on the
+ * number of threads available for the particular system it's running in,
+ * so some of the jobs started may be waiting until another one finishes
+ * before it can execute its own @p func_blocking.
+ *
+ * @see ecore_thread_feedback_run()
+ * @see ecore_thread_cancel()
+ * @see ecore_thread_reschedule()
+ * @see ecore_thread_max_set()
+ */
+EAPI Ecore_Thread *
+ecore_thread_run(Ecore_Thread_Cb func_blocking,
+ Ecore_Thread_Cb func_end,
+ Ecore_Thread_Cb func_cancel,
+ const void *data);
+/**
+ * Launch a thread to run a task than can talk back to the main thread
+ *
+ * @param func_heavy The function that should run in another thread.
+ * @param func_notify Function that receives the data sent from the thread
+ * @param func_end Function to call from main loop when @p func_heavy
+ * completes its task successfully
+ * @param func_cancel Function to call from main loop if the thread running
+ * @p func_heavy is cancelled or fails to start
+ * @param data User context data to pass to all callback.
+ * @param try_no_queue If you want to run outside of the thread pool.
+ * @return A new thread handler, or NULL on failure
+ *
+ * See ecore_thread_run() for a general description of this function.
+ *
+ * The difference with the above is that ecore_thread_run() is meant for
+ * tasks that don't need to communicate anything until they finish, while
+ * this function is provided with a new callback, @p func_notify, that will
+ * be called from the main thread for every message sent from @p func_heavy
+ * with ecore_thread_feedback().
+ *
+ * Like with ecore_thread_run(), a new thread will be launched to run
+ * @p func_heavy unless the maximum number of simultaneous threadas has been
+ * reached, in which case the function will be scheduled to run whenever a
+ * running task ends and a thread becomes free. But if @p try_no_queue is
+ * set, Ecore will first try to launch a thread outside of the pool to run
+ * the task. If it fails, it will revert to the normal behaviour of using a
+ * thread from the pool as if @p try_no_queue had not been set.
+ *
+ * Keep in mind that Ecore handles the thread pool based on the number of
+ * CPUs available, but running a thread outside of the pool doesn't count for
+ * this, so having too many of them may have drastic effects over the
+ * program's performance.
+ *
+ * @see ecore_thread_feedback()
+ * @see ecore_thread_run()
+ * @see ecore_thread_cancel()
+ * @see ecore_thread_reschedule()
+ * @see ecore_thread_max_set()
+ */
+EAPI Ecore_Thread *
+ecore_thread_feedback_run(Ecore_Thread_Cb func_heavy,
+ Ecore_Thread_Notify_Cb func_notify,
+ Ecore_Thread_Cb func_end,
+ Ecore_Thread_Cb func_cancel,
+ const void *data,
+ Eina_Bool try_no_queue);
+/**
+ * Cancel a running thread.
+ *
+ * @param thread The thread to cancel.
+ * @return Will return EINA_TRUE if the thread has been cancelled,
+ * EINA_FALSE if it is pending.
+ *
+ * This function can be called both in the main loop or in the running thread.
+ *
+ * This function cancels a running thread. If @p thread can be immediately
+ * cancelled (it's still pending execution after creation or rescheduling),
+ * then the @c cancel callback will be called, @p thread will be freed and
+ * the function will return EINA_TRUE.
+ *
+ * If the thread is already running, then this function returns EINA_FALSE
+ * after marking the @p thread as pending cancellation. For the thread to
+ * actually be terminated, it needs to return from the user function back
+ * into Ecore control. This can happen in several ways:
+ * @li The function ends and returns normally. If it hadn't been cancelled,
+ * @c func_end would be called here, but instead @c func_cancel will happen.
+ * @li The function returns after requesting to be rescheduled with
+ * ecore_thread_reschedule().
+ * @li The function is prepared to leave early by checking if
+ * ecore_thread_check() returns EINA_TRUE.
+ *
+ * The user function can cancel itself by calling ecore_thread_cancel(), but
+ * it should always use the ::Ecore_Thread handle passed to it and never
+ * share it with the main loop thread by means of shared user data or any
+ * other way.
+ *
+ * @p thread will be freed and should not be used again if this function
+ * returns EINA_TRUE or after the @c func_cancel callback returns.
+ *
+ * @see ecore_thread_check()
+ */
+EAPI Eina_Bool
+ecore_thread_cancel(Ecore_Thread *thread);
+/**
+ * Checks if a thread is pending cancellation
+ *
+ * @param thread The thread to test.
+ * @return EINA_TRUE if the thread is pending cancellation,
+ * EINA_FALSE if it is not.
+ *
+ * This function can be called both in the main loop or in the running thread.
+ *
+ * When ecore_thread_cancel() is called on an already running task, the
+ * thread is marked as pending cancellation. This function returns EINA_TRUE
+ * if this mark is set for the given @p thread and can be used from the
+ * main loop thread to check if a still active thread has been cancelled,
+ * or from the user function running in the thread to check if it should
+ * stop doing what it's doing and return early, effectively cancelling the
+ * task.
+ *
+ * @see ecore_thread_cancel()
+ */
+EAPI Eina_Bool
+ecore_thread_check(Ecore_Thread *thread);
+/**
+ * Sends data from the worker thread to the main loop
+ *
+ * @param thread The current ::Ecore_Thread context to send data from
+ * @param msg_data Data to be transmitted to the main loop
+ * @return EINA_TRUE if @p msg_data was successfully sent to main loop,
+ * EINA_FALSE if anything goes wrong.
+ *
+ * You should use this function only in the @c func_heavy call.
+ *
+ * Only the address to @p msg_data will be sent and once this function
+ * returns EINA_TRUE, the job running in the thread should never touch the
+ * contents of it again. The data sent should be malloc()'ed or something
+ * similar, as long as it's not memory local to the thread that risks being
+ * overwritten or deleted once it goes out of scope or the thread finishes.
+ *
+ * Care must be taken that @p msg_data is properly freed in the @c func_notify
+ * callback set when creating the thread.
+ *
+ * @see ecore_thread_feedback_run()
+ */
+EAPI Eina_Bool
+ecore_thread_feedback(Ecore_Thread *thread,
+ const void *msg_data);
+/**
+ * Asks for the function in the thread to be called again at a later time
+ *
+ * @param thread The current ::Ecore_Thread context to rescheduled
+ * @return EINA_TRUE if the task was successfully rescheduled,
+ * EINA_FALSE if anything goes wrong.
+ *
+ * This function should be called only from the same function represented
+ * by @pthread.
+ *
+ * Calling this function will mark the thread for a reschedule, so as soon
+ * as it returns, it will be added to the end of the list of pending tasks.
+ * If no other tasks are waiting or there are sufficient threads available,
+ * the rescheduled task will be launched again immediately.
+ *
+ * This should never return EINA_FALSE, unless it was called from the wrong
+ * thread or with the wrong arguments.
+ *
+ * The @c func_end callback set when the thread is created will not be
+ * called until the function in the thread returns without being rescheduled.
+ * Similarly, if the @p thread is cancelled, the reschedule will not take
+ * effect.
+ */
+EAPI Eina_Bool
+ecore_thread_reschedule(Ecore_Thread *thread);
+/**
+ * Gets the number of active threads running jobs
+ *
+ * @return Number of active threads running jobs
+ *
+ * This returns the number of threads currently running jobs of any type
+ * through the Ecore_Thread API.
+ *
+ * @note Jobs started through the ecore_thread_feedback_run() function with
+ * the @c try_no_queue parameter set to EINA_TRUE will not be accounted for
+ * in the return of this function unless the thread creation fails and it
+ * falls back to using one from the pool.
+ */
+EAPI int
+ecore_thread_active_get(void);
+/**
+ * Gets the number of short jobs waiting for a thread to run
+ *
+ * @return Number of pending threads running "short" jobs
+ *
+ * This returns the number of tasks started with ecore_thread_run() that are
+ * pending, waiting for a thread to become available to run them.
+ */
+EAPI int
+ecore_thread_pending_get(void);
+/**
+ * Gets the number of feedback jobs waiting for a thread to run
+ *
+ * @return Number of pending threads running "feedback" jobs
+ *
+ * This returns the number of tasks started with ecore_thread_feedback_run()
+ * that are pending, waiting for a thread to become available to run them.
+ */
+EAPI int
+ecore_thread_pending_feedback_get(void);
+/**
+ * Gets the total number of pending jobs
+ *
+ * @return Number of pending threads running jobs
+ *
+ * Same as the sum of ecore_thread_pending_get() and
+ * ecore_thread_pending_feedback_get().
+ */
+EAPI int
+ecore_thread_pending_total_get(void);
+/**
+ * Gets the maximum number of threads that can run simultaneously
+ *
+ * @return Max possible number of Ecore_Thread's running concurrently
+ *
+ * This returns the maximum number of Ecore_Thread's that may be running at
+ * the same time. If this number is reached, new jobs started by either
+ * ecore_thread_run() or ecore_thread_feedback_run() will be added to the
+ * respective pending queue until one of the running threads finishes its
+ * task and becomes available to run a new one.
+ *
+ * By default, this will be the number of available CPUs for the
+ * running program (as returned by eina_cpu_count()), or 1 if this value
+ * could not be fetched.
+ *
+ * @see ecore_thread_max_set()
+ * @see ecore_thread_max_reset()
+ */
+EAPI int
+ecore_thread_max_get(void);
+/**
+ * Sets the maximum number of threads allowed to run simultaneously
+ *
+ * @param num The new maximum
+ *
+ * This sets a new value for the maximum number of concurrently running
+ * Ecore_Thread's. It @b must an integer between 1 and (2 * @c x), where @c x
+ * is the number for CPUs available.
+ *
+ * @see ecore_thread_max_get()
+ * @see ecore_thread_max_reset()
+ */
+EAPI void
+ecore_thread_max_set(int num);
+/**
+ * Resets the maximum number of concurrently running threads to the default
+ *
+ * This resets the value returned by ecore_thread_max_get() back to its
+ * default.
+ *
+ * @see ecore_thread_max_get()
+ * @see ecore_thread_max_set()
+ */
+EAPI void
+ecore_thread_max_reset(void);
+/**
+ * Gets the number of threads available for running tasks
+ *
+ * @return The number of available threads
+ *
+ * Same as doing ecore_thread_max_get() - ecore_thread_active_get().
+ *
+ * This function may return a negative number only in the case the user
+ * changed the maximum number of running threads while other tasks are
+ * running.
+ */
+EAPI int
+ecore_thread_available_get(void);
+/**
+ * Adds some data to a hash local to the thread
+ *
+ * @param thread The thread context the data belongs to
+ * @param key The name under which the data will be stored
+ * @param value The data to add
+ * @param cb Function to free the data when removed from the hash
+ * @param direct If true, this will not copy the key string (like
+ * eina_hash_direct_add())
+ * @return EINA_TRUE on success, EINA_FALSE on failure
+ *
+ * Ecore Thread has a mechanism to share data across several worker functions
+ * that run on the same system thread. That is, the data is stored per
+ * thread and for a worker function to have access to it, it must be run
+ * by the same thread that stored the data.
+ *
+ * When there are no more workers pending, the thread will be destroyed
+ * along with the internal hash and any data left in it will be freed with
+ * the @p cb function given.
+ *
+ * This set of functions is useful to share things around several instances
+ * of a function when that thing is costly to create and can be reused, but
+ * may only be used by one function at a time.
+ *
+ * For example, if you have a program doing requisitions to a database,
+ * these requisitions can be done in threads so that waiting for the
+ * database to respond doesn't block the UI. Each of these threads will
+ * run a function, and each function will be dependent on a connection to
+ * the database, which may not be able to handle more than one request at
+ * a time so for each running function you will need one connection handle.
+ * The options then are:
+ * @li Each function opens a connection when it's called, does the work and
+ * closes the connection when it finishes. This may be costly, wasting a lot
+ * of time on resolving hostnames, negotiating permissions and allocating
+ * memory.
+ * @li Open the connections in the main loop and pass it to the threads
+ * using the data pointer. Even worse, it's just as costly as before and now
+ * it may even be kept with connections open doing nothing until a thread
+ * becomes available to run the function.
+ * @li Have a way to share connection handles, so that each instance of the
+ * function can check if an available connection exists, and if it doesn't,
+ * create one and add it to the pool. When no more connections are needed,
+ * they are all closed.
+ *
+ * The last option is the most efficient, but it requires a lot of work to
+ * implement properly. Using thread local data helps to achieve the same
+ * result while avoiding doing all the tracking work on your code. The way
+ * to use it would be, at the worker function, to ask for the connection
+ * with ecore_thread_local_data_find() and if it doesn't exist, then open
+ * a new one and save it with ecore_thread_local_data_add(). Do the work and
+ * forget about the connection handle, when everything is done the function
+ * just ends. The next worker to run on that thread will check if a
+ * connection exists and find that it does, so the process of opening a
+ * new one has been spared. When no more workers exist, the thread is
+ * destroyed and the callback used when saving the connection will be called
+ * to close it.
+ *
+ * This function adds the data @p value to the thread data under the given
+ * @p key.
+ * No other value in the hash may have the same @p key. If you need to
+ * change the value under a @p key, or you don't know if one exists already,
+ * you can use ecore_thread_local_data_set().
+ *
+ * Neither @p key nor @p value may be NULL and @p key will be copied in the
+ * hash, unless @p direct is set, in which case the string used should not
+ * be freed until the data is removed from the hash.
+ *
+ * The @p cb function will be called when the data in the hash needs to be
+ * freed, be it because it got deleted with ecore_thread_local_data_del() or
+ * because @p thread was terminated and the hash destroyed. This parameter
+ * may be NULL, in which case @p value needs to be manually freed after
+ * removing it from the hash with either ecore_thread_local_data_del() or
+ * ecore_thread_local_data_set(), but it's very unlikely that this is what
+ * you want.
+ *
+ * This function, and all of the others in the @c ecore_thread_local_data
+ * family of functions, can only be called within the worker function running
+ * in the thread. Do not call them from the main loop or from a thread
+ * other than the one represented by @p thread.
+ *
+ * @see ecore_thread_local_data_set()
+ * @see ecore_thread_local_data_find()
+ * @see ecore_thread_local_data_del()
+ */
+EAPI Eina_Bool
+ecore_thread_local_data_add(Ecore_Thread *thread,
+ const char *key,
+ void *value,
+ Eina_Free_Cb cb,
+ Eina_Bool direct);
+/**
+ * Sets some data in the hash local to the given thread
+ *
+ * @param thread The thread context the data belongs to
+ * @param key The name under which the data will be stored
+ * @param value The data to add
+ * @param cb Function to free the data when removed from the hash
+ *
+ * If no data exists in the hash under the @p key, this function adds
+ * @p value in the hash under the given @p key and returns NULL.
+ * The key itself is copied.
+ *
+ * If the hash already contains something under @p key, the data will be
+ * replaced by @p value and the old value will be returned.
+ *
+ * NULL will also be returned if either @p key or @p value are NULL, or if
+ * an error occurred.
+ *
+ * This function, and all of the others in the @c ecore_thread_local_data
+ * family of functions, can only be called within the worker function running
+ * in the thread. Do not call them from the main loop or from a thread
+ * other than the one represented by @p thread.
+ *
+ * @see ecore_thread_local_data_add()
+ * @see ecore_thread_local_data_del()
+ * @see ecore_thread_local_data_find()
+ */
+EAPI void *
+ecore_thread_local_data_set(Ecore_Thread *thread,
+ const char *key,
+ void *value,
+ Eina_Free_Cb cb);
+/**
+ * Gets data stored in the hash local to the given thread
+ *
+ * @param thread The thread context the data belongs to
+ * @param key The name under which the data is stored
+ * @return The value under the given key, or NULL on error
+ *
+ * Finds and return the data stored in the shared hash under the key @p key.
+ *
+ * This function, and all of the others in the @c ecore_thread_local_data
+ * family of functions, can only be called within the worker function running
+ * in the thread. Do not call them from the main loop or from a thread
+ * other than the one represented by @p thread.
+ *
+ * @see ecore_thread_local_data_add()
+ * @see ecore_thread_local_data_wait()
+ */
+EAPI void *
+ecore_thread_local_data_find(Ecore_Thread *thread,
+ const char *key);
+/**
+ * Deletes from the thread's hash the data corresponding to the given key
+ *
+ * @param thread The thread context the data belongs to
+ * @param key The name under which the data is stored
+ * @return EINA_TRUE on success, EINA_FALSE on failure
+ *
+ * If there's any data stored associated with @p key in the global hash,
+ * this function will remove it from it and return EINA_TRUE. If no data
+ * exists or an error occurs, it returns EINA_FALSE.
+ *
+ * If the data was added to the hash with a free function, then it will
+ * also be freed after removing it from the hash, otherwise it requires
+ * to be manually freed by the user, which means that if no other reference
+ * to it exists before calling this function, it will result in a memory
+ * leak.
+ *
+ * This function, and all of the others in the @c ecore_thread_local_data
+ * family of functions, can only be called within the worker function running
+ * in the thread. Do not call them from the main loop or from a thread
+ * other than the one represented by @p thread.
+ *
+ * @see ecore_thread_local_data_add()
+ */
+EAPI Eina_Bool
+ecore_thread_local_data_del(Ecore_Thread *thread,
+ const char *key);
+
+/**
+ * Adds some data to a hash shared by all threads
+ *
+ * @param key The name under which the data will be stored
+ * @param value The data to add
+ * @param cb Function to free the data when removed from the hash
+ * @param direct If true, this will not copy the key string (like
+ * eina_hash_direct_add())
+ * @return EINA_TRUE on success, EINA_FALSE on failure
+ *
+ * Ecore Thread keeps a hash that can be used to share data across several
+ * threads, including the main loop one, without having to manually handle
+ * mutexes to do so safely.
+ *
+ * This function adds the data @p value to this hash under the given @p key.
+ * No other value in the hash may have the same @p key. If you need to
+ * change the value under a @p key, or you don't know if one exists already,
+ * you can use ecore_thread_global_data_set().
+ *
+ * Neither @p key nor @p value may be NULL and @p key will be copied in the
+ * hash, unless @p direct is set, in which case the string used should not
+ * be freed until the data is removed from the hash.
+ *
+ * The @p cb function will be called when the data in the hash needs to be
+ * freed, be it because it got deleted with ecore_thread_global_data_del() or
+ * because Ecore Thread was shut down and the hash destroyed. This parameter
+ * may be NULL, in which case @p value needs to be manually freed after
+ * removing it from the hash with either ecore_thread_global_data_del() or
+ * ecore_thread_global_data_set().
+ *
+ * Manually freeing any data that was added to the hash with a @p cb function
+ * is likely to produce a segmentation fault, or any other strange
+ * happenings, later on in the program.
+ *
+ * @see ecore_thread_global_data_del()
+ * @see ecore_thread_global_data_set()
+ * @see ecore_thread_global_data_find()
+ */
+EAPI Eina_Bool
+ecore_thread_global_data_add(const char *key,
+ void *value,
+ Eina_Free_Cb cb,
+ Eina_Bool direct);
+/**
+ * Sets some data in the hash shared by all threads
+ *
+ * @param key The name under which the data will be stored
+ * @param value The data to add
+ * @param cb Function to free the data when removed from the hash
+ *
+ * If no data exists in the hash under the @p key, this function adds
+ * @p value in the hash under the given @p key and returns NULL.
+ * The key itself is copied.
+ *
+ * If the hash already contains something under @p key, the data will be
+ * replaced by @p value and the old value will be returned.
+ *
+ * NULL will also be returned if either @p key or @p value are NULL, or if
+ * an error occurred.
+ *
+ * @see ecore_thread_global_data_add()
+ * @see ecore_thread_global_data_del()
+ * @see ecore_thread_global_data_find()
+ */
+EAPI void *
+ecore_thread_global_data_set(const char *key,
+ void *value,
+ Eina_Free_Cb cb);
+/**
+ * Gets data stored in the hash shared by all threads
+ *
+ * @param key The name under which the data is stored
+ * @return The value under the given key, or NULL on error
+ *
+ * Finds and return the data stored in the shared hash under the key @p key.
+ *
+ * Keep in mind that the data returned may be used by more than one thread
+ * at the same time and no reference counting is done on it by Ecore.
+ * Freeing the data or modifying its contents may require additional
+ * precautions to be considered, depending on the application's design.
+ *
+ * @see ecore_thread_global_data_add()
+ * @see ecore_thread_global_data_wait()
+ */
+EAPI void *
+ecore_thread_global_data_find(const char *key);
+/**
+ * Deletes from the shared hash the data corresponding to the given key
+ *
+ * @param key The name under which the data is stored
+ * @return EINA_TRUE on success, EINA_FALSE on failure
+ *
+ * If there's any data stored associated with @p key in the global hash,
+ * this function will remove it from it and return EINA_TRUE. If no data
+ * exists or an error occurs, it returns EINA_FALSE.
+ *
+ * If the data was added to the hash with a free function, then it will
+ * also be freed after removing it from the hash, otherwise it requires
+ * to be manually freed by the user, which means that if no other reference
+ * to it exists before calling this function, it will result in a memory
+ * leak.
+ *
+ * Note, also, that freeing data that other threads may be using will result
+ * in a crash, so appropriate care must be taken by the application when
+ * that possibility exists.
+ *
+ * @see ecore_thread_global_data_add()
+ */
+EAPI Eina_Bool
+ecore_thread_global_data_del(const char *key);
+/**
+ * Gets data stored in the shared hash, or wait for it if it doesn't exist
+ *
+ * @param key The name under which the data is stored
+ * @param seconds The amount of time in seconds to wait for the data.
+ * @return The value under the given key, or NULL on error
+ *
+ * Finds and return the data stored in the shared hash under the key @p key.
+ *
+ * If there's nothing in the hash under the given @p key, the function
+ * will block and wait up to @p seconds seconds for some other thread to
+ * add it with either ecore_thread_global_data_add() or
+ * ecore_thread_global_data_set(). If after waiting there's still no data
+ * to get, NULL will be returned.
+ *
+ * If @p seconds is 0, then no waiting will happen and this function works
+ * like ecore_thread_global_data_find(). If @p seconds is less than 0, then
+ * the function will wait indefinitely.
+ *
+ * Keep in mind that the data returned may be used by more than one thread
+ * at the same time and no reference counting is done on it by Ecore.
+ * Freeing the data or modifying its contents may require additional
+ * precautions to be considered, depending on the application's design.
+ *
+ * @see ecore_thread_global_data_add()
+ * @see ecore_thread_global_data_find()
+ */
+EAPI void *
+ecore_thread_global_data_wait(const char *key,
+ double seconds);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Ecore_Pipe_Group Pipe wrapper
+ *
+ * These functions wrap the pipe / write / read functions to easily
+ * integrate its use into ecore's main loop.
+ *
+ * The ecore_pipe_add() function creates file descriptors (sockets
+ * on Windows) and attach a handle to the ecore main loop. That
+ * handle is called when data is read in the pipe. To write data in
+ * the pipe, just call ecore_pipe_write(). When you are done, just
+ * call ecore_pipe_del().
+ *
+ * For examples see here:
+ * @li @ref tutorial_ecore_pipe_gstreamer_example
+ * @li @ref tutorial_ecore_pipe_simple_example
+ *
+ * @ingroup Ecore_Main_Loop_Group
+ *
+ * @{
+ */
+
+typedef struct _Ecore_Pipe Ecore_Pipe; /**< A handle for pipes */
+
+/**
+ * @typedef Ecore_Pipe_Cb Ecore_Pipe_Cb
+ * The callback that data written to the pipe is sent to.
+ */
+typedef void (*Ecore_Pipe_Cb)(void *data, void *buffer, unsigned int nbyte);
+
+EAPI Ecore_Pipe *
+ecore_pipe_add(Ecore_Pipe_Cb handler,
+ const void *data);
+EAPI void *
+ ecore_pipe_del(Ecore_Pipe *p);
+EAPI Eina_Bool
+ ecore_pipe_write(Ecore_Pipe *p,
+ const void *buffer,
+ unsigned int nbytes);
+EAPI void
+ ecore_pipe_write_close(Ecore_Pipe *p);
+EAPI void
+ ecore_pipe_read_close(Ecore_Pipe *p);
+EAPI void
+ ecore_pipe_thaw(Ecore_Pipe *p);
+EAPI void
+ ecore_pipe_freeze(Ecore_Pipe *p);
+EAPI int
+ ecore_pipe_wait(Ecore_Pipe *p,
+ int message_count,
+ double wait);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Ecore_Job_Group Ecore Job functions
+ *
+ * You can queue jobs that are to be done by the main loop when the
+ * current event is dealt with.
+ *
+ * Jobs are processed by the main loop similarly to events. They
+ * also will be executed in the order in which they were added.
+ *
+ * A good use for them is when you don't want to execute an action
+ * immeditately, but want to give the control back to the main loop
+ * so that it will call your job callback when jobs start being
+ * processed (and if there are other jobs added before yours, they
+ * will be processed first). This also gives the chance to other
+ * actions in your program to cancel the job before it is started.
+ *
+ * Examples of using @ref Ecore_Job:
+ * @li @ref ecore_job_example_c
+ *
+ * @ingroup Ecore_Main_Loop_Group
+ *
+ * @{
+ */
+
+typedef struct _Ecore_Job Ecore_Job; /**< A job handle */
+
+EAPI Ecore_Job *
+ecore_job_add(Ecore_Cb func,
+ const void *data);
+EAPI void *
+ecore_job_del(Ecore_Job *job);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Ecore_Application_Group Ecore Application functions
+ *
+ * @{
+ */
+
+EAPI void
+ecore_app_args_set(int argc,
+ const char **argv);
+EAPI void
+ecore_app_args_get(int *argc,
+ char ***argv);
+EAPI void
+ecore_app_restart(void);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Ecore_Throttle_Group Ecore Throttle functions
+ *
+ * @ingroup Ecore_Main_Loop_Group
+ *
+ * @{
+ */
+
+EAPI void
+ ecore_throttle_adjust(double amount);
+EAPI double
+ ecore_throttle_get(void);
+
+/**
+ * @}
+ */
#ifdef __cplusplus
}
* use multiple values with the same parser.
*/
-
#ifdef __cplusplus
extern "C" {
#endif
- typedef enum {
- ECORE_GETOPT_ACTION_STORE,
- ECORE_GETOPT_ACTION_STORE_CONST,
- ECORE_GETOPT_ACTION_STORE_TRUE,
- ECORE_GETOPT_ACTION_STORE_FALSE,
- ECORE_GETOPT_ACTION_CHOICE,
- ECORE_GETOPT_ACTION_APPEND,
- ECORE_GETOPT_ACTION_COUNT,
- ECORE_GETOPT_ACTION_CALLBACK,
- ECORE_GETOPT_ACTION_HELP,
- ECORE_GETOPT_ACTION_VERSION,
- ECORE_GETOPT_ACTION_COPYRIGHT,
- ECORE_GETOPT_ACTION_LICENSE
- } Ecore_Getopt_Action;
-
- typedef enum {
- ECORE_GETOPT_TYPE_STR,
- ECORE_GETOPT_TYPE_BOOL,
- ECORE_GETOPT_TYPE_SHORT,
- ECORE_GETOPT_TYPE_INT,
- ECORE_GETOPT_TYPE_LONG,
- ECORE_GETOPT_TYPE_USHORT,
- ECORE_GETOPT_TYPE_UINT,
- ECORE_GETOPT_TYPE_ULONG,
- ECORE_GETOPT_TYPE_DOUBLE
- } Ecore_Getopt_Type;
-
- typedef enum {
- ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO = 0,
- ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES = 1,
- ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL = 3
- } Ecore_Getopt_Desc_Arg_Requirement;
-
- typedef union _Ecore_Getopt_Value Ecore_Getopt_Value;
-
- typedef struct _Ecore_Getopt_Desc_Store Ecore_Getopt_Desc_Store;
- typedef struct _Ecore_Getopt_Desc_Callback Ecore_Getopt_Desc_Callback;
- typedef struct _Ecore_Getopt_Desc Ecore_Getopt_Desc;
- typedef struct _Ecore_Getopt Ecore_Getopt;
-
- union _Ecore_Getopt_Value
- {
- char **strp;
- unsigned char *boolp;
- short *shortp;
- int *intp;
- long *longp;
- unsigned short *ushortp;
- unsigned int *uintp;
- unsigned long *ulongp;
- double *doublep;
- Eina_List **listp;
- void **ptrp;
- };
-
- struct _Ecore_Getopt_Desc_Store
- {
- Ecore_Getopt_Type type; /**< type of data being handled */
- Ecore_Getopt_Desc_Arg_Requirement arg_req;
- union
- {
- const char *strv;
- Eina_Bool boolv;
- short shortv;
- int intv;
- long longv;
- unsigned short ushortv;
- unsigned int uintv;
- unsigned long ulongv;
- double doublev;
- } def;
- };
-
- struct _Ecore_Getopt_Desc_Callback
- {
- Eina_Bool (*func)(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc, const char *str, void *data, Ecore_Getopt_Value *storage);
- const void *data;
- Ecore_Getopt_Desc_Arg_Requirement arg_req;
- const char *def;
- };
-
- struct _Ecore_Getopt_Desc
- {
- char shortname; /**< used with a single dash */
- const char *longname; /**< used with double dashes */
- const char *help; /**< used by --help/ecore_getopt_help() */
- const char *metavar; /**< used by ecore_getopt_help() with nargs > 0 */
-
- Ecore_Getopt_Action action; /**< define how to handle it */
- union
- {
- const Ecore_Getopt_Desc_Store store;
- const void *store_const;
- const char *const *choices; /* NULL terminated. */
- const Ecore_Getopt_Type append_type;
- const Ecore_Getopt_Desc_Callback callback;
- const void *dummy;
- } action_param;
- };
-
- struct _Ecore_Getopt
- {
- const char *prog; /**< to be used when ecore_app_args_get() fails */
- const char *usage; /**< usage example, %prog is replaced */
- const char *version; /**< if exists, --version will work */
- const char *copyright; /**< if exists, --copyright will work */
- const char *license; /**< if exists, --license will work */
- const char *description; /**< long description, possible multiline */
- Eina_Bool strict : 1; /**< fail on errors */
- const Ecore_Getopt_Desc descs[]; /* NULL terminated. */
- };
+typedef enum {
+ ECORE_GETOPT_ACTION_STORE,
+ ECORE_GETOPT_ACTION_STORE_CONST,
+ ECORE_GETOPT_ACTION_STORE_TRUE,
+ ECORE_GETOPT_ACTION_STORE_FALSE,
+ ECORE_GETOPT_ACTION_CHOICE,
+ ECORE_GETOPT_ACTION_APPEND,
+ ECORE_GETOPT_ACTION_COUNT,
+ ECORE_GETOPT_ACTION_CALLBACK,
+ ECORE_GETOPT_ACTION_HELP,
+ ECORE_GETOPT_ACTION_VERSION,
+ ECORE_GETOPT_ACTION_COPYRIGHT,
+ ECORE_GETOPT_ACTION_LICENSE
+} Ecore_Getopt_Action;
+
+typedef enum {
+ ECORE_GETOPT_TYPE_STR,
+ ECORE_GETOPT_TYPE_BOOL,
+ ECORE_GETOPT_TYPE_SHORT,
+ ECORE_GETOPT_TYPE_INT,
+ ECORE_GETOPT_TYPE_LONG,
+ ECORE_GETOPT_TYPE_USHORT,
+ ECORE_GETOPT_TYPE_UINT,
+ ECORE_GETOPT_TYPE_ULONG,
+ ECORE_GETOPT_TYPE_DOUBLE
+} Ecore_Getopt_Type;
+
+typedef enum {
+ ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO = 0,
+ ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES = 1,
+ ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL = 3
+} Ecore_Getopt_Desc_Arg_Requirement;
+
+typedef union _Ecore_Getopt_Value Ecore_Getopt_Value;
+
+typedef struct _Ecore_Getopt_Desc_Store Ecore_Getopt_Desc_Store;
+typedef struct _Ecore_Getopt_Desc_Callback Ecore_Getopt_Desc_Callback;
+typedef struct _Ecore_Getopt_Desc Ecore_Getopt_Desc;
+typedef struct _Ecore_Getopt Ecore_Getopt;
+
+union _Ecore_Getopt_Value
+{
+ char **strp;
+ unsigned char *boolp;
+ short *shortp;
+ int *intp;
+ long *longp;
+ unsigned short *ushortp;
+ unsigned int *uintp;
+ unsigned long *ulongp;
+ double *doublep;
+ Eina_List **listp;
+ void **ptrp;
+};
+
+struct _Ecore_Getopt_Desc_Store
+{
+ Ecore_Getopt_Type type; /**< type of data being handled */
+ Ecore_Getopt_Desc_Arg_Requirement arg_req;
+ union
+ {
+ const char *strv;
+ Eina_Bool boolv;
+ short shortv;
+ int intv;
+ long longv;
+ unsigned short ushortv;
+ unsigned int uintv;
+ unsigned long ulongv;
+ double doublev;
+ } def;
+};
+
+struct _Ecore_Getopt_Desc_Callback
+{
+ Eina_Bool (*func)(const Ecore_Getopt *parser,
+ const Ecore_Getopt_Desc *desc,
+ const char *str,
+ void *data,
+ Ecore_Getopt_Value *storage);
+ const void *data;
+ Ecore_Getopt_Desc_Arg_Requirement arg_req;
+ const char *def;
+};
+
+struct _Ecore_Getopt_Desc
+{
+ char shortname; /**< used with a single dash */
+ const char *longname; /**< used with double dashes */
+ const char *help; /**< used by --help/ecore_getopt_help() */
+ const char *metavar; /**< used by ecore_getopt_help() with nargs > 0 */
+
+ Ecore_Getopt_Action action; /**< define how to handle it */
+ union
+ {
+ const Ecore_Getopt_Desc_Store store;
+ const void *store_const;
+ const char *const *choices; /* NULL terminated. */
+ const Ecore_Getopt_Type append_type;
+ const Ecore_Getopt_Desc_Callback callback;
+ const void *dummy;
+ } action_param;
+};
+
+struct _Ecore_Getopt
+{
+ const char *prog; /**< to be used when ecore_app_args_get() fails */
+ const char *usage; /**< usage example, %prog is replaced */
+ const char *version; /**< if exists, --version will work */
+ const char *copyright; /**< if exists, --copyright will work */
+ const char *license; /**< if exists, --license will work */
+ const char *description; /**< long description, possible multiline */
+ Eina_Bool strict : 1; /**< fail on errors */
+ const Ecore_Getopt_Desc descs[]; /* NULL terminated. */
+};
#define ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, type, arg_requirement, default_value) \
- {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_STORE, \
- {.store = {type, arg_requirement, default_value}}}
+ {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_STORE, \
+ {.store = {type, arg_requirement, default_value}}}
-#define ECORE_GETOPT_STORE(shortname, longname, help, type) \
- ECORE_GETOPT_STORE_FULL(shortname, longname, help, NULL, type, \
+#define ECORE_GETOPT_STORE(shortname, longname, help, type) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, NULL, type, \
ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES, {})
-#define ECORE_GETOPT_STORE_STR(shortname, longname, help) \
+#define ECORE_GETOPT_STORE_STR(shortname, longname, help) \
ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_STR)
-#define ECORE_GETOPT_STORE_BOOL(shortname, longname, help) \
+#define ECORE_GETOPT_STORE_BOOL(shortname, longname, help) \
ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_BOOL)
-#define ECORE_GETOPT_STORE_SHORT(shortname, longname, help) \
+#define ECORE_GETOPT_STORE_SHORT(shortname, longname, help) \
ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_SHORT)
-#define ECORE_GETOPT_STORE_INT(shortname, longname, help) \
+#define ECORE_GETOPT_STORE_INT(shortname, longname, help) \
ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_INT)
-#define ECORE_GETOPT_STORE_LONG(shortname, longname, help) \
+#define ECORE_GETOPT_STORE_LONG(shortname, longname, help) \
ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_LONG)
-#define ECORE_GETOPT_STORE_USHORT(shortname, longname, help) \
+#define ECORE_GETOPT_STORE_USHORT(shortname, longname, help) \
ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_USHORT)
-#define ECORE_GETOPT_STORE_UINT(shortname, longname, help) \
+#define ECORE_GETOPT_STORE_UINT(shortname, longname, help) \
ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_UINT)
-#define ECORE_GETOPT_STORE_ULONG(shortname, longname, help) \
+#define ECORE_GETOPT_STORE_ULONG(shortname, longname, help) \
ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_ULONG)
-#define ECORE_GETOPT_STORE_DOUBLE(shortname, longname, help) \
+#define ECORE_GETOPT_STORE_DOUBLE(shortname, longname, help) \
ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_DOUBLE)
-
#define ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, type) \
- ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, type, \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, type, \
ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES, {})
#define ECORE_GETOPT_STORE_METAVAR_STR(shortname, longname, help, metavar) \
#define ECORE_GETOPT_STORE_METAVAR_DOUBLE(shortname, longname, help, metavar) \
ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_DOUBLE)
-
#define ECORE_GETOPT_STORE_DEF(shortname, longname, help, type, default_value) \
ECORE_GETOPT_STORE_FULL(shortname, longname, help, NULL, type, \
ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL, \
#define ECORE_GETOPT_STORE_FULL_STR(shortname, longname, help, metavar, arg_requirement, default_value) \
ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \
ECORE_GETOPT_TYPE_STR, \
- arg_requirement, \
+ arg_requirement, \
{.strv = default_value})
#define ECORE_GETOPT_STORE_FULL_BOOL(shortname, longname, help, metavar, arg_requirement, default_value) \
ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \
#define ECORE_GETOPT_STORE_CONST(shortname, longname, help, value) \
{shortname, longname, help, NULL, ECORE_GETOPT_ACTION_STORE_CONST, \
- {.store_const = value}}
+ {.store_const = value}}
#define ECORE_GETOPT_STORE_TRUE(shortname, longname, help) \
{shortname, longname, help, NULL, ECORE_GETOPT_ACTION_STORE_TRUE, \
- {.dummy = NULL}}
+ {.dummy = NULL}}
#define ECORE_GETOPT_STORE_FALSE(shortname, longname, help) \
{shortname, longname, help, NULL, ECORE_GETOPT_ACTION_STORE_FALSE, \
- {.dummy = NULL}}
+ {.dummy = NULL}}
#define ECORE_GETOPT_CHOICE(shortname, longname, help, choices_array) \
{shortname, longname, help, NULL, ECORE_GETOPT_ACTION_CHOICE, \
- {.choices = choices_array}}
+ {.choices = choices_array}}
#define ECORE_GETOPT_CHOICE_METAVAR(shortname, longname, help, metavar, choices_array) \
{shortname, longname, help, metavar, ECORE_GETOPT_ACTION_CHOICE, \
- {.choices = choices_array}}
-
+ {.choices = choices_array}}
#define ECORE_GETOPT_APPEND(shortname, longname, help, sub_type) \
{shortname, longname, help, NULL, ECORE_GETOPT_ACTION_APPEND, \
- {.append_type = sub_type}}
+ {.append_type = sub_type}}
#define ECORE_GETOPT_APPEND_METAVAR(shortname, longname, help, metavar, type) \
{shortname, longname, help, metavar, ECORE_GETOPT_ACTION_APPEND, \
- {.append_type = type}}
+ {.append_type = type}}
#define ECORE_GETOPT_COUNT(shortname, longname, help) \
{shortname, longname, help, NULL, ECORE_GETOPT_ACTION_COUNT, \
- {.dummy = NULL}}
+ {.dummy = NULL}}
#define ECORE_GETOPT_CALLBACK_FULL(shortname, longname, help, metavar, callback_func, callback_data, argument_requirement, default_value) \
{shortname, longname, help, metavar, ECORE_GETOPT_ACTION_CALLBACK, \
- {.callback = {callback_func, callback_data, \
- argument_requirement, default_value}}}
+ {.callback = {callback_func, callback_data, \
+ argument_requirement, default_value}}}
#define ECORE_GETOPT_CALLBACK_NOARGS(shortname, longname, help, callback_func, callback_data) \
ECORE_GETOPT_CALLBACK_FULL(shortname, longname, help, NULL, \
callback_func, callback_data, \
#define ECORE_GETOPT_HELP(shortname, longname) \
{shortname, longname, "show this message.", NULL, \
- ECORE_GETOPT_ACTION_HELP, \
- {.dummy = NULL}}
+ ECORE_GETOPT_ACTION_HELP, \
+ {.dummy = NULL}}
#define ECORE_GETOPT_VERSION(shortname, longname) \
{shortname, longname, "show program version.", NULL, \
- ECORE_GETOPT_ACTION_VERSION, \
- {.dummy = NULL}}
+ ECORE_GETOPT_ACTION_VERSION, \
+ {.dummy = NULL}}
#define ECORE_GETOPT_COPYRIGHT(shortname, longname) \
{shortname, longname, "show copyright.", NULL, \
- ECORE_GETOPT_ACTION_COPYRIGHT, \
- {.dummy = NULL}}
+ ECORE_GETOPT_ACTION_COPYRIGHT, \
+ {.dummy = NULL}}
#define ECORE_GETOPT_LICENSE(shortname, longname) \
{shortname, longname, "show license.", NULL, \
- ECORE_GETOPT_ACTION_LICENSE, \
- {.dummy = NULL}}
+ ECORE_GETOPT_ACTION_LICENSE, \
+ {.dummy = NULL}}
#define ECORE_GETOPT_SENTINEL {0, NULL, NULL, NULL, 0, {.dummy = NULL}}
#define ECORE_GETOPT_VALUE_PTR(val) {.ptrp = &(val)}
#define ECORE_GETOPT_VALUE_PTR_CAST(val) {.ptrp = (void **)&(val)}
#define ECORE_GETOPT_VALUE_LIST(val) {.listp = &(val)}
-#define ECORE_GETOPT_VALUE_NONE {.ptrp = NULL}
-
- EAPI void ecore_getopt_help(FILE *fp, const Ecore_Getopt *info);
-
- EAPI Eina_Bool ecore_getopt_parser_has_duplicates(const Ecore_Getopt *parser);
- EAPI int ecore_getopt_parse(const Ecore_Getopt *parser, Ecore_Getopt_Value *values, int argc, char **argv);
-
- EAPI Eina_List *ecore_getopt_list_free(Eina_List *list);
-
- /* helper functions to be used with ECORE_GETOPT_CALLBACK_*() */
- EAPI Eina_Bool ecore_getopt_callback_geometry_parse(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc, const char *str, void *data, Ecore_Getopt_Value *storage);
- EAPI Eina_Bool ecore_getopt_callback_size_parse(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc, const char *str, void *data, Ecore_Getopt_Value *storage);
-
+#define ECORE_GETOPT_VALUE_NONE {.ptrp = NULL}
+
+EAPI void
+ecore_getopt_help(FILE *fp,
+ const Ecore_Getopt *info);
+
+EAPI Eina_Bool
+ ecore_getopt_parser_has_duplicates(const Ecore_Getopt *parser);
+EAPI int
+ ecore_getopt_parse(const Ecore_Getopt *parser,
+ Ecore_Getopt_Value *values,
+ int argc,
+ char **argv);
+
+EAPI Eina_List *ecore_getopt_list_free(Eina_List *list);
+
+/* helper functions to be used with ECORE_GETOPT_CALLBACK_*() */
+EAPI Eina_Bool
+ecore_getopt_callback_geometry_parse(const Ecore_Getopt *parser,
+ const Ecore_Getopt_Desc *desc,
+ const char *str,
+ void *data,
+ Ecore_Getopt_Value *storage);
+EAPI Eina_Bool
+ecore_getopt_callback_size_parse(const Ecore_Getopt *parser,
+ const Ecore_Getopt_Desc *desc,
+ const char *str,
+ void *data,
+ Ecore_Getopt_Value *storage);
#ifdef __cplusplus
}
static Ecore_Version _version = { VERS_MAJ, VERS_MIN, VERS_MIC, VERS_REV };
EAPI Ecore_Version *ecore_version = &_version;
-#define KEEP_MAX(Global, Local) \
- if (Global < (Local)) \
- Global = Local;
+#define KEEP_MAX(Global, Local) \
+ if (Global < (Local)) \
+ Global = Local;
static Eina_Bool _ecore_memory_statistic(void *data);
static int _ecore_memory_max_total = 0;
struct _Ecore_Safe_Call
{
union {
- Ecore_Cb async;
+ Ecore_Cb async;
Ecore_Data_Cb sync;
} cb;
- void *data;
+ void *data;
- Eina_Lock m;
+ Eina_Lock m;
Eina_Condition c;
- int current_id;
+ int current_id;
- Eina_Bool sync : 1;
- Eina_Bool suspend : 1;
+ Eina_Bool sync : 1;
+ Eina_Bool suspend : 1;
};
static void _ecore_main_loop_thread_safe_call(Ecore_Safe_Call *order);
static void _thread_safe_cleanup(void *data);
-static void _thread_callback(void *data, void *buffer, unsigned int nbyte);
+static void _thread_callback(void *data,
+ void *buffer,
+ unsigned int nbyte);
static Eina_List *_thread_cb = NULL;
static Ecore_Pipe *_thread_call = NULL;
static Eina_Lock _thread_safety;
setlocale(LC_CTYPE, "");
#endif
/*
- if (strcmp(nl_langinfo(CODESET), "UTF-8"))
- {
+ if (strcmp(nl_langinfo(CODESET), "UTF-8"))
+ {
WRN("Not a utf8 locale!");
- }
- */
+ }
+ */
#ifdef HAVE_EVIL
if (!evil_init())
return --_ecore_init_count;
return _ecore_init_count;
- shutdown_log_dom:
+shutdown_log_dom:
eina_shutdown();
- shutdown_evil:
+shutdown_evil:
#ifdef HAVE_EVIL
evil_shutdown();
#endif
/*
* take a lock here because _ecore_event_shutdown() does callbacks
*/
- _ecore_lock();
- if (--_ecore_init_count != 0)
- goto unlock;
-
- ecore_pipe_del(_thread_call);
- eina_lock_free(&_thread_safety);
- eina_condition_free(&_thread_cond);
- eina_lock_free(&_thread_mutex);
- eina_condition_free(&_thread_feedback_cond);
- eina_lock_free(&_thread_feedback_mutex);
- eina_lock_free(&_thread_id_lock);
-
- if (_ecore_fps_debug) _ecore_fps_debug_shutdown();
- _ecore_poller_shutdown();
- _ecore_animator_shutdown();
- _ecore_glib_shutdown();
- _ecore_job_shutdown();
- _ecore_thread_shutdown();
- _ecore_exe_shutdown();
- _ecore_idle_enterer_shutdown();
- _ecore_idle_exiter_shutdown();
- _ecore_idler_shutdown();
- _ecore_timer_shutdown();
- _ecore_event_shutdown();
- _ecore_main_shutdown();
- _ecore_signal_shutdown();
- _ecore_main_loop_shutdown();
+ _ecore_lock();
+ if (--_ecore_init_count != 0)
+ goto unlock;
+
+ ecore_pipe_del(_thread_call);
+ eina_lock_free(&_thread_safety);
+ eina_condition_free(&_thread_cond);
+ eina_lock_free(&_thread_mutex);
+ eina_condition_free(&_thread_feedback_cond);
+ eina_lock_free(&_thread_feedback_mutex);
+ eina_lock_free(&_thread_id_lock);
+
+ if (_ecore_fps_debug) _ecore_fps_debug_shutdown();
+ _ecore_poller_shutdown();
+ _ecore_animator_shutdown();
+ _ecore_glib_shutdown();
+ _ecore_job_shutdown();
+ _ecore_thread_shutdown();
+ _ecore_exe_shutdown();
+ _ecore_idle_enterer_shutdown();
+ _ecore_idle_exiter_shutdown();
+ _ecore_idler_shutdown();
+ _ecore_timer_shutdown();
+ _ecore_event_shutdown();
+ _ecore_main_shutdown();
+ _ecore_signal_shutdown();
+ _ecore_main_loop_shutdown();
#if HAVE_MALLINFO
- if (getenv("ECORE_MEM_STAT"))
- {
- _ecore_memory_statistic(NULL);
-
- ERR("[%i] Memory MAX total: %i, free: %i",
- _ecore_memory_pid,
- _ecore_memory_max_total,
- _ecore_memory_max_free);
- }
+ if (getenv("ECORE_MEM_STAT"))
+ {
+ _ecore_memory_statistic(NULL);
+
+ ERR("[%i] Memory MAX total: %i, free: %i",
+ _ecore_memory_pid,
+ _ecore_memory_max_total,
+ _ecore_memory_max_free);
+ }
#endif
- eina_log_domain_unregister(_ecore_log_dom);
- _ecore_log_dom = -1;
- eina_shutdown();
+ eina_log_domain_unregister(_ecore_log_dom);
+ _ecore_log_dom = -1;
+ eina_shutdown();
#ifdef HAVE_EVIL
- evil_shutdown();
+ evil_shutdown();
#endif
unlock:
- _ecore_unlock();
+ _ecore_unlock();
- return _ecore_init_count;
+ return _ecore_init_count;
}
/**
static int wakeup = 42;
EAPI void
-ecore_main_loop_thread_safe_call_async(Ecore_Cb callback, void *data)
+ecore_main_loop_thread_safe_call_async(Ecore_Cb callback,
+ void *data)
{
Ecore_Safe_Call *order;
- if (!callback) return ;
+ if (!callback) return;
if (eina_main_loop_is())
{
callback(data);
- return ;
+ return;
}
order = malloc(sizeof (Ecore_Safe_Call));
- if (!order) return ;
+ if (!order) return;
order->cb.async = callback;
order->data = data;
}
EAPI void *
-ecore_main_loop_thread_safe_call_sync(Ecore_Data_Cb callback, void *data)
+ecore_main_loop_thread_safe_call_sync(Ecore_Data_Cb callback,
+ void *data)
{
Ecore_Safe_Call *order;
void *ret;
if (order->current_id < 0)
{
_thread_id_max = 0;
- order->current_id = ++_thread_id_max;
+ order->current_id = ++_thread_id_max;
}
eina_lock_release(&_thread_id_lock);
}
EAPI void
-ecore_print_warning(const char *function, const char *sparam)
+ecore_print_warning(const char *function,
+ const char *sparam)
{
WRN("***** Developer Warning ***** :\n"
"\tThis program is calling:\n\n"
}
EAPI void
-_ecore_magic_fail(const void *d, Ecore_Magic m, Ecore_Magic req_m, const char *fname)
+_ecore_magic_fail(const void *d,
+ Ecore_Magic m,
+ Ecore_Magic req_m,
+ const char *fname)
{
ERR("\n"
"*** ECORE ERROR: Ecore Magic Check Failed!!!\n"
" Supplied: %08x - %s",
(unsigned int)req_m, _ecore_magic_string_get(req_m),
(unsigned int)m, _ecore_magic_string_get(m));
- ERR("*** NAUGHTY PROGRAMMER!!!\n"
- "*** SPANK SPANK SPANK!!!\n"
- "*** Now go fix your code. Tut tut tut!");
+ ERR("*** NAUGHTY PROGRAMMER!!!\n"
+ "*** SPANK SPANK SPANK!!!\n"
+ "*** Now go fix your code. Tut tut tut!");
if (getenv("ECORE_ERROR_ABORT")) abort();
}
case ECORE_MAGIC_NONE:
return "None (Freed Object)";
break;
+
case ECORE_MAGIC_EXE:
return "Ecore_Exe (Executable)";
break;
+
case ECORE_MAGIC_TIMER:
return "Ecore_Timer (Timer)";
break;
+
case ECORE_MAGIC_IDLER:
return "Ecore_Idler (Idler)";
break;
+
case ECORE_MAGIC_IDLE_ENTERER:
return "Ecore_Idle_Enterer (Idler Enterer)";
break;
+
case ECORE_MAGIC_IDLE_EXITER:
return "Ecore_Idle_Exiter (Idler Exiter)";
break;
+
case ECORE_MAGIC_FD_HANDLER:
return "Ecore_Fd_Handler (Fd Handler)";
break;
+
case ECORE_MAGIC_WIN32_HANDLER:
return "Ecore_Win32_Handler (Win32 Handler)";
break;
+
case ECORE_MAGIC_EVENT_HANDLER:
return "Ecore_Event_Handler (Event Handler)";
break;
+
case ECORE_MAGIC_EVENT:
return "Ecore_Event (Event)";
break;
+
default:
return "<UNKNOWN>";
- };
+ }
}
/* fps debug calls - for debugging how much time your app actually spends */
void
_ecore_fps_debug_init(void)
{
- char buf[PATH_MAX];
+ char buf[PATH_MAX];
const char *tmp;
- int pid;
+ int pid;
_ecore_fps_debug_init_count++;
if (_ecore_fps_debug_init_count > 1) return;
{
char buf[4096];
const char *tmp;
- int pid;
+ int pid;
#ifndef HAVE_EVIL
- tmp = "/tmp";
+ tmp = "/tmp";
#else
- tmp = (char *)evil_tmpdir_get ();
+ tmp = (char *)evil_tmpdir_get ();
#endif /* HAVE_EVIL */
- pid = (int)getpid();
+ pid = (int)getpid();
snprintf(buf, sizeof(buf), "%s/.ecore_fps_debug-%i", tmp, pid);
unlink(buf);
if (_ecore_fps_runtime_mmap)
mi = mallinfo();
-#define HAS_CHANGED(Global, Local) \
- if (Global != Local) \
- { \
- Global = Local; \
- changed = EINA_TRUE; \
- }
+#define HAS_CHANGED(Global, Local) \
+ if (Global != Local) \
+ { \
+ Global = Local; \
+ changed = EINA_TRUE; \
+ }
HAS_CHANGED(uordblks, mi.uordblks);
HAS_CHANGED(fordblks, mi.fordblks);
}
static void
-_thread_callback(void *data __UNUSED__,
- void *buffer __UNUSED__,
+_thread_callback(void *data __UNUSED__,
+ void *buffer __UNUSED__,
unsigned int nbyte __UNUSED__)
{
Ecore_Safe_Call *call;
{
eina_lock_take(&_thread_mutex);
- eina_lock_take(&call->m);
- _thread_id = call->current_id;
+ eina_lock_take(&call->m);
+ _thread_id = call->current_id;
eina_condition_broadcast(&call->c);
- eina_lock_release(&call->m);
+ eina_lock_release(&call->m);
- while (_thread_id_update != _thread_id)
- eina_condition_wait(&_thread_cond);
+ while (_thread_id_update != _thread_id)
+ eina_condition_wait(&_thread_cond);
eina_lock_release(&_thread_mutex);
eina_main_loop_define();
- eina_lock_take(&_thread_feedback_mutex);
+ eina_lock_take(&_thread_feedback_mutex);
- _thread_id = -1;
+ _thread_id = -1;
- eina_condition_broadcast(&_thread_feedback_cond);
- eina_lock_release(&_thread_feedback_mutex);
+ eina_condition_broadcast(&_thread_feedback_cond);
+ eina_lock_release(&_thread_feedback_mutex);
_thread_safe_cleanup(call);
free(call);
}
}
}
+
#include "Ecore.h"
#include "ecore_private.h"
-
struct _Ecore_Animator
{
EINA_INLIST;
- ECORE_MAGIC;
+ ECORE_MAGIC;
- Ecore_Task_Cb func;
- void *data;
+ Ecore_Task_Cb func;
+ void *data;
- double start, run;
- Ecore_Timeline_Cb run_func;
- void *run_data;
+ double start, run;
+ Ecore_Timeline_Cb run_func;
+ void *run_data;
- Eina_Bool delete_me : 1;
- Eina_Bool suspended : 1;
+ Eina_Bool delete_me : 1;
+ Eina_Bool suspended : 1;
};
-
static Eina_Bool _ecore_animator_run(void *data);
static Eina_Bool _ecore_animator(void *data);
-static int animators_delete_me = 0;
-static Ecore_Animator *animators = NULL;
-static double animators_frametime = 1.0 / 30.0;
+static int animators_delete_me = 0;
+static Ecore_Animator *animators = NULL;
+static double animators_frametime = 1.0 / 30.0;
-static Ecore_Animator_Source src = ECORE_ANIMATOR_SOURCE_TIMER;
-static Ecore_Timer *timer = NULL;
-static int ticking = 0;
-static Ecore_Cb begin_tick_cb = NULL;
-static const void *begin_tick_data = NULL;
-static Ecore_Cb end_tick_cb = NULL;
-static const void *end_tick_data = NULL;
+static Ecore_Animator_Source src = ECORE_ANIMATOR_SOURCE_TIMER;
+static Ecore_Timer *timer = NULL;
+static int ticking = 0;
+static Ecore_Cb begin_tick_cb = NULL;
+static const void *begin_tick_data = NULL;
+static Ecore_Cb end_tick_cb = NULL;
+static const void *end_tick_data = NULL;
static void
_begin_tick(void)
double d = -fmod(t_loop - sync_0, animators_frametime);
timer = _ecore_timer_loop_add(animators_frametime,
- _ecore_animator, NULL);
+ _ecore_animator, NULL);
_ecore_timer_delay(timer, d);
}
break;
+
case ECORE_ANIMATOR_SOURCE_CUSTOM:
if (begin_tick_cb) begin_tick_cb((void *)begin_tick_data);
break;
+
default:
break;
}
timer = NULL;
}
break;
+
case ECORE_ANIMATOR_SOURCE_CUSTOM:
if (end_tick_cb) end_tick_cb((void *)end_tick_data);
break;
+
default:
break;
}
if (animators_delete_me)
{
Ecore_Animator *l;
- for (l = animators; l;)
+ for (l = animators; l; )
{
animator = l;
- l = (Ecore_Animator *) EINA_INLIST_GET(l)->next;
+ l = (Ecore_Animator *)EINA_INLIST_GET(l)->next;
if (animator->delete_me)
{
animators = (Ecore_Animator *)
- eina_inlist_remove(EINA_INLIST_GET(animators),
- EINA_INLIST_GET(animator));
+ eina_inlist_remove(EINA_INLIST_GET(animators),
+ EINA_INLIST_GET(animator));
ECORE_MAGIC_SET(animator, ECORE_MAGIC_NONE);
free(animator);
animators_delete_me--;
}
static Ecore_Animator *
-_ecore_animator_add(Ecore_Task_Cb func, const void *data)
+_ecore_animator_add(Ecore_Task_Cb func,
+ const void *data)
{
Ecore_Animator *animator = NULL;
}
EAPI Ecore_Animator *
-ecore_animator_add(Ecore_Task_Cb func, const void *data)
+ecore_animator_add(Ecore_Task_Cb func,
+ const void *data)
{
Ecore_Animator *animator;
}
EAPI Ecore_Animator *
-ecore_animator_timeline_add(double runtime, Ecore_Timeline_Cb func, const void *data)
+ecore_animator_timeline_add(double runtime,
+ Ecore_Timeline_Cb func,
+ const void *data)
{
Ecore_Animator *animator;
}
static double
-_pos_map_accel_factor(double pos, double v1)
+_pos_map_accel_factor(double pos,
+ double v1)
{
int i, fact = (int)v1;
double p, o1 = pos, o2 = pos, v;
}
static double
-_pos_map_pow(double pos, double divis, int p)
+_pos_map_pow(double pos,
+ double divis,
+ int p)
{
double v = 1.0;
int i;
}
static double
-_pos_map_spring(double pos, int bounces, double decfac)
+_pos_map_spring(double pos,
+ int bounces,
+ double decfac)
{
int segnum, segpos, b1, b2;
double len, decay, decpos, p2;
}
EAPI double
-ecore_animator_pos_map(double pos, Ecore_Pos_Map map, double v1, double v2)
+ecore_animator_pos_map(double pos,
+ Ecore_Pos_Map map,
+ double v1,
+ double v2)
{
/* purely functional - locking not required */
- if (pos > 1.0) pos = 1.0;
- else if (pos < 0.0) pos = 0.0;
- switch (map)
- {
- case ECORE_POS_MAP_LINEAR:
- return pos;
- case ECORE_POS_MAP_ACCELERATE:
- pos = 1.0 - _pos_map_sin((M_PI / 2.0) + ((pos * M_PI) / 2.0));
- return pos;
- case ECORE_POS_MAP_DECELERATE:
- pos = _pos_map_sin((pos * M_PI) / 2.0);
- return pos;
- case ECORE_POS_MAP_SINUSOIDAL:
- pos = (1.0 - _pos_map_cos(pos * M_PI)) / 2.0;
- return pos;
- case ECORE_POS_MAP_ACCELERATE_FACTOR:
- pos = _pos_map_accel_factor(pos, v1);
- return pos;
- case ECORE_POS_MAP_DECELERATE_FACTOR:
- pos = 1.0 - _pos_map_accel_factor(1.0 - pos, v1);
- return pos;
- case ECORE_POS_MAP_SINUSOIDAL_FACTOR:
- if (pos < 0.5) pos = _pos_map_accel_factor(pos * 2.0, v1) / 2.0;
- else pos = 1.0 - (_pos_map_accel_factor((1.0 - pos) * 2.0, v1) / 2.0);
- return pos;
- case ECORE_POS_MAP_DIVISOR_INTERP:
- pos = _pos_map_pow(pos, v1, (int)v2);
- return pos;
- case ECORE_POS_MAP_BOUNCE:
- pos = _pos_map_spring(pos, (int)v2, v1);
- if (pos < 0.0) pos = -pos;
- pos = 1.0 - pos;
- return pos;
- case ECORE_POS_MAP_SPRING:
- pos = 1.0 - _pos_map_spring(pos, (int)v2, v1);
- return pos;
- default:
- return pos;
- }
- return pos;
+ if (pos > 1.0) pos = 1.0;
+ else if (pos < 0.0)
+ pos = 0.0;
+ switch (map)
+ {
+ case ECORE_POS_MAP_LINEAR:
+ return pos;
+
+ case ECORE_POS_MAP_ACCELERATE:
+ pos = 1.0 - _pos_map_sin((M_PI / 2.0) + ((pos * M_PI) / 2.0));
+ return pos;
+
+ case ECORE_POS_MAP_DECELERATE:
+ pos = _pos_map_sin((pos * M_PI) / 2.0);
+ return pos;
+
+ case ECORE_POS_MAP_SINUSOIDAL:
+ pos = (1.0 - _pos_map_cos(pos * M_PI)) / 2.0;
+ return pos;
+
+ case ECORE_POS_MAP_ACCELERATE_FACTOR:
+ pos = _pos_map_accel_factor(pos, v1);
+ return pos;
+
+ case ECORE_POS_MAP_DECELERATE_FACTOR:
+ pos = 1.0 - _pos_map_accel_factor(1.0 - pos, v1);
+ return pos;
+
+ case ECORE_POS_MAP_SINUSOIDAL_FACTOR:
+ if (pos < 0.5) pos = _pos_map_accel_factor(pos * 2.0, v1) / 2.0;
+ else pos = 1.0 - (_pos_map_accel_factor((1.0 - pos) * 2.0, v1) / 2.0);
+ return pos;
+
+ case ECORE_POS_MAP_DIVISOR_INTERP:
+ pos = _pos_map_pow(pos, v1, (int)v2);
+ return pos;
+
+ case ECORE_POS_MAP_BOUNCE:
+ pos = _pos_map_spring(pos, (int)v2, v1);
+ if (pos < 0.0) pos = -pos;
+ pos = 1.0 - pos;
+ return pos;
+
+ case ECORE_POS_MAP_SPRING:
+ pos = 1.0 - _pos_map_spring(pos, (int)v2, v1);
+ return pos;
+
+ default:
+ return pos;
+ }
+ return pos;
}
EAPI void *
}
EAPI void
-ecore_animator_custom_source_tick_begin_callback_set(Ecore_Cb func, const void *data)
+ecore_animator_custom_source_tick_begin_callback_set(Ecore_Cb func,
+ const void *data)
{
_ecore_lock();
begin_tick_cb = func;
}
EAPI void
-ecore_animator_custom_source_tick_end_callback_set(Ecore_Cb func, const void *data)
+ecore_animator_custom_source_tick_end_callback_set(Ecore_Cb func,
+ const void *data)
{
_ecore_lock();
end_tick_cb = func;
Ecore_Animator *animator;
animator = animators;
- animators = (Ecore_Animator *) eina_inlist_remove(EINA_INLIST_GET(animators), EINA_INLIST_GET(animators));
+ animators = (Ecore_Animator *)eina_inlist_remove(EINA_INLIST_GET(animators), EINA_INLIST_GET(animators));
ECORE_MAGIC_SET(animator, ECORE_MAGIC_NONE);
free(animator);
}
{
pos = (t - animator->start) / animator->run;
if (pos > 1.0) pos = 1.0;
- else if (pos < 0.0) pos = 0.0;
+ else if (pos < 0.0)
+ pos = 0.0;
}
run_ret = animator->run_func(animator->run_data, pos);
if (t >= (animator->start + animator->run)) run_ret = EINA_FALSE;
_ecore_unlock();
return r;
}
+
* for later use by ecore_app_restart() or ecore_app_args_get().
*/
EAPI void
-ecore_app_args_set(int argc, const char **argv)
+ecore_app_args_set(int argc,
+ const char **argv)
{
EINA_MAIN_LOOP_CHECK_RETURN;
* same set by ecore_app_args_set().
*/
EAPI void
-ecore_app_args_get(int *argc, char ***argv)
+ecore_app_args_get(int *argc,
+ char ***argv)
{
EINA_MAIN_LOOP_CHECK_RETURN;
struct _Ecore_Event_Handler
{
EINA_INLIST;
- ECORE_MAGIC;
- int type;
+ ECORE_MAGIC;
+ int type;
Ecore_Event_Handler_Cb func;
- void *data;
- int references;
- Eina_Bool delete_me : 1;
+ void *data;
+ int references;
+ Eina_Bool delete_me : 1;
};
struct _Ecore_Event_Filter
{
EINA_INLIST;
- ECORE_MAGIC;
- Ecore_Data_Cb func_start;
+ ECORE_MAGIC;
+ Ecore_Data_Cb func_start;
Ecore_Filter_Cb func_filter;
- Ecore_End_Cb func_end;
- void *loop_data;
- void *data;
- int references;
- Eina_Bool delete_me : 1;
+ Ecore_End_Cb func_end;
+ void *loop_data;
+ void *data;
+ int references;
+ Eina_Bool delete_me : 1;
};
struct _Ecore_Event
{
EINA_INLIST;
- ECORE_MAGIC;
- int type;
- void *event;
+ ECORE_MAGIC;
+ int type;
+ void *event;
Ecore_End_Cb func_free;
- void *data;
- int references;
- Eina_Bool delete_me : 1;
+ void *data;
+ int references;
+ Eina_Bool delete_me : 1;
};
-
static int events_num = 0;
static Ecore_Event *events = NULL;
static Ecore_Event *event_current = NULL;
static int event_filters_delete_me = 0;
static int event_id_max = ECORE_EVENT_COUNT;
static int ecore_raw_event_type = ECORE_EVENT_NONE;
-static void *ecore_raw_event_event = NULL;
-
+static void *ecore_raw_event_event = NULL;
-static void _ecore_event_purge_deleted(void);
+static void _ecore_event_purge_deleted(void);
static void *_ecore_event_del(Ecore_Event *event);
-
/**
* @addtogroup Ecore_Event_Group
*
* been called, will not be.
*/
EAPI Ecore_Event_Handler *
-ecore_event_handler_add(int type, Ecore_Event_Handler_Cb func, const void *data)
+ecore_event_handler_add(int type,
+ Ecore_Event_Handler_Cb func,
+ const void *data)
{
Ecore_Event_Handler *eh = NULL;
* which was previously associated with @p eh by ecore_event_handler_add().
*/
EAPI void *
-ecore_event_handler_data_set(Ecore_Event_Handler *eh, const void *data)
+ecore_event_handler_data_set(Ecore_Event_Handler *eh,
+ const void *data)
{
void *old = NULL;
}
static void
-_ecore_event_generic_free (void *data __UNUSED__, void *event)
+_ecore_event_generic_free(void *data __UNUSED__,
+ void *event)
{
free (event);
}
* func_free is passed @p data as its data parameter.
*/
EAPI Ecore_Event *
-ecore_event_add(int type, void *ev, Ecore_End_Cb func_free, void *data)
+ecore_event_add(int type,
+ void *ev,
+ Ecore_End_Cb func_free,
+ void *data)
{
Ecore_Event *event = NULL;
* and @p data pointer to clean up.
*/
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)
+ecore_event_filter_add(Ecore_Data_Cb func_start,
+ Ecore_Filter_Cb func_filter,
+ Ecore_End_Cb func_end,
+ const void *data)
{
Ecore_Event_Filter *ef = NULL;
ef->func_filter = func_filter;
ef->func_end = func_end;
ef->data = (void *)data;
- event_filters = (Ecore_Event_Filter *) eina_inlist_append(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(ef));
+ event_filters = (Ecore_Event_Filter *)eina_inlist_append(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(ef));
unlock:
_ecore_unlock();
return ef;
{
while ((eh = event_handlers[i]))
{
- event_handlers[i] = (Ecore_Event_Handler *) eina_inlist_remove(EINA_INLIST_GET(event_handlers[i]), EINA_INLIST_GET(event_handlers[i]));
+ event_handlers[i] = (Ecore_Event_Handler *)eina_inlist_remove(EINA_INLIST_GET(event_handlers[i]), EINA_INLIST_GET(event_handlers[i]));
ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE);
if (!eh->delete_me) free(eh);
}
event_handlers_alloc_num = 0;
while ((ef = event_filters))
{
- event_filters = (Ecore_Event_Filter *) eina_inlist_remove(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(event_filters));
+ event_filters = (Ecore_Event_Filter *)eina_inlist_remove(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(event_filters));
ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE);
free(ef);
}
}
Ecore_Event *
-_ecore_event_add(int type, void *ev, Ecore_End_Cb func_free, void *data)
+_ecore_event_add(int type,
+ void *ev,
+ Ecore_End_Cb func_free,
+ void *data)
{
Ecore_Event *e;
data = event->data;
if (event->func_free) _ecore_call_end_cb(event->func_free, event->data, event->event);
- events = (Ecore_Event *) eina_inlist_remove(EINA_INLIST_GET(events), EINA_INLIST_GET(event));
+ events = (Ecore_Event *)eina_inlist_remove(EINA_INLIST_GET(events), EINA_INLIST_GET(event));
ECORE_MAGIC_SET(event, ECORE_MAGIC_NONE);
free(event);
events_num--;
static inline void
_ecore_event_filters_apply()
{
-
if (!event_filter_current)
{
/* regular main loop, start from head */
- event_filter_current = event_filters;
+ event_filter_current = event_filters;
}
else
{
/* recursive main loop, continue from where we were */
- event_filter_current = (Ecore_Event_Filter *)EINA_INLIST_GET(event_filter_current)->next;
+ event_filter_current = (Ecore_Event_Filter *)EINA_INLIST_GET(event_filter_current)->next;
}
while (event_filter_current)
if (!event_filter_event_current)
{
- /* regular main loop, start from head */
- event_filter_event_current = events;
+ /* regular main loop, start from head */
+ event_filter_event_current = events;
}
else
{
- /* recursive main loop, continue from where we were */
- event_filter_event_current = (Ecore_Event *)EINA_INLIST_GET(event_filter_event_current)->next;
+ /* recursive main loop, continue from where we were */
+ event_filter_event_current = (Ecore_Event *)EINA_INLIST_GET(event_filter_event_current)->next;
}
while (event_filter_event_current)
Ecore_Event *e = event_filter_event_current;
if (!_ecore_call_filter_cb(ef->func_filter, ef->data,
- ef->loop_data, e->type, e->event))
+ ef->loop_data, e->type, e->event))
{
ecore_event_del(e);
}
{
int deleted_in_use = 0;
Ecore_Event_Filter *l;
- for (l = event_filters; l;)
+ for (l = event_filters; l; )
{
Ecore_Event_Filter *ef = l;
- l = (Ecore_Event_Filter *) EINA_INLIST_GET(l)->next;
+ l = (Ecore_Event_Filter *)EINA_INLIST_GET(l)->next;
if (ef->delete_me)
{
if (ef->references)
continue;
}
- event_filters = (Ecore_Event_Filter *) eina_inlist_remove(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(ef));
+ event_filters = (Ecore_Event_Filter *)eina_inlist_remove(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(ef));
ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE);
free(ef);
}
event_filters_delete_me = 0;
}
}
+
void
_ecore_event_call(void)
{
if (!event_current)
{
/* regular main loop, start from head */
- event_current = events;
- event_handler_current = NULL;
+ event_current = events;
+ event_handler_current = NULL;
}
while (event_current)
{
if (!event_handler_current)
{
- /* regular main loop, start from head */
- event_handler_current = event_handlers[e->type];
+ /* regular main loop, start from head */
+ event_handler_current = event_handlers[e->type];
}
else
{
- /* recursive main loop, continue from where we were */
- event_handler_current = (Ecore_Event_Handler *)EINA_INLIST_GET(event_handler_current)->next;
+ /* recursive main loop, continue from where we were */
+ event_handler_current = (Ecore_Event_Handler *)EINA_INLIST_GET(event_handler_current)->next;
}
while ((event_handler_current) && (!e->delete_me))
event_handlers_delete_list = eina_list_remove_list(event_handlers_delete_list, l);
- event_handlers[eh->type] = (Ecore_Event_Handler *) eina_inlist_remove(EINA_INLIST_GET(event_handlers[eh->type]), EINA_INLIST_GET(eh));
+ event_handlers[eh->type] = (Ecore_Event_Handler *)eina_inlist_remove(EINA_INLIST_GET(event_handlers[eh->type]), EINA_INLIST_GET(eh));
ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE);
free(eh);
}
{
return calloc(1, sizeof(Ecore_Event_Signal_Realtime));
}
+
#include "Ecore.h"
#include "ecore_private.h"
-
- /* FIXME: Getting respawn to work
- *
- * There is no way that we can do anything about the internal state info of
- * an external exe. The same can be said about the state of user code. User
- * code in this context means the code that is using ecore_exe to manage exe's
- * for it.
- *
- * Document that the exe must be respawnable, in other words, there is no
- * state that it cannot regenerate by just killing it and starting it again.
- * This includes state that the user code knows about, as the respawn is
- * transparent to that code. On the other hand, maybe a respawn event might
- * be useful, or maybe resend the currently non existent add event. For
- * consistancy with ecore_con, an add event is good anyway.
- *
- * The Ecore_exe structure is reused for respawning, so that the (opaque)
- * pointer held by the user remains valid. This means that the Ecore_Exe
- * init and del functions may need to be split into two parts each to avoid
- * duplicating code - common code part, and the rest. This implies that
- * the unchanging members mentioned next should NEVER change.
- *
- * These structure members don't need to change -
- * __list_data - we stay on the list
- * ECORE_MAGIC - this is a constant
- * data - passed in originally
- * cmd - passed in originally
- * flags - passed in originally
- *
- * These structure members need to change -
- * tag - state that must be regenerated, zap it
- * pid - it will be different
- * child_fd_write - it will be different
- * child_fd_read - it will be different
- * child_fd_error - it will be different
- * write_fd_handler - we cannot change the fd used by a handler, this changes coz the fd changes.
- * read_fd_handler - we cannot change the fd used by a handler, this changes coz the fd changes.
- * error_fd_handler - we cannot change the fd used by a handler, this changes coz the fd changes.
- *
- * Hmm, the read, write, and error buffers could be tricky.
- * They are not atomic, and could be in a semi complete state.
- * They fall into the "state must be regenerated" mentioned above.
- * A respawn/add event should take care of it.
- *
- * These structure members need to change -
- * write_data_buf - state that must be regenerated, zap it
- * write_data_size - state that must be regenerated, zap it
- * write_data_offset - state that must be regenerated, zap it
- * read_data_buf - state that must be regenerated, zap it
- * read_data_size - state that must be regenerated, zap it
- * error_data_buf - state that must be regenerated, zap it
- * error_data_size - state that must be regenerated, zap it
- * close_write - state that must be regenerated, zap it
- *
- * There is the problem that an exe that fell over and needs respawning
- * might keep falling over, keep needing to be respawned, and tie up system
- * resources with the constant respawning. An exponentially increasing
- * timeout (with maximum timeout) between respawns should take care of that.
- * Although this is not a "contention for a resource" problem, the exe falling
- * over may be, so a random element added to the timeout may help, and won't
- * hurt. The user code may need to be informed that a timeout is in progress.
- */
+/* FIXME: Getting respawn to work
+ *
+ * There is no way that we can do anything about the internal state info of
+ * an external exe. The same can be said about the state of user code. User
+ * code in this context means the code that is using ecore_exe to manage exe's
+ * for it.
+ *
+ * Document that the exe must be respawnable, in other words, there is no
+ * state that it cannot regenerate by just killing it and starting it again.
+ * This includes state that the user code knows about, as the respawn is
+ * transparent to that code. On the other hand, maybe a respawn event might
+ * be useful, or maybe resend the currently non existent add event. For
+ * consistancy with ecore_con, an add event is good anyway.
+ *
+ * The Ecore_exe structure is reused for respawning, so that the (opaque)
+ * pointer held by the user remains valid. This means that the Ecore_Exe
+ * init and del functions may need to be split into two parts each to avoid
+ * duplicating code - common code part, and the rest. This implies that
+ * the unchanging members mentioned next should NEVER change.
+ *
+ * These structure members don't need to change -
+ * __list_data - we stay on the list
+ * ECORE_MAGIC - this is a constant
+ * data - passed in originally
+ * cmd - passed in originally
+ * flags - passed in originally
+ *
+ * These structure members need to change -
+ * tag - state that must be regenerated, zap it
+ * pid - it will be different
+ * child_fd_write - it will be different
+ * child_fd_read - it will be different
+ * child_fd_error - it will be different
+ * write_fd_handler - we cannot change the fd used by a handler, this changes coz the fd changes.
+ * read_fd_handler - we cannot change the fd used by a handler, this changes coz the fd changes.
+ * error_fd_handler - we cannot change the fd used by a handler, this changes coz the fd changes.
+ *
+ * Hmm, the read, write, and error buffers could be tricky.
+ * They are not atomic, and could be in a semi complete state.
+ * They fall into the "state must be regenerated" mentioned above.
+ * A respawn/add event should take care of it.
+ *
+ * These structure members need to change -
+ * write_data_buf - state that must be regenerated, zap it
+ * write_data_size - state that must be regenerated, zap it
+ * write_data_offset - state that must be regenerated, zap it
+ * read_data_buf - state that must be regenerated, zap it
+ * read_data_size - state that must be regenerated, zap it
+ * error_data_buf - state that must be regenerated, zap it
+ * error_data_size - state that must be regenerated, zap it
+ * close_write - state that must be regenerated, zap it
+ *
+ * There is the problem that an exe that fell over and needs respawning
+ * might keep falling over, keep needing to be respawned, and tie up system
+ * resources with the constant respawning. An exponentially increasing
+ * timeout (with maximum timeout) between respawns should take care of that.
+ * Although this is not a "contention for a resource" problem, the exe falling
+ * over may be, so a random element added to the timeout may help, and won't
+ * hurt. The user code may need to be informed that a timeout is in progress.
+ */
struct _Ecore_Exe
{
EINA_INLIST;
- ECORE_MAGIC;
- pid_t pid;
- void *data;
- char *tag, *cmd;
- Ecore_Exe_Flags flags;
+ ECORE_MAGIC;
+ pid_t pid;
+ void *data;
+ char *tag, *cmd;
+ Ecore_Exe_Flags flags;
Ecore_Fd_Handler *write_fd_handler; /* the fd_handler to handle write to child - if this was used, or NULL if not */
Ecore_Fd_Handler *read_fd_handler; /* the fd_handler to handle read from child - if this was used, or NULL if not */
Ecore_Fd_Handler *error_fd_handler; /* the fd_handler to handle errors from child - if this was used, or NULL if not */
- void *write_data_buf; /* a data buffer for data to write to the child -
- * realloced as needed for more data and flushed when the fd handler says writes are possible
- */
- int write_data_size; /* the size in bytes of the data buffer */
- int write_data_offset; /* the offset in bytes in the data buffer */
- void *read_data_buf; /* data read from the child awating delivery to an event */
- int read_data_size; /* data read from child in bytes */
- void *error_data_buf; /* errors read from the child awating delivery to an event */
- int error_data_size; /* errors read from child in bytes */
- int child_fd_write; /* fd to write TO to send data to the child */
- int child_fd_read; /* fd to read FROM when child has sent us (the parent) data */
- int child_fd_error; /* fd to read FROM when child has sent us (the parent) errors */
- int child_fd_write_x; /* fd to write TO to send data to the child */
- int child_fd_read_x; /* fd to read FROM when child has sent us (the parent) data */
- int child_fd_error_x; /* fd to read FROM when child has sent us (the parent) errors */
- Eina_Bool close_stdin : 1;
-
- int start_bytes, end_bytes, start_lines, end_lines; /* Number of bytes/lines to auto pipe at start/end of stdout/stderr. */
-
- Ecore_Timer *doomsday_clock; /* The Timer of Death. Muahahahaha. */
- void *doomsday_clock_dead; /* data for the doomsday clock */
-
- Ecore_Exe_Cb pre_free_cb;
+ void *write_data_buf; /* a data buffer for data to write to the child -
+ * realloced as needed for more data and flushed when the fd handler says writes are possible
+ */
+ int write_data_size; /* the size in bytes of the data buffer */
+ int write_data_offset; /* the offset in bytes in the data buffer */
+ void *read_data_buf; /* data read from the child awating delivery to an event */
+ int read_data_size; /* data read from child in bytes */
+ void *error_data_buf; /* errors read from the child awating delivery to an event */
+ int error_data_size; /* errors read from child in bytes */
+ int child_fd_write; /* fd to write TO to send data to the child */
+ int child_fd_read; /* fd to read FROM when child has sent us (the parent) data */
+ int child_fd_error; /* fd to read FROM when child has sent us (the parent) errors */
+ int child_fd_write_x; /* fd to write TO to send data to the child */
+ int child_fd_read_x; /* fd to read FROM when child has sent us (the parent) data */
+ int child_fd_error_x; /* fd to read FROM when child has sent us (the parent) errors */
+ Eina_Bool close_stdin : 1;
+
+ int start_bytes, end_bytes, start_lines, end_lines; /* Number of bytes/lines to auto pipe at start/end of stdout/stderr. */
+
+ Ecore_Timer *doomsday_clock; /* The Timer of Death. Muahahahaha. */
+ void *doomsday_clock_dead; /* data for the doomsday clock */
+
+ Ecore_Exe_Cb pre_free_cb;
};
-
/* TODO: Something to let people build a command line and does auto escaping -
*
* ecore_exe_snprintf()
char *cmd;
};
-static inline void _ecore_exe_exec_it(const char *exe_cmd, Ecore_Exe_Flags flags);
-static Eina_Bool _ecore_exe_data_generic_handler(void *data, Ecore_Fd_Handler *fd_handler, Ecore_Exe_Flags flags);
-static Eina_Bool _ecore_exe_data_error_handler(void *data, Ecore_Fd_Handler *fd_handler);
-static Eina_Bool _ecore_exe_data_read_handler(void *data, Ecore_Fd_Handler *fd_handler);
-static Eina_Bool _ecore_exe_data_write_handler(void *data, Ecore_Fd_Handler *fd_handler);
-static void _ecore_exe_flush(Ecore_Exe * exe);
-static void _ecore_exe_event_exe_data_free(void *data __UNUSED__, void *ev);
-static Ecore_Exe *_ecore_exe_is_it_alive(pid_t pid);
-static Eina_Bool _ecore_exe_make_sure_its_dead(void *data);
-static Eina_Bool _ecore_exe_make_sure_its_really_dead(void *data);
+static inline void _ecore_exe_exec_it(const char *exe_cmd,
+ Ecore_Exe_Flags flags);
+static Eina_Bool _ecore_exe_data_generic_handler(void *data,
+ Ecore_Fd_Handler *fd_handler,
+ Ecore_Exe_Flags flags);
+static Eina_Bool _ecore_exe_data_error_handler(void *data,
+ Ecore_Fd_Handler *fd_handler);
+static Eina_Bool _ecore_exe_data_read_handler(void *data,
+ Ecore_Fd_Handler *fd_handler);
+static Eina_Bool _ecore_exe_data_write_handler(void *data,
+ Ecore_Fd_Handler *fd_handler);
+static void _ecore_exe_flush(Ecore_Exe *exe);
+static void _ecore_exe_event_exe_data_free(void *data __UNUSED__,
+ void *ev);
+static Ecore_Exe *_ecore_exe_is_it_alive(pid_t pid);
+static Eina_Bool _ecore_exe_make_sure_its_dead(void *data);
+static Eina_Bool _ecore_exe_make_sure_its_really_dead(void *data);
static Ecore_Exe_Event_Add *_ecore_exe_event_add_new(void);
-static void _ecore_exe_event_add_free(void *data, void *ev);
-static void _ecore_exe_dead_attach(Ecore_Exe *exe);
+static void _ecore_exe_event_add_free(void *data,
+ void *ev);
+static void _ecore_exe_dead_attach(Ecore_Exe *exe);
EAPI int ECORE_EXE_EVENT_ADD = 0;
EAPI int ECORE_EXE_EVENT_DEL = 0;
/* FIXME: This errno checking stuff should be put elsewhere for everybody to use.
* For now it lives here though, just to make testing easier.
*/
-static int _ecore_exe_check_errno(int result, const char *file, int line);
+static int _ecore_exe_check_errno(int result,
+ const char *file,
+ int line);
-#define E_IF_NO_ERRNO(result, foo, ok) \
- while (((ok) = _ecore_exe_check_errno( (result) = (foo), __FILE__, __LINE__)) == -1) sleep(1); \
- if (ok)
+#define E_IF_NO_ERRNO(result, foo, ok) \
+ while (((ok) = _ecore_exe_check_errno((result) = (foo), __FILE__, __LINE__)) == -1) sleep(1); \
+ if (ok)
#define E_NO_ERRNO(result, foo, ok) \
- while (((ok) = _ecore_exe_check_errno( (result) = (foo), __FILE__, __LINE__)) == -1) sleep(1)
+ while (((ok) = _ecore_exe_check_errno((result) = (foo), __FILE__, __LINE__)) == -1) sleep(1)
#define E_IF_NO_ERRNO_NOLOOP(result, foo, ok) \
- if (((ok) = _ecore_exe_check_errno( (result) = (foo), __FILE__, __LINE__)))
+ if (((ok) = _ecore_exe_check_errno((result) = (foo), __FILE__, __LINE__)))
static int
-_ecore_exe_check_errno(int result, const char *file, int line)
+_ecore_exe_check_errno(int result,
+ const char *file,
+ int line)
{
int saved_errno = errno;
if (result == -1)
- {
- perror("*** errno reports ");
+ {
+ perror("*** errno reports ");
/* What is currently supported -
*
* pipe
* // Something failed, cleanup.
* }
*/
- switch (saved_errno)
- {
- case EACCES:
- case EAGAIN:
- case EINTR:
- { /* Not now, try later. */
- ERR("*** Must try again in %s @%u.", file, line);
- result = -1;
- break;
- }
- case EMFILE:
- case ENFILE:
- case ENOLCK:
- { /* Low on resources. */
- ERR("*** Low on resources in %s @%u.", file,
- line);
- result = 0;
- break;
- }
- case EIO:
- { /* I/O error. */
- ERR("*** I/O error in %s @%u.", file, line);
- result = 0;
- break;
- }
- case EFAULT:
- case EBADF:
- case EINVAL:
- case EROFS:
- case EISDIR:
- case EDEADLK:
- case EPERM:
- case EBUSY:
- { /* Programmer fucked up. */
- ERR("*** NAUGHTY PROGRAMMER!!!\n"
- "*** SPANK SPANK SPANK!!!\n"
- "*** Now go fix your code in %s @%u. Tut tut tut!",
- file, line);
- result = 0;
- break;
- }
- default:
- { /* Unsupported errno code, please add this one. */
- ERR("*** NAUGHTY PROGRAMMER!!!\n"
- "*** SPANK SPANK SPANK!!!\n"
- "*** Unsupported errno code %d, please add this one.\n"
- "*** Now go fix your code in %s @%u, from %s @%u. Tut tut tut!",
- saved_errno, __FILE__, __LINE__, file, line);
- result = 0;
- break;
- }
- }
- }
+ switch (saved_errno)
+ {
+ case EACCES:
+ case EAGAIN:
+ case EINTR:
+ { /* Not now, try later. */
+ ERR("*** Must try again in %s @%u.", file, line);
+ result = -1;
+ break;
+ }
+
+ case EMFILE:
+ case ENFILE:
+ case ENOLCK:
+ { /* Low on resources. */
+ ERR("*** Low on resources in %s @%u.", file,
+ line);
+ result = 0;
+ break;
+ }
+
+ case EIO:
+ { /* I/O error. */
+ ERR("*** I/O error in %s @%u.", file, line);
+ result = 0;
+ break;
+ }
+
+ case EFAULT:
+ case EBADF:
+ case EINVAL:
+ case EROFS:
+ case EISDIR:
+ case EDEADLK:
+ case EPERM:
+ case EBUSY:
+ { /* Programmer fucked up. */
+ ERR("*** NAUGHTY PROGRAMMER!!!\n"
+ "*** SPANK SPANK SPANK!!!\n"
+ "*** Now go fix your code in %s @%u. Tut tut tut!",
+ file, line);
+ result = 0;
+ break;
+ }
+
+ default:
+ { /* Unsupported errno code, please add this one. */
+ ERR("*** NAUGHTY PROGRAMMER!!!\n"
+ "*** SPANK SPANK SPANK!!!\n"
+ "*** Unsupported errno code %d, please add this one.\n"
+ "*** Now go fix your code in %s @%u, from %s @%u. Tut tut tut!",
+ saved_errno, __FILE__, __LINE__, file, line);
+ result = 0;
+ break;
+ }
+ }
+ }
else /* Everything is fine. */
result = 1;
* @return A process handle to the spawned process.
*/
EAPI Ecore_Exe *
-ecore_exe_run(const char *exe_cmd, const void *data)
+ecore_exe_run(const char *exe_cmd,
+ const void *data)
{
return ecore_exe_pipe_run(exe_cmd, 0, data);
}
* @return A process handle to the spawned process.
*/
EAPI Ecore_Exe *
-ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, const void *data)
+ecore_exe_pipe_run(const char *exe_cmd,
+ Ecore_Exe_Flags flags,
+ const void *data)
{
Ecore_Exe *exe = NULL;
int statusPipe[2] = { -1, -1 };
/* Create some pipes. */
if (ok)
- {
- E_IF_NO_ERRNO_NOLOOP(result, pipe(statusPipe), ok)
- {
- }
- }
+ {
+ E_IF_NO_ERRNO_NOLOOP(result, pipe(statusPipe), ok)
+ {
+ }
+ }
if (ok && (flags & ECORE_EXE_PIPE_ERROR))
- {
- E_IF_NO_ERRNO_NOLOOP(result, pipe(errorPipe), ok)
- {
- exe->child_fd_error = errorPipe[0];
- exe->child_fd_error_x = errorPipe[1];
- }
- }
+ {
+ E_IF_NO_ERRNO_NOLOOP(result, pipe(errorPipe), ok)
+ {
+ exe->child_fd_error = errorPipe[0];
+ exe->child_fd_error_x = errorPipe[1];
+ }
+ }
if (ok && (flags & ECORE_EXE_PIPE_READ))
- {
- E_IF_NO_ERRNO_NOLOOP(result, pipe(readPipe), ok)
- {
- exe->child_fd_read = readPipe[0];
- exe->child_fd_read_x = readPipe[1];
- }
- }
+ {
+ E_IF_NO_ERRNO_NOLOOP(result, pipe(readPipe), ok)
+ {
+ exe->child_fd_read = readPipe[0];
+ exe->child_fd_read_x = readPipe[1];
+ }
+ }
if (ok && (flags & ECORE_EXE_PIPE_WRITE))
- {
- E_IF_NO_ERRNO_NOLOOP(result, pipe(writePipe), ok)
- {
- exe->child_fd_write = writePipe[1];
- exe->child_fd_write_x = writePipe[0];
- }
- }
+ {
+ E_IF_NO_ERRNO_NOLOOP(result, pipe(writePipe), ok)
+ {
+ exe->child_fd_write = writePipe[1];
+ exe->child_fd_write_x = writePipe[0];
+ }
+ }
if (ok)
- {
- pid_t pid = 0;
- volatile int vfork_exec_errno = 0;
-
- /* FIXME: I should double check this. After a quick look around, this is already done, but via a more modern method. */
- /* signal(SIGPIPE, SIG_IGN); We only want EPIPE on errors */
- pid = fork();
-
- if (pid == -1)
- {
- ERR("Failed to fork process");
- pid = 0;
- }
- else if (pid == 0) /* child */
- {
- if (run_pri != ECORE_EXE_PRIORITY_INHERIT)
- {
- if ((run_pri >= -20) && (run_pri <= 19))
- setpriority(PRIO_PROCESS, 0, run_pri);
- }
- /* dup2 STDERR, STDIN, and STDOUT. dup2() allegedly closes the
- * second pipe if it's open. On the other hand, there was the
- * Great FD Leak Scare of '06, so let's be paranoid. */
- if (ok && (flags & ECORE_EXE_PIPE_ERROR))
- {
- E_NO_ERRNO(result, close(STDERR_FILENO), ok);
- E_NO_ERRNO(result, dup2(errorPipe[1], STDERR_FILENO), ok);
- }
- if (ok && (flags & ECORE_EXE_PIPE_READ))
- {
- E_NO_ERRNO(result, close(STDOUT_FILENO), ok);
- E_NO_ERRNO(result, dup2(readPipe[1], STDOUT_FILENO), ok);
- }
- if (ok && (flags & ECORE_EXE_PIPE_WRITE))
- {
- E_NO_ERRNO(result, close(STDIN_FILENO), ok);
- E_NO_ERRNO(result, dup2(writePipe[0], STDIN_FILENO), ok);
- }
-
- if (ok)
- {
- /* Setup the status pipe. */
- E_NO_ERRNO(result, close(statusPipe[0]), ok);
- E_IF_NO_ERRNO(result, fcntl(statusPipe[1], F_SETFD, FD_CLOEXEC), ok) /* close on exec shows success */
- {
- /* Run the actual command. */
- _ecore_exe_exec_it(exe_cmd, flags); /* no return */
- }
- }
-
- /* Something went 'orribly wrong. */
- vfork_exec_errno = errno;
-
- /* Close the pipes. */
- if (flags & ECORE_EXE_PIPE_ERROR)
- E_NO_ERRNO(result, close(errorPipe[1]), ok);
- if (flags & ECORE_EXE_PIPE_READ)
- E_NO_ERRNO(result, close(readPipe[1]), ok);
- if (flags & ECORE_EXE_PIPE_WRITE)
- E_NO_ERRNO(result, close(writePipe[0]), ok);
- E_NO_ERRNO(result, close(statusPipe[1]), ok);
-
- _exit(-1);
- }
- else /* parent */
- {
- /* Close the unused pipes. */
- E_NO_ERRNO(result, close(statusPipe[1]), ok);
-
- /* FIXME: after having a good look at the current e fd
- * handling, investigate fcntl(dataPipe[x], F_SETSIG, ...) */
- /* FIXME: above F_SETSIG etc. - this is async SIGIO based IO
- * which is also linux specific so we probably don't want to
- * do this as long as select() is working fine. the only time
- * we really want to think of SIGIO async IO is when it all
- * actually works basically everywhere and we can turn all
- * IO into DMA async activities (i.e. you do a read() then
- * the read is complete not on return but when you get a
- * SIGIO - the read() just starts the transfer and it is
- * completed in the background by DMA (or whatever mechanism
- * the kernel choses)) */
-
- /* Wait for it to start executing. */
- /* FIXME: this doesn't seem very nice - we sit and block
- * waiting on a child process... even though it's just
- * the segment between the fork() and the exec) it just feels
- * wrong */
- for (;;)
- {
- char buf;
-
- E_NO_ERRNO(result, read(statusPipe[0], &buf, 1), ok);
- if (result == 0)
- {
- if (vfork_exec_errno != 0)
- {
- n = vfork_exec_errno;
- ERR("Could not start \"%s\"", exe_cmd);
- pid = 0;
- }
- break;
- }
- }
-
- /* Close the status pipe. */
+ {
+ pid_t pid = 0;
+ volatile int vfork_exec_errno = 0;
+
+ /* FIXME: I should double check this. After a quick look around, this is already done, but via a more modern method. */
+ /* signal(SIGPIPE, SIG_IGN); We only want EPIPE on errors */
+ pid = fork();
+
+ if (pid == -1)
+ {
+ ERR("Failed to fork process");
+ pid = 0;
+ }
+ else if (pid == 0) /* child */
+ {
+ if (run_pri != ECORE_EXE_PRIORITY_INHERIT)
+ {
+ if ((run_pri >= -20) && (run_pri <= 19))
+ setpriority(PRIO_PROCESS, 0, run_pri);
+ }
+ /* dup2 STDERR, STDIN, and STDOUT. dup2() allegedly closes the
+ * second pipe if it's open. On the other hand, there was the
+ * Great FD Leak Scare of '06, so let's be paranoid. */
+ if (ok && (flags & ECORE_EXE_PIPE_ERROR))
+ {
+ E_NO_ERRNO(result, close(STDERR_FILENO), ok);
+ E_NO_ERRNO(result, dup2(errorPipe[1], STDERR_FILENO), ok);
+ }
+ if (ok && (flags & ECORE_EXE_PIPE_READ))
+ {
+ E_NO_ERRNO(result, close(STDOUT_FILENO), ok);
+ E_NO_ERRNO(result, dup2(readPipe[1], STDOUT_FILENO), ok);
+ }
+ if (ok && (flags & ECORE_EXE_PIPE_WRITE))
+ {
+ E_NO_ERRNO(result, close(STDIN_FILENO), ok);
+ E_NO_ERRNO(result, dup2(writePipe[0], STDIN_FILENO), ok);
+ }
+
+ if (ok)
+ {
+ /* Setup the status pipe. */
E_NO_ERRNO(result, close(statusPipe[0]), ok);
+ E_IF_NO_ERRNO(result, fcntl(statusPipe[1], F_SETFD, FD_CLOEXEC), ok) /* close on exec shows success */
+ {
+ /* Run the actual command. */
+ _ecore_exe_exec_it(exe_cmd, flags); /* no return */
+ }
+ }
+
+ /* Something went 'orribly wrong. */
+ vfork_exec_errno = errno;
+
+ /* Close the pipes. */
+ if (flags & ECORE_EXE_PIPE_ERROR)
+ E_NO_ERRNO(result, close(errorPipe[1]), ok);
+ if (flags & ECORE_EXE_PIPE_READ)
+ E_NO_ERRNO(result, close(readPipe[1]), ok);
+ if (flags & ECORE_EXE_PIPE_WRITE)
+ E_NO_ERRNO(result, close(writePipe[0]), ok);
+ E_NO_ERRNO(result, close(statusPipe[1]), ok);
+
+ _exit(-1);
+ }
+ else /* parent */
+ {
+ /* Close the unused pipes. */
+ E_NO_ERRNO(result, close(statusPipe[1]), ok);
+
+ /* FIXME: after having a good look at the current e fd
+ * handling, investigate fcntl(dataPipe[x], F_SETSIG, ...) */
+ /* FIXME: above F_SETSIG etc. - this is async SIGIO based IO
+ * which is also linux specific so we probably don't want to
+ * do this as long as select() is working fine. the only time
+ * we really want to think of SIGIO async IO is when it all
+ * actually works basically everywhere and we can turn all
+ * IO into DMA async activities (i.e. you do a read() then
+ * the read is complete not on return but when you get a
+ * SIGIO - the read() just starts the transfer and it is
+ * completed in the background by DMA (or whatever mechanism
+ * the kernel choses)) */
+
+ /* Wait for it to start executing. */
+ /* FIXME: this doesn't seem very nice - we sit and block
+ * waiting on a child process... even though it's just
+ * the segment between the fork() and the exec) it just feels
+ * wrong */
+ for (;; )
+ {
+ char buf;
+
+ E_NO_ERRNO(result, read(statusPipe[0], &buf, 1), ok);
+ if (result == 0)
+ {
+ if (vfork_exec_errno != 0)
+ {
+ n = vfork_exec_errno;
+ ERR("Could not start \"%s\"", exe_cmd);
+ pid = 0;
+ }
+ break;
+ }
}
- if (pid)
+ /* Close the status pipe. */
+ E_NO_ERRNO(result, close(statusPipe[0]), ok);
+ }
+
+ if (pid)
+ {
+ /* Setup the exe structure. */
+ ECORE_MAGIC_SET(exe, ECORE_MAGIC_EXE);
+ exe->start_bytes = -1;
+ exe->end_bytes = -1;
+ exe->start_lines = -1;
+ exe->end_lines = -1;
+ exe->pid = pid;
+ exe->flags = flags;
+ exe->data = (void *)data;
+ if ((exe->cmd = strdup(exe_cmd)))
{
- /* Setup the exe structure. */
- ECORE_MAGIC_SET(exe, ECORE_MAGIC_EXE);
- exe->start_bytes = -1;
- exe->end_bytes = -1;
- exe->start_lines = -1;
- exe->end_lines = -1;
- exe->pid = pid;
- exe->flags = flags;
- exe->data = (void *)data;
- if ((exe->cmd = strdup(exe_cmd)))
- {
- if (flags & ECORE_EXE_PIPE_ERROR)
- { /* Setup the error stuff. */
- E_IF_NO_ERRNO(result,
- fcntl(exe->child_fd_error, F_SETFL,
- O_NONBLOCK), ok) {}
- E_IF_NO_ERRNO(result,
- fcntl(exe->child_fd_error, F_SETFD,
- FD_CLOEXEC), ok) {}
- E_IF_NO_ERRNO(result,
- fcntl(exe->child_fd_error_x, F_SETFD,
- FD_CLOEXEC), ok) {}
- {
- exe->error_fd_handler =
- ecore_main_fd_handler_add(exe->child_fd_error,
- ECORE_FD_READ,
- _ecore_exe_data_error_handler,
- exe, NULL, NULL);
- if (!exe->error_fd_handler)
- ok = 0;
- }
- }
- if (ok && (flags & ECORE_EXE_PIPE_READ))
- { /* Setup the read stuff. */
- E_IF_NO_ERRNO(result,
- fcntl(exe->child_fd_read, F_SETFL,
- O_NONBLOCK), ok) {}
- E_IF_NO_ERRNO(result,
- fcntl(exe->child_fd_read, F_SETFD,
- FD_CLOEXEC), ok) {}
- E_IF_NO_ERRNO(result,
- fcntl(exe->child_fd_read_x, F_SETFD,
- FD_CLOEXEC), ok) {}
- {
- exe->read_fd_handler =
- ecore_main_fd_handler_add(exe->child_fd_read,
- ECORE_FD_READ,
- _ecore_exe_data_read_handler,
- exe, NULL, NULL);
- if (!exe->read_fd_handler)
- ok = 0;
- }
- }
- if (ok && (flags & ECORE_EXE_PIPE_WRITE))
- { /* Setup the write stuff. */
- E_IF_NO_ERRNO(result,
- fcntl(exe->child_fd_write, F_SETFL,
- O_NONBLOCK), ok) {}
- E_IF_NO_ERRNO(result,
- fcntl(exe->child_fd_write, F_SETFD,
- FD_CLOEXEC), ok) {}
- E_IF_NO_ERRNO(result,
- fcntl(exe->child_fd_write_x, F_SETFD,
- FD_CLOEXEC), ok) {}
- {
- exe->write_fd_handler =
- ecore_main_fd_handler_add(exe->child_fd_write,
- ECORE_FD_WRITE,
- _ecore_exe_data_write_handler,
- exe, NULL, NULL);
- if (exe->write_fd_handler)
- ecore_main_fd_handler_active_set(exe->write_fd_handler, 0); /* Nothing to write to start with. */
- else
- ok = 0;
- }
- }
-
- exes = (Ecore_Exe *) eina_inlist_append(EINA_INLIST_GET(exes), EINA_INLIST_GET(exe));
- n = 0;
- }
- else
- ok = 0;
+ if (flags & ECORE_EXE_PIPE_ERROR) /* Setup the error stuff. */
+ {
+ E_IF_NO_ERRNO(result,
+ fcntl(exe->child_fd_error, F_SETFL,
+ O_NONBLOCK), ok) {
+ }
+ E_IF_NO_ERRNO(result,
+ fcntl(exe->child_fd_error, F_SETFD,
+ FD_CLOEXEC), ok) {
+ }
+ E_IF_NO_ERRNO(result,
+ fcntl(exe->child_fd_error_x, F_SETFD,
+ FD_CLOEXEC), ok) {
+ }
+ {
+ exe->error_fd_handler =
+ ecore_main_fd_handler_add(exe->child_fd_error,
+ ECORE_FD_READ,
+ _ecore_exe_data_error_handler,
+ exe, NULL, NULL);
+ if (!exe->error_fd_handler)
+ ok = 0;
+ }
+ }
+ if (ok && (flags & ECORE_EXE_PIPE_READ)) /* Setup the read stuff. */
+ {
+ E_IF_NO_ERRNO(result,
+ fcntl(exe->child_fd_read, F_SETFL,
+ O_NONBLOCK), ok) {
+ }
+ E_IF_NO_ERRNO(result,
+ fcntl(exe->child_fd_read, F_SETFD,
+ FD_CLOEXEC), ok) {
+ }
+ E_IF_NO_ERRNO(result,
+ fcntl(exe->child_fd_read_x, F_SETFD,
+ FD_CLOEXEC), ok) {
+ }
+ {
+ exe->read_fd_handler =
+ ecore_main_fd_handler_add(exe->child_fd_read,
+ ECORE_FD_READ,
+ _ecore_exe_data_read_handler,
+ exe, NULL, NULL);
+ if (!exe->read_fd_handler)
+ ok = 0;
+ }
+ }
+ if (ok && (flags & ECORE_EXE_PIPE_WRITE)) /* Setup the write stuff. */
+ {
+ E_IF_NO_ERRNO(result,
+ fcntl(exe->child_fd_write, F_SETFL,
+ O_NONBLOCK), ok) {
+ }
+ E_IF_NO_ERRNO(result,
+ fcntl(exe->child_fd_write, F_SETFD,
+ FD_CLOEXEC), ok) {
+ }
+ E_IF_NO_ERRNO(result,
+ fcntl(exe->child_fd_write_x, F_SETFD,
+ FD_CLOEXEC), ok) {
+ }
+ {
+ exe->write_fd_handler =
+ ecore_main_fd_handler_add(exe->child_fd_write,
+ ECORE_FD_WRITE,
+ _ecore_exe_data_write_handler,
+ exe, NULL, NULL);
+ if (exe->write_fd_handler)
+ ecore_main_fd_handler_active_set(exe->write_fd_handler, 0); /* Nothing to write to start with. */
+ else
+ ok = 0;
+ }
+ }
+
+ exes = (Ecore_Exe *)eina_inlist_append(EINA_INLIST_GET(exes), EINA_INLIST_GET(exe));
+ n = 0;
}
- else
- ok = 0;
- }
-
- if (!ok)
- { /* Something went wrong, so pull down everything. */
- if (exe->pid) ecore_exe_terminate(exe);
- IF_FN_DEL(ecore_exe_free, exe);
- }
+ else
+ ok = 0;
+ }
+ else
+ ok = 0;
+ }
+
+ if (!ok) /* Something went wrong, so pull down everything. */
+ {
+ if (exe->pid) ecore_exe_terminate(exe);
+ IF_FN_DEL(ecore_exe_free, exe);
+ }
else
- {
- Ecore_Exe_Event_Add *e;
+ {
+ Ecore_Exe_Event_Add *e;
- e = _ecore_exe_event_add_new();
- e->exe = exe;
- if (e) /* Send the event. */
- ecore_event_add(ECORE_EXE_EVENT_ADD, e,
- _ecore_exe_event_add_free, NULL);
- /* INF("Running as %d for %s.\n", exe->pid, exe->cmd); */
- }
+ e = _ecore_exe_event_add_new();
+ e->exe = exe;
+ if (e) /* Send the event. */
+ ecore_event_add(ECORE_EXE_EVENT_ADD, e,
+ _ecore_exe_event_add_free, NULL);
+ /* INF("Running as %d for %s.\n", exe->pid, exe->cmd); */
+ }
errno = n;
return exe;
* @param func The function to call before @a exe is freed.
*/
EAPI void
-ecore_exe_callback_pre_free_set(Ecore_Exe *exe, Ecore_Exe_Cb func)
+ecore_exe_callback_pre_free_set(Ecore_Exe *exe,
+ Ecore_Exe_Cb func)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
- {
- ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
- "ecore_exe_callback_pre_free_set");
- return;
- }
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
+ "ecore_exe_callback_pre_free_set");
+ return;
+ }
exe->pre_free_cb = func;
}
* @return EINA_TRUE if successful, EINA_FALSE on failure.
*/
EAPI Eina_Bool
-ecore_exe_send(Ecore_Exe * exe, const void *data, int size)
+ecore_exe_send(Ecore_Exe *exe,
+ const void *data,
+ int size)
{
void *buf;
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
- {
- ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_send");
- return EINA_FALSE;
- }
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_send");
+ return EINA_FALSE;
+ }
if (exe->close_stdin)
- {
- ERR("Ecore_Exe %p stdin is closed! Cannot send %d bytes from %p",
- exe, size, data);
- return EINA_FALSE;
- }
+ {
+ ERR("Ecore_Exe %p stdin is closed! Cannot send %d bytes from %p",
+ exe, size, data);
+ return EINA_FALSE;
+ }
if (exe->child_fd_write == -1)
- {
- ERR("Ecore_Exe %p created without ECORE_EXE_PIPE_WRITE! "
- "Cannot send %d bytes from %p", exe, size, data);
- return EINA_FALSE;
- }
+ {
+ ERR("Ecore_Exe %p created without ECORE_EXE_PIPE_WRITE! "
+ "Cannot send %d bytes from %p", exe, size, data);
+ return EINA_FALSE;
+ }
buf = realloc(exe->write_data_buf, exe->write_data_size + size);
if (!buf) return EINA_FALSE;
exe->write_data_size += size;
if (exe->write_fd_handler)
- ecore_main_fd_handler_active_set(exe->write_fd_handler, ECORE_FD_WRITE);
+ ecore_main_fd_handler_active_set(exe->write_fd_handler, ECORE_FD_WRITE);
return EINA_TRUE;
}
ecore_exe_close_stdin(Ecore_Exe *exe)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
- {
- ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_close_stdin");
- return;
- }
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_close_stdin");
+ return;
+ }
exe->close_stdin = 1;
}
* @param end_lines limit of lines at end of output to buffer.
*/
EAPI void
-ecore_exe_auto_limits_set(Ecore_Exe *exe, int start_bytes, int end_bytes, int start_lines, int end_lines)
+ecore_exe_auto_limits_set(Ecore_Exe *exe,
+ int start_bytes,
+ int end_bytes,
+ int start_lines,
+ int end_lines)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
- {
- ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_auto_limits_set");
- return;
- }
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_auto_limits_set");
+ return;
+ }
/* FIXME: sanitize the input. */
exe->start_bytes = start_bytes;
exe->end_bytes = end_bytes;
* @param flags Is this a ECORE_EXE_PIPE_READ or ECORE_EXE_PIPE_ERROR?
*/
EAPI Ecore_Exe_Event_Data *
-ecore_exe_event_data_get(Ecore_Exe *exe, Ecore_Exe_Flags flags)
+ecore_exe_event_data_get(Ecore_Exe *exe,
+ Ecore_Exe_Flags flags)
{
Ecore_Exe_Event_Data *e = NULL;
int is_buffered = 0;
int inbuf_num;
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
- {
- ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_event_data_get");
- return NULL;
- }
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_event_data_get");
+ return NULL;
+ }
/* Sort out what sort of event we are. */
if (flags & ECORE_EXE_PIPE_READ)
- {
- flags = ECORE_EXE_PIPE_READ;
- if (exe->flags & ECORE_EXE_PIPE_READ_LINE_BUFFERED)
- is_buffered = 1;
- }
+ {
+ flags = ECORE_EXE_PIPE_READ;
+ if (exe->flags & ECORE_EXE_PIPE_READ_LINE_BUFFERED)
+ is_buffered = 1;
+ }
else
- {
- flags = ECORE_EXE_PIPE_ERROR;
- if (exe->flags & ECORE_EXE_PIPE_ERROR_LINE_BUFFERED)
- is_buffered = 1;
- }
+ {
+ flags = ECORE_EXE_PIPE_ERROR;
+ if (exe->flags & ECORE_EXE_PIPE_ERROR_LINE_BUFFERED)
+ is_buffered = 1;
+ }
/* Get the data. */
if (flags & ECORE_EXE_PIPE_READ)
- {
- inbuf = exe->read_data_buf;
- inbuf_num = exe->read_data_size;
- exe->read_data_buf = NULL;
- exe->read_data_size = 0;
- }
+ {
+ inbuf = exe->read_data_buf;
+ inbuf_num = exe->read_data_size;
+ exe->read_data_buf = NULL;
+ exe->read_data_size = 0;
+ }
else
- {
- inbuf = exe->error_data_buf;
- inbuf_num = exe->error_data_size;
- exe->error_data_buf = NULL;
- exe->error_data_size = 0;
- }
+ {
+ inbuf = exe->error_data_buf;
+ inbuf_num = exe->error_data_size;
+ exe->error_data_buf = NULL;
+ exe->error_data_size = 0;
+ }
e = calloc(1, sizeof(Ecore_Exe_Event_Data));
if (e)
- {
- e->exe = exe;
- e->data = inbuf;
- e->size = inbuf_num;
-
- if (is_buffered)
- { /* Deal with line buffering. */
- int max = 0;
- int count = 0;
- int i;
- int last = 0;
- char *c;
-
- c = (char *)inbuf;
- for (i = 0; i < inbuf_num; i++) /* Find the lines. */
- {
- if (inbuf[i] == '\n')
- {
- if (count >= max)
- {
- /* In testing, the lines seem to arrive in batches of 500 to 1000 lines at most, roughly speaking. */
- max += 10; /* FIXME: Maybe keep track of the largest number of lines ever sent, and add half that many instead of 10. */
- e->lines = realloc(e->lines, sizeof(Ecore_Exe_Event_Data_Line) * (max + 1)); /* Allow room for the NULL termination. */
- }
- /* raster said to leave the line endings as line endings, however -
- * This is line buffered mode, we are not dealing with binary here, but lines.
- * If we are not dealing with binary, we must be dealing with ASCII, unicode, or some other text format.
- * Thus the user is most likely gonna deal with this text as strings.
- * Thus the user is most likely gonna pass this data to str functions.
- * rasters way - the endings are always gonna be '\n'; onefangs way - they will always be '\0'
- * We are handing them the string length as a convenience.
- * Thus if they really want it in raw format, they can e->lines[i].line[e->lines[i].size - 1] = '\n'; easily enough.
- * In the default case, we can do this conversion quicker than the user can, as we already have the index and pointer.
- * Let's make it easy on them to use these as standard C strings.
- *
- * onefang is proud to announce that he has just set a new personal record for the
- * most over documentation of a simple assignment statement. B-)
- */
- inbuf[i] = '\0';
- e->lines[count].line = c;
- e->lines[count].size = i - last;
- last = i + 1;
- c = (char *)&inbuf[last];
- count++;
- }
- }
- if (i > last) /* Partial line left over, save it for next time. */
- {
- if (count != 0) e->size = last;
- if (flags & ECORE_EXE_PIPE_READ)
- {
- exe->read_data_size = i - last;
- exe->read_data_buf = malloc(exe->read_data_size);
- memcpy(exe->read_data_buf, c, exe->read_data_size);
- }
- else
- {
- exe->error_data_size = i - last;
- exe->error_data_buf = malloc(exe->error_data_size);
- memcpy(exe->error_data_buf, c, exe->error_data_size);
- }
- }
- if (count == 0) /* No lines to send, cancel the event. */
- {
- _ecore_exe_event_exe_data_free(NULL, e);
- e = NULL;
- }
- else /* NULL terminate the array, so that people know where the end is. */
+ {
+ e->exe = exe;
+ e->data = inbuf;
+ e->size = inbuf_num;
+
+ if (is_buffered) /* Deal with line buffering. */
+ {
+ int max = 0;
+ int count = 0;
+ int i;
+ int last = 0;
+ char *c;
+
+ c = (char *)inbuf;
+ for (i = 0; i < inbuf_num; i++) /* Find the lines. */
+ {
+ if (inbuf[i] == '\n')
+ {
+ if (count >= max)
{
- e->lines[count].line = NULL;
- e->lines[count].size = 0;
+ /* In testing, the lines seem to arrive in batches of 500 to 1000 lines at most, roughly speaking. */
+ max += 10; /* FIXME: Maybe keep track of the largest number of lines ever sent, and add half that many instead of 10. */
+ e->lines = realloc(e->lines, sizeof(Ecore_Exe_Event_Data_Line) * (max + 1)); /* Allow room for the NULL termination. */
}
- }
- }
+ /* raster said to leave the line endings as line endings, however -
+ * This is line buffered mode, we are not dealing with binary here, but lines.
+ * If we are not dealing with binary, we must be dealing with ASCII, unicode, or some other text format.
+ * Thus the user is most likely gonna deal with this text as strings.
+ * Thus the user is most likely gonna pass this data to str functions.
+ * rasters way - the endings are always gonna be '\n'; onefangs way - they will always be '\0'
+ * We are handing them the string length as a convenience.
+ * Thus if they really want it in raw format, they can e->lines[i].line[e->lines[i].size - 1] = '\n'; easily enough.
+ * In the default case, we can do this conversion quicker than the user can, as we already have the index and pointer.
+ * Let's make it easy on them to use these as standard C strings.
+ *
+ * onefang is proud to announce that he has just set a new personal record for the
+ * most over documentation of a simple assignment statement. B-)
+ */
+ inbuf[i] = '\0';
+ e->lines[count].line = c;
+ e->lines[count].size = i - last;
+ last = i + 1;
+ c = (char *)&inbuf[last];
+ count++;
+ }
+ }
+ if (i > last) /* Partial line left over, save it for next time. */
+ {
+ if (count != 0) e->size = last;
+ if (flags & ECORE_EXE_PIPE_READ)
+ {
+ exe->read_data_size = i - last;
+ exe->read_data_buf = malloc(exe->read_data_size);
+ memcpy(exe->read_data_buf, c, exe->read_data_size);
+ }
+ else
+ {
+ exe->error_data_size = i - last;
+ exe->error_data_buf = malloc(exe->error_data_size);
+ memcpy(exe->error_data_buf, c, exe->error_data_size);
+ }
+ }
+ if (count == 0) /* No lines to send, cancel the event. */
+ {
+ _ecore_exe_event_exe_data_free(NULL, e);
+ e = NULL;
+ }
+ else /* NULL terminate the array, so that people know where the end is. */
+ {
+ e->lines[count].line = NULL;
+ e->lines[count].size = 0;
+ }
+ }
+ }
return e;
}
* @param tag The string tag to set on the process handle.
*/
EAPI void
-ecore_exe_tag_set(Ecore_Exe *exe, const char *tag)
+ecore_exe_tag_set(Ecore_Exe *exe,
+ const char *tag)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
- {
- ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_tag_set");
- return;
- }
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_tag_set");
+ return;
+ }
IF_FREE(exe->tag);
if (tag)
- exe->tag = strdup(tag);
+ exe->tag = strdup(tag);
else
- exe->tag = NULL;
+ exe->tag = NULL;
}
/**
ecore_exe_tag_get(const Ecore_Exe *exe)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
- {
- ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_tag_get");
- return NULL;
- }
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_tag_get");
+ return NULL;
+ }
return exe->tag;
}
int result;
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
- {
- ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_free");
- return NULL;
- }
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_free");
+ return NULL;
+ }
data = exe->data;
exe->pre_free_cb(data, exe);
if (exe->doomsday_clock)
- {
- struct _ecore_exe_dead_exe *dead;
-
- ecore_timer_del(exe->doomsday_clock);
- exe->doomsday_clock = NULL;
- dead = exe->doomsday_clock_dead;
- if (dead)
- {
- IF_FREE(dead->cmd);
- free(dead);
- exe->doomsday_clock_dead = NULL;
- }
- }
+ {
+ struct _ecore_exe_dead_exe *dead;
+
+ ecore_timer_del(exe->doomsday_clock);
+ exe->doomsday_clock = NULL;
+ dead = exe->doomsday_clock_dead;
+ if (dead)
+ {
+ IF_FREE(dead->cmd);
+ free(dead);
+ exe->doomsday_clock_dead = NULL;
+ }
+ }
IF_FN_DEL(ecore_main_fd_handler_del, exe->write_fd_handler);
IF_FN_DEL(ecore_main_fd_handler_del, exe->read_fd_handler);
IF_FN_DEL(ecore_main_fd_handler_del, exe->error_fd_handler);
if (exe->child_fd_write_x != -1)
- E_NO_ERRNO(result, close(exe->child_fd_write_x), ok);
+ E_NO_ERRNO(result, close(exe->child_fd_write_x), ok);
if (exe->child_fd_read_x != -1)
- E_NO_ERRNO(result, close(exe->child_fd_read_x), ok);
+ E_NO_ERRNO(result, close(exe->child_fd_read_x), ok);
if (exe->child_fd_error_x != -1)
- E_NO_ERRNO(result, close(exe->child_fd_error_x), ok);
+ E_NO_ERRNO(result, close(exe->child_fd_error_x), ok);
if (exe->child_fd_write != -1)
- E_NO_ERRNO(result, close(exe->child_fd_write), ok);
+ E_NO_ERRNO(result, close(exe->child_fd_write), ok);
if (exe->child_fd_read != -1)
- E_NO_ERRNO(result, close(exe->child_fd_read), ok);
+ E_NO_ERRNO(result, close(exe->child_fd_read), ok);
if (exe->child_fd_error != -1)
- E_NO_ERRNO(result, close(exe->child_fd_error), ok);
+ E_NO_ERRNO(result, close(exe->child_fd_error), ok);
IF_FREE(exe->write_data_buf);
IF_FREE(exe->read_data_buf);
IF_FREE(exe->error_data_buf);
IF_FREE(exe->cmd);
- exes = (Ecore_Exe *) eina_inlist_remove(EINA_INLIST_GET(exes), EINA_INLIST_GET(exe));
+ exes = (Ecore_Exe *)eina_inlist_remove(EINA_INLIST_GET(exes), EINA_INLIST_GET(exe));
ECORE_MAGIC_SET(exe, ECORE_MAGIC_NONE);
IF_FREE(exe->tag);
free(exe);
ecore_exe_pid_get(const Ecore_Exe *exe)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
- {
- ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_pid_get");
- return -1;
- }
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_pid_get");
+ return -1;
+ }
return exe->pid;
}
ecore_exe_cmd_get(const Ecore_Exe *exe)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
- {
- ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_cmd_get");
- return NULL;
- }
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_cmd_get");
+ return NULL;
+ }
return exe->cmd;
}
ecore_exe_data_get(const Ecore_Exe *exe)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
- {
- ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_data_get");
- return NULL;
- }
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_data_get");
+ return NULL;
+ }
return exe->data;
}
* @since 1.1
*/
EAPI void *
-ecore_exe_data_set(Ecore_Exe *exe, void *data)
+ecore_exe_data_set(Ecore_Exe *exe,
+ void *data)
{
void *ret;
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
- {
- ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, __func__);
- return NULL;
- }
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, __func__);
+ return NULL;
+ }
ret = exe->data;
exe->data = data;
return ret;
ecore_exe_flags_get(const Ecore_Exe *exe)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
- {
- ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_data_get");
- return 0;
- }
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_data_get");
+ return 0;
+ }
return exe->flags;
}
ecore_exe_pause(Ecore_Exe *exe)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
- {
- ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_pause");
- return;
- }
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_pause");
+ return;
+ }
kill(exe->pid, SIGSTOP);
}
ecore_exe_continue(Ecore_Exe *exe)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
- {
- ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_continue");
- return;
- }
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_continue");
+ return;
+ }
kill(exe->pid, SIGCONT);
}
ecore_exe_interrupt(Ecore_Exe *exe)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
- {
- ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_interrupt");
- return;
- }
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_interrupt");
+ return;
+ }
_ecore_exe_dead_attach(exe);
kill(exe->pid, SIGINT);
}
ecore_exe_quit(Ecore_Exe *exe)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
- {
- ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_quit");
- return;
- }
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_quit");
+ return;
+ }
_ecore_exe_dead_attach(exe);
kill(exe->pid, SIGQUIT);
}
ecore_exe_terminate(Ecore_Exe *exe)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
- {
- ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_terminate");
- return;
- }
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_terminate");
+ return;
+ }
_ecore_exe_dead_attach(exe);
INF("Sending TERM signal to %s (%d).", exe->cmd, exe->pid);
kill(exe->pid, SIGTERM);
struct _ecore_exe_dead_exe *dead;
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
- {
- ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_kill");
- return;
- }
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_kill");
+ return;
+ }
dead = calloc(1, sizeof(struct _ecore_exe_dead_exe));
if (dead)
- {
- dead->pid = exe->pid;
- dead->cmd = strdup(exe->cmd);
- IF_FN_DEL(ecore_timer_del, exe->doomsday_clock);
- exe->doomsday_clock =
- ecore_timer_add(10.0, _ecore_exe_make_sure_its_really_dead, dead);
- }
+ {
+ dead->pid = exe->pid;
+ dead->cmd = strdup(exe->cmd);
+ IF_FN_DEL(ecore_timer_del, exe->doomsday_clock);
+ exe->doomsday_clock =
+ ecore_timer_add(10.0, _ecore_exe_make_sure_its_really_dead, dead);
+ }
INF("Sending KILL signal to %s (%d).", exe->cmd, exe->pid);
kill(exe->pid, SIGKILL);
* the signal will be ignored.
*/
EAPI void
-ecore_exe_signal(Ecore_Exe *exe, int num)
+ecore_exe_signal(Ecore_Exe *exe,
+ int num)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
- {
- ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_signal");
- return;
- }
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_signal");
+ return;
+ }
if (num == 1)
- kill(exe->pid, SIGUSR1);
+ kill(exe->pid, SIGUSR1);
else if (num == 2)
- kill(exe->pid, SIGUSR2);
+ kill(exe->pid, SIGUSR2);
}
/**
ecore_exe_hup(Ecore_Exe *exe)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
- {
- ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_hup");
- return;
- }
+ {
+ ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_hup");
+ return;
+ }
kill(exe->pid, SIGHUP);
}
*/
exe = _ecore_exe_find(pid);
if (exe)
- {
- if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
- exe = NULL;
- }
+ {
+ if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
+ exe = NULL;
+ }
return exe;
}
dead = data;
if (dead)
- {
- Ecore_Exe *exe = NULL;
-
- if ((exe = _ecore_exe_is_it_alive(dead->pid)))
- {
- if (dead->cmd)
- INF("Sending KILL signal to allegedly dead %s (%d).",
- dead->cmd, dead->pid);
- else
- INF("Sending KILL signal to allegedly dead PID %d.",
- dead->pid);
- exe->doomsday_clock =
- ecore_timer_add(10.0, _ecore_exe_make_sure_its_really_dead,
- dead);
- kill(dead->pid, SIGKILL);
- }
- else
- {
- IF_FREE(dead->cmd);
- free(dead);
- }
- }
+ {
+ Ecore_Exe *exe = NULL;
+
+ if ((exe = _ecore_exe_is_it_alive(dead->pid)))
+ {
+ if (dead->cmd)
+ INF("Sending KILL signal to allegedly dead %s (%d).",
+ dead->cmd, dead->pid);
+ else
+ INF("Sending KILL signal to allegedly dead PID %d.",
+ dead->pid);
+ exe->doomsday_clock =
+ ecore_timer_add(10.0, _ecore_exe_make_sure_its_really_dead,
+ dead);
+ kill(dead->pid, SIGKILL);
+ }
+ else
+ {
+ IF_FREE(dead->cmd);
+ free(dead);
+ }
+ }
return ECORE_CALLBACK_CANCEL;
}
dead = data;
if (dead)
- {
- Ecore_Exe *exe = NULL;
-
- if ((exe = _ecore_exe_is_it_alive(dead->pid)))
- {
- ERR("RUN! The zombie wants to eat your brains! And your CPU!");
- if (dead->cmd)
- INF("%s (%d) is not really dead.", dead->cmd, dead->pid);
- else
- INF("PID %d is not really dead.", dead->pid);
- exe->doomsday_clock = NULL;
- }
- IF_FREE(dead->cmd);
- free(dead);
- }
+ {
+ Ecore_Exe *exe = NULL;
+
+ if ((exe = _ecore_exe_is_it_alive(dead->pid)))
+ {
+ ERR("RUN! The zombie wants to eat your brains! And your CPU!");
+ if (dead->cmd)
+ INF("%s (%d) is not really dead.", dead->cmd, dead->pid);
+ else
+ INF("PID %d is not really dead.", dead->pid);
+ exe->doomsday_clock = NULL;
+ }
+ IF_FREE(dead->cmd);
+ free(dead);
+ }
return ECORE_CALLBACK_CANCEL;
}
Ecore_Exe *exe;
EINA_INLIST_FOREACH(exes, exe)
- {
- if (exe->pid == pid)
- return exe;
- }
+ {
+ if (exe->pid == pid)
+ return exe;
+ }
return NULL;
}
}
void
-_ecore_exe_doomsday_clock_set(Ecore_Exe *exe, Ecore_Timer *dc)
+_ecore_exe_doomsday_clock_set(Ecore_Exe *exe,
+ Ecore_Timer *dc)
{
exe->doomsday_clock = dc;
}
static inline void
-_ecore_exe_exec_it(const char *exe_cmd, Ecore_Exe_Flags flags)
+_ecore_exe_exec_it(const char *exe_cmd,
+ Ecore_Exe_Flags flags)
{
char use_sh = 1;
char *buf = NULL;
char **args = NULL;
- int save_errno = 0;
+ int save_errno = 0;
/* So what is this doing?
*
* If we don't find them, we can call the exe directly.
*/
if (!strpbrk(exe_cmd, "|&;<>()$`\\\"'*?#"))
- {
- char *token;
- char pre_command = 1;
- int num_tokens = 0;
+ {
+ char *token;
+ char pre_command = 1;
+ int num_tokens = 0;
- if (!(buf = strdup(exe_cmd)))
- return;
-
- token = strtok(buf, " \t\n\v");
- while (token)
- {
- if (token[0] == '~')
- break;
- if (pre_command)
- {
- if (token[0] == '[')
- break;
- if (strchr(token, '='))
- break;
- else
- pre_command = 0;
- }
- num_tokens++;
- token = strtok(NULL, " \t\n\v");
- }
- IF_FREE(buf);
- if ((!token) && (num_tokens))
- {
- int i = 0;
+ if (!(buf = strdup(exe_cmd)))
+ return;
- if (!(buf = strdup(exe_cmd)))
- return;
+ token = strtok(buf, " \t\n\v");
+ while (token)
+ {
+ if (token[0] == '~')
+ break;
+ if (pre_command)
+ {
+ if (token[0] == '[')
+ break;
+ if (strchr(token, '='))
+ break;
+ else
+ pre_command = 0;
+ }
+ num_tokens++;
+ token = strtok(NULL, " \t\n\v");
+ }
+ IF_FREE(buf);
+ if ((!token) && (num_tokens))
+ {
+ int i = 0;
+
+ if (!(buf = strdup(exe_cmd)))
+ return;
- token = strtok(buf, " \t\n\v");
- use_sh = 0;
- if (!(args = (char **)calloc(num_tokens + 1, sizeof(char *))))
- {
- IF_FREE(buf);
- return;
- }
- for (i = 0; i < num_tokens; i++)
- {
- if (token)
- args[i] = token;
- token = strtok(NULL, " \t\n\v");
- }
- args[num_tokens] = NULL;
- }
- }
+ token = strtok(buf, " \t\n\v");
+ use_sh = 0;
+ if (!(args = (char **)calloc(num_tokens + 1, sizeof(char *))))
+ {
+ IF_FREE(buf);
+ return;
+ }
+ for (i = 0; i < num_tokens; i++)
+ {
+ if (token)
+ args[i] = token;
+ token = strtok(NULL, " \t\n\v");
+ }
+ args[num_tokens] = NULL;
+ }
+ }
#ifdef HAVE_SYS_PRCTL_H
if ((flags & ECORE_EXE_TERM_WITH_PARENT))
- {
- prctl(PR_SET_PDEATHSIG, SIGTERM);
- }
+ {
+ prctl(PR_SET_PDEATHSIG, SIGTERM);
+ }
#endif
if (!(flags & ECORE_EXE_NOT_LEADER)) setsid();
if ((flags & ECORE_EXE_USE_SH))
- {
- errno = 0;
- execl("/bin/sh", "/bin/sh", "-c", exe_cmd, (char *)NULL);
- }
- else if (use_sh)
- { /* We have to use a shell to run this. */
- if (!shell)
- { /* Find users preferred shell. */
- shell = getenv("SHELL");
- if (!shell)
- shell = "/bin/sh";
- }
- errno = 0;
- execl(shell, shell, "-c", exe_cmd, (char *)NULL);
- }
+ {
+ errno = 0;
+ execl("/bin/sh", "/bin/sh", "-c", exe_cmd, (char *)NULL);
+ }
+ else if (use_sh) /* We have to use a shell to run this. */
+ {
+ if (!shell) /* Find users preferred shell. */
+ {
+ shell = getenv("SHELL");
+ if (!shell)
+ shell = "/bin/sh";
+ }
+ errno = 0;
+ execl(shell, shell, "-c", exe_cmd, (char *)NULL);
+ }
else
- { /* We can run this directly. */
- if (!args)
- {
- IF_FREE(buf);
- IF_FREE(args);
- ERR("arg[0] is NULL!");
- return;
- }
- errno = 0;
- execvp(args[0], args);
- }
+ { /* We can run this directly. */
+ if (!args)
+ {
+ IF_FREE(buf);
+ IF_FREE(args);
+ ERR("arg[0] is NULL!");
+ return;
+ }
+ errno = 0;
+ execvp(args[0], args);
+ }
save_errno = errno;
IF_FREE(buf);
}
static Eina_Bool
-_ecore_exe_data_generic_handler(void *data, Ecore_Fd_Handler *fd_handler, Ecore_Exe_Flags flags)
+_ecore_exe_data_generic_handler(void *data,
+ Ecore_Fd_Handler *fd_handler,
+ Ecore_Exe_Flags flags)
{
Ecore_Exe *exe;
int child_fd;
/* Sort out what sort of handler we are. */
if (flags & ECORE_EXE_PIPE_READ)
- {
- flags = ECORE_EXE_PIPE_READ;
- event_type = ECORE_EXE_EVENT_DATA;
- child_fd = exe->child_fd_read;
- }
+ {
+ flags = ECORE_EXE_PIPE_READ;
+ event_type = ECORE_EXE_EVENT_DATA;
+ child_fd = exe->child_fd_read;
+ }
else
- {
- flags = ECORE_EXE_PIPE_ERROR;
- event_type = ECORE_EXE_EVENT_ERROR;
- child_fd = exe->child_fd_error;
- }
+ {
+ flags = ECORE_EXE_PIPE_ERROR;
+ event_type = ECORE_EXE_EVENT_ERROR;
+ child_fd = exe->child_fd_error;
+ }
if ((fd_handler)
&& (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)))
- {
- unsigned char *inbuf;
- int inbuf_num;
-
- /* Get any left over data from last time. */
- if (flags & ECORE_EXE_PIPE_READ)
- {
- inbuf = exe->read_data_buf;
- inbuf_num = exe->read_data_size;
- exe->read_data_buf = NULL;
- exe->read_data_size = 0;
- }
- else
- {
- inbuf = exe->error_data_buf;
- inbuf_num = exe->error_data_size;
- exe->error_data_buf = NULL;
- exe->error_data_size = 0;
- }
+ {
+ unsigned char *inbuf;
+ int inbuf_num;
+
+ /* Get any left over data from last time. */
+ if (flags & ECORE_EXE_PIPE_READ)
+ {
+ inbuf = exe->read_data_buf;
+ inbuf_num = exe->read_data_size;
+ exe->read_data_buf = NULL;
+ exe->read_data_size = 0;
+ }
+ else
+ {
+ inbuf = exe->error_data_buf;
+ inbuf_num = exe->error_data_size;
+ exe->error_data_buf = NULL;
+ exe->error_data_size = 0;
+ }
+
+ for (;; )
+ {
+ int num, lost_exe;
+ char buf[READBUFSIZ];
+
+ lost_exe = 0;
+ errno = 0;
+ if ((num = read(child_fd, buf, READBUFSIZ)) < 1)
+ {
+ /* FIXME: SPEED/SIZE TRADE OFF - add a smaller READBUFSIZE
+ * (currently 64k) to inbuf, use that instead of buf, and
+ * save ourselves a memcpy(). */
+ lost_exe = ((errno == EIO) ||
+ (errno == EBADF) ||
+ (errno == EPIPE) ||
+ (errno == EINVAL) || (errno == ENOSPC));
+ if ((errno != EAGAIN) && (errno != EINTR))
+ perror("_ecore_exe_generic_handler() read problem ");
+ }
+ if (num > 0) /* data got read. */
+ {
+ inbuf = realloc(inbuf, inbuf_num + num);
+ memcpy(inbuf + inbuf_num, buf, num);
+ inbuf_num += num;
+ }
+ else
+ { /* No more data to read. */
+ if (inbuf)
+ {
+ Ecore_Exe_Event_Data *e;
+
+ /* Stash the data away for later. */
+ if (flags & ECORE_EXE_PIPE_READ)
+ {
+ exe->read_data_buf = inbuf;
+ exe->read_data_size = inbuf_num;
+ }
+ else
+ {
+ exe->error_data_buf = inbuf;
+ exe->error_data_size = inbuf_num;
+ }
- for (;;)
- {
- int num, lost_exe;
- char buf[READBUFSIZ];
-
- lost_exe = 0;
- errno = 0;
- if ((num = read(child_fd, buf, READBUFSIZ)) < 1)
- /* FIXME: SPEED/SIZE TRADE OFF - add a smaller READBUFSIZE
- * (currently 64k) to inbuf, use that instead of buf, and
- * save ourselves a memcpy(). */
+ if (!(exe->flags & ECORE_EXE_PIPE_AUTO))
{
- lost_exe = ((errno == EIO) ||
- (errno == EBADF) ||
- (errno == EPIPE) ||
- (errno == EINVAL) || (errno == ENOSPC));
- if ((errno != EAGAIN) && (errno != EINTR))
- perror("_ecore_exe_generic_handler() read problem ");
+ e = ecore_exe_event_data_get(exe, flags);
+ if (e) /* Send the event. */
+ ecore_event_add(event_type, e,
+ _ecore_exe_event_exe_data_free,
+ NULL);
}
- if (num > 0)
- { /* data got read. */
- inbuf = realloc(inbuf, inbuf_num + num);
- memcpy(inbuf + inbuf_num, buf, num);
- inbuf_num += num;
+ }
+ if (lost_exe)
+ {
+ if (flags & ECORE_EXE_PIPE_READ)
+ {
+ if (exe->read_data_size)
+ INF("There are %d bytes left unsent from the dead exe %s.",
+ exe->read_data_size, exe->cmd);
}
- else
- { /* No more data to read. */
- if (inbuf)
- {
- Ecore_Exe_Event_Data *e;
-
- /* Stash the data away for later. */
- if (flags & ECORE_EXE_PIPE_READ)
- {
- exe->read_data_buf = inbuf;
- exe->read_data_size = inbuf_num;
- }
- else
- {
- exe->error_data_buf = inbuf;
- exe->error_data_size = inbuf_num;
- }
-
- if (!(exe->flags & ECORE_EXE_PIPE_AUTO))
- {
- e = ecore_exe_event_data_get(exe, flags);
- if (e) /* Send the event. */
- ecore_event_add(event_type, e,
- _ecore_exe_event_exe_data_free,
- NULL);
- }
- }
- if (lost_exe)
- {
- if (flags & ECORE_EXE_PIPE_READ)
- {
- if (exe->read_data_size)
- INF("There are %d bytes left unsent from the dead exe %s.",
- exe->read_data_size, exe->cmd);
- }
- else
- {
- if (exe->error_data_size)
- INF("There are %d bytes left unsent from the dead exe %s.",
- exe->error_data_size, exe->cmd);
- }
- /* Thought about this a bit. If the exe has actually
- * died, this won't do any harm as it must have died
- * recently and the pid has not had a chance to recycle.
- * It is also a paranoid catchall, coz the usual ecore_signal
- * mechenism should kick in. But let's give it a good
- * kick in the head anyway.
- */
- ecore_exe_terminate(exe);
- }
- break;
+ else
+ {
+ if (exe->error_data_size)
+ INF("There are %d bytes left unsent from the dead exe %s.",
+ exe->error_data_size, exe->cmd);
}
- }
- }
+ /* Thought about this a bit. If the exe has actually
+ * died, this won't do any harm as it must have died
+ * recently and the pid has not had a chance to recycle.
+ * It is also a paranoid catchall, coz the usual ecore_signal
+ * mechenism should kick in. But let's give it a good
+ * kick in the head anyway.
+ */
+ ecore_exe_terminate(exe);
+ }
+ break;
+ }
+ }
+ }
return ECORE_CALLBACK_RENEW;
}
static Eina_Bool
-_ecore_exe_data_error_handler(void *data, Ecore_Fd_Handler *fd_handler)
+_ecore_exe_data_error_handler(void *data,
+ Ecore_Fd_Handler *fd_handler)
{
return _ecore_exe_data_generic_handler(data, fd_handler,
ECORE_EXE_PIPE_ERROR);
}
static Eina_Bool
-_ecore_exe_data_read_handler(void *data, Ecore_Fd_Handler *fd_handler)
+_ecore_exe_data_read_handler(void *data,
+ Ecore_Fd_Handler *fd_handler)
{
return _ecore_exe_data_generic_handler(data, fd_handler,
ECORE_EXE_PIPE_READ);
}
static Eina_Bool
-_ecore_exe_data_write_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
+_ecore_exe_data_write_handler(void *data,
+ Ecore_Fd_Handler *fd_handler __UNUSED__)
{
Ecore_Exe *exe;
exe = data;
if ((exe->write_fd_handler) &&
(ecore_main_fd_handler_active_get
- (exe->write_fd_handler, ECORE_FD_WRITE)))
+ (exe->write_fd_handler, ECORE_FD_WRITE)))
_ecore_exe_flush(exe);
/* If we have sent all there is to send, and we need to close the pipe, then close it. */
if ((exe->close_stdin == 1)
&& (exe->write_data_size == exe->write_data_offset))
- {
- int ok = 0;
- int result;
-
- INF("Closing stdin for %s", exe->cmd);
- /* if (exe->child_fd_write != -1) E_NO_ERRNO(result, fsync(exe->child_fd_write), ok); This a) doesn't work, and b) isn't needed. */
- IF_FN_DEL(ecore_main_fd_handler_del, exe->write_fd_handler);
- if (exe->child_fd_write != -1)
- E_NO_ERRNO(result, close(exe->child_fd_write), ok);
- exe->child_fd_write = -1;
- IF_FREE(exe->write_data_buf);
- }
+ {
+ int ok = 0;
+ int result;
+
+ INF("Closing stdin for %s", exe->cmd);
+ /* if (exe->child_fd_write != -1) E_NO_ERRNO(result, fsync(exe->child_fd_write), ok); This a) doesn't work, and b) isn't needed. */
+ IF_FN_DEL(ecore_main_fd_handler_del, exe->write_fd_handler);
+ if (exe->child_fd_write != -1)
+ E_NO_ERRNO(result, close(exe->child_fd_write), ok);
+ exe->child_fd_write = -1;
+ IF_FREE(exe->write_data_buf);
+ }
return ECORE_CALLBACK_RENEW;
}
/* check whether we need to write anything at all. */
if ((exe->child_fd_write == -1) || (!exe->write_data_buf))
- return;
+ return;
if (exe->write_data_size == exe->write_data_offset)
- return;
+ return;
count = write(exe->child_fd_write,
(char *)exe->write_data_buf + exe->write_data_offset,
exe->write_data_size - exe->write_data_offset);
if (count < 1)
- {
- if (errno == EIO || errno == EBADF || errno == EPIPE || errno == EINVAL || errno == ENOSPC) /* we lost our exe! */
- {
- ecore_exe_terminate(exe);
- if (exe->write_fd_handler)
- ecore_main_fd_handler_active_set(exe->write_fd_handler, 0);
- }
- }
+ {
+ if (errno == EIO || errno == EBADF || errno == EPIPE || errno == EINVAL || errno == ENOSPC) /* we lost our exe! */
+ {
+ ecore_exe_terminate(exe);
+ if (exe->write_fd_handler)
+ ecore_main_fd_handler_active_set(exe->write_fd_handler, 0);
+ }
+ }
else
- {
- exe->write_data_offset += count;
- if (exe->write_data_offset >= exe->write_data_size)
- { /* Nothing left to write, clean up. */
- exe->write_data_size = 0;
- exe->write_data_offset = 0;
- IF_FREE(exe->write_data_buf);
- if (exe->write_fd_handler)
- ecore_main_fd_handler_active_set(exe->write_fd_handler, 0);
- }
- }
+ {
+ exe->write_data_offset += count;
+ if (exe->write_data_offset >= exe->write_data_size) /* Nothing left to write, clean up. */
+ {
+ exe->write_data_size = 0;
+ exe->write_data_offset = 0;
+ IF_FREE(exe->write_data_buf);
+ if (exe->write_fd_handler)
+ ecore_main_fd_handler_active_set(exe->write_fd_handler, 0);
+ }
+ }
}
static void
-_ecore_exe_event_exe_data_free(void *data __UNUSED__, void *ev)
+_ecore_exe_event_exe_data_free(void *data __UNUSED__,
+ void *ev)
{
Ecore_Exe_Event_Data *e;
}
static void
-_ecore_exe_event_add_free(void *data __UNUSED__, void *ev)
+_ecore_exe_event_add_free(void *data __UNUSED__,
+ void *ev)
{
Ecore_Exe_Event_Add *e;
free(e);
}
-void *
+void *
_ecore_exe_event_del_new(void)
{
Ecore_Exe_Event_Del *e;
}
void
-_ecore_exe_event_del_free(void *data __UNUSED__, void *ev)
+_ecore_exe_event_del_free(void *data __UNUSED__,
+ void *ev)
{
Ecore_Exe_Event_Del *e;
if (exe->doomsday_clock_dead) return;
dead = calloc(1, sizeof(struct _ecore_exe_dead_exe));
if (dead)
- {
- dead->pid = exe->pid;
- dead->cmd = strdup(exe->cmd);
- IF_FN_DEL(ecore_timer_del, exe->doomsday_clock);
- exe->doomsday_clock =
- ecore_timer_add(10.0, _ecore_exe_make_sure_its_dead, dead);
- exe->doomsday_clock_dead = dead;
- }
+ {
+ dead->pid = exe->pid;
+ dead->cmd = strdup(exe->cmd);
+ IF_FN_DEL(ecore_timer_del, exe->doomsday_clock);
+ exe->doomsday_clock =
+ ecore_timer_add(10.0, _ecore_exe_make_sure_its_dead, dead);
+ exe->doomsday_clock_dead = dead;
+ }
}
+
typedef enum
{
- ECORE_EXE_WIN32_SIGINT,
- ECORE_EXE_WIN32_SIGQUIT,
- ECORE_EXE_WIN32_SIGTERM,
- ECORE_EXE_WIN32_SIGKILL
+ ECORE_EXE_WIN32_SIGINT,
+ ECORE_EXE_WIN32_SIGQUIT,
+ ECORE_EXE_WIN32_SIGTERM,
+ ECORE_EXE_WIN32_SIGKILL
} Ecore_Exe_Win32_Signal;
struct _Ecore_Exe
{
EINA_INLIST;
- ECORE_MAGIC;
-
- HANDLE process2;
- HANDLE process; /* CloseHandle */
- HANDLE process_thread;
- DWORD process_id;
- DWORD thread_id;
- void *data;
- char *tag;
- char *cmd;
- Ecore_Exe_Flags flags;
+ ECORE_MAGIC;
+
+ HANDLE process2;
+ HANDLE process; /* CloseHandle */
+ HANDLE process_thread;
+ DWORD process_id;
+ DWORD thread_id;
+ void *data;
+ char *tag;
+ char *cmd;
+ Ecore_Exe_Flags flags;
Ecore_Exe_Win32_Signal sig;
- Ecore_Win32_Handler *h_close;
+ Ecore_Win32_Handler *h_close;
struct
{
- HANDLE child_pipe;
- HANDLE child_pipe_x;
+ HANDLE child_pipe;
+ HANDLE child_pipe_x;
Ecore_Pipe *p;
- HANDLE thread;
- void *data_buf;
- int data_size;
+ HANDLE thread;
+ void *data_buf;
+ int data_size;
} pipe_read;
struct
{
- HANDLE child_pipe;
- HANDLE child_pipe_x;
- HANDLE thread;
+ HANDLE child_pipe;
+ HANDLE child_pipe_x;
+ HANDLE thread;
Ecore_Win32_Handler *h;
- void *data_buf;
- int data_size;
+ void *data_buf;
+ int data_size;
} pipe_write;
struct
{
- HANDLE child_pipe;
- HANDLE child_pipe_x;
+ HANDLE child_pipe;
+ HANDLE child_pipe_x;
Ecore_Pipe *p;
- HANDLE thread;
- void *data_buf;
- int data_size;
+ HANDLE thread;
+ void *data_buf;
+ int data_size;
} pipe_error;
Eina_Bool close_stdin : 1;
Eina_Bool is_suspended : 1;
static int _ecore_exe_win32_pipes_set(Ecore_Exe *exe);
static void _ecore_exe_win32_pipes_close(Ecore_Exe *exe);
-static BOOL CALLBACK _ecore_exe_enum_windows_procedure(HWND window, LPARAM data);
-static void _ecore_exe_event_add_free(void *data, void *ev);
-static void _ecore_exe_event_del_free(void *data, void *ev);
+static BOOL CALLBACK _ecore_exe_enum_windows_procedure(HWND window,
+ LPARAM data);
+static void _ecore_exe_event_add_free(void *data,
+ void *ev);
+static void _ecore_exe_event_del_free(void *data,
+ void *ev);
static void _ecore_exe_event_exe_data_free(void *data,
void *ev);
-static int _ecore_exe_win32_pipe_thread_generic_cb(void *data, Ecore_Exe_Flags flags);
+static int _ecore_exe_win32_pipe_thread_generic_cb(void *data,
+ Ecore_Exe_Flags flags);
static DWORD WINAPI _ecore_exe_win32_pipe_thread_read_cb(void *data);
static DWORD WINAPI _ecore_exe_win32_pipe_thread_error_cb(void *data);
-static Eina_Bool _ecore_exe_close_cb(void *data, Ecore_Win32_Handler *wh);
-static void _ecore_exe_pipe_read_cb(void *data, void *buf, unsigned int size);
-static int _ecore_exe_pipe_write_cb(void *data, Ecore_Win32_Handler *wh);
-static void _ecore_exe_pipe_error_cb(void *data, void *buf, unsigned int size);
+static Eina_Bool _ecore_exe_close_cb(void *data,
+ Ecore_Win32_Handler *wh);
+static void _ecore_exe_pipe_read_cb(void *data,
+ void *buf,
+ unsigned int size);
+static int _ecore_exe_pipe_write_cb(void *data,
+ Ecore_Win32_Handler *wh);
+static void _ecore_exe_pipe_error_cb(void *data,
+ void *buf,
+ unsigned int size);
EAPI int ECORE_EXE_EVENT_ADD = 0;
EAPI int ECORE_EXE_EVENT_DEL = 0;
_ecore_exe_shutdown(void)
{
while (exes)
- ecore_exe_free(exes);
+ ecore_exe_free(exes);
}
static int run_pri = NORMAL_PRIORITY_CLASS;
{
switch (pri)
{
- case ECORE_EXE_WIN32_PRIORITY_IDLE:
- run_pri = IDLE_PRIORITY_CLASS;
- break;
- case ECORE_EXE_WIN32_PRIORITY_BELOW_NORMAL:
- run_pri = BELOW_NORMAL_PRIORITY_CLASS;
- break;
- case ECORE_EXE_WIN32_PRIORITY_NORMAL:
- run_pri = NORMAL_PRIORITY_CLASS;
- break;
- case ECORE_EXE_WIN32_PRIORITY_ABOVE_NORMAL:
- run_pri = ABOVE_NORMAL_PRIORITY_CLASS;
- break;
- case ECORE_EXE_WIN32_PRIORITY_HIGH:
- run_pri = HIGH_PRIORITY_CLASS;
- break;
- case ECORE_EXE_WIN32_PRIORITY_REALTIME:
- run_pri = REALTIME_PRIORITY_CLASS;
- break;
- default:
- break;
+ case ECORE_EXE_WIN32_PRIORITY_IDLE:
+ run_pri = IDLE_PRIORITY_CLASS;
+ break;
+
+ case ECORE_EXE_WIN32_PRIORITY_BELOW_NORMAL:
+ run_pri = BELOW_NORMAL_PRIORITY_CLASS;
+ break;
+
+ case ECORE_EXE_WIN32_PRIORITY_NORMAL:
+ run_pri = NORMAL_PRIORITY_CLASS;
+ break;
+
+ case ECORE_EXE_WIN32_PRIORITY_ABOVE_NORMAL:
+ run_pri = ABOVE_NORMAL_PRIORITY_CLASS;
+ break;
+
+ case ECORE_EXE_WIN32_PRIORITY_HIGH:
+ run_pri = HIGH_PRIORITY_CLASS;
+ break;
+
+ case ECORE_EXE_WIN32_PRIORITY_REALTIME:
+ run_pri = REALTIME_PRIORITY_CLASS;
+ break;
+
+ default:
+ break;
}
}
{
switch (run_pri)
{
- case IDLE_PRIORITY_CLASS:
- return ECORE_EXE_WIN32_PRIORITY_IDLE;
- case BELOW_NORMAL_PRIORITY_CLASS:
- return ECORE_EXE_WIN32_PRIORITY_BELOW_NORMAL;
- case NORMAL_PRIORITY_CLASS:
- return ECORE_EXE_WIN32_PRIORITY_NORMAL;
- case ABOVE_NORMAL_PRIORITY_CLASS:
- return ECORE_EXE_WIN32_PRIORITY_ABOVE_NORMAL;
- case HIGH_PRIORITY_CLASS:
- return ECORE_EXE_WIN32_PRIORITY_HIGH;
- case REALTIME_PRIORITY_CLASS:
- return ECORE_EXE_WIN32_PRIORITY_REALTIME;
- /* default should not be reached */
- default:
- return ECORE_EXE_WIN32_PRIORITY_NORMAL;
+ case IDLE_PRIORITY_CLASS:
+ return ECORE_EXE_WIN32_PRIORITY_IDLE;
+
+ case BELOW_NORMAL_PRIORITY_CLASS:
+ return ECORE_EXE_WIN32_PRIORITY_BELOW_NORMAL;
+
+ case NORMAL_PRIORITY_CLASS:
+ return ECORE_EXE_WIN32_PRIORITY_NORMAL;
+
+ case ABOVE_NORMAL_PRIORITY_CLASS:
+ return ECORE_EXE_WIN32_PRIORITY_ABOVE_NORMAL;
+
+ case HIGH_PRIORITY_CLASS:
+ return ECORE_EXE_WIN32_PRIORITY_HIGH;
+
+ case REALTIME_PRIORITY_CLASS:
+ return ECORE_EXE_WIN32_PRIORITY_REALTIME;
+
+ /* default should not be reached */
+ default:
+ return ECORE_EXE_WIN32_PRIORITY_NORMAL;
}
}
EAPI Ecore_Exe *
-ecore_exe_run(const char *exe_cmd, const void *data)
+ecore_exe_run(const char *exe_cmd,
+ const void *data)
{
return ecore_exe_pipe_run(exe_cmd, 0, data);
}
EAPI Ecore_Exe *
-ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, const void *data)
+ecore_exe_pipe_run(const char *exe_cmd,
+ Ecore_Exe_Flags flags,
+ const void *data)
{
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
Ecore_Exe_Event_Add *e;
- Ecore_Exe *exe;
- char *ret = NULL;
+ Ecore_Exe *exe;
+ char *ret = NULL;
exe = calloc(1, sizeof(Ecore_Exe));
if (!exe)
return exe;
- delete_h_close:
+delete_h_close:
ecore_main_win32_handler_del(exe->h_close);
- close_process2:
+close_process2:
CloseHandle(exe->process2);
- close_thread:
+close_thread:
CloseHandle(exe->process_thread);
CloseHandle(exe->process);
- free_exe_cmd:
+free_exe_cmd:
free(exe->cmd);
- close_pipes:
+close_pipes:
_ecore_exe_win32_pipes_close(exe);
- free_exe:
+free_exe:
free(exe);
return NULL;
}
EAPI void
-ecore_exe_callback_pre_free_set(Ecore_Exe *exe, Ecore_Exe_Cb func)
+ecore_exe_callback_pre_free_set(Ecore_Exe *exe,
+ Ecore_Exe_Cb func)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
{
}
EAPI Eina_Bool
-ecore_exe_send(Ecore_Exe *exe, const void *data, int size)
+ecore_exe_send(Ecore_Exe *exe,
+ const void *data,
+ int size)
{
void *buf;
/* Not used on Windows */
EAPI void
-ecore_exe_auto_limits_set(Ecore_Exe *exe __UNUSED__, int start_bytes __UNUSED__, int end_bytes __UNUSED__, int start_lines __UNUSED__, int end_lines __UNUSED__)
+ecore_exe_auto_limits_set(Ecore_Exe *exe __UNUSED__,
+ int start_bytes __UNUSED__,
+ int end_bytes __UNUSED__,
+ int start_lines __UNUSED__,
+ int end_lines __UNUSED__)
{
}
EAPI Ecore_Exe_Event_Data *
-ecore_exe_event_data_get(Ecore_Exe *exe, Ecore_Exe_Flags flags)
+ecore_exe_event_data_get(Ecore_Exe *exe,
+ Ecore_Exe_Flags flags)
{
Ecore_Exe_Event_Data *e = NULL;
- unsigned char *inbuf;
- int inbuf_num;
+ unsigned char *inbuf;
+ int inbuf_num;
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
{
}
EAPI void
-ecore_exe_tag_set(Ecore_Exe *exe, const char *tag)
+ecore_exe_tag_set(Ecore_Exe *exe,
+ const char *tag)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
{
}
IF_FREE(exe->tag);
if (tag)
- exe->tag = strdup(tag);
+ exe->tag = strdup(tag);
}
EAPI const char *
CloseHandle(exe->process_thread);
CloseHandle(exe->process);
exe->sig = ECORE_EXE_WIN32_SIGINT;
- while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)exe));
+ while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)exe)) ;
}
EAPI void
CloseHandle(exe->process_thread);
CloseHandle(exe->process);
exe->sig = ECORE_EXE_WIN32_SIGQUIT;
- while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)exe));
+ while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)exe)) ;
}
EAPI void
/* CloseHandle(exe->thread); */
CloseHandle(exe->process);
exe->sig = ECORE_EXE_WIN32_SIGTERM;
- while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)exe));
+ while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)exe)) ;
}
EAPI void
CloseHandle(exe->process_thread);
CloseHandle(exe->process);
exe->sig = ECORE_EXE_WIN32_SIGKILL;
- while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)exe));
+ while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)exe)) ;
}
EAPI void
-ecore_exe_signal(Ecore_Exe *exe, int num __UNUSED__)
+ecore_exe_signal(Ecore_Exe *exe,
+ int num __UNUSED__)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
{
/* FIXME: manage error mode */
static int
-_ecore_exe_win32_pipe_thread_generic_cb(void *data, Ecore_Exe_Flags flags)
+_ecore_exe_win32_pipe_thread_generic_cb(void *data,
+ Ecore_Exe_Flags flags)
{
#define BUFSIZE 2048
- char buf[BUFSIZE];
- Ecore_Exe *exe;
- char *current_buf = NULL;
- HANDLE child_pipe;
+ char buf[BUFSIZE];
+ Ecore_Exe *exe;
+ char *current_buf = NULL;
+ HANDLE child_pipe;
Ecore_Pipe *ecore_pipe;
Ecore_Exe_Event_Data *event;
- DWORD size;
- DWORD current_size = 0;
+ DWORD size;
+ DWORD current_size = 0;
BOOL res;
exe = (Ecore_Exe *)data;
while (1)
{
- if (!PeekNamedPipe(child_pipe, buf, sizeof(buf), &size, ¤t_size, NULL))
+ if (!PeekNamedPipe(child_pipe, buf, sizeof(buf), &size, ¤t_size, NULL))
continue;
if (size == 0)
continue;
static DWORD WINAPI
_ecore_exe_win32_pipe_thread_read_cb(void *data)
{
- return _ecore_exe_win32_pipe_thread_generic_cb(data, ECORE_EXE_PIPE_READ);
+ return _ecore_exe_win32_pipe_thread_generic_cb(data, ECORE_EXE_PIPE_READ);
}
static DWORD WINAPI
_ecore_exe_win32_pipe_thread_error_cb(void *data)
{
- return _ecore_exe_win32_pipe_thread_generic_cb(data, ECORE_EXE_PIPE_ERROR);
+ return _ecore_exe_win32_pipe_thread_generic_cb(data, ECORE_EXE_PIPE_ERROR);
}
static int
exe->pipe_error.child_pipe_x = child_pipe_x;
exe->pipe_error.p = ecore_pipe_add(_ecore_exe_pipe_error_cb, exe);
exe->pipe_error.thread = CreateThread(NULL, 0,
- _ecore_exe_win32_pipe_thread_error_cb,
- exe, 0, NULL);
+ _ecore_exe_win32_pipe_thread_error_cb,
+ exe, 0, NULL);
}
return 1;
- close_pipe:
+close_pipe:
CloseHandle(child_pipe);
CloseHandle(child_pipe_x);
{
if (exe->flags & ECORE_EXE_PIPE_READ)
{
- if (exe->pipe_read.child_pipe)
- {
- CloseHandle(exe->pipe_read.child_pipe);
- exe->pipe_read.child_pipe = NULL;
- }
- if (exe->pipe_read.child_pipe_x)
- {
- CloseHandle(exe->pipe_read.child_pipe_x);
- exe->pipe_read.child_pipe_x = NULL;
- }
+ if (exe->pipe_read.child_pipe)
+ {
+ CloseHandle(exe->pipe_read.child_pipe);
+ exe->pipe_read.child_pipe = NULL;
+ }
+ if (exe->pipe_read.child_pipe_x)
+ {
+ CloseHandle(exe->pipe_read.child_pipe_x);
+ exe->pipe_read.child_pipe_x = NULL;
+ }
}
if (exe->flags & ECORE_EXE_PIPE_WRITE)
{
- if (exe->pipe_write.child_pipe)
- {
- CloseHandle(exe->pipe_write.child_pipe);
- exe->pipe_write.child_pipe = NULL;
- }
- if (exe->pipe_write.child_pipe_x)
- {
- CloseHandle(exe->pipe_write.child_pipe_x);
- exe->pipe_write.child_pipe_x = NULL;
- }
+ if (exe->pipe_write.child_pipe)
+ {
+ CloseHandle(exe->pipe_write.child_pipe);
+ exe->pipe_write.child_pipe = NULL;
+ }
+ if (exe->pipe_write.child_pipe_x)
+ {
+ CloseHandle(exe->pipe_write.child_pipe_x);
+ exe->pipe_write.child_pipe_x = NULL;
+ }
}
if (exe->flags & ECORE_EXE_PIPE_ERROR)
{
- if (exe->pipe_error.child_pipe)
- {
- CloseHandle(exe->pipe_error.child_pipe);
- exe->pipe_error.child_pipe = NULL;
- }
- if (exe->pipe_error.child_pipe_x)
- {
- CloseHandle(exe->pipe_error.child_pipe_x);
- exe->pipe_error.child_pipe_x = NULL;
- }
+ if (exe->pipe_error.child_pipe)
+ {
+ CloseHandle(exe->pipe_error.child_pipe);
+ exe->pipe_error.child_pipe = NULL;
+ }
+ if (exe->pipe_error.child_pipe_x)
+ {
+ CloseHandle(exe->pipe_error.child_pipe_x);
+ exe->pipe_error.child_pipe_x = NULL;
+ }
}
}
}
static BOOL CALLBACK
-_ecore_exe_enum_windows_procedure(HWND window, LPARAM data)
+_ecore_exe_enum_windows_procedure(HWND window,
+ LPARAM data)
{
Ecore_Exe *exe;
- DWORD thread_id;
+ DWORD thread_id;
exe = (Ecore_Exe *)data;
thread_id = GetWindowThreadProcessId(window, NULL);
if (thread_id == exe->thread_id)
{
/* Ctrl-C or Ctrl-Break */
- if (CreateRemoteThread(exe->process, NULL, 0,
- (LPTHREAD_START_ROUTINE)_ecore_exe_thread_procedure, NULL,
- 0, NULL))
- {
- printf ("remote thread\n");
- return EINA_FALSE;
- }
-
- if ((exe->sig == ECORE_EXE_WIN32_SIGINT) ||
- (exe->sig == ECORE_EXE_WIN32_SIGQUIT))
- {
- printf ("int or quit\n");
- return EINA_FALSE;
- }
-
- /* WM_CLOSE message */
- PostMessage(window, WM_CLOSE, 0, 0);
- if (WaitForSingleObject(exe->process, ECORE_EXE_WIN32_TIMEOUT) == WAIT_OBJECT_0)
- {
- printf ("CLOSE\n");
- return EINA_FALSE;
- }
-
- /* WM_QUIT message */
- PostMessage(window, WM_QUIT, 0, 0);
- if (WaitForSingleObject(exe->process, ECORE_EXE_WIN32_TIMEOUT) == WAIT_OBJECT_0)
- {
- printf ("QUIT\n");
- return EINA_FALSE;
- }
-
- /* Exit process */
- if (CreateRemoteThread(exe->process, NULL, 0,
- (LPTHREAD_START_ROUTINE)ExitProcess, NULL,
- 0, NULL))
- {
- printf ("remote thread 2\n");
- return EINA_FALSE;
- }
-
- if (exe->sig == ECORE_EXE_WIN32_SIGTERM)
- {
- printf ("term\n");
- return EINA_FALSE;
- }
-
- TerminateProcess(exe->process, 0);
-
- return EINA_FALSE;
+ if (CreateRemoteThread(exe->process, NULL, 0,
+ (LPTHREAD_START_ROUTINE)_ecore_exe_thread_procedure, NULL,
+ 0, NULL))
+ {
+ printf ("remote thread\n");
+ return EINA_FALSE;
+ }
+
+ if ((exe->sig == ECORE_EXE_WIN32_SIGINT) ||
+ (exe->sig == ECORE_EXE_WIN32_SIGQUIT))
+ {
+ printf ("int or quit\n");
+ return EINA_FALSE;
+ }
+
+ /* WM_CLOSE message */
+ PostMessage(window, WM_CLOSE, 0, 0);
+ if (WaitForSingleObject(exe->process, ECORE_EXE_WIN32_TIMEOUT) == WAIT_OBJECT_0)
+ {
+ printf ("CLOSE\n");
+ return EINA_FALSE;
+ }
+
+ /* WM_QUIT message */
+ PostMessage(window, WM_QUIT, 0, 0);
+ if (WaitForSingleObject(exe->process, ECORE_EXE_WIN32_TIMEOUT) == WAIT_OBJECT_0)
+ {
+ printf ("QUIT\n");
+ return EINA_FALSE;
+ }
+
+ /* Exit process */
+ if (CreateRemoteThread(exe->process, NULL, 0,
+ (LPTHREAD_START_ROUTINE)ExitProcess, NULL,
+ 0, NULL))
+ {
+ printf ("remote thread 2\n");
+ return EINA_FALSE;
+ }
+
+ if (exe->sig == ECORE_EXE_WIN32_SIGTERM)
+ {
+ printf ("term\n");
+ return EINA_FALSE;
+ }
+
+ TerminateProcess(exe->process, 0);
+
+ return EINA_FALSE;
}
return EINA_TRUE;
}
static void
-_ecore_exe_event_add_free(void *data __UNUSED__, void *ev)
+_ecore_exe_event_add_free(void *data __UNUSED__,
+ void *ev)
{
Ecore_Exe_Event_Add *e;
}
static void
-_ecore_exe_event_del_free(void *data __UNUSED__, void *ev)
+_ecore_exe_event_del_free(void *data __UNUSED__,
+ void *ev)
{
Ecore_Exe_Event_Del *e;
}
static void
-_ecore_exe_event_exe_data_free(void *data __UNUSED__, void *ev)
+_ecore_exe_event_exe_data_free(void *data __UNUSED__,
+ void *ev)
{
Ecore_Exe_Event_Data *e;
}
static Eina_Bool
-_ecore_exe_close_cb(void *data, Ecore_Win32_Handler *wh __UNUSED__)
+_ecore_exe_close_cb(void *data,
+ Ecore_Win32_Handler *wh __UNUSED__)
{
Ecore_Exe_Event_Del *e;
- Ecore_Exe *exe;
- DWORD exit_code = 0;
+ Ecore_Exe *exe;
+ DWORD exit_code = 0;
e = calloc(1, sizeof(Ecore_Exe_Event_Del));
if (!e) return 0;
printf("%s\n", msg);
free(msg);
}
- e->pid = exe->process_id;
- e->exe = exe;
+ e->pid = exe->process_id;
+ e->exe = exe;
- ecore_event_add(ECORE_EXE_EVENT_DEL, e,
- _ecore_exe_event_del_free, NULL);
+ ecore_event_add(ECORE_EXE_EVENT_DEL, e,
+ _ecore_exe_event_del_free, NULL);
return 0;
}
static void
-_ecore_exe_pipe_read_cb(void *data, void *buf, unsigned int size)
+_ecore_exe_pipe_read_cb(void *data,
+ void *buf,
+ unsigned int size)
{
Ecore_Exe_Event_Data *e;
}
static int
-_ecore_exe_pipe_write_cb(void *data, Ecore_Win32_Handler *wh __UNUSED__)
+_ecore_exe_pipe_write_cb(void *data,
+ Ecore_Win32_Handler *wh __UNUSED__)
{
- char buf[READBUFSIZ];
+ char buf[READBUFSIZ];
Ecore_Exe *exe;
- DWORD num_exe;
- BOOL res;
+ DWORD num_exe;
+ BOOL res;
exe = (Ecore_Exe *)data;
res = WriteFile(exe->pipe_write.child_pipe_x, buf, READBUFSIZ, &num_exe, NULL);
if (!res || num_exe == 0)
{
- /* FIXME: what to do here ?? */
+ /* FIXME: what to do here ?? */
}
if (exe->close_stdin == 1)
}
static void
-_ecore_exe_pipe_error_cb(void *data, void *buf, unsigned int size)
+_ecore_exe_pipe_error_cb(void *data,
+ void *buf,
+ unsigned int size)
{
Ecore_Exe_Event_Data *e;
_ecore_exe_event_exe_data_free,
NULL);
}
+
_ecore_exe_shutdown(void)
{
}
+
# ifdef __cplusplus
extern "C"
# endif
-void *alloca (size_t);
+void *alloca(size_t);
#endif
#include <stdio.h>
#ifdef ENABLE_NLS
# include <libintl.h>
#else
-# define gettext(x) (x)
+# define gettext(x) (x)
# define dgettext(domain, x) (x)
#endif
-#define _(x) dgettext("ecore", x)
+#define _(x) dgettext("ecore", x)
#ifdef _WIN32_WCE
# include <Evil.h>
static int helpcol = 80 / 3;
static void
-_ecore_getopt_help_print_replace_program(FILE *fp, const Ecore_Getopt *parser __UNUSED__, const char *text)
+_ecore_getopt_help_print_replace_program(FILE *fp,
+ const Ecore_Getopt *parser __UNUSED__,
+ const char *text)
{
do
{
}
static void
-_ecore_getopt_version(FILE *fp, const Ecore_Getopt *parser)
+_ecore_getopt_version(FILE *fp,
+ const Ecore_Getopt *parser)
{
fputs(_("Version:"), fp);
fputc(' ', fp);
}
static void
-_ecore_getopt_help_usage(FILE *fp, const Ecore_Getopt *parser)
+_ecore_getopt_help_usage(FILE *fp,
+ const Ecore_Getopt *parser)
{
fputs(_("Usage:"), fp);
fputc(' ', fp);
}
static int
-_ecore_getopt_help_line(FILE *fp, const int base, const int total, int used, const char *text, int len)
+_ecore_getopt_help_line(FILE *fp,
+ const int base,
+ const int total,
+ int used,
+ const char *text,
+ int len)
{
int linebreak = 0;
do
{
/* process line considering spaces (new line and tabs are spaces!) */
- while ((used < total) && (len > 0))
- {
- const char *space = NULL;
- int i, todo;
-
- todo = total - used;
- if (todo > len)
- todo = len;
-
- for (i = 0; i < todo; i++)
- if (isspace(text[i]))
- {
- space = text + i;
- break;
- }
-
- if (space)
- {
- i = fwrite(text, 1, i, fp);
- i++;
- text += i;
- len -= i;
- used += i;
-
- if (linebreak)
- {
- linebreak = 0;
- continue;
- }
-
- if (space[0] == '\n')
- break;
- else if (space[0] == '\t')
- {
- int c;
-
- used--;
- c = ((used / 8) + 1) * 8;
- if (c < total)
- {
- for (; used < c; used++)
- fputc(' ', fp);
- }
- else
- {
- text--;
- len++;
- break;
- }
- }
- else if (used < total)
- fputc(space[0], fp);
- }
- else
- {
- i = fwrite(text, 1, i, fp);
- text += i;
- len -= i;
- used += i;
- }
- linebreak = 0;
- }
- if (len <= 0)
- break;
- linebreak = 1;
- fputc('\n', fp);
- for (used = 0; used < base; used++)
- fputc(' ', fp);
+ while ((used < total) && (len > 0))
+ {
+ const char *space = NULL;
+ int i, todo;
+
+ todo = total - used;
+ if (todo > len)
+ todo = len;
+
+ for (i = 0; i < todo; i++)
+ if (isspace(text[i]))
+ {
+ space = text + i;
+ break;
+ }
+
+ if (space)
+ {
+ i = fwrite(text, 1, i, fp);
+ i++;
+ text += i;
+ len -= i;
+ used += i;
+
+ if (linebreak)
+ {
+ linebreak = 0;
+ continue;
+ }
+
+ if (space[0] == '\n')
+ break;
+ else if (space[0] == '\t')
+ {
+ int c;
+
+ used--;
+ c = ((used / 8) + 1) * 8;
+ if (c < total)
+ {
+ for (; used < c; used++)
+ fputc(' ', fp);
+ }
+ else
+ {
+ text--;
+ len++;
+ break;
+ }
+ }
+ else if (used < total)
+ fputc(space[0], fp);
+ }
+ else
+ {
+ i = fwrite(text, 1, i, fp);
+ text += i;
+ len -= i;
+ used += i;
+ }
+ linebreak = 0;
+ }
+ if (len <= 0)
+ break;
+ linebreak = 1;
+ fputc('\n', fp);
+ for (used = 0; used < base; used++)
+ fputc(' ', fp);
}
while (1);
}
static void
-_ecore_getopt_help_description(FILE *fp, const Ecore_Getopt *parser)
+_ecore_getopt_help_description(FILE *fp,
+ const Ecore_Getopt *parser)
{
const char *p, *prg, *ver;
int used, prglen, verlen;
}
static void
-_ecore_getopt_copyright(FILE *fp, const Ecore_Getopt *parser)
+_ecore_getopt_copyright(FILE *fp,
+ const Ecore_Getopt *parser)
{
const char *txt = gettext(parser->copyright);
fputs(_("Copyright:"), fp);
}
static void
-_ecore_getopt_license(FILE *fp, const Ecore_Getopt *parser)
+_ecore_getopt_license(FILE *fp,
+ const Ecore_Getopt *parser)
{
const char *txt = gettext(parser->license);
fputs(_("License:"), fp);
switch (desc->action)
{
case ECORE_GETOPT_ACTION_STORE:
- return desc->action_param.store.arg_req;
+ return desc->action_param.store.arg_req;
+
case ECORE_GETOPT_ACTION_STORE_CONST:
- return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
+ return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
+
case ECORE_GETOPT_ACTION_STORE_TRUE:
- return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
+ return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
+
case ECORE_GETOPT_ACTION_STORE_FALSE:
- return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
+ return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
+
case ECORE_GETOPT_ACTION_CHOICE:
- return ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES;
+ return ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES;
+
case ECORE_GETOPT_ACTION_APPEND:
- return ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES;
+ return ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES;
+
case ECORE_GETOPT_ACTION_COUNT:
- return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
+ return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
+
case ECORE_GETOPT_ACTION_CALLBACK:
- return desc->action_param.callback.arg_req;
+ return desc->action_param.callback.arg_req;
+
case ECORE_GETOPT_ACTION_HELP:
- return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
+ return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
+
case ECORE_GETOPT_ACTION_VERSION:
- return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
+ return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
+
default:
- return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
+ return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
}
}
static void
-_ecore_getopt_help_desc_setup_metavar(const Ecore_Getopt_Desc *desc, char *metavar, int *metavarlen, int maxsize)
+_ecore_getopt_help_desc_setup_metavar(const Ecore_Getopt_Desc *desc,
+ char *metavar,
+ int *metavarlen,
+ int maxsize)
{
if (desc->metavar)
{
}
static int
-_ecore_getopt_help_desc_show_arg(FILE *fp, Ecore_Getopt_Desc_Arg_Requirement requirement, const char *metavar, int metavarlen)
+_ecore_getopt_help_desc_show_arg(FILE *fp,
+ Ecore_Getopt_Desc_Arg_Requirement requirement,
+ const char *metavar,
+ int metavarlen)
{
int used;
}
static int
-_ecore_getopt_help_desc_store(FILE *fp, const int base, const int total, int used, const Ecore_Getopt_Desc *desc)
+_ecore_getopt_help_desc_store(FILE *fp,
+ const int base,
+ const int total,
+ int used,
+ const Ecore_Getopt_Desc *desc)
{
const Ecore_Getopt_Desc_Store *store = &desc->action_param.store;
char buf[64];
switch (store->type)
{
case ECORE_GETOPT_TYPE_STR:
- str = "STR";
- len = sizeof("STR") - 1;
- break;
+ str = "STR";
+ len = sizeof("STR") - 1;
+ break;
+
case ECORE_GETOPT_TYPE_BOOL:
- str = "BOOL";
- len = sizeof("BOOL") - 1;
- break;
+ str = "BOOL";
+ len = sizeof("BOOL") - 1;
+ break;
+
case ECORE_GETOPT_TYPE_SHORT:
- str = "SHORT";
- len = sizeof("SHORT") - 1;
- break;
+ str = "SHORT";
+ len = sizeof("SHORT") - 1;
+ break;
+
case ECORE_GETOPT_TYPE_INT:
- str = "INT";
- len = sizeof("INT") - 1;
- break;
+ str = "INT";
+ len = sizeof("INT") - 1;
+ break;
+
case ECORE_GETOPT_TYPE_LONG:
- str = "LONG";
- len = sizeof("LONG") - 1;
- break;
+ str = "LONG";
+ len = sizeof("LONG") - 1;
+ break;
+
case ECORE_GETOPT_TYPE_USHORT:
- str = "USHORT";
- len = sizeof("USHORT") - 1;
- break;
+ str = "USHORT";
+ len = sizeof("USHORT") - 1;
+ break;
+
case ECORE_GETOPT_TYPE_UINT:
- str = "UINT";
- len = sizeof("UINT") - 1;
- break;
+ str = "UINT";
+ len = sizeof("UINT") - 1;
+ break;
+
case ECORE_GETOPT_TYPE_ULONG:
- str = "ULONG";
- len = sizeof("ULONG") - 1;
- break;
+ str = "ULONG";
+ len = sizeof("ULONG") - 1;
+ break;
+
case ECORE_GETOPT_TYPE_DOUBLE:
- str = "DOUBLE";
- len = sizeof("DOUBLE") - 1;
- break;
+ str = "DOUBLE";
+ len = sizeof("DOUBLE") - 1;
+ break;
+
default:
- str = "???";
- len = sizeof("???") - 1;
+ str = "???";
+ len = sizeof("???") - 1;
}
used = _ecore_getopt_help_line
- (fp, base, total, used, _("Type: "), strlen(_("Type: ")));
+ (fp, base, total, used, _("Type: "), strlen(_("Type: ")));
used = _ecore_getopt_help_line(fp, base, total, used, str, len);
if (store->arg_req == ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES)
goto end;
used = _ecore_getopt_help_line
- (fp, base, total, used, ". ", sizeof(". ") - 1);
+ (fp, base, total, used, ". ", sizeof(". ") - 1);
switch (store->type)
{
case ECORE_GETOPT_TYPE_STR:
- str = store->def.strv;
- len = str ? strlen(str) : 0;
- break;
+ str = store->def.strv;
+ len = str ? strlen(str) : 0;
+ break;
+
case ECORE_GETOPT_TYPE_BOOL:
- str = store->def.boolv ? "true" : "false";
- len = strlen(str);
- break;
+ str = store->def.boolv ? "true" : "false";
+ len = strlen(str);
+ break;
+
case ECORE_GETOPT_TYPE_SHORT:
- str = buf;
- len = snprintf(buf, sizeof(buf), "%hd", store->def.shortv);
- if (len > sizeof(buf) - 1)
- len = sizeof(buf) - 1;
- break;
+ str = buf;
+ len = snprintf(buf, sizeof(buf), "%hd", store->def.shortv);
+ if (len > sizeof(buf) - 1)
+ len = sizeof(buf) - 1;
+ break;
+
case ECORE_GETOPT_TYPE_INT:
- str = buf;
- len = snprintf(buf, sizeof(buf), "%d", store->def.intv);
- if (len > sizeof(buf) - 1)
- len = sizeof(buf) - 1;
- break;
+ str = buf;
+ len = snprintf(buf, sizeof(buf), "%d", store->def.intv);
+ if (len > sizeof(buf) - 1)
+ len = sizeof(buf) - 1;
+ break;
+
case ECORE_GETOPT_TYPE_LONG:
- str = buf;
- len = snprintf(buf, sizeof(buf), "%ld", store->def.longv);
- if (len > sizeof(buf) - 1)
- len = sizeof(buf) - 1;
- break;
+ str = buf;
+ len = snprintf(buf, sizeof(buf), "%ld", store->def.longv);
+ if (len > sizeof(buf) - 1)
+ len = sizeof(buf) - 1;
+ break;
+
case ECORE_GETOPT_TYPE_USHORT:
- str = buf;
- len = snprintf(buf, sizeof(buf), "%hu", store->def.ushortv);
- if (len > sizeof(buf) - 1)
- len = sizeof(buf) - 1;
- break;
+ str = buf;
+ len = snprintf(buf, sizeof(buf), "%hu", store->def.ushortv);
+ if (len > sizeof(buf) - 1)
+ len = sizeof(buf) - 1;
+ break;
+
case ECORE_GETOPT_TYPE_UINT:
- str = buf;
- len = snprintf(buf, sizeof(buf), "%u", store->def.uintv);
- if (len > sizeof(buf) - 1)
- len = sizeof(buf) - 1;
- break;
+ str = buf;
+ len = snprintf(buf, sizeof(buf), "%u", store->def.uintv);
+ if (len > sizeof(buf) - 1)
+ len = sizeof(buf) - 1;
+ break;
+
case ECORE_GETOPT_TYPE_ULONG:
- str = buf;
- len = snprintf(buf, sizeof(buf), "%lu", store->def.ulongv);
- if (len > sizeof(buf) - 1)
- len = sizeof(buf) - 1;
- break;
+ str = buf;
+ len = snprintf(buf, sizeof(buf), "%lu", store->def.ulongv);
+ if (len > sizeof(buf) - 1)
+ len = sizeof(buf) - 1;
+ break;
+
case ECORE_GETOPT_TYPE_DOUBLE:
- str = buf;
- len = snprintf(buf, sizeof(buf), "%f", store->def.doublev);
- if (len > sizeof(buf) - 1)
- len = sizeof(buf) - 1;
- break;
+ str = buf;
+ len = snprintf(buf, sizeof(buf), "%f", store->def.doublev);
+ if (len > sizeof(buf) - 1)
+ len = sizeof(buf) - 1;
+ break;
+
default:
- str = "???";
- len = sizeof("???") - 1;
+ str = "???";
+ len = sizeof("???") - 1;
}
used = _ecore_getopt_help_line
- (fp, base, total, used, _("Default: "), strlen(_("Default: ")));
+ (fp, base, total, used, _("Default: "), strlen(_("Default: ")));
used = _ecore_getopt_help_line(fp, base, total, used, str, len);
- end:
+end:
return _ecore_getopt_help_line(fp, base, total, used, ".", 1);
}
static int
-_ecore_getopt_help_desc_choices(FILE *fp, const int base, const int total, int used, const Ecore_Getopt_Desc *desc)
+_ecore_getopt_help_desc_choices(FILE *fp,
+ const int base,
+ const int total,
+ int used,
+ const Ecore_Getopt_Desc *desc)
{
const char *const *itr;
const char sep[] = ", ";
fputc(' ', fp);
used = _ecore_getopt_help_line
- (fp, base, total, used, _("Choices: "), strlen(_("Choices: ")));
+ (fp, base, total, used, _("Choices: "), strlen(_("Choices: ")));
for (itr = desc->action_param.choices; *itr; itr++)
{
used = _ecore_getopt_help_line
- (fp, base, total, used, *itr, strlen(*itr));
+ (fp, base, total, used, *itr, strlen(*itr));
if (itr[1])
used = _ecore_getopt_help_line(fp, base, total, used, sep, seplen);
}
}
static void
-_ecore_getopt_help_desc(FILE *fp, const Ecore_Getopt_Desc *desc)
+_ecore_getopt_help_desc(FILE *fp,
+ const Ecore_Getopt_Desc *desc)
{
Ecore_Getopt_Desc_Arg_Requirement arg_req;
char metavar[32] = "ARG";
fputc(desc->shortname, fp);
used += 2;
used += _ecore_getopt_help_desc_show_arg
- (fp, arg_req, metavar, metavarlen);
+ (fp, arg_req, metavar, metavarlen);
}
if (desc->shortname && desc->longname)
fputs(desc->longname, fp);
used += 2 + namelen;
used += _ecore_getopt_help_desc_show_arg
- (fp, arg_req, metavar, metavarlen);
+ (fp, arg_req, metavar, metavarlen);
}
if (!desc->help)
fputc(' ', fp);
used = _ecore_getopt_help_line
- (fp, helpcol, cols, used, desc->help, strlen(desc->help));
+ (fp, helpcol, cols, used, desc->help, strlen(desc->help));
switch (desc->action)
{
case ECORE_GETOPT_ACTION_STORE:
- _ecore_getopt_help_desc_store(fp, helpcol, cols, used, desc);
- break;
+ _ecore_getopt_help_desc_store(fp, helpcol, cols, used, desc);
+ break;
+
case ECORE_GETOPT_ACTION_CHOICE:
- _ecore_getopt_help_desc_choices(fp, helpcol, cols, used, desc);
- break;
+ _ecore_getopt_help_desc_choices(fp, helpcol, cols, used, desc);
+ break;
+
default:
- break;
+ break;
}
- end:
+end:
fputc('\n', fp);
}
}
static void
-_ecore_getopt_help_options(FILE *fp, const Ecore_Getopt *parser)
+_ecore_getopt_help_options(FILE *fp,
+ const Ecore_Getopt *parser)
{
const Ecore_Getopt_Desc *desc;
* Message will be print to stderr.
*/
void
-ecore_getopt_help(FILE *fp, const Ecore_Getopt *parser)
+ecore_getopt_help(FILE *fp,
+ const Ecore_Getopt *parser)
{
const char *var;
}
static const Ecore_Getopt_Desc *
-_ecore_getopt_parse_find_long(const Ecore_Getopt *parser, const char *name)
+_ecore_getopt_parse_find_long(const Ecore_Getopt *parser,
+ const char *name)
{
const Ecore_Getopt_Desc *desc = parser->descs;
const char *p = strchr(name, '=');
}
static const Ecore_Getopt_Desc *
-_ecore_getopt_parse_find_short(const Ecore_Getopt *parser, char name)
+_ecore_getopt_parse_find_short(const Ecore_Getopt *parser,
+ char name)
{
const Ecore_Getopt_Desc *desc = parser->descs;
for (; !_ecore_getopt_desc_is_sentinel(desc); desc++)
}
static int
-_ecore_getopt_parse_find_nonargs_base(const Ecore_Getopt *parser, int argc, char **argv)
+_ecore_getopt_parse_find_nonargs_base(const Ecore_Getopt *parser,
+ int argc,
+ char **argv)
{
char **nonargs;
int src, dst, used, base;
- nonargs = alloca(sizeof(char*) * argc);
+ nonargs = alloca(sizeof(char *) * argc);
src = 1;
dst = 1;
used = 0;
dst++;
continue;
- found_nonarg:
+found_nonarg:
nonargs[used] = arg;
used++;
src++;
}
static void
-_ecore_getopt_desc_print_error(const Ecore_Getopt_Desc *desc, const char *fmt, ...)
+_ecore_getopt_desc_print_error(const Ecore_Getopt_Desc *desc,
+ const char *fmt,
+ ...)
{
va_list ap;
}
static Eina_Bool
-_ecore_getopt_parse_bool(const char *str, Eina_Bool *v)
+_ecore_getopt_parse_bool(const char *str,
+ Eina_Bool *v)
{
if ((strcmp(str, "0") == 0) ||
(strcasecmp(str, "f") == 0) ||
}
static Eina_Bool
-_ecore_getopt_parse_long(const char *str, long int *v)
+_ecore_getopt_parse_long(const char *str,
+ long int *v)
{
char *endptr = NULL;
*v = strtol(str, &endptr, 0);
}
static Eina_Bool
-_ecore_getopt_parse_double(const char *str, double *v)
+_ecore_getopt_parse_double(const char *str,
+ double *v)
{
char *endptr = NULL;
*v = strtod(str, &endptr);
}
static Eina_Bool
-_ecore_getopt_parse_store(const Ecore_Getopt *parser __UNUSED__, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *value, const char *arg_val)
+_ecore_getopt_parse_store(const Ecore_Getopt *parser __UNUSED__,
+ const Ecore_Getopt_Desc *desc,
+ Ecore_Getopt_Value *value,
+ const char *arg_val)
{
const Ecore_Getopt_Desc_Store *store = &desc->action_param.store;
long int v;
switch (store->arg_req)
{
case ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO:
- goto use_optional;
+ goto use_optional;
+
case ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL:
- if (!arg_val)
- goto use_optional;
+ if (!arg_val)
+ goto use_optional;
+
case ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES:
- break;
+ break;
}
switch (store->type)
{
case ECORE_GETOPT_TYPE_STR:
- *value->strp = (char *)arg_val;
- return EINA_TRUE;
+ *value->strp = (char *)arg_val;
+ return EINA_TRUE;
+
case ECORE_GETOPT_TYPE_BOOL:
- if (_ecore_getopt_parse_bool(arg_val, &b))
- {
- *value->boolp = b;
- return EINA_TRUE;
- }
- else
- {
- _ecore_getopt_desc_print_error
- (desc, _("unknown boolean value %s.\n"), arg_val);
- return EINA_FALSE;
- }
+ if (_ecore_getopt_parse_bool(arg_val, &b))
+ {
+ *value->boolp = b;
+ return EINA_TRUE;
+ }
+ else
+ {
+ _ecore_getopt_desc_print_error
+ (desc, _("unknown boolean value %s.\n"), arg_val);
+ return EINA_FALSE;
+ }
+
case ECORE_GETOPT_TYPE_SHORT:
- if (!_ecore_getopt_parse_long(arg_val, &v))
- goto error;
- *value->shortp = v;
- return EINA_TRUE;
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ *value->shortp = v;
+ return EINA_TRUE;
+
case ECORE_GETOPT_TYPE_INT:
- if (!_ecore_getopt_parse_long(arg_val, &v))
- goto error;
- *value->intp = v;
- return EINA_TRUE;
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ *value->intp = v;
+ return EINA_TRUE;
+
case ECORE_GETOPT_TYPE_LONG:
- if (!_ecore_getopt_parse_long(arg_val, &v))
- goto error;
- *value->longp = v;
- return EINA_TRUE;
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ *value->longp = v;
+ return EINA_TRUE;
+
case ECORE_GETOPT_TYPE_USHORT:
- if (!_ecore_getopt_parse_long(arg_val, &v))
- goto error;
- *value->ushortp = v;
- return EINA_TRUE;
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ *value->ushortp = v;
+ return EINA_TRUE;
+
case ECORE_GETOPT_TYPE_UINT:
- if (!_ecore_getopt_parse_long(arg_val, &v))
- goto error;
- *value->uintp = v;
- return EINA_TRUE;
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ *value->uintp = v;
+ return EINA_TRUE;
+
case ECORE_GETOPT_TYPE_ULONG:
- if (!_ecore_getopt_parse_long(arg_val, &v))
- goto error;
- *value->ulongp = v;
- return EINA_TRUE;
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ *value->ulongp = v;
+ return EINA_TRUE;
+
case ECORE_GETOPT_TYPE_DOUBLE:
- if (!_ecore_getopt_parse_double(arg_val, &d))
- goto error;
- *value->doublep = d;
- break;
+ if (!_ecore_getopt_parse_double(arg_val, &d))
+ goto error;
+ *value->doublep = d;
+ break;
}
return EINA_TRUE;
- error:
+error:
_ecore_getopt_desc_print_error
(desc, _("invalid number format %s\n"), arg_val);
return EINA_FALSE;
- use_optional:
+use_optional:
switch (store->type)
{
case ECORE_GETOPT_TYPE_STR:
- *value->strp = (char *)store->def.strv;
- break;
+ *value->strp = (char *)store->def.strv;
+ break;
+
case ECORE_GETOPT_TYPE_BOOL:
- *value->boolp = store->def.boolv;
- break;
+ *value->boolp = store->def.boolv;
+ break;
+
case ECORE_GETOPT_TYPE_SHORT:
- *value->shortp = store->def.shortv;
- break;
+ *value->shortp = store->def.shortv;
+ break;
+
case ECORE_GETOPT_TYPE_INT:
- *value->intp = store->def.intv;
- break;
+ *value->intp = store->def.intv;
+ break;
+
case ECORE_GETOPT_TYPE_LONG:
- *value->longp = store->def.longv;
- break;
+ *value->longp = store->def.longv;
+ break;
+
case ECORE_GETOPT_TYPE_USHORT:
- *value->ushortp = store->def.ushortv;
- break;
+ *value->ushortp = store->def.ushortv;
+ break;
+
case ECORE_GETOPT_TYPE_UINT:
- *value->uintp = store->def.uintv;
- break;
+ *value->uintp = store->def.uintv;
+ break;
+
case ECORE_GETOPT_TYPE_ULONG:
- *value->ulongp = store->def.ulongv;
- break;
+ *value->ulongp = store->def.ulongv;
+ break;
+
case ECORE_GETOPT_TYPE_DOUBLE:
- *value->doublep = store->def.doublev;
- break;
+ *value->doublep = store->def.doublev;
+ break;
}
return EINA_TRUE;
}
static Eina_Bool
-_ecore_getopt_parse_store_const(const Ecore_Getopt *parser __UNUSED__, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *val, const char *arg_val __UNUSED__)
+_ecore_getopt_parse_store_const(const Ecore_Getopt *parser __UNUSED__,
+ const Ecore_Getopt_Desc *desc,
+ Ecore_Getopt_Value *val,
+ const char *arg_val __UNUSED__)
{
if (!val->ptrp)
{
}
static Eina_Bool
-_ecore_getopt_parse_store_true(const Ecore_Getopt *parser __UNUSED__, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *val, const char *arg_val __UNUSED__)
+_ecore_getopt_parse_store_true(const Ecore_Getopt *parser __UNUSED__,
+ const Ecore_Getopt_Desc *desc,
+ Ecore_Getopt_Value *val,
+ const char *arg_val __UNUSED__)
{
if (!val->boolp)
{
}
static Eina_Bool
-_ecore_getopt_parse_store_false(const Ecore_Getopt *parser __UNUSED__, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *val, const char *arg_val __UNUSED__)
+_ecore_getopt_parse_store_false(const Ecore_Getopt *parser __UNUSED__,
+ const Ecore_Getopt_Desc *desc,
+ Ecore_Getopt_Value *val,
+ const char *arg_val __UNUSED__)
{
if (!val->boolp)
{
}
static Eina_Bool
-_ecore_getopt_parse_choice(const Ecore_Getopt *parser __UNUSED__, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *val, const char *arg_val)
+_ecore_getopt_parse_choice(const Ecore_Getopt *parser __UNUSED__,
+ const Ecore_Getopt_Desc *desc,
+ Ecore_Getopt_Value *val,
+ const char *arg_val)
{
- const char * const *pchoice;
+ const char *const *pchoice;
if (!val->strp)
{
}
static Eina_Bool
-_ecore_getopt_parse_append(const Ecore_Getopt *parser __UNUSED__, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *val, const char *arg_val)
+_ecore_getopt_parse_append(const Ecore_Getopt *parser __UNUSED__,
+ const Ecore_Getopt_Desc *desc,
+ Ecore_Getopt_Value *val,
+ const char *arg_val)
{
void *data;
long int v;
switch (desc->action_param.append_type)
{
case ECORE_GETOPT_TYPE_STR:
- data = strdup(arg_val);
- break;
- case ECORE_GETOPT_TYPE_BOOL:
- {
- if (_ecore_getopt_parse_bool(arg_val, &b))
- {
- data = malloc(sizeof(Eina_Bool));
- if (data)
- *(Eina_Bool *)data = b;
- }
- else
- {
- _ecore_getopt_desc_print_error(desc, _("unknown boolean value %s.\n"), arg_val);
- return EINA_FALSE;
- }
- }
+ data = strdup(arg_val);
break;
+
+ case ECORE_GETOPT_TYPE_BOOL:
+ {
+ if (_ecore_getopt_parse_bool(arg_val, &b))
+ {
+ data = malloc(sizeof(Eina_Bool));
+ if (data)
+ *(Eina_Bool *)data = b;
+ }
+ else
+ {
+ _ecore_getopt_desc_print_error(desc, _("unknown boolean value %s.\n"), arg_val);
+ return EINA_FALSE;
+ }
+ }
+ break;
+
case ECORE_GETOPT_TYPE_SHORT:
- {
- if (!_ecore_getopt_parse_long(arg_val, &v))
- goto error;
- data = malloc(sizeof(short));
- if (data)
- *(short *)data = (short)v;
- }
- break;
+ {
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ data = malloc(sizeof(short));
+ if (data)
+ *(short *)data = (short)v;
+ }
+ break;
+
case ECORE_GETOPT_TYPE_INT:
- {
- if (!_ecore_getopt_parse_long(arg_val, &v))
- goto error;
- data = malloc(sizeof(int));
- if (data)
- *(int *)data = (int)v;
- }
- break;
+ {
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ data = malloc(sizeof(int));
+ if (data)
+ *(int *)data = (int)v;
+ }
+ break;
+
case ECORE_GETOPT_TYPE_LONG:
- {
- if (!_ecore_getopt_parse_long(arg_val, &v))
- goto error;
- data = malloc(sizeof(long));
- if (data)
- *(long *)data = v;
- }
- break;
+ {
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ data = malloc(sizeof(long));
+ if (data)
+ *(long *)data = v;
+ }
+ break;
+
case ECORE_GETOPT_TYPE_USHORT:
- {
- if (!_ecore_getopt_parse_long(arg_val, &v))
- goto error;
- data = malloc(sizeof(unsigned short));
- if (data)
- *(unsigned short *)data = (unsigned short)v;
- }
- break;
+ {
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ data = malloc(sizeof(unsigned short));
+ if (data)
+ *(unsigned short *)data = (unsigned short)v;
+ }
+ break;
+
case ECORE_GETOPT_TYPE_UINT:
- {
- if (!_ecore_getopt_parse_long(arg_val, &v))
- goto error;
- data = malloc(sizeof(unsigned int));
- if (data)
- *(unsigned int *)data = (unsigned int)v;
- }
- break;
+ {
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ data = malloc(sizeof(unsigned int));
+ if (data)
+ *(unsigned int *)data = (unsigned int)v;
+ }
+ break;
+
case ECORE_GETOPT_TYPE_ULONG:
- {
- if (!_ecore_getopt_parse_long(arg_val, &v))
- goto error;
- data = malloc(sizeof(unsigned long));
- if (data)
- *(unsigned long *)data = v;
- }
- break;
+ {
+ if (!_ecore_getopt_parse_long(arg_val, &v))
+ goto error;
+ data = malloc(sizeof(unsigned long));
+ if (data)
+ *(unsigned long *)data = v;
+ }
+ break;
+
case ECORE_GETOPT_TYPE_DOUBLE:
- {
- if (!_ecore_getopt_parse_double(arg_val, &d))
- goto error;
- data = malloc(sizeof(double));
- if (data)
- *(double *)data = d;
- }
- break;
+ {
+ if (!_ecore_getopt_parse_double(arg_val, &d))
+ goto error;
+ data = malloc(sizeof(double));
+ if (data)
+ *(double *)data = d;
+ }
+ break;
+
default:
- {
- _ecore_getopt_desc_print_error(desc, _("could not parse value.\n"));
- return EINA_FALSE;
- }
+ {
+ _ecore_getopt_desc_print_error(desc, _("could not parse value.\n"));
+ return EINA_FALSE;
+ }
}
*val->listp = eina_list_append(*val->listp, data);
return EINA_TRUE;
- error:
+error:
_ecore_getopt_desc_print_error
(desc, _("invalid number format %s\n"), arg_val);
return EINA_FALSE;
}
static Eina_Bool
-_ecore_getopt_parse_count(const Ecore_Getopt *parser __UNUSED__, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *val, const char *arg_val __UNUSED__)
+_ecore_getopt_parse_count(const Ecore_Getopt *parser __UNUSED__,
+ const Ecore_Getopt_Desc *desc,
+ Ecore_Getopt_Value *val,
+ const char *arg_val __UNUSED__)
{
if (!val->intp)
{
}
static Eina_Bool
-_ecore_getopt_parse_callback(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *val, const char *arg_val)
+_ecore_getopt_parse_callback(const Ecore_Getopt *parser,
+ const Ecore_Getopt_Desc *desc,
+ Ecore_Getopt_Value *val,
+ const char *arg_val)
{
const Ecore_Getopt_Desc_Callback *cb = &desc->action_param.callback;
switch (cb->arg_req)
{
case ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO:
- arg_val = cb->def;
- break;
+ arg_val = cb->def;
+ break;
+
case ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL:
- if (!arg_val)
- arg_val = cb->def;
- break;
+ if (!arg_val)
+ arg_val = cb->def;
+ break;
+
case ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES:
- break;
+ break;
}
if (cb->arg_req != ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO)
}
static Eina_Bool
-_ecore_getopt_parse_help(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc __UNUSED__, Ecore_Getopt_Value *val, const char *arg_val __UNUSED__)
+_ecore_getopt_parse_help(const Ecore_Getopt *parser,
+ const Ecore_Getopt_Desc *desc __UNUSED__,
+ Ecore_Getopt_Value *val,
+ const char *arg_val __UNUSED__)
{
if (val->boolp)
(*val->boolp) = EINA_TRUE;
}
static Eina_Bool
-_ecore_getopt_parse_version(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *val, const char *arg_val __UNUSED__)
+_ecore_getopt_parse_version(const Ecore_Getopt *parser,
+ const Ecore_Getopt_Desc *desc,
+ Ecore_Getopt_Value *val,
+ const char *arg_val __UNUSED__)
{
if (val->boolp)
(*val->boolp) = EINA_TRUE;
}
static Eina_Bool
-_ecore_getopt_parse_copyright(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *val, const char *arg_val __UNUSED__)
+_ecore_getopt_parse_copyright(const Ecore_Getopt *parser,
+ const Ecore_Getopt_Desc *desc,
+ Ecore_Getopt_Value *val,
+ const char *arg_val __UNUSED__)
{
if (val->boolp)
(*val->boolp) = EINA_TRUE;
}
static Eina_Bool
-_ecore_getopt_parse_license(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *val, const char *arg_val __UNUSED__)
+_ecore_getopt_parse_license(const Ecore_Getopt *parser,
+ const Ecore_Getopt_Desc *desc,
+ Ecore_Getopt_Value *val,
+ const char *arg_val __UNUSED__)
{
if (val->boolp)
(*val->boolp) = EINA_TRUE;
}
static Eina_Bool
-_ecore_getopt_desc_handle(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc, Ecore_Getopt_Value *value, const char *arg_val)
+_ecore_getopt_desc_handle(const Ecore_Getopt *parser,
+ const Ecore_Getopt_Desc *desc,
+ Ecore_Getopt_Value *value,
+ const char *arg_val)
{
switch (desc->action)
{
case ECORE_GETOPT_ACTION_STORE:
- return _ecore_getopt_parse_store(parser, desc, value, arg_val);
+ return _ecore_getopt_parse_store(parser, desc, value, arg_val);
+
case ECORE_GETOPT_ACTION_STORE_CONST:
- return _ecore_getopt_parse_store_const(parser, desc, value, arg_val);
+ return _ecore_getopt_parse_store_const(parser, desc, value, arg_val);
+
case ECORE_GETOPT_ACTION_STORE_TRUE:
- return _ecore_getopt_parse_store_true(parser, desc, value, arg_val);
+ return _ecore_getopt_parse_store_true(parser, desc, value, arg_val);
+
case ECORE_GETOPT_ACTION_STORE_FALSE:
- return _ecore_getopt_parse_store_false(parser, desc, value, arg_val);
+ return _ecore_getopt_parse_store_false(parser, desc, value, arg_val);
+
case ECORE_GETOPT_ACTION_CHOICE:
- return _ecore_getopt_parse_choice(parser, desc, value, arg_val);
+ return _ecore_getopt_parse_choice(parser, desc, value, arg_val);
+
case ECORE_GETOPT_ACTION_APPEND:
- return _ecore_getopt_parse_append(parser, desc, value, arg_val);
+ return _ecore_getopt_parse_append(parser, desc, value, arg_val);
+
case ECORE_GETOPT_ACTION_COUNT:
- return _ecore_getopt_parse_count(parser, desc, value, arg_val);
+ return _ecore_getopt_parse_count(parser, desc, value, arg_val);
+
case ECORE_GETOPT_ACTION_CALLBACK:
- return _ecore_getopt_parse_callback(parser, desc, value, arg_val);
+ return _ecore_getopt_parse_callback(parser, desc, value, arg_val);
+
case ECORE_GETOPT_ACTION_HELP:
- return _ecore_getopt_parse_help(parser, desc, value, arg_val);
+ return _ecore_getopt_parse_help(parser, desc, value, arg_val);
+
case ECORE_GETOPT_ACTION_VERSION:
- return _ecore_getopt_parse_version(parser, desc, value, arg_val);
+ return _ecore_getopt_parse_version(parser, desc, value, arg_val);
+
case ECORE_GETOPT_ACTION_COPYRIGHT:
- return _ecore_getopt_parse_copyright(parser, desc, value, arg_val);
+ return _ecore_getopt_parse_copyright(parser, desc, value, arg_val);
+
case ECORE_GETOPT_ACTION_LICENSE:
- return _ecore_getopt_parse_license(parser, desc, value, arg_val);
+ return _ecore_getopt_parse_license(parser, desc, value, arg_val);
+
default:
- return EINA_FALSE;
+ return EINA_FALSE;
}
}
static Eina_Bool
-_ecore_getopt_parse_arg_long(const Ecore_Getopt *parser, Ecore_Getopt_Value *values, int argc __UNUSED__, char **argv, int *idx, int *nonargs, const char *arg)
+_ecore_getopt_parse_arg_long(const Ecore_Getopt *parser,
+ Ecore_Getopt_Value *values,
+ int argc __UNUSED__,
+ char **argv,
+ int *idx,
+ int *nonargs,
+ const char *arg)
{
const Ecore_Getopt_Desc *desc;
Ecore_Getopt_Desc_Arg_Requirement arg_req;
}
static Eina_Bool
-_ecore_getopt_parse_arg_short(const Ecore_Getopt *parser, Ecore_Getopt_Value *values, int argc __UNUSED__, char **argv, int *idx, int *nonargs, const char *arg)
+_ecore_getopt_parse_arg_short(const Ecore_Getopt *parser,
+ Ecore_Getopt_Value *values,
+ int argc __UNUSED__,
+ char **argv,
+ int *idx,
+ int *nonargs,
+ const char *arg)
{
int run = 1;
while (run && (arg[0] != '\0'))
{
fprintf
(stderr, _("ERROR: option -%c requires an argument!\n"),
- opt);
+ opt);
if (parser->strict)
return EINA_FALSE;
return EINA_TRUE;
}
static Eina_Bool
-_ecore_getopt_parse_arg(const Ecore_Getopt *parser, Ecore_Getopt_Value *values, int argc, char **argv, int *idx, int *nonargs)
+_ecore_getopt_parse_arg(const Ecore_Getopt *parser,
+ Ecore_Getopt_Value *values,
+ int argc,
+ char **argv,
+ int *idx,
+ int *nonargs)
{
char *arg = argv[*idx];
}
static const Ecore_Getopt_Desc *
-_ecore_getopt_parse_find_short_other(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *orig)
+_ecore_getopt_parse_find_short_other(const Ecore_Getopt *parser,
+ const Ecore_Getopt_Desc *orig)
{
const Ecore_Getopt_Desc *desc = parser->descs;
const char c = orig->shortname;
}
static const Ecore_Getopt_Desc *
-_ecore_getopt_parse_find_long_other(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *orig)
+_ecore_getopt_parse_find_long_other(const Ecore_Getopt *parser,
+ const Ecore_Getopt_Desc *orig)
{
const Ecore_Getopt_Desc *desc = parser->descs;
const char *name = orig->longname;
const Ecore_Getopt_Desc *desc = parser->descs;
for (; !_ecore_getopt_desc_is_sentinel(desc); desc++)
{
- if (desc->shortname)
- {
- const Ecore_Getopt_Desc *other;
- other = _ecore_getopt_parse_find_short_other(parser, desc);
- if (other)
- {
- _ecore_getopt_desc_print_error(desc, "short name -%c already exists.", desc->shortname);
-
- if (other->longname)
- fprintf(stderr, " Other is --%s.\n", other->longname);
- else
- fputc('\n', stderr);
- return EINA_TRUE;
- }
- }
-
- if (desc->longname)
- {
- const Ecore_Getopt_Desc *other;
- other = _ecore_getopt_parse_find_long_other(parser, desc);
- if (other)
- {
- _ecore_getopt_desc_print_error(desc, "long name --%s already exists.", desc->longname);
-
- if (other->shortname)
- fprintf(stderr, " Other is -%c.\n", other->shortname);
- else
- fputc('\n', stderr);
- return EINA_TRUE;
- }
- }
+ if (desc->shortname)
+ {
+ const Ecore_Getopt_Desc *other;
+ other = _ecore_getopt_parse_find_short_other(parser, desc);
+ if (other)
+ {
+ _ecore_getopt_desc_print_error(desc, "short name -%c already exists.", desc->shortname);
+
+ if (other->longname)
+ fprintf(stderr, " Other is --%s.\n", other->longname);
+ else
+ fputc('\n', stderr);
+ return EINA_TRUE;
+ }
+ }
+
+ if (desc->longname)
+ {
+ const Ecore_Getopt_Desc *other;
+ other = _ecore_getopt_parse_find_long_other(parser, desc);
+ if (other)
+ {
+ _ecore_getopt_desc_print_error(desc, "long name --%s already exists.", desc->longname);
+
+ if (other->shortname)
+ fprintf(stderr, " Other is -%c.\n", other->shortname);
+ else
+ fputc('\n', stderr);
+ return EINA_TRUE;
+ }
+ }
}
return EINA_FALSE;
}
* @return index of first non-option parameter or -1 on error.
*/
int
-ecore_getopt_parse(const Ecore_Getopt *parser, Ecore_Getopt_Value *values, int argc, char **argv)
+ecore_getopt_parse(const Ecore_Getopt *parser,
+ Ecore_Getopt_Value *values,
+ int argc,
+ char **argv)
{
int i, nonargs;
return nonargs;
- error:
+error:
{
const Ecore_Getopt_Desc *help;
fputs(_("ERROR: invalid options found."), stderr);
* @c callback_data value is ignored, you can safely use @c NULL.
*/
Eina_Bool
-ecore_getopt_callback_geometry_parse(const Ecore_Getopt *parser __UNUSED__, const Ecore_Getopt_Desc *desc __UNUSED__, const char *str, void *data __UNUSED__, Ecore_Getopt_Value *storage)
+ecore_getopt_callback_geometry_parse(const Ecore_Getopt *parser __UNUSED__,
+ const Ecore_Getopt_Desc *desc __UNUSED__,
+ const char *str,
+ void *data __UNUSED__,
+ Ecore_Getopt_Value *storage)
{
Eina_Rectangle *v = (Eina_Rectangle *)storage->ptrp;
* @c callback_data value is ignored, you can safely use @c NULL.
*/
Eina_Bool
-ecore_getopt_callback_size_parse(const Ecore_Getopt *parser __UNUSED__, const Ecore_Getopt_Desc *desc __UNUSED__, const char *str, void *data __UNUSED__, Ecore_Getopt_Value *storage)
+ecore_getopt_callback_size_parse(const Ecore_Getopt *parser __UNUSED__,
+ const Ecore_Getopt_Desc *desc __UNUSED__,
+ const char *str,
+ void *data __UNUSED__,
+ Ecore_Getopt_Value *storage)
{
Eina_Rectangle *v = (Eina_Rectangle *)storage->ptrp;
return EINA_TRUE;
}
+
}
static int
-_ecore_glib_context_query(GMainContext *ctx, int priority, int *p_timer)
+_ecore_glib_context_query(GMainContext *ctx,
+ int priority,
+ int *p_timer)
{
int reqfds;
size_t size;
reqfds = g_main_context_query
- (ctx, priority, p_timer, _ecore_glib_fds, _ecore_glib_fds_size);
+ (ctx, priority, p_timer, _ecore_glib_fds, _ecore_glib_fds_size);
if (reqfds <= (int)_ecore_glib_fds_size) break;
size = (1 + reqfds / ECORE_GLIB_FDS_STEP) * ECORE_GLIB_FDS_STEP;
}
static int
-_ecore_glib_context_poll_from(const GPollFD *pfds, int count, fd_set *rfds, fd_set *wfds, fd_set *efds)
+_ecore_glib_context_poll_from(const GPollFD *pfds,
+ int count,
+ fd_set *rfds,
+ fd_set *wfds,
+ fd_set *efds)
{
const GPollFD *itr = pfds, *itr_end = pfds + count;
int glib_fds = -1;
}
static int
-_ecore_glib_context_poll_to(GPollFD *pfds, int count, const fd_set *rfds, const fd_set *wfds, const fd_set *efds, int ready)
+_ecore_glib_context_poll_to(GPollFD *pfds,
+ int count,
+ const fd_set *rfds,
+ const fd_set *wfds,
+ const fd_set *efds,
+ int ready)
{
GPollFD *itr = pfds, *itr_end = pfds + count;
}
static int
-_ecore_glib_select__locked(GMainContext *ctx, int ecore_fds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *ecore_timeout)
+_ecore_glib_select__locked(GMainContext *ctx,
+ int ecore_fds,
+ fd_set *rfds,
+ fd_set *wfds,
+ fd_set *efds,
+ struct timeval *ecore_timeout)
{
int priority, maxfds, glib_fds, reqfds, reqtimeout, ret;
struct timeval *timeout, glib_timeout;
if (reqfds < 0) goto error;
glib_fds = _ecore_glib_context_poll_from
- (_ecore_glib_fds, reqfds, rfds, wfds, efds);
+ (_ecore_glib_fds, reqfds, rfds, wfds, efds);
if (reqtimeout == -1)
timeout = ecore_timeout;
ret = _ecore_glib_select_original(maxfds, rfds, wfds, efds, timeout);
ret = _ecore_glib_context_poll_to
- (_ecore_glib_fds, reqfds, rfds, wfds, efds, ret);
+ (_ecore_glib_fds, reqfds, rfds, wfds, efds, ret);
if (g_main_context_check(ctx, priority, _ecore_glib_fds, reqfds))
g_main_context_dispatch(ctx);
return ret;
- error:
+error:
return _ecore_glib_select_original
- (ecore_fds, rfds, wfds, efds, ecore_timeout);
+ (ecore_fds, rfds, wfds, efds, ecore_timeout);
}
static int
-_ecore_glib_select(int ecore_fds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *ecore_timeout)
+_ecore_glib_select(int ecore_fds,
+ fd_set *rfds,
+ fd_set *wfds,
+ fd_set *efds,
+ struct timeval *ecore_timeout)
{
GStaticMutex lock = G_STATIC_MUTEX_INIT;
GMutex *mutex = g_static_mutex_get_mutex(&lock);
}
ret = _ecore_glib_select__locked
- (ctx, ecore_fds, rfds, wfds, efds, ecore_timeout);
+ (ctx, ecore_fds, rfds, wfds, efds, ecore_timeout);
g_mutex_unlock(mutex);
g_main_context_release(ctx);
return ret;
}
+
#endif
void
#include "Ecore.h"
#include "ecore_private.h"
-
struct _Ecore_Idle_Enterer
{
EINA_INLIST;
- ECORE_MAGIC;
+ ECORE_MAGIC;
Ecore_Task_Cb func;
- void *data;
- int references;
- Eina_Bool delete_me : 1;
+ void *data;
+ int references;
+ Eina_Bool delete_me : 1;
};
-
static Ecore_Idle_Enterer *idle_enterers = NULL;
static Ecore_Idle_Enterer *idle_enterer_current = NULL;
-static int idle_enterers_delete_me = 0;
+static int idle_enterers_delete_me = 0;
static void *
_ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer);
* (or ECORE_CALLBACK_CANCEL) deletes the idle enterer.
*/
EAPI Ecore_Idle_Enterer *
-ecore_idle_enterer_add(Ecore_Task_Cb func, const void *data)
+ecore_idle_enterer_add(Ecore_Task_Cb func,
+ const void *data)
{
Ecore_Idle_Enterer *ie = NULL;
ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_ENTERER);
ie->func = func;
ie->data = (void *)data;
- idle_enterers = (Ecore_Idle_Enterer *) eina_inlist_append(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
+ idle_enterers = (Ecore_Idle_Enterer *)eina_inlist_append(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
unlock:
_ecore_unlock();
return ie;
* (or ECORE_CALLBACK_CANCEL) deletes the idle enterer.
*/
EAPI Ecore_Idle_Enterer *
-ecore_idle_enterer_before_add(Ecore_Task_Cb func, const void *data)
+ecore_idle_enterer_before_add(Ecore_Task_Cb func,
+ const void *data)
{
Ecore_Idle_Enterer *ie = NULL;
ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_ENTERER);
ie->func = func;
ie->data = (void *)data;
- idle_enterers = (Ecore_Idle_Enterer *) eina_inlist_prepend(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
+ idle_enterers = (Ecore_Idle_Enterer *)eina_inlist_prepend(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
unlock:
_ecore_unlock();
return ie;
return idle_enterer->data;
}
-
void
_ecore_idle_enterer_shutdown(void)
{
Ecore_Idle_Enterer *ie;
while ((ie = idle_enterers))
{
- idle_enterers = (Ecore_Idle_Enterer *) eina_inlist_remove(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(idle_enterers));
+ idle_enterers = (Ecore_Idle_Enterer *)eina_inlist_remove(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(idle_enterers));
ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
free(ie);
}
if (!idle_enterer_current)
{
/* regular main loop, start from head */
- idle_enterer_current = idle_enterers;
+ idle_enterer_current = idle_enterers;
}
else
{
/* recursive main loop, continue from where we were */
- idle_enterer_current =
- (Ecore_Idle_Enterer *)EINA_INLIST_GET(idle_enterer_current)->next;
+ idle_enterer_current =
+ (Ecore_Idle_Enterer *)EINA_INLIST_GET(idle_enterer_current)->next;
}
while (idle_enterer_current)
Ecore_Idle_Enterer *l;
int deleted_idler_enterers_in_use = 0;
- for (l = idle_enterers; l;)
+ for (l = idle_enterers; l; )
{
Ecore_Idle_Enterer *ie = l;
- l = (Ecore_Idle_Enterer *) EINA_INLIST_GET(l)->next;
+ l = (Ecore_Idle_Enterer *)EINA_INLIST_GET(l)->next;
if (ie->delete_me)
{
if (ie->references)
continue;
}
- idle_enterers = (Ecore_Idle_Enterer *) eina_inlist_remove(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
+ idle_enterers = (Ecore_Idle_Enterer *)eina_inlist_remove(EINA_INLIST_GET(idle_enterers), EINA_INLIST_GET(ie));
ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
free(ie);
}
if (idle_enterers) return 1;
return 0;
}
+
#include "Ecore.h"
#include "ecore_private.h"
-
struct _Ecore_Idle_Exiter
{
EINA_INLIST;
- ECORE_MAGIC;
+ ECORE_MAGIC;
Ecore_Task_Cb func;
- void *data;
- int references;
- Eina_Bool delete_me : 1;
+ void *data;
+ int references;
+ Eina_Bool delete_me : 1;
};
-
static Ecore_Idle_Exiter *idle_exiters = NULL;
static Ecore_Idle_Exiter *idle_exiter_current = NULL;
-static int idle_exiters_delete_me = 0;
+static int idle_exiters_delete_me = 0;
static void *
_ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter);
* (or ECORE_CALLBACK_CANCEL) deletes the idle exiter.
*/
EAPI Ecore_Idle_Exiter *
-ecore_idle_exiter_add(Ecore_Task_Cb func, const void *data)
+ecore_idle_exiter_add(Ecore_Task_Cb func,
+ const void *data)
{
Ecore_Idle_Exiter *ie = NULL;
ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLE_EXITER);
ie->func = func;
ie->data = (void *)data;
- idle_exiters = (Ecore_Idle_Exiter *) eina_inlist_append(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(ie));
+ idle_exiters = (Ecore_Idle_Exiter *)eina_inlist_append(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(ie));
unlock:
_ecore_unlock();
return ie;
Ecore_Idle_Exiter *ie;
while ((ie = idle_exiters))
{
- idle_exiters = (Ecore_Idle_Exiter *) eina_inlist_remove(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(idle_exiters));
+ idle_exiters = (Ecore_Idle_Exiter *)eina_inlist_remove(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(idle_exiters));
ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
free(ie);
}
if (!idle_exiter_current)
{
/* regular main loop, start from head */
- idle_exiter_current = idle_exiters;
+ idle_exiter_current = idle_exiters;
}
else
{
/* recursive main loop, continue from where we were */
- idle_exiter_current =
- (Ecore_Idle_Exiter *)EINA_INLIST_GET(idle_exiter_current)->next;
+ idle_exiter_current =
+ (Ecore_Idle_Exiter *)EINA_INLIST_GET(idle_exiter_current)->next;
}
while (idle_exiter_current)
Ecore_Idle_Exiter *l;
int deleted_idler_exiters_in_use = 0;
- for (l = idle_exiters; l;)
+ for (l = idle_exiters; l; )
{
Ecore_Idle_Exiter *ie = l;
- l = (Ecore_Idle_Exiter *) EINA_INLIST_GET(l)->next;
+ l = (Ecore_Idle_Exiter *)EINA_INLIST_GET(l)->next;
if (ie->delete_me)
{
if (ie->references)
continue;
}
- idle_exiters = (Ecore_Idle_Exiter *) eina_inlist_remove(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(ie));
+ idle_exiters = (Ecore_Idle_Exiter *)eina_inlist_remove(EINA_INLIST_GET(idle_exiters), EINA_INLIST_GET(ie));
ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
free(ie);
}
if (idle_exiters) return 1;
return 0;
}
+
#include "Ecore.h"
#include "ecore_private.h"
-
struct _Ecore_Idler
{
EINA_INLIST;
- ECORE_MAGIC;
+ ECORE_MAGIC;
Ecore_Task_Cb func;
- void *data;
- int references;
- Eina_Bool delete_me : 1;
+ void *data;
+ int references;
+ Eina_Bool delete_me : 1;
};
-
static Ecore_Idler *idlers = NULL;
static Ecore_Idler *idler_current = NULL;
-static int idlers_delete_me = 0;
+static int idlers_delete_me = 0;
static void *
_ecore_idler_del(Ecore_Idler *idler);
EAPI Ecore_Idler *
-ecore_idler_add(Ecore_Task_Cb func, const void *data)
+ecore_idler_add(Ecore_Task_Cb func,
+ const void *data)
{
Ecore_Idler *ie = NULL;
ECORE_MAGIC_SET(ie, ECORE_MAGIC_IDLER);
ie->func = func;
ie->data = (void *)data;
- idlers = (Ecore_Idler *) eina_inlist_append(EINA_INLIST_GET(idlers), EINA_INLIST_GET(ie));
+ idlers = (Ecore_Idler *)eina_inlist_append(EINA_INLIST_GET(idlers), EINA_INLIST_GET(ie));
unlock:
_ecore_unlock();
return ie;
return idler->data;
}
-
void
_ecore_idler_shutdown(void)
{
Ecore_Idler *ie;
while ((ie = idlers))
{
- idlers = (Ecore_Idler *) eina_inlist_remove(EINA_INLIST_GET(idlers), EINA_INLIST_GET(idlers));
+ idlers = (Ecore_Idler *)eina_inlist_remove(EINA_INLIST_GET(idlers), EINA_INLIST_GET(idlers));
ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
free(ie);
}
if (!idler_current)
{
/* regular main loop, start from head */
- idler_current = idlers;
+ idler_current = idlers;
}
else
{
/* recursive main loop, continue from where we were */
- idler_current = (Ecore_Idler *)EINA_INLIST_GET(idler_current)->next;
+ idler_current = (Ecore_Idler *)EINA_INLIST_GET(idler_current)->next;
}
while (idler_current)
{
Ecore_Idler *l;
int deleted_idlers_in_use = 0;
- for (l = idlers; l;)
+ for (l = idlers; l; )
{
Ecore_Idler *ie = l;
- l = (Ecore_Idler *) EINA_INLIST_GET(l)->next;
+ l = (Ecore_Idler *)EINA_INLIST_GET(l)->next;
if (ie->delete_me)
{
if (ie->references)
continue;
}
- idlers = (Ecore_Idler *) eina_inlist_remove(EINA_INLIST_GET(idlers), EINA_INLIST_GET(ie));
+ idlers = (Ecore_Idler *)eina_inlist_remove(EINA_INLIST_GET(idlers), EINA_INLIST_GET(ie));
ECORE_MAGIC_SET(ie, ECORE_MAGIC_NONE);
free(ie);
}
if (idlers) return 1;
return 0;
}
+
#include "Ecore.h"
#include "ecore_private.h"
-static Eina_Bool _ecore_job_event_handler(void *data, int type, void *ev);
-static void _ecore_job_event_free(void *data, void *ev);
+static Eina_Bool _ecore_job_event_handler(void *data,
+ int type,
+ void *ev);
+static void _ecore_job_event_free(void *data,
+ void *ev);
static int ecore_event_job_type = 0;
-static Ecore_Event_Handler* _ecore_job_handler = NULL;
+static Ecore_Event_Handler *_ecore_job_handler = NULL;
struct _Ecore_Job
{
- ECORE_MAGIC;
- Ecore_Event *event;
- Ecore_Cb func;
- void *data;
+ ECORE_MAGIC;
+ Ecore_Event *event;
+ Ecore_Cb func;
+ void *data;
};
void
* @note Once the job has been executed, the job handle is invalid.
*/
EAPI Ecore_Job *
-ecore_job_add(Ecore_Cb func, const void *data)
+ecore_job_add(Ecore_Cb func,
+ const void *data)
{
Ecore_Job *job;
*/
static Eina_Bool
-_ecore_job_event_handler(void *data __UNUSED__, int type __UNUSED__, void *ev)
+_ecore_job_event_handler(void *data __UNUSED__,
+ int type __UNUSED__,
+ void *ev)
{
Ecore_Job *job;
}
static void
-_ecore_job_event_free(void *data __UNUSED__, void *ev)
+_ecore_job_event_free(void *data __UNUSED__,
+ void *ev)
{
free(ev);
}
+
#endif
#ifdef HAVE_ISFINITE
-# define ECORE_FINITE(t) isfinite(t)
+# define ECORE_FINITE(t) isfinite(t)
#else
# ifdef _MSC_VER
# define ECORE_FINITE(t) _finite(t)
#include "ecore_private.h"
#ifdef HAVE_SYS_EPOLL_H
-# define HAVE_EPOLL 1
+# define HAVE_EPOLL 1
# include <sys/epoll.h>
#else
-# define HAVE_EPOLL 0
-# define EPOLLIN 1
-# define EPOLLOUT 2
-# define EPOLLERR 8
+# define HAVE_EPOLL 0
+# define EPOLLIN 1
+# define EPOLLOUT 2
+# define EPOLLERR 8
#define EPOLL_CTL_ADD 1
#define EPOLL_CTL_DEL 2
uint64_t u64;
} epoll_data_t;
-struct epoll_event {
+struct epoll_event
+{
uint32_t events;
epoll_data_t data;
};
static inline int
epoll_create(int size __UNUSED__)
{
- return -1;
+ return -1;
}
static inline int
-epoll_wait(int epfd __UNUSED__, struct epoll_event *events __UNUSED__,
- int maxevents __UNUSED__, int timeout __UNUSED__)
+epoll_wait(int epfd __UNUSED__,
+ struct epoll_event *events __UNUSED__,
+ int maxevents __UNUSED__,
+ int timeout __UNUSED__)
{
- return -1;
+ return -1;
}
static inline int
-epoll_ctl(int epfd __UNUSED__, int op __UNUSED__, int fd __UNUSED__,
+epoll_ctl(int epfd __UNUSED__,
+ int op __UNUSED__,
+ int fd __UNUSED__,
struct epoll_event *event __UNUSED__)
{
- return -1;
+ return -1;
}
#endif
#define CLOCK_MONOTONIC 0 /* bogus value */
#endif
#ifndef TFD_NONBLOCK
-#define TFD_NONBLOCK 0 /* bogus value */
+#define TFD_NONBLOCK 0 /* bogus value */
#endif
static inline int
-timerfd_create(int clockid __UNUSED__, int flags __UNUSED__)
+timerfd_create(int clockid __UNUSED__,
+ int flags __UNUSED__)
{
- return -1;
+ return -1;
}
+
static inline int
-timerfd_settime(int fd __UNUSED__, int flags __UNUSED__,
+timerfd_settime(int fd __UNUSED__,
+ int flags __UNUSED__,
const struct itimerspec *new_value __UNUSED__,
- struct itimerspec *old_value __UNUSED__)
+ struct itimerspec *old_value __UNUSED__)
{
- return -1;
+ return -1;
}
+
#endif /* HAVE_SYS_TIMERFD_H */
#ifdef USE_G_MAIN_LOOP
struct _Ecore_Fd_Handler
{
EINA_INLIST;
- ECORE_MAGIC;
- Ecore_Fd_Handler *next_ready;
- int fd;
- Ecore_Fd_Handler_Flags flags;
- Ecore_Fd_Cb func;
- void *data;
- Ecore_Fd_Cb buf_func;
- void *buf_data;
- Ecore_Fd_Prep_Cb prep_func;
- void *prep_data;
- int references;
- Eina_Bool read_active : 1;
- Eina_Bool write_active : 1;
- Eina_Bool error_active : 1;
- Eina_Bool delete_me : 1;
+ ECORE_MAGIC;
+ Ecore_Fd_Handler *next_ready;
+ int fd;
+ Ecore_Fd_Handler_Flags flags;
+ Ecore_Fd_Cb func;
+ void *data;
+ Ecore_Fd_Cb buf_func;
+ void *buf_data;
+ Ecore_Fd_Prep_Cb prep_func;
+ void *prep_data;
+ int references;
+ Eina_Bool read_active : 1;
+ Eina_Bool write_active : 1;
+ Eina_Bool error_active : 1;
+ Eina_Bool delete_me : 1;
#if defined(USE_G_MAIN_LOOP)
- GPollFD gfd;
+ GPollFD gfd;
#endif
};
struct _Ecore_Win32_Handler
{
EINA_INLIST;
- ECORE_MAGIC;
+ ECORE_MAGIC;
HANDLE h;
Ecore_Win32_Handle_Cb func;
void *data;
};
#endif
-
#ifndef USE_G_MAIN_LOOP
static int _ecore_main_select(double timeout);
#endif
#endif
#ifdef _WIN32
-static int _ecore_main_win32_select(int nfds, fd_set *readfds, fd_set *writefds,
- fd_set *exceptfds, struct timeval *timeout);
+static int _ecore_main_win32_select(int nfds,
+ fd_set *readfds,
+ fd_set *writefds,
+ fd_set *exceptfds,
+ struct timeval *timeout);
static void _ecore_main_win32_handlers_cleanup(void);
#endif
-static int in_main_loop = 0;
+static int in_main_loop = 0;
#ifndef USE_G_MAIN_LOOP
-static int do_quit = 0;
+static int do_quit = 0;
#endif
static Ecore_Fd_Handler *fd_handlers = NULL;
static Ecore_Fd_Handler *fd_handler_current = NULL;
-static Eina_List *fd_handlers_with_prep = NULL;
-static Eina_List *fd_handlers_with_buffer = NULL;
-static Eina_List *fd_handlers_to_delete = NULL;
+static Eina_List *fd_handlers_with_prep = NULL;
+static Eina_List *fd_handlers_with_buffer = NULL;
+static Eina_List *fd_handlers_to_delete = NULL;
/* single linked list of ready fdhs, terminated by loop to self */
-static Ecore_Fd_Handler *fd_handlers_to_call;
-static Ecore_Fd_Handler *fd_handlers_to_call_current;
+static Ecore_Fd_Handler *fd_handlers_to_call;
+static Ecore_Fd_Handler *fd_handlers_to_call_current;
#ifdef _WIN32
static Ecore_Win32_Handler *win32_handlers = NULL;
static Ecore_Win32_Handler *win32_handler_current = NULL;
-static Eina_Bool win32_handlers_delete_me = EINA_FALSE;
+static Eina_Bool win32_handlers_delete_me = EINA_FALSE;
#endif
#ifdef _WIN32
#endif
#ifndef USE_G_MAIN_LOOP
-static double t1 = 0.0;
-static double t2 = 0.0;
+static double t1 = 0.0;
+static double t2 = 0.0;
#endif
static int timer_fd = -1;
static GPollFD ecore_timer_fd;
static GSource *ecore_glib_source;
static guint ecore_glib_source_id;
-static GMainLoop* ecore_main_loop;
+static GMainLoop *ecore_main_loop;
static gboolean ecore_idling;
static gboolean _ecore_glib_idle_enterer_called;
static gboolean ecore_fds_ready;
_ecore_try_add_to_call_list(Ecore_Fd_Handler *fdh)
{
/* check if this fdh is already in the list */
- if (fdh->next_ready)
- return;
- if (fdh->read_active || fdh->write_active || fdh->error_active)
- {
- /*
- * make sure next_ready is non-null by pointing to ourselves
- * use that to indicate this fdh is in the ready list
- * insert at the head of the list to avoid trouble
- */
- fdh->next_ready = fd_handlers_to_call ? fd_handlers_to_call : fdh;
- fd_handlers_to_call = fdh;
- }
+ if (fdh->next_ready)
+ return;
+ if (fdh->read_active || fdh->write_active || fdh->error_active)
+ {
+ /*
+ * make sure next_ready is non-null by pointing to ourselves
+ * use that to indicate this fdh is in the ready list
+ * insert at the head of the list to avoid trouble
+ */
+ fdh->next_ready = fd_handlers_to_call ? fd_handlers_to_call : fdh;
+ fd_handlers_to_call = fdh;
+ }
}
static inline int
if (epoll_pid && epoll_pid != getpid())
{
/* forked! */
- _ecore_main_loop_shutdown();
+ _ecore_main_loop_shutdown();
}
if (epoll_pid == 0 && epoll_fd < 0)
{
}
static inline int
-_ecore_epoll_add(int efd, int fd, int events, void *ptr)
+_ecore_epoll_add(int efd,
+ int fd,
+ int events,
+ void *ptr)
{
struct epoll_event ev;
_ecore_poll_events_from_fdh(Ecore_Fd_Handler *fdh)
{
int events = 0;
- if (fdh->flags & ECORE_FD_READ) events |= EPOLLIN;
+ if (fdh->flags & ECORE_FD_READ) events |= EPOLLIN;
if (fdh->flags & ECORE_FD_WRITE) events |= EPOLLOUT;
if (fdh->flags & ECORE_FD_ERROR) events |= EPOLLERR;
return events;
_gfd_events_from_fdh(Ecore_Fd_Handler *fdh)
{
int events = 0;
- if (fdh->flags & ECORE_FD_READ) events |= G_IO_IN;
+ if (fdh->flags & ECORE_FD_READ) events |= G_IO_IN;
if (fdh->flags & ECORE_FD_WRITE) events |= G_IO_OUT;
if (fdh->flags & ECORE_FD_ERROR) events |= G_IO_ERR;
return events;
}
+
#endif
static inline int
return r;
}
-static inline int _ecore_main_fdh_epoll_mark_active(void)
+static inline int
+_ecore_main_fdh_epoll_mark_active(void)
{
struct epoll_event ev[32];
int i, ret;
#ifdef USE_G_MAIN_LOOP
-static inline int _ecore_main_fdh_glib_mark_active(void)
+static inline int
+_ecore_main_fdh_glib_mark_active(void)
{
Ecore_Fd_Handler *fdh;
int ret = 0;
EINA_INLIST_FOREACH(fd_handlers, fdh)
{
if (fdh->delete_me)
- continue;
+ continue;
if (fdh->gfd.revents & G_IO_IN)
- fdh->read_active = EINA_TRUE;
+ fdh->read_active = EINA_TRUE;
if (fdh->gfd.revents & G_IO_OUT)
- fdh->write_active = EINA_TRUE;
+ fdh->write_active = EINA_TRUE;
if (fdh->gfd.revents & G_IO_ERR)
- fdh->error_active = EINA_TRUE;
+ fdh->error_active = EINA_TRUE;
_ecore_try_add_to_call_list(fdh);
- if (fdh->gfd.revents & (G_IO_IN|G_IO_OUT|G_IO_ERR)) ret++;
+ if (fdh->gfd.revents & (G_IO_IN | G_IO_OUT | G_IO_ERR)) ret++;
}
return ret;
/* like we are about to enter main_loop_select in _ecore_main_select */
static gboolean
-_ecore_main_gsource_prepare(GSource *source __UNUSED__, gint *next_time)
+_ecore_main_gsource_prepare(GSource *source __UNUSED__,
+ gint *next_time)
{
gboolean ready = FALSE;
if (g_main_loop_is_running(ecore_main_loop))
{
/* only set idling state in dispatch */
- if (ecore_idling && !_ecore_idler_exist() && !_ecore_event_exist())
- {
- if (_ecore_timers_exists())
- {
- int r = -1;
- double t = _ecore_timer_next_get();
- if (timer_fd >= 0 && t > 0.0)
- {
- struct itimerspec ts;
-
- ts.it_interval.tv_sec = 0;
- ts.it_interval.tv_nsec = 0;
- ts.it_value.tv_sec = t;
- ts.it_value.tv_nsec = fmod(t*NS_PER_SEC, NS_PER_SEC);
-
- /* timerfd cannot sleep for 0 time */
- if (ts.it_value.tv_sec || ts.it_value.tv_nsec)
- {
- r = timerfd_settime(timer_fd, 0, &ts, NULL);
- if (r < 0)
- {
- ERR("timer set returned %d (errno=%d)", r, errno);
- close(timer_fd);
- timer_fd = -1;
- }
- else
- INF("sleeping for %ld s %06ldus",
- ts.it_value.tv_sec,
- ts.it_value.tv_nsec/1000);
- }
- }
- if (r == -1)
- {
- *next_time = ceil(t * 1000.0);
- if (t == 0.0)
- ready = TRUE;
- }
- }
- else
- *next_time = -1;
- }
- else
- {
- *next_time = 0;
- if (_ecore_event_exist())
- ready = TRUE;
- }
-
- if (fd_handlers_with_prep)
- _ecore_main_prepare_handlers();
+ if (ecore_idling && !_ecore_idler_exist() && !_ecore_event_exist())
+ {
+ if (_ecore_timers_exists())
+ {
+ int r = -1;
+ double t = _ecore_timer_next_get();
+ if (timer_fd >= 0 && t > 0.0)
+ {
+ struct itimerspec ts;
+
+ ts.it_interval.tv_sec = 0;
+ ts.it_interval.tv_nsec = 0;
+ ts.it_value.tv_sec = t;
+ ts.it_value.tv_nsec = fmod(t * NS_PER_SEC, NS_PER_SEC);
+
+ /* timerfd cannot sleep for 0 time */
+ if (ts.it_value.tv_sec || ts.it_value.tv_nsec)
+ {
+ r = timerfd_settime(timer_fd, 0, &ts, NULL);
+ if (r < 0)
+ {
+ ERR("timer set returned %d (errno=%d)", r, errno);
+ close(timer_fd);
+ timer_fd = -1;
+ }
+ else
+ INF("sleeping for %ld s %06ldus",
+ ts.it_value.tv_sec,
+ ts.it_value.tv_nsec / 1000);
+ }
+ }
+ if (r == -1)
+ {
+ *next_time = ceil(t * 1000.0);
+ if (t == 0.0)
+ ready = TRUE;
+ }
+ }
+ else
+ *next_time = -1;
+ }
+ else
+ {
+ *next_time = 0;
+ if (_ecore_event_exist())
+ ready = TRUE;
+ }
+
+ if (fd_handlers_with_prep)
+ _ecore_main_prepare_handlers();
}
else
ready = TRUE;
ret = TRUE;
else
{
- /* unexpected things happened... fail back to old way */
- ERR("timer read returned %d (errno=%d)", r, errno);
- close(timer_fd);
- timer_fd = -1;
+ /* unexpected things happened... fail back to old way */
+ ERR("timer read returned %d (errno=%d)", r, errno);
+ close(timer_fd);
+ timer_fd = -1;
}
}
}
/* like we just came out of main_loop_select in _ecore_main_select */
static gboolean
-_ecore_main_gsource_dispatch(GSource *source __UNUSED__, GSourceFunc callback __UNUSED__, gpointer user_data __UNUSED__)
+_ecore_main_gsource_dispatch(GSource *source __UNUSED__,
+ GSourceFunc callback __UNUSED__,
+ gpointer user_data __UNUSED__)
{
gboolean events_ready, timers_ready, idlers_ready;
double next_time;
static GSourceFuncs ecore_gsource_funcs =
{
- .prepare = _ecore_main_gsource_prepare,
- .check = _ecore_main_gsource_check,
+ .prepare = _ecore_main_gsource_prepare,
+ .check = _ecore_main_gsource_check,
.dispatch = _ecore_main_gsource_dispatch,
.finalize = _ecore_main_gsource_finalize,
};
{
epoll_fd = epoll_create(1);
if (epoll_fd < 0)
- WRN("Failed to create epoll fd!");
+ WRN("Failed to create epoll fd!");
epoll_pid = getpid();
/* add polls on all our file descriptors */
EINA_INLIST_FOREACH(fd_handlers, fdh)
{
if (fdh->delete_me)
- continue;
+ continue;
_ecore_epoll_add(epoll_fd, fdh->fd,
_ecore_poll_events_from_fdh(fdh), fdh);
_ecore_main_fdh_poll_add(fdh);
#ifdef USE_G_MAIN_LOOP
ecore_glib_source = g_source_new(&ecore_gsource_funcs, sizeof (GSource));
if (!ecore_glib_source)
- CRIT("Failed to create glib source for epoll!");
+ CRIT("Failed to create glib source for epoll!");
else
{
g_source_set_priority(ecore_glib_source, G_PRIORITY_HIGH_IDLE + 20);
if (HAVE_EPOLL && epoll_fd >= 0)
{
/* epoll multiplexes fds into the g_main_loop */
- ecore_epoll_fd.fd = epoll_fd;
- ecore_epoll_fd.events = G_IO_IN;
- ecore_epoll_fd.revents = 0;
- g_source_add_poll(ecore_glib_source, &ecore_epoll_fd);
+ ecore_epoll_fd.fd = epoll_fd;
+ ecore_epoll_fd.events = G_IO_IN;
+ ecore_epoll_fd.revents = 0;
+ g_source_add_poll(ecore_glib_source, &ecore_epoll_fd);
}
- /* timerfd gives us better than millisecond accuracy in g_main_loop */
- timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
- if (timer_fd < 0)
+ /* timerfd gives us better than millisecond accuracy in g_main_loop */
+ timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
+ if (timer_fd < 0)
WRN("failed to create timer fd!");
- else
- {
- ecore_timer_fd.fd = timer_fd;
- ecore_timer_fd.events = G_IO_IN;
- ecore_timer_fd.revents = 0;
- g_source_add_poll(ecore_glib_source, &ecore_timer_fd);
- }
+ else
+ {
+ ecore_timer_fd.fd = timer_fd;
+ ecore_timer_fd.events = G_IO_IN;
+ ecore_timer_fd.revents = 0;
+ g_source_add_poll(ecore_glib_source, &ecore_timer_fd);
+ }
ecore_glib_source_id = g_source_attach(ecore_glib_source, NULL);
if (ecore_glib_source_id <= 0)
- CRIT("Failed to attach glib source to default context");
+ CRIT("Failed to attach glib source to default context");
}
#endif
}
close(epoll_fd);
epoll_fd = -1;
}
- epoll_pid = 0;
+ epoll_pid = 0;
if (timer_fd >= 0)
{
* @ingroup Ecore_FD_Handler_Group
*/
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)
+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)
{
Ecore_Fd_Handler *fdh = NULL;
fd_handlers_with_buffer = eina_list_append(fd_handlers_with_buffer, fdh);
fdh->buf_data = (void *)buf_data;
fd_handlers = (Ecore_Fd_Handler *)
- eina_inlist_append(EINA_INLIST_GET(fd_handlers),
- EINA_INLIST_GET(fdh));
+ eina_inlist_append(EINA_INLIST_GET(fd_handlers),
+ EINA_INLIST_GET(fdh));
unlock:
_ecore_unlock();
#ifdef _WIN32
EAPI Ecore_Win32_Handler *
-ecore_main_win32_handler_add(void *h, Ecore_Win32_Handle_Cb func, const void *data)
+ecore_main_win32_handler_add(void *h,
+ Ecore_Win32_Handle_Cb func,
+ const void *data)
{
Ecore_Win32_Handler *wh;
wh->func = func;
wh->data = (void *)data;
win32_handlers = (Ecore_Win32_Handler *)
- eina_inlist_append(EINA_INLIST_GET(win32_handlers),
- EINA_INLIST_GET(wh));
+ eina_inlist_append(EINA_INLIST_GET(win32_handlers),
+ EINA_INLIST_GET(wh));
return wh;
}
+
#else
EAPI Ecore_Win32_Handler *
-ecore_main_win32_handler_add(void *h __UNUSED__, Ecore_Win32_Handle_Cb func __UNUSED__,
- const void *data __UNUSED__)
+ecore_main_win32_handler_add(void *h __UNUSED__,
+ Ecore_Win32_Handle_Cb func __UNUSED__,
+ const void *data __UNUSED__)
{
return NULL;
}
-#endif
+#endif
/**
* Marks an FD handler for deletion.
win32_handlers_delete_me = EINA_TRUE;
return win32_handler->data;
}
+
#else
EAPI void *
ecore_main_win32_handler_del(Ecore_Win32_Handler *win32_handler __UNUSED__)
{
return NULL;
}
+
#endif
/**
* @ingroup Ecore_FD_Handler_Group
*/
EAPI void
-ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Prep_Cb func, const void *data)
+ecore_main_fd_handler_prepare_callback_set(Ecore_Fd_Handler *fd_handler,
+ Ecore_Fd_Prep_Cb func,
+ const void *data)
{
_ecore_lock();
fd_handler->prep_func = func;
fd_handler->prep_data = (void *)data;
if ((!fd_handlers_with_prep) ||
- (fd_handlers_with_prep && (!eina_list_data_find(fd_handlers_with_prep, fd_handler))))
+ (fd_handlers_with_prep && (!eina_list_data_find(fd_handlers_with_prep, fd_handler))))
/* FIXME: THIS WILL NOT SCALE WITH LOTS OF PREP FUNCTIONS!!! */
fd_handlers_with_prep = eina_list_append(fd_handlers_with_prep, fd_handler);
unlock:
* @ingroup Ecore_FD_Handler_Group
*/
EAPI Eina_Bool
-ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags)
+ecore_main_fd_handler_active_get(Ecore_Fd_Handler *fd_handler,
+ Ecore_Fd_Handler_Flags flags)
{
int ret = EINA_FALSE;
* @ingroup Ecore_FD_Handler_Group
*/
EAPI void
-ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler, Ecore_Fd_Handler_Flags flags)
+ecore_main_fd_handler_active_set(Ecore_Fd_Handler *fd_handler,
+ Ecore_Fd_Handler_Flags flags)
{
int ret;
{
if (in_main_loop)
{
- ERR("\n"
- "*** ECORE WARINING: Calling ecore_shutdown() while still in the main loop.\n"
- "*** Program may crash or behave strangely now.");
+ ERR("\n"
+ "*** ECORE WARINING: Calling ecore_shutdown() while still in the main loop.\n"
+ "*** Program may crash or behave strangely now.");
return;
}
while (fd_handlers)
Ecore_Fd_Handler *fdh;
fdh = fd_handlers;
- fd_handlers = (Ecore_Fd_Handler *) eina_inlist_remove(EINA_INLIST_GET(fd_handlers),
- EINA_INLIST_GET(fdh));
+ fd_handlers = (Ecore_Fd_Handler *)eina_inlist_remove(EINA_INLIST_GET(fd_handlers),
+ EINA_INLIST_GET(fdh));
ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
free(fdh);
}
Ecore_Win32_Handler *wh;
wh = win32_handlers;
- win32_handlers = (Ecore_Win32_Handler *) eina_inlist_remove(EINA_INLIST_GET(win32_handlers),
- EINA_INLIST_GET(wh));
+ win32_handlers = (Ecore_Win32_Handler *)eina_inlist_remove(EINA_INLIST_GET(win32_handlers),
+ EINA_INLIST_GET(wh));
ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE);
free(wh);
}
_ecore_main_select(double timeout)
{
struct timeval tv, *t;
- fd_set rfds, wfds, exfds;
- int max_fd;
- int ret;
+ fd_set rfds, wfds, exfds;
+ int max_fd;
+ int ret;
t = NULL;
if ((!ECORE_FINITE(timeout)) || (timeout == 0.0)) /* finite() tests for NaN, too big, too small, and infinity. */
if (fdh->fd > max_fd) max_fd = fdh->fd;
}
}
- }
+ }
}
else
{
/* polling on the epoll fd will wake when an fd in the epoll set is active */
- max_fd = _ecore_get_epoll_fd();
- FD_SET(max_fd, &rfds);
+ max_fd = _ecore_get_epoll_fd();
+ FD_SET(max_fd, &rfds);
}
if (_ecore_signal_count_get()) return -1;
{
#ifndef _WIN32
if (errno == EINTR) return -1;
- else if (errno == EBADF) _ecore_main_fd_handlers_bads_rem();
+ else if (errno == EBADF)
+ _ecore_main_fd_handlers_bads_rem();
#endif
}
if (ret > 0)
}
return 0;
}
+
#endif
#ifndef _WIN32
ERR("Removing bad fds");
for (l = EINA_INLIST_GET(fd_handlers); l; )
{
- fdh = (Ecore_Fd_Handler *) l;
+ fdh = (Ecore_Fd_Handler *)l;
l = l->next;
errno = 0;
found++;
}
}
- }
+ }
if (found == 0)
{
# ifdef HAVE_GLIB
}
_ecore_main_fd_handlers_cleanup();
}
+
# endif
#endif
if (fdh->prep_func && fd_handlers_with_prep)
fd_handlers_with_prep = eina_list_remove(fd_handlers_with_prep, fdh);
fd_handlers = (Ecore_Fd_Handler *)
- eina_inlist_remove(EINA_INLIST_GET(fd_handlers), EINA_INLIST_GET(fdh));
+ eina_inlist_remove(EINA_INLIST_GET(fd_handlers), EINA_INLIST_GET(fdh));
ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
free(fdh);
fd_handlers_to_delete = eina_list_remove_list(fd_handlers_to_delete, l);
}
win32_handlers = (Ecore_Win32_Handler *)
- eina_inlist_remove(EINA_INLIST_GET(win32_handlers),
- EINA_INLIST_GET(wh));
+ eina_inlist_remove(EINA_INLIST_GET(win32_handlers),
+ EINA_INLIST_GET(wh));
ECORE_MAGIC_SET(wh, ECORE_MAGIC_NONE);
free(wh);
}
}
if (!deleted_in_use) win32_handlers_delete_me = EINA_FALSE;
}
+
#endif
static void
_ecore_main_fd_handlers_call(void)
{
/* grab a new list */
- if (!fd_handlers_to_call_current)
- {
- fd_handlers_to_call_current = fd_handlers_to_call;
- fd_handlers_to_call = NULL;
- }
-
- while (fd_handlers_to_call_current)
- {
- Ecore_Fd_Handler *fdh = fd_handlers_to_call_current;
-
- if (!fdh->delete_me)
- {
- if ((fdh->read_active) ||
- (fdh->write_active) ||
- (fdh->error_active))
- {
- fdh->references++;
- if (!_ecore_call_fd_cb(fdh->func, fdh->data, fdh))
- {
- if (!fdh->delete_me)
- {
- fdh->delete_me = EINA_TRUE;
- fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh);
- }
-
- }
- fdh->references--;
- _ecore_fd_valid();
-
- fdh->read_active = EINA_FALSE;
- fdh->write_active = EINA_FALSE;
- fdh->error_active = EINA_FALSE;
- }
- }
-
- /* stop when we point to ourselves */
- if (fdh->next_ready == fdh)
- {
- fdh->next_ready = NULL;
- fd_handlers_to_call_current = NULL;
- break;
- }
-
- fd_handlers_to_call_current = fdh->next_ready;
- fdh->next_ready = NULL;
- }
+ if (!fd_handlers_to_call_current)
+ {
+ fd_handlers_to_call_current = fd_handlers_to_call;
+ fd_handlers_to_call = NULL;
+ }
+
+ while (fd_handlers_to_call_current)
+ {
+ Ecore_Fd_Handler *fdh = fd_handlers_to_call_current;
+
+ if (!fdh->delete_me)
+ {
+ if ((fdh->read_active) ||
+ (fdh->write_active) ||
+ (fdh->error_active))
+ {
+ fdh->references++;
+ if (!_ecore_call_fd_cb(fdh->func, fdh->data, fdh))
+ {
+ if (!fdh->delete_me)
+ {
+ fdh->delete_me = EINA_TRUE;
+ fd_handlers_to_delete = eina_list_append(fd_handlers_to_delete, fdh);
+ }
+ }
+ fdh->references--;
+ _ecore_fd_valid();
+
+ fdh->read_active = EINA_FALSE;
+ fdh->write_active = EINA_FALSE;
+ fdh->error_active = EINA_FALSE;
+ }
+ }
+
+ /* stop when we point to ourselves */
+ if (fdh->next_ready == fdh)
+ {
+ fdh->next_ready = NULL;
+ fd_handlers_to_call_current = NULL;
+ break;
+ }
+
+ fd_handlers_to_call_current = fdh->next_ready;
+ fdh->next_ready = NULL;
+ }
}
static int
_ecore_main_loop_spin_core(void)
{
/* as we are spinning we need to update loop time per spin */
- _ecore_time_loop_time = ecore_time_get();
- /* call all idlers, which returns false if no more idelrs exist */
- if (!_ecore_idler_all_call()) return SPIN_RESTART;
- /* sneaky - drop through or if checks - the first one to succeed
- * drops through and returns "continue" so further ones dont run */
- if ((_ecore_main_select(0.0) > 0) || (_ecore_event_exist()) ||
- (_ecore_signal_count_get() > 0) || (do_quit))
+ _ecore_time_loop_time = ecore_time_get();
+ /* call all idlers, which returns false if no more idelrs exist */
+ if (!_ecore_idler_all_call()) return SPIN_RESTART;
+ /* sneaky - drop through or if checks - the first one to succeed
+ * drops through and returns "continue" so further ones dont run */
+ if ((_ecore_main_select(0.0) > 0) || (_ecore_event_exist()) ||
+ (_ecore_signal_count_get() > 0) || (do_quit))
return LOOP_CONTINUE;
- /* default - spin more */
- return SPIN_MORE;
+ /* default - spin more */
+ return SPIN_MORE;
}
static int
{
/* if we have idlers we HAVE to spin and handle everything
* in a polling way - spin in a tight polling loop */
- for (;;)
- {
- int action = _ecore_main_loop_spin_core();
- if (action != SPIN_MORE) return action;
- /* if an idler has added a timer then we need to go through
- * the start of the spin cycle again to handle cases properly */
- if (_ecore_timers_exists()) return SPIN_RESTART;
- }
- /* just contiune handling events etc. */
- return LOOP_CONTINUE;
+ for (;; )
+ {
+ int action = _ecore_main_loop_spin_core();
+ if (action != SPIN_MORE) return action;
+ /* if an idler has added a timer then we need to go through
+ * the start of the spin cycle again to handle cases properly */
+ if (_ecore_timers_exists()) return SPIN_RESTART;
+ }
+ /* just contiune handling events etc. */
+ return LOOP_CONTINUE;
}
static int
{
/* if we have idlers we HAVE to spin and handle everything
* in a polling way - spin in a tight polling loop */
- for (;;)
- {
- int action = _ecore_main_loop_spin_core();
- if (action != SPIN_MORE) return action;
- /* if next timer expires now or in the past - stop spinning and
- * continue the mainloop walk as our "select" timeout has
- * expired now */
- if (_ecore_timer_next_get() <= 0.0) return LOOP_CONTINUE;
- }
- /* just contiune handling events etc. */
- return LOOP_CONTINUE;
+ for (;; )
+ {
+ int action = _ecore_main_loop_spin_core();
+ if (action != SPIN_MORE) return action;
+ /* if next timer expires now or in the past - stop spinning and
+ * continue the mainloop walk as our "select" timeout has
+ * expired now */
+ if (_ecore_timer_next_get() <= 0.0) return LOOP_CONTINUE;
+ }
+ /* just contiune handling events etc. */
+ return LOOP_CONTINUE;
}
static void
if (_ecore_event_exist())
{
/* but first conceptually enter an idle state */
- _ecore_idle_enterer_call();
- _ecore_throttle();
- /* now quickly poll to see which input fd's are active */
- _ecore_main_select(0.0);
- /* allow newly queued timers to expire from now on */
- _ecore_timer_enable_new();
- /* go straight to processing the events we had queued */
- goto process_all;
+ _ecore_idle_enterer_call();
+ _ecore_throttle();
+ /* now quickly poll to see which input fd's are active */
+ _ecore_main_select(0.0);
+ /* allow newly queued timers to expire from now on */
+ _ecore_timer_enable_new();
+ /* go straight to processing the events we had queued */
+ goto process_all;
}
-
+
if (once_only)
{
/* in once_only mode we should quickly poll for inputs, signals
* if we got any events or signals, allow new timers to process.
* use bitwise or to force both conditions to be tested and
* merged together */
- if (_ecore_main_select(0.0) | _ecore_signal_count_get())
- {
- _ecore_timer_enable_new();
- goto process_all;
- }
+ if (_ecore_main_select(0.0) | _ecore_signal_count_get())
+ {
+ _ecore_timer_enable_new();
+ goto process_all;
+ }
}
else
{
/* call idle enterers ... */
- _ecore_idle_enterer_call();
- _ecore_throttle();
+ _ecore_idle_enterer_call();
+ _ecore_throttle();
}
/* if these calls caused any buffered events to appear - deal with them */
if (fd_handlers_with_buffer)
_ecore_main_fd_handlers_buf_call();
- /* if there are any (buffered fd handling may generate them)
+ /* if there are any (buffered fd handling may generate them)
* then jump to processing them */
if (_ecore_event_exist())
{
_ecore_timer_enable_new();
goto process_all;
}
-
+
if (once_only)
{
/* in once_only mode enter idle here instead and then return */
- _ecore_idle_enterer_call();
- _ecore_throttle();
- _ecore_timer_enable_new();
- goto done;
+ _ecore_idle_enterer_call();
+ _ecore_throttle();
+ _ecore_timer_enable_new();
+ goto done;
}
_ecore_fps_marker_1();
-
+
/* start of the sleeping or looping section */
start_loop: /***************************************************************/
/* any timers re-added as a result of these are allowed to go */
if (!_ecore_event_exist())
{
/* init flags */
- next_time = _ecore_timer_next_get();
- /* no idlers */
- if (!_ecore_idler_exist())
- {
- /* sleep until timeout or forever (-1.0) waiting for on fds */
- _ecore_main_select(next_time);
- }
- else
- {
- int action = LOOP_CONTINUE;
-
- /* no timers - spin */
- if (next_time < 0) action = _ecore_main_loop_spin_no_timers();
- /* timers - spin */
- else action = _ecore_main_loop_spin_timers();
- if (action == SPIN_RESTART) goto start_loop;
- }
+ next_time = _ecore_timer_next_get();
+ /* no idlers */
+ if (!_ecore_idler_exist())
+ {
+ /* sleep until timeout or forever (-1.0) waiting for on fds */
+ _ecore_main_select(next_time);
+ }
+ else
+ {
+ int action = LOOP_CONTINUE;
+
+ /* no timers - spin */
+ if (next_time < 0) action = _ecore_main_loop_spin_no_timers();
+ /* timers - spin */
+ else action = _ecore_main_loop_spin_timers();
+ if (action == SPIN_RESTART) goto start_loop;
+ }
}
_ecore_fps_marker_2();
-
/* actually wake up and deal with input, events etc. */
process_all: /***********************************************************/
-
+
/* we came out of our "wait state" so idle has exited */
if (!once_only) _ecore_idle_exiter_call();
/* call the fd handler per fd that became alive... */
if (once_only)
{
/* if in once_only mode handle idle exiting */
- _ecore_idle_enterer_call();
- _ecore_throttle();
+ _ecore_idle_enterer_call();
+ _ecore_throttle();
}
-
+
done: /*******************************************************************/
in_main_loop--;
}
+
#endif
#ifdef _WIN32
static int
-_ecore_main_win32_select(int nfds __UNUSED__, fd_set *readfds, fd_set *writefds,
- fd_set *exceptfds, struct timeval *tv)
+_ecore_main_win32_select(int nfds __UNUSED__,
+ fd_set *readfds,
+ fd_set *writefds,
+ fd_set *exceptfds,
+ struct timeval *tv)
{
- HANDLE objects[MAXIMUM_WAIT_OBJECTS];
- int sockets[MAXIMUM_WAIT_OBJECTS];
+ HANDLE objects[MAXIMUM_WAIT_OBJECTS];
+ int sockets[MAXIMUM_WAIT_OBJECTS];
Ecore_Fd_Handler *fdh;
Ecore_Win32_Handler *wh;
unsigned int objects_nbr = 0;
unsigned int handles_nbr = 0;
unsigned int events_nbr = 0;
- DWORD result;
- DWORD timeout;
- MSG msg;
+ DWORD result;
+ DWORD timeout;
+ MSG msg;
unsigned int i;
- int res;
+ int res;
/* Create an event object per socket */
EINA_INLIST_FOREACH(fd_handlers, fdh)
else if (result == WAIT_TIMEOUT)
{
/* ERR("time out\n"); */
- res = 0;
+ res = 0;
}
else if (result == (WAIT_OBJECT_0 + objects_nbr))
{
WSAEnumNetworkEvents(sockets[result], objects[result], &network_event);
if (network_event.lNetworkEvents & FD_READ)
- FD_SET(sockets[result], readfds);
+ FD_SET(sockets[result], readfds);
if (network_event.lNetworkEvents & FD_WRITE)
- FD_SET(sockets[result], writefds);
+ FD_SET(sockets[result], writefds);
if (network_event.lNetworkEvents & FD_OOB)
- FD_SET(sockets[result], exceptfds);
+ FD_SET(sockets[result], exceptfds);
res = 1;
}
if (!win32_handler_current)
{
/* regular main loop, start from head */
- win32_handler_current = win32_handlers;
+ win32_handler_current = win32_handlers;
}
else
{
/* recursive main loop, continue from where we were */
- win32_handler_current = (Ecore_Win32_Handler *)EINA_INLIST_GET(win32_handler_current)->next;
+ win32_handler_current = (Ecore_Win32_Handler *)EINA_INLIST_GET(win32_handler_current)->next;
}
while (win32_handler_current)
return res;
}
+
#endif
#include <math.h>
#ifdef HAVE_ISFINITE
-# define ECORE_FINITE(t) isfinite(t)
+# define ECORE_FINITE(t) isfinite(t)
#else
# ifdef _MSC_VER
# define ECORE_FINITE(t) _finite(t)
# define pipe_write(fd, buffer, size) send((fd), (char *)(buffer), size, 0)
# define pipe_read(fd, buffer, size) recv((fd), (char *)(buffer), size, 0)
# define pipe_close(fd) closesocket(fd)
-# define PIPE_FD_INVALID INVALID_SOCKET
-# define PIPE_FD_ERROR SOCKET_ERROR
+# define PIPE_FD_INVALID INVALID_SOCKET
+# define PIPE_FD_ERROR SOCKET_ERROR
#else
# define pipe_write(fd, buffer, size) write((fd), buffer, size)
# define pipe_read(fd, buffer, size) read((fd), buffer, size)
# define pipe_close(fd) close(fd)
-# define PIPE_FD_INVALID -1
-# define PIPE_FD_ERROR -1
+# define PIPE_FD_INVALID -1
+# define PIPE_FD_ERROR -1
#endif /* ! _WIN32 */
struct _Ecore_Pipe
{
- ECORE_MAGIC;
+ ECORE_MAGIC;
int fd_read;
int fd_write;
Ecore_Fd_Handler *fd_handler;
Eina_Bool delete_me : 1;
};
-
-static Eina_Bool _ecore_pipe_read(void *data, Ecore_Fd_Handler *fd_handler);
-
+static Eina_Bool _ecore_pipe_read(void *data,
+ Ecore_Fd_Handler *fd_handler);
/**
* @addtogroup Ecore_Pipe_Group
* @c NULL otherwise.
*/
EAPI Ecore_Pipe *
-ecore_pipe_add(Ecore_Pipe_Cb handler, const void *data)
+ecore_pipe_add(Ecore_Pipe_Cb handler,
+ const void *data)
{
Ecore_Pipe *p;
- int fds[2];
+ int fds[2];
if (!handler) return NULL;
fcntl(p->fd_read, F_SETFL, O_NONBLOCK);
p->fd_handler = ecore_main_fd_handler_add(p->fd_read,
- ECORE_FD_READ,
- _ecore_pipe_read,
- p,
- NULL, NULL);
+ ECORE_FD_READ,
+ _ecore_pipe_read,
+ p,
+ NULL, NULL);
return p;
}
* Negative value for @p wait means infite wait.
*/
EAPI int
-ecore_pipe_wait(Ecore_Pipe *p, int message_count, double wait)
+ecore_pipe_wait(Ecore_Pipe *p,
+ int message_count,
+ double wait)
{
struct timeval tv, *t;
fd_set rset;
if (wait >= 0.0)
{
/* finite() tests for NaN, too big, too small, and infinity. */
- if ((!ECORE_FINITE(timeout)) || (timeout == 0.0))
- {
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- }
- else if (timeout > 0.0)
- {
- int sec, usec;
+ if ((!ECORE_FINITE(timeout)) || (timeout == 0.0))
+ {
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ }
+ else if (timeout > 0.0)
+ {
+ int sec, usec;
#ifdef FIX_HZ
- timeout += (0.5 / HZ);
- sec = (int)timeout;
- usec = (int)((timeout - (double)sec) * 1000000);
+ timeout += (0.5 / HZ);
+ sec = (int)timeout;
+ usec = (int)((timeout - (double)sec) * 1000000);
#else
- sec = (int)timeout;
- usec = (int)((timeout - (double)sec) * 1000000);
+ sec = (int)timeout;
+ usec = (int)((timeout - (double)sec) * 1000000);
#endif
- tv.tv_sec = sec;
- tv.tv_usec = usec;
- }
- t = &tv;
+ tv.tv_sec = sec;
+ tv.tv_usec = usec;
+ }
+ t = &tv;
}
else
{
* @return Returns EINA_TRUE on a successful write, EINA_FALSE on an error
*/
EAPI Eina_Bool
-ecore_pipe_write(Ecore_Pipe *p, const void *buffer, unsigned int nbytes)
+ecore_pipe_write(Ecore_Pipe *p,
+ const void *buffer,
+ unsigned int nbytes)
{
ssize_t ret;
- size_t already_written = 0;
- int retry = ECORE_PIPE_WRITE_RETRY;
+ size_t already_written = 0;
+ int retry = ECORE_PIPE_WRITE_RETRY;
if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE))
{
else if (ret > 0)
{
/* XXX What should we do here? */
- ERR("The length of the data was not written complete"
- " to the pipe");
- return EINA_FALSE;
+ ERR("The length of the data was not written complete"
+ " to the pipe");
+ return EINA_FALSE;
}
else if (ret == PIPE_FD_ERROR && errno == EPIPE)
{
}
static Eina_Bool
-_ecore_pipe_read(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
+_ecore_pipe_read(void *data,
+ Ecore_Fd_Handler *fd_handler __UNUSED__)
{
- Ecore_Pipe *p = (Ecore_Pipe *)data;
- int i;
+ Ecore_Pipe *p = (Ecore_Pipe *)data;
+ int i;
p->handling++;
for (i = 0; i < 16; i++)
{
- ssize_t ret;
+ ssize_t ret;
/* if we already have read some data we don't need to read the len
* but to finish the already started job
if (p->len == 0)
{
/* read the len of the passed data */
- ret = pipe_read(p->fd_read, &p->len, sizeof(p->len));
-
- /* catch the non error case first */
- /* read amount ok - nothing more to do */
- if (ret == sizeof(p->len))
- ;
- else if (ret > 0)
- {
- /* we got more data than we asked for - definite error */
- ERR("Only read %i bytes from the pipe, although"
- " we need to read %i bytes.",
- (int)ret, (int)sizeof(p->len));
- _ecore_pipe_unhandle(p);
- return ECORE_CALLBACK_CANCEL;
- }
- else if (ret == 0)
- {
- /* we got no data */
- if (i == 0)
- {
- /* no data on first try through means an error */
- if (!p->delete_me)
- p->handler((void *)p->data, NULL, 0);
- if (p->passed_data) free(p->passed_data);
- p->passed_data = NULL;
- p->already_read = 0;
- p->len = 0;
- p->message++;
- pipe_close(p->fd_read);
- p->fd_read = PIPE_FD_INVALID;
- p->fd_handler = NULL;
- _ecore_pipe_unhandle(p);
- return ECORE_CALLBACK_CANCEL;
- }
- else
- {
- /* no data after first loop try is ok */
- _ecore_pipe_unhandle(p);
- return ECORE_CALLBACK_RENEW;
- }
- }
+ ret = pipe_read(p->fd_read, &p->len, sizeof(p->len));
+
+ /* catch the non error case first */
+ /* read amount ok - nothing more to do */
+ if (ret == sizeof(p->len))
+ ;
+ else if (ret > 0)
+ {
+ /* we got more data than we asked for - definite error */
+ ERR("Only read %i bytes from the pipe, although"
+ " we need to read %i bytes.",
+ (int)ret, (int)sizeof(p->len));
+ _ecore_pipe_unhandle(p);
+ return ECORE_CALLBACK_CANCEL;
+ }
+ else if (ret == 0)
+ {
+ /* we got no data */
+ if (i == 0)
+ {
+ /* no data on first try through means an error */
+ if (!p->delete_me)
+ p->handler((void *)p->data, NULL, 0);
+ if (p->passed_data) free(p->passed_data);
+ p->passed_data = NULL;
+ p->already_read = 0;
+ p->len = 0;
+ p->message++;
+ pipe_close(p->fd_read);
+ p->fd_read = PIPE_FD_INVALID;
+ p->fd_handler = NULL;
+ _ecore_pipe_unhandle(p);
+ return ECORE_CALLBACK_CANCEL;
+ }
+ else
+ {
+ /* no data after first loop try is ok */
+ _ecore_pipe_unhandle(p);
+ return ECORE_CALLBACK_RENEW;
+ }
+ }
#ifndef _WIN32
- else if ((ret == PIPE_FD_ERROR) &&
- ((errno == EINTR) || (errno == EAGAIN)))
- {
- _ecore_pipe_unhandle(p);
- return ECORE_CALLBACK_RENEW;
- }
- else
- {
- ERR("An unhandled error (ret: %i errno: %i [%s])"
- "occurred while reading from the pipe the length",
- (int)ret, errno, strerror(errno));
- _ecore_pipe_unhandle(p);
- return ECORE_CALLBACK_RENEW;
- }
+ else if ((ret == PIPE_FD_ERROR) &&
+ ((errno == EINTR) || (errno == EAGAIN)))
+ {
+ _ecore_pipe_unhandle(p);
+ return ECORE_CALLBACK_RENEW;
+ }
+ else
+ {
+ ERR("An unhandled error (ret: %i errno: %i [%s])"
+ "occurred while reading from the pipe the length",
+ (int)ret, errno, strerror(errno));
+ _ecore_pipe_unhandle(p);
+ return ECORE_CALLBACK_RENEW;
+ }
#else
- else /* ret == PIPE_FD_ERROR is the only other case on Windows */
- {
- if (WSAGetLastError() != WSAEWOULDBLOCK)
- {
- if (!p->delete_me)
+ else /* ret == PIPE_FD_ERROR is the only other case on Windows */
+ {
+ if (WSAGetLastError() != WSAEWOULDBLOCK)
+ {
+ if (!p->delete_me)
p->handler((void *)p->data, NULL, 0);
- if (p->passed_data) free(p->passed_data);
- p->passed_data = NULL;
- p->already_read = 0;
- p->len = 0;
- p->message++;
- pipe_close(p->fd_read);
- p->fd_read = PIPE_FD_INVALID;
- p->fd_handler = NULL;
- _ecore_pipe_unhandle(p);
- return ECORE_CALLBACK_CANCEL;
- }
- }
+ if (p->passed_data) free(p->passed_data);
+ p->passed_data = NULL;
+ p->already_read = 0;
+ p->len = 0;
+ p->message++;
+ pipe_close(p->fd_read);
+ p->fd_read = PIPE_FD_INVALID;
+ p->fd_handler = NULL;
+ _ecore_pipe_unhandle(p);
+ return ECORE_CALLBACK_CANCEL;
+ }
+ }
#endif
}
if (p->len == 0)
{
if (!p->delete_me)
- p->handler((void *)p->data, NULL, 0);
+ p->handler((void *)p->data, NULL, 0);
/* reset all values to 0 */
if (p->passed_data) free(p->passed_data);
p->passed_data = NULL;
if (!p->passed_data)
{
if (!p->delete_me)
- p->handler((void *)p->data, NULL, 0);
- /* close the pipe */
+ p->handler((void *)p->data, NULL, 0);
+ /* close the pipe */
p->already_read = 0;
p->len = 0;
p->message++;
if (ret == (ssize_t)(p->len - p->already_read))
{
if (!p->delete_me)
- p->handler((void *)p->data, p->passed_data, p->len);
+ p->handler((void *)p->data, p->passed_data, p->len);
free(p->passed_data);
/* reset all values to 0 */
p->passed_data = NULL;
else if (ret > 0)
{
/* more data left to read */
- p->already_read += ret;
- _ecore_pipe_unhandle(p);
- return ECORE_CALLBACK_RENEW;
+ p->already_read += ret;
+ _ecore_pipe_unhandle(p);
+ return ECORE_CALLBACK_RENEW;
}
else if (ret == 0)
{
/* 0 bytes to read - could be more to read next select wake up */
- _ecore_pipe_unhandle(p);
- return ECORE_CALLBACK_RENEW;
+ _ecore_pipe_unhandle(p);
+ return ECORE_CALLBACK_RENEW;
}
#ifndef _WIN32
else if ((ret == PIPE_FD_ERROR) &&
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
if (!p->delete_me)
- p->handler((void *)p->data, NULL, 0);
+ p->handler((void *)p->data, NULL, 0);
if (p->passed_data) free(p->passed_data);
p->passed_data = NULL;
p->already_read = 0;
_ecore_pipe_unhandle(p);
return ECORE_CALLBACK_RENEW;
}
+
#include "Ecore.h"
#include "ecore_private.h"
-
struct _Ecore_Poller
{
EINA_INLIST;
- ECORE_MAGIC;
+ ECORE_MAGIC;
int ibit;
unsigned char delete_me : 1;
Ecore_Task_Cb func;
- void *data;
+ void *data;
};
-
-static Ecore_Timer *timer = NULL;
-static int min_interval = -1;
-static int interval_incr = 0;
-static int at_tick = 0;
-static int just_added_poller = 0;
-static int poller_delete_count = 0;
-static int poller_walking = 0;
-static double poll_interval = 0.125;
-static double poll_cur_interval = 0.0;
-static double last_tick = 0.0;
-static Ecore_Poller *pollers[16] =
+static Ecore_Timer *timer = NULL;
+static int min_interval = -1;
+static int interval_incr = 0;
+static int at_tick = 0;
+static int just_added_poller = 0;
+static int poller_delete_count = 0;
+static int poller_walking = 0;
+static double poll_interval = 0.125;
+static double poll_cur_interval = 0.0;
+static double last_tick = 0.0;
+static Ecore_Poller *pollers[16] =
{
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
-static unsigned short poller_counters[16] =
+static unsigned short poller_counters[16] =
{
- 0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
};
-static void _ecore_poller_next_tick_eval(void);
+static void _ecore_poller_next_tick_eval(void);
static Eina_Bool _ecore_poller_cb_timer(void *data);
static void
if (min_interval < 0)
{
/* no pollers */
- if (timer)
- {
- ecore_timer_del(timer);
- timer = NULL;
- }
- return;
+ if (timer)
+ {
+ ecore_timer_del(timer);
+ timer = NULL;
+ }
+ return;
}
interval_incr = (1 << min_interval);
interval = interval_incr * poll_interval;
if (interval != poll_cur_interval)
{
t -= last_tick; /* time since we last ticked */
- /* delete the timer and reset it to tick off in the new
- * time interval. at the tick this will be adjusted */
+ /* delete the timer and reset it to tick off in the new
+ * time interval. at the tick this will be adjusted */
ecore_timer_del(timer);
timer = ecore_timer_add(interval - t,
_ecore_poller_cb_timer, NULL);
{
/* if the counter is @ 0 - this means that counter "went off" this
* tick interval, so run all pollers hooked to that counter */
- if (poller_counters[i] == 0)
- {
- EINA_INLIST_FOREACH(pollers[i], poller)
- {
- if (!poller->delete_me)
- {
- if (!poller->func(poller->data))
- {
- if (!poller->delete_me)
- {
- poller->delete_me = 1;
- poller_delete_count++;
- }
- }
- }
- }
- }
+ if (poller_counters[i] == 0)
+ {
+ EINA_INLIST_FOREACH(pollers[i], poller)
+ {
+ if (!poller->delete_me)
+ {
+ if (!poller->func(poller->data))
+ {
+ if (!poller->delete_me)
+ {
+ poller->delete_me = 1;
+ poller_delete_count++;
+ }
+ }
+ }
+ }
+ }
}
poller_walking--;
if (poller_delete_count > 0)
{
/* FIXME: walk all pollers and remove deleted ones */
- for (i = 0; i < 15; i++)
- {
- for (l = pollers[i]; l;)
- {
- poller = l;
- l = (Ecore_Poller *) EINA_INLIST_GET(l)->next;
- if (poller->delete_me)
- {
- pollers[i] = (Ecore_Poller *) eina_inlist_remove(EINA_INLIST_GET(pollers[i]), EINA_INLIST_GET(poller));
- free(poller);
- poller_delete_count--;
- changes++;
- if (poller_delete_count <= 0) break;
- }
- }
- if (poller_delete_count <= 0) break;
- }
+ for (i = 0; i < 15; i++)
+ {
+ for (l = pollers[i]; l; )
+ {
+ poller = l;
+ l = (Ecore_Poller *)EINA_INLIST_GET(l)->next;
+ if (poller->delete_me)
+ {
+ pollers[i] = (Ecore_Poller *)eina_inlist_remove(EINA_INLIST_GET(pollers[i]), EINA_INLIST_GET(poller));
+ free(poller);
+ poller_delete_count--;
+ changes++;
+ if (poller_delete_count <= 0) break;
+ }
+ }
+ if (poller_delete_count <= 0) break;
+ }
}
/* if we deleted or added any pollers, then we need to re-evaluate our
* minimum poll interval */
* @{
*/
-
/**
* Sets the time between ticks (in seconds) for the given ticker clock.
* @param type The ticker type to adjust
* by @p type to the time period defined by @p poll_time.
*/
EAPI void
-ecore_poller_poll_interval_set(Ecore_Poller_Type type __UNUSED__, double poll_time)
+ecore_poller_poll_interval_set(Ecore_Poller_Type type __UNUSED__,
+ double poll_time)
{
poll_interval = poll_time;
_ecore_poller_next_tick_eval();
* invalid.
*/
EAPI Ecore_Poller *
-ecore_poller_add(Ecore_Poller_Type type __UNUSED__, int interval, Ecore_Task_Cb func, const void *data)
+ecore_poller_add(Ecore_Poller_Type type __UNUSED__,
+ int interval,
+ Ecore_Task_Cb func,
+ const void *data)
{
Ecore_Poller *poller;
int ibit;
poller->ibit = ibit;
poller->func = func;
poller->data = (void *)data;
- pollers[poller->ibit] = (Ecore_Poller *) eina_inlist_prepend(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
+ pollers[poller->ibit] = (Ecore_Poller *)eina_inlist_prepend(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
if (poller_walking)
just_added_poller++;
else
* a poll rate without deleting and re-creating a poller.
*/
EAPI Eina_Bool
-ecore_poller_poller_interval_set(Ecore_Poller *poller, int interval)
+ecore_poller_poller_interval_set(Ecore_Poller *poller,
+ int interval)
{
int ibit;
if (!ECORE_MAGIC_CHECK(poller, ECORE_MAGIC_POLLER))
{
ECORE_MAGIC_FAIL(poller, ECORE_MAGIC_POLLER,
- "ecore_poller_poller_interval_set");
+ "ecore_poller_poller_interval_set");
return EINA_FALSE;
}
ibit = -1;
while (interval != 0)
{
- ibit++;
- interval >>= 1;
+ ibit++;
+ interval >>= 1;
}
/* only allow up to 32768 - i.e. ibit == 15, so limit it */
if (ibit > 15) ibit = 15;
/* if interval specified is the same as interval set, return true without wasting time */
if (poller->ibit == ibit)
return EINA_TRUE;
- pollers[poller->ibit] = (Ecore_Poller *) eina_inlist_remove(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
+ pollers[poller->ibit] = (Ecore_Poller *)eina_inlist_remove(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
poller->ibit = ibit;
- pollers[poller->ibit] = (Ecore_Poller *) eina_inlist_prepend(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
+ pollers[poller->ibit] = (Ecore_Poller *)eina_inlist_prepend(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
if (poller_walking)
just_added_poller++;
else
if (!ECORE_MAGIC_CHECK(poller, ECORE_MAGIC_POLLER))
{
ECORE_MAGIC_FAIL(poller, ECORE_MAGIC_POLLER,
- "ecore_poller_poller_interval_get");
+ "ecore_poller_poller_interval_get");
return 0;
}
ibit = poller->ibit;
while (ibit != 0)
{
- ibit--;
- interval <<= 1;
+ ibit--;
+ interval <<= 1;
}
return interval;
}
if (!ECORE_MAGIC_CHECK(poller, ECORE_MAGIC_POLLER))
{
ECORE_MAGIC_FAIL(poller, ECORE_MAGIC_POLLER,
- "ecore_poller_del");
+ "ecore_poller_del");
return NULL;
}
/* we are walking the poller list - a bad idea to remove from it while
}
/* not in loop so safe - delete immediately */
data = poller->data;
- pollers[poller->ibit] = (Ecore_Poller *) eina_inlist_remove(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
+ pollers[poller->ibit] = (Ecore_Poller *)eina_inlist_remove(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
free(poller);
_ecore_poller_next_tick_eval();
return data;
{
while ((poller = pollers[i]))
{
- pollers[i] = (Ecore_Poller *) eina_inlist_remove(EINA_INLIST_GET(pollers[i]), EINA_INLIST_GET(pollers[i]));
+ pollers[i] = (Ecore_Poller *)eina_inlist_remove(EINA_INLIST_GET(pollers[i]), EINA_INLIST_GET(pollers[i]));
free(poller);
}
}
}
+
#include <assert.h>
-extern int _ecore_log_dom ;
+extern int _ecore_log_dom;
#ifdef _ECORE_DEFAULT_LOG_DOM
# undef _ECORE_DEFAULT_LOG_DOM
#endif
#endif
#ifndef MIN
-# define MIN(x, y) (((x) > (y)) ? (y) : (x))
+# define MIN(x, y) (((x) > (y)) ? (y) : (x))
#endif
#ifndef MAX
-# define MAX(x, y) (((x) > (y)) ? (x) : (y))
+# define MAX(x, y) (((x) > (y)) ? (x) : (y))
#endif
#ifndef ABS
-# define ABS(x) ((x) < 0 ? -(x) : (x))
+# define ABS(x) ((x) < 0 ? -(x) : (x))
#endif
#ifndef CLAMP
# define CLAMP(x, min, max) (((x) > (max)) ? (max) : (((x) < (min)) ? (min) : (x)))
#endif
-#define EVAS_FRAME_QUEUING 1 /* for test */
+#define EVAS_FRAME_QUEUING 1 /* for test */
-#define READBUFSIZ 65536
+#define READBUFSIZ 65536
-#define ECORE_MAGIC_NONE 0x1234fedc
-#define ECORE_MAGIC_EXE 0xf7e812f5
-#define ECORE_MAGIC_TIMER 0xf7d713f4
-#define ECORE_MAGIC_IDLER 0xf7c614f3
-#define ECORE_MAGIC_IDLE_ENTERER 0xf7b515f2
-#define ECORE_MAGIC_IDLE_EXITER 0xf7601afd
-#define ECORE_MAGIC_FD_HANDLER 0xf7a416f1
-#define ECORE_MAGIC_EVENT_HANDLER 0xf79317f0
-#define ECORE_MAGIC_EVENT_FILTER 0xf78218ff
-#define ECORE_MAGIC_EVENT 0xf77119fe
-#define ECORE_MAGIC_ANIMATOR 0xf7643ea5
-#define ECORE_MAGIC_POLLER 0xf7568127
-#define ECORE_MAGIC_PIPE 0xf7458226
-#define ECORE_MAGIC_WIN32_HANDLER 0xf7e8f1a3
-#define ECORE_MAGIC_JOB 0x76543210
+#define ECORE_MAGIC_NONE 0x1234fedc
+#define ECORE_MAGIC_EXE 0xf7e812f5
+#define ECORE_MAGIC_TIMER 0xf7d713f4
+#define ECORE_MAGIC_IDLER 0xf7c614f3
+#define ECORE_MAGIC_IDLE_ENTERER 0xf7b515f2
+#define ECORE_MAGIC_IDLE_EXITER 0xf7601afd
+#define ECORE_MAGIC_FD_HANDLER 0xf7a416f1
+#define ECORE_MAGIC_EVENT_HANDLER 0xf79317f0
+#define ECORE_MAGIC_EVENT_FILTER 0xf78218ff
+#define ECORE_MAGIC_EVENT 0xf77119fe
+#define ECORE_MAGIC_ANIMATOR 0xf7643ea5
+#define ECORE_MAGIC_POLLER 0xf7568127
+#define ECORE_MAGIC_PIPE 0xf7458226
+#define ECORE_MAGIC_WIN32_HANDLER 0xf7e8f1a3
+#define ECORE_MAGIC_JOB 0x76543210
+#define ECORE_MAGIC Ecore_Magic __magic
-#define ECORE_MAGIC Ecore_Magic __magic
-
-#define ECORE_MAGIC_SET(d, m) (d)->__magic = (m)
-#define ECORE_MAGIC_CHECK(d, m) ((d) && ((d)->__magic == (m)))
-#define ECORE_MAGIC_FAIL(d, m, fn) _ecore_magic_fail((d), (d) ? (d)->__magic : 0, (m), (fn));
+#define ECORE_MAGIC_SET(d, m) (d)->__magic = (m)
+#define ECORE_MAGIC_CHECK(d, m) ((d) && ((d)->__magic == (m)))
+#define ECORE_MAGIC_FAIL(d, m, fn) _ecore_magic_fail((d), (d) ? (d)->__magic : 0, (m), (fn));
/* undef the following, we want our version */
#undef FREE
-#define FREE(ptr) free(ptr); ptr = NULL;
+#define FREE(ptr) free(ptr); ptr = NULL;
#undef IF_FREE
-#define IF_FREE(ptr) if (ptr) free(ptr); ptr = NULL;
+#define IF_FREE(ptr) if (ptr) free(ptr); ptr = NULL;
#undef IF_FN_DEL
-#define IF_FN_DEL(_fn, ptr) if (ptr) { _fn(ptr); ptr = NULL; }
+#define IF_FN_DEL(_fn, ptr) if (ptr) { _fn(ptr); ptr = NULL; }
-EAPI void ecore_print_warning(const char *function, const char *sparam);
+EAPI void
+ecore_print_warning(const char *function,
+ const char *sparam);
/* convenience macros for checking pointer parameters for non-NULL */
#undef CHECK_PARAM_POINTER_RETURN
#define CHECK_PARAM_POINTER_RETURN(sparam, param, ret) \
- if (!(param)) \
- { \
- ecore_print_warning(__FUNCTION__, sparam); \
- return ret; \
- }
+ if (!(param)) \
+ { \
+ ecore_print_warning(__FUNCTION__, sparam); \
+ return ret; \
+ }
#undef CHECK_PARAM_POINTER
-#define CHECK_PARAM_POINTER(sparam, param) \
- if (!(param)) \
- { \
- ecore_print_warning(__FUNCTION__, sparam); \
- return; \
- }
-
-typedef unsigned int Ecore_Magic;
-
-EAPI void _ecore_magic_fail(const void *d, Ecore_Magic m, Ecore_Magic req_m, const char *fname);
-
-void _ecore_time_init(void);
-
-Ecore_Timer *_ecore_timer_loop_add(double in, Ecore_Task_Cb func, const void *data);
-void *_ecore_timer_del(Ecore_Timer *timer);
-void _ecore_timer_delay(Ecore_Timer *timer, double add);
-void _ecore_timer_shutdown(void);
-void _ecore_timer_cleanup(void);
-void _ecore_timer_enable_new(void);
-double _ecore_timer_next_get(void);
-void _ecore_timer_expired_timers_call(double when);
-int _ecore_timers_exists(void);
-
-int _ecore_timer_expired_call(double when);
-
-void _ecore_idler_shutdown(void);
-int _ecore_idler_all_call(void);
-int _ecore_idler_exist(void);
-
-void _ecore_idle_enterer_shutdown(void);
-void _ecore_idle_enterer_call(void);
-int _ecore_idle_enterer_exist(void);
-
-void _ecore_idle_exiter_shutdown(void);
-void _ecore_idle_exiter_call(void);
-int _ecore_idle_exiter_exist(void);
-
-void _ecore_event_shutdown(void);
-int _ecore_event_exist(void);
-Ecore_Event *_ecore_event_add(int type, void *ev, Ecore_End_Cb func_free, void *data);
-void _ecore_event_call(void);
-void *_ecore_event_handler_del(Ecore_Event_Handler *event_handler);
-
-Ecore_Timer *_ecore_exe_doomsday_clock_get(Ecore_Exe *exe);
-void _ecore_exe_doomsday_clock_set(Ecore_Exe *exe, Ecore_Timer *dc);
-
-EAPI void *_ecore_event_signal_user_new(void);
-void *_ecore_event_signal_hup_new(void);
-void *_ecore_event_signal_exit_new(void);
-void *_ecore_event_signal_power_new(void);
-void *_ecore_event_signal_realtime_new(void);
-
-void *_ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler);
-
-void _ecore_main_shutdown(void);
+#define CHECK_PARAM_POINTER(sparam, param) \
+ if (!(param)) \
+ { \
+ ecore_print_warning(__FUNCTION__, sparam); \
+ return; \
+ }
+
+typedef unsigned int Ecore_Magic;
+
+EAPI void _ecore_magic_fail(const void *d,
+ Ecore_Magic m,
+ Ecore_Magic req_m,
+ const char *fname);
+
+void _ecore_time_init(void);
+
+Ecore_Timer *_ecore_timer_loop_add(double in,
+ Ecore_Task_Cb func,
+ const void *data);
+void *_ecore_timer_del(Ecore_Timer *timer);
+void _ecore_timer_delay(Ecore_Timer *timer,
+ double add);
+void _ecore_timer_shutdown(void);
+void _ecore_timer_cleanup(void);
+void _ecore_timer_enable_new(void);
+double _ecore_timer_next_get(void);
+void _ecore_timer_expired_timers_call(double when);
+int _ecore_timers_exists(void);
+
+int _ecore_timer_expired_call(double when);
+
+void _ecore_idler_shutdown(void);
+int _ecore_idler_all_call(void);
+int _ecore_idler_exist(void);
+
+void _ecore_idle_enterer_shutdown(void);
+void _ecore_idle_enterer_call(void);
+int _ecore_idle_enterer_exist(void);
+
+void _ecore_idle_exiter_shutdown(void);
+void _ecore_idle_exiter_call(void);
+int _ecore_idle_exiter_exist(void);
+
+void _ecore_event_shutdown(void);
+int _ecore_event_exist(void);
+Ecore_Event *_ecore_event_add(int type,
+ void *ev,
+ Ecore_End_Cb func_free,
+ void *data);
+void _ecore_event_call(void);
+void *_ecore_event_handler_del(Ecore_Event_Handler *event_handler);
+
+Ecore_Timer *_ecore_exe_doomsday_clock_get(Ecore_Exe *exe);
+void _ecore_exe_doomsday_clock_set(Ecore_Exe *exe,
+ Ecore_Timer *dc);
+
+EAPI void *_ecore_event_signal_user_new(void);
+void *_ecore_event_signal_hup_new(void);
+void *_ecore_event_signal_exit_new(void);
+void *_ecore_event_signal_power_new(void);
+void *_ecore_event_signal_realtime_new(void);
+
+void *_ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler);
+
+void _ecore_main_shutdown(void);
#if defined (_WIN32) || defined (__lv2ppu__)
static inline void _ecore_signal_shutdown(void) { }
+
static inline void _ecore_signal_init(void) { }
+
static inline void _ecore_signal_received_process(void) { }
-static inline int _ecore_signal_count_get(void) { return 0; }
+
+static inline int _ecore_signal_count_get(void) { return 0; }
+
static inline void _ecore_signal_call(void) { }
+
#else
-void _ecore_signal_shutdown(void);
-void _ecore_signal_init(void);
-void _ecore_signal_received_process(void);
-int _ecore_signal_count_get(void);
-void _ecore_signal_call(void);
+void _ecore_signal_shutdown(void);
+void _ecore_signal_init(void);
+void _ecore_signal_received_process(void);
+int _ecore_signal_count_get(void);
+void _ecore_signal_call(void);
#endif
-void _ecore_exe_init(void);
-void _ecore_exe_shutdown(void);
+void _ecore_exe_init(void);
+void _ecore_exe_shutdown(void);
#ifndef _WIN32
-Ecore_Exe *_ecore_exe_find(pid_t pid);
-void *_ecore_exe_event_del_new(void);
-void _ecore_exe_event_del_free(void *data, void *ev);
+Ecore_Exe *_ecore_exe_find(pid_t pid);
+void *_ecore_exe_event_del_new(void);
+void _ecore_exe_event_del_free(void *data,
+ void *ev);
#endif
-void _ecore_animator_shutdown(void);
+void _ecore_animator_shutdown(void);
-void _ecore_poller_shutdown(void);
+void _ecore_poller_shutdown(void);
-void _ecore_fps_debug_init(void);
-void _ecore_fps_debug_shutdown(void);
-void _ecore_fps_debug_runtime_add(double t);
+void _ecore_fps_debug_init(void);
+void _ecore_fps_debug_shutdown(void);
+void _ecore_fps_debug_runtime_add(double t);
void _ecore_thread_init(void);
void _ecore_thread_shutdown(void);
* Callback wrappers all assume that ecore _ecore_lock has been called
*/
static inline Eina_Bool
-_ecore_call_task_cb(Ecore_Task_Cb func, void *data)
+_ecore_call_task_cb(Ecore_Task_Cb func,
+ void *data)
{
Eina_Bool r;
}
static inline void *
-_ecore_call_data_cb(Ecore_Data_Cb func, void *data)
+_ecore_call_data_cb(Ecore_Data_Cb func,
+ void *data)
{
void *r;
}
static inline void
-_ecore_call_end_cb(Ecore_End_Cb func, void *user_data, void *func_data)
+_ecore_call_end_cb(Ecore_End_Cb func,
+ void *user_data,
+ void *func_data)
{
_ecore_unlock();
func(user_data, func_data);
}
static inline Eina_Bool
-_ecore_call_filter_cb(Ecore_Filter_Cb func, void *data,
- void *loop_data, int type, void *event)
+_ecore_call_filter_cb(Ecore_Filter_Cb func,
+ void *data,
+ void *loop_data,
+ int type,
+ void *event)
{
Eina_Bool r;
}
static inline Eina_Bool
-_ecore_call_handler_cb(Ecore_Event_Handler_Cb func, void *data, int type, void *event)
+_ecore_call_handler_cb(Ecore_Event_Handler_Cb func,
+ void *data,
+ int type,
+ void *event)
{
Eina_Bool r;
}
static inline void
-_ecore_call_prep_cb(Ecore_Fd_Prep_Cb func, void *data, Ecore_Fd_Handler *fd_handler)
+_ecore_call_prep_cb(Ecore_Fd_Prep_Cb func,
+ void *data,
+ Ecore_Fd_Handler *fd_handler)
{
_ecore_unlock();
func(data, fd_handler);
}
static inline Eina_Bool
-_ecore_call_fd_cb(Ecore_Fd_Cb func, void *data, Ecore_Fd_Handler *fd_handler)
+_ecore_call_fd_cb(Ecore_Fd_Cb func,
+ void *data,
+ Ecore_Fd_Handler *fd_handler)
{
Eina_Bool r;
return r;
}
-extern int _ecore_fps_debug;
+extern int _ecore_fps_debug;
extern double _ecore_time_loop_time;
extern Eina_Bool _ecore_glib_always_integrate;
extern Ecore_Select_Function main_loop_select;
typedef void (*Signal_Handler)(int sig, siginfo_t *si, void *foo);
-static void _ecore_signal_callback_set(int sig, Signal_Handler func);
-static void _ecore_signal_callback_ignore(int sig, siginfo_t *si, void *foo);
-static void _ecore_signal_callback_sigchld(int sig, siginfo_t *si, void *foo);
-static void _ecore_signal_callback_sigusr1(int sig, siginfo_t *si, void *foo);
-static void _ecore_signal_callback_sigusr2(int sig, siginfo_t *si, void *foo);
-static void _ecore_signal_callback_sighup(int sig, siginfo_t *si, void *foo);
-static void _ecore_signal_callback_sigquit(int sig, siginfo_t *si, void *foo);
-static void _ecore_signal_callback_sigint(int sig, siginfo_t *si, void *foo);
-static void _ecore_signal_callback_sigterm(int sig, siginfo_t *si, void *foo);
+static void _ecore_signal_callback_set(int sig,
+ Signal_Handler func);
+static void _ecore_signal_callback_ignore(int sig,
+ siginfo_t *si,
+ void *foo);
+static void _ecore_signal_callback_sigchld(int sig,
+ siginfo_t *si,
+ void *foo);
+static void _ecore_signal_callback_sigusr1(int sig,
+ siginfo_t *si,
+ void *foo);
+static void _ecore_signal_callback_sigusr2(int sig,
+ siginfo_t *si,
+ void *foo);
+static void _ecore_signal_callback_sighup(int sig,
+ siginfo_t *si,
+ void *foo);
+static void _ecore_signal_callback_sigquit(int sig,
+ siginfo_t *si,
+ void *foo);
+static void _ecore_signal_callback_sigint(int sig,
+ siginfo_t *si,
+ void *foo);
+static void _ecore_signal_callback_sigterm(int sig,
+ siginfo_t *si,
+ void *foo);
#ifdef SIGPWR
-static void _ecore_signal_callback_sigpwr(int sig, siginfo_t *si, void *foo);
+static void _ecore_signal_callback_sigpwr(int sig,
+ siginfo_t *si,
+ void *foo);
#endif
static Eina_Bool _ecore_signal_exe_exit_delay(void *data);
void
_ecore_signal_shutdown(void)
{
- _ecore_signal_callback_set(SIGPIPE, (Signal_Handler) SIG_DFL);
- _ecore_signal_callback_set(SIGALRM, (Signal_Handler) SIG_DFL);
- _ecore_signal_callback_set(SIGCHLD, (Signal_Handler) SIG_DFL);
- _ecore_signal_callback_set(SIGUSR1, (Signal_Handler) SIG_DFL);
- _ecore_signal_callback_set(SIGUSR2, (Signal_Handler) SIG_DFL);
- _ecore_signal_callback_set(SIGHUP, (Signal_Handler) SIG_DFL);
- _ecore_signal_callback_set(SIGQUIT, (Signal_Handler) SIG_DFL);
- _ecore_signal_callback_set(SIGINT, (Signal_Handler) SIG_DFL);
- _ecore_signal_callback_set(SIGTERM, (Signal_Handler) SIG_DFL);
+ _ecore_signal_callback_set(SIGPIPE, (Signal_Handler)SIG_DFL);
+ _ecore_signal_callback_set(SIGALRM, (Signal_Handler)SIG_DFL);
+ _ecore_signal_callback_set(SIGCHLD, (Signal_Handler)SIG_DFL);
+ _ecore_signal_callback_set(SIGUSR1, (Signal_Handler)SIG_DFL);
+ _ecore_signal_callback_set(SIGUSR2, (Signal_Handler)SIG_DFL);
+ _ecore_signal_callback_set(SIGHUP, (Signal_Handler)SIG_DFL);
+ _ecore_signal_callback_set(SIGQUIT, (Signal_Handler)SIG_DFL);
+ _ecore_signal_callback_set(SIGINT, (Signal_Handler)SIG_DFL);
+ _ecore_signal_callback_set(SIGTERM, (Signal_Handler)SIG_DFL);
#ifdef SIGPWR
- _ecore_signal_callback_set(SIGPWR, (Signal_Handler) SIG_DFL);
+ _ecore_signal_callback_set(SIGPWR, (Signal_Handler)SIG_DFL);
sigpwr_count = 0;
#endif
sigchld_count = 0;
sigint_count = 0;
sigterm_count = 0;
sig_count = 0;
-
}
void
_ecore_signal_callback_set(SIGCHLD, _ecore_signal_callback_sigchld);
_ecore_signal_callback_set(SIGUSR1, _ecore_signal_callback_sigusr1);
_ecore_signal_callback_set(SIGUSR2, _ecore_signal_callback_sigusr2);
- _ecore_signal_callback_set(SIGHUP, _ecore_signal_callback_sighup);
+ _ecore_signal_callback_set(SIGHUP, _ecore_signal_callback_sighup);
_ecore_signal_callback_set(SIGQUIT, _ecore_signal_callback_sigquit);
- _ecore_signal_callback_set(SIGINT, _ecore_signal_callback_sigint);
+ _ecore_signal_callback_set(SIGINT, _ecore_signal_callback_sigint);
_ecore_signal_callback_set(SIGTERM, _ecore_signal_callback_sigterm);
#ifdef SIGPWR
- _ecore_signal_callback_set(SIGPWR, _ecore_signal_callback_sigpwr);
+ _ecore_signal_callback_set(SIGPWR, _ecore_signal_callback_sigpwr);
#endif
}
sigprocmask(SIG_BLOCK, &newset, &oldset);
if (sigchld_count > MAXSIGQ)
WRN("%i SIGCHLD in queue. max queue size %i. losing "
- "siginfo for extra signals.", sigchld_count, MAXSIGQ);
+ "siginfo for extra signals.", sigchld_count, MAXSIGQ);
for (n = 0; n < sigchld_count; n++)
{
pid_t pid;
e->exe = _ecore_exe_find(pid);
if ((n < MAXSIGQ) && (sigchld_info[n].si_signo))
- e->data = sigchld_info[n]; /* No need to clone this. */
+ e->data = sigchld_info[n]; /* No need to clone this. */
if ((e->exe) && (ecore_exe_flags_get(e->exe) & (ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR)))
- {
- /* We want to report the Last Words of the exe, so delay this event.
- * This is twice as relevant for stderr.
- * There are three possibilities here -
- * 1 There are no Last Words.
- * 2 There are Last Words, they are not ready to be read.
- * 3 There are Last Words, they are ready to be read.
- *
- * For 1 we don't want to delay, for 3 we want to delay.
- * 2 is the problem. If we check for data now and there
- * is none, then there is no way to differentiate 1 and 2.
- * If we don't delay, we may loose data, but if we do delay,
- * there may not be data and the exit event never gets sent.
- *
- * Any way you look at it, there has to be some time passed
- * before the exit event gets sent. So the strategy here is
- * to setup a timer event that will send the exit event after
- * an arbitrary, but brief, time.
- *
- * This is probably paranoid, for the less paraniod, we could
- * check to see for Last Words, and only delay if there are any.
- * This has it's own set of problems.
- */
- Ecore_Timer *doomsday_clock;
-
- doomsday_clock = _ecore_exe_doomsday_clock_get(e->exe);
- IF_FN_DEL(ecore_timer_del, doomsday_clock);
- _ecore_unlock();
- doomsday_clock = ecore_timer_add
- (0.1, _ecore_signal_exe_exit_delay, e);
- _ecore_lock();
- _ecore_exe_doomsday_clock_set(e->exe, doomsday_clock);
- }
+ {
+ /* We want to report the Last Words of the exe, so delay this event.
+ * This is twice as relevant for stderr.
+ * There are three possibilities here -
+ * 1 There are no Last Words.
+ * 2 There are Last Words, they are not ready to be read.
+ * 3 There are Last Words, they are ready to be read.
+ *
+ * For 1 we don't want to delay, for 3 we want to delay.
+ * 2 is the problem. If we check for data now and there
+ * is none, then there is no way to differentiate 1 and 2.
+ * If we don't delay, we may loose data, but if we do delay,
+ * there may not be data and the exit event never gets sent.
+ *
+ * Any way you look at it, there has to be some time passed
+ * before the exit event gets sent. So the strategy here is
+ * to setup a timer event that will send the exit event after
+ * an arbitrary, but brief, time.
+ *
+ * This is probably paranoid, for the less paraniod, we could
+ * check to see for Last Words, and only delay if there are any.
+ * This has it's own set of problems.
+ */
+ Ecore_Timer *doomsday_clock;
+
+ doomsday_clock = _ecore_exe_doomsday_clock_get(e->exe);
+ IF_FN_DEL(ecore_timer_del, doomsday_clock);
+ _ecore_unlock();
+ doomsday_clock = ecore_timer_add
+ (0.1, _ecore_signal_exe_exit_delay, e);
+ _ecore_lock();
+ _ecore_exe_doomsday_clock_set(e->exe, doomsday_clock);
+ }
else
{
_ecore_event_add(ECORE_EXE_EVENT_DEL, e,
- _ecore_exe_event_del_free, NULL);
+ _ecore_exe_event_del_free, NULL);
}
}
}
}
static void
-_ecore_signal_callback_set(int sig, Signal_Handler func)
+_ecore_signal_callback_set(int sig,
+ Signal_Handler func)
{
- struct sigaction sa;
+ struct sigaction sa;
sa.sa_sigaction = func;
sa.sa_flags = SA_RESTART | SA_SIGINFO;
}
static void
-_ecore_signal_callback_ignore(int sig __UNUSED__, siginfo_t *si __UNUSED__, void *foo __UNUSED__)
+_ecore_signal_callback_ignore(int sig __UNUSED__,
+ siginfo_t *si __UNUSED__,
+ void *foo __UNUSED__)
{
}
static void
-_ecore_signal_callback_sigchld(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+_ecore_signal_callback_sigchld(int sig __UNUSED__,
+ siginfo_t *si,
+ void *foo __UNUSED__)
{
volatile sig_atomic_t n;
n = sigchld_count;
}
static void
-_ecore_signal_callback_sigusr1(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+_ecore_signal_callback_sigusr1(int sig __UNUSED__,
+ siginfo_t *si,
+ void *foo __UNUSED__)
{
volatile sig_atomic_t n;
n = sigusr1_count;
}
static void
-_ecore_signal_callback_sigusr2(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+_ecore_signal_callback_sigusr2(int sig __UNUSED__,
+ siginfo_t *si,
+ void *foo __UNUSED__)
{
volatile sig_atomic_t n;
n = sigusr2_count;
}
static void
-_ecore_signal_callback_sighup(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+_ecore_signal_callback_sighup(int sig __UNUSED__,
+ siginfo_t *si,
+ void *foo __UNUSED__)
{
volatile sig_atomic_t n;
n = sighup_count;
}
static void
-_ecore_signal_callback_sigquit(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+_ecore_signal_callback_sigquit(int sig __UNUSED__,
+ siginfo_t *si,
+ void *foo __UNUSED__)
{
volatile sig_atomic_t n;
n = sigquit_count;
}
static void
-_ecore_signal_callback_sigint(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+_ecore_signal_callback_sigint(int sig __UNUSED__,
+ siginfo_t *si,
+ void *foo __UNUSED__)
{
volatile sig_atomic_t n;
n = sigint_count;
}
static void
-_ecore_signal_callback_sigterm(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+_ecore_signal_callback_sigterm(int sig __UNUSED__,
+ siginfo_t *si,
+ void *foo __UNUSED__)
{
volatile sig_atomic_t n;
n = sigterm_count;
#ifdef SIGPWR
static void
-_ecore_signal_callback_sigpwr(int sig __UNUSED__, siginfo_t *si, void *foo __UNUSED__)
+_ecore_signal_callback_sigpwr(int sig __UNUSED__,
+ siginfo_t *si,
+ void *foo __UNUSED__)
{
volatile sig_atomic_t n;
n = sigpwr_count;
sigpwr_count++;
sig_count++;
}
+
#endif
static Eina_Bool
}
return ECORE_CALLBACK_CANCEL;
}
+
# define PH(x) pthread_t x
# define PHE(x, y) pthread_equal(x, y)
# define PHS() pthread_self()
-# define PHC(x, f, d) pthread_create(&(x), NULL, (void*) f, d)
-# define PHJ(x, p) pthread_join(x, (void**)(&(p)))
+# define PHC(x, f, d) pthread_create(&(x), NULL, (void *)f, d)
+# define PHJ(x, p) pthread_join(x, (void **)(&(p)))
# define PHA(x) pthread_cancel(x)
-# define CD(x) pthread_cond_t x
-# define CDI(x) pthread_cond_init(&(x), NULL);
-# define CDD(x) pthread_cond_destroy(&(x));
-# define CDB(x) pthread_cond_broadcast(&(x));
+# define CD(x) pthread_cond_t x
+# define CDI(x) pthread_cond_init(&(x), NULL);
+# define CDD(x) pthread_cond_destroy(&(x));
+# define CDB(x) pthread_cond_broadcast(&(x));
# define CDW(x, y, t) pthread_cond_timedwait(&(x), &(y), t);
-# define LK(x) pthread_mutex_t x
-# define LKI(x) pthread_mutex_init(&(x), NULL);
-# define LKD(x) pthread_mutex_destroy(&(x));
-# define LKL(x) pthread_mutex_lock(&(x));
-# define LKU(x) pthread_mutex_unlock(&(x));
+# define LK(x) pthread_mutex_t x
+# define LKI(x) pthread_mutex_init(&(x), NULL);
+# define LKD(x) pthread_mutex_destroy(&(x));
+# define LKL(x) pthread_mutex_lock(&(x));
+# define LKU(x) pthread_mutex_unlock(&(x));
-# define LRWK(x) pthread_rwlock_t x
-# define LRWKI(x) pthread_rwlock_init(&(x), NULL);
-# define LRWKD(x) pthread_rwlock_destroy(&(x));
-# define LRWKWL(x) pthread_rwlock_wrlock(&(x));
-# define LRWKRL(x) pthread_rwlock_rdlock(&(x));
-# define LRWKU(x) pthread_rwlock_unlock(&(x));
+# define LRWK(x) pthread_rwlock_t x
+# define LRWKI(x) pthread_rwlock_init(&(x), NULL);
+# define LRWKD(x) pthread_rwlock_destroy(&(x));
+# define LRWKWL(x) pthread_rwlock_wrlock(&(x));
+# define LRWKRL(x) pthread_rwlock_rdlock(&(x));
+# define LRWKU(x) pthread_rwlock_unlock(&(x));
# else /* EFL_HAVE_WIN32_THREADS */
typedef struct
{
- HANDLE thread;
- void *val;
+ HANDLE thread;
+ void *val;
} win32_thread;
-# define PH(x) win32_thread *x
-# define PHE(x, y) ((x) == (y))
-# define PHS() (HANDLE)GetCurrentThreadId()
+# define PH(x) win32_thread * x
+# define PHE(x, y) ((x) == (y))
+# define PHS() (HANDLE)GetCurrentThreadId()
-int _ecore_thread_win32_create(win32_thread **x, LPTHREAD_START_ROUTINE f, void *d)
+int
+_ecore_thread_win32_create(win32_thread **x,
+ LPTHREAD_START_ROUTINE f,
+ void *d)
{
- win32_thread *t;
- t = (win32_thread *)calloc(1, sizeof(win32_thread));
- if (!t)
- return -1;
-
- (t)->thread = CreateThread(NULL, 0, f, d, 0, NULL);
- if (!t->thread)
- {
- free(t);
- return -1;
- }
- t->val = d;
- *x = t;
-
- return 0;
+ win32_thread *t;
+ t = (win32_thread *)calloc(1, sizeof(win32_thread));
+ if (!t)
+ return -1;
+
+ (t)->thread = CreateThread(NULL, 0, f, d, 0, NULL);
+ if (!t->thread)
+ {
+ free(t);
+ return -1;
+ }
+ t->val = d;
+ *x = t;
+
+ return 0;
}
+
# define PHC(x, f, d) _ecore_thread_win32_create(&(x), (LPTHREAD_START_ROUTINE)f, d)
-int _ecore_thread_win32_join(win32_thread *x, void **res)
+int
+_ecore_thread_win32_join(win32_thread *x,
+ void **res)
{
- if (!PHE(x, PHS()))
- {
- WaitForSingleObject(x->thread, INFINITE);
- CloseHandle(x->thread);
- }
- if (res) *res = x->val;
- free(x);
-
- return 0;
+ if (!PHE(x, PHS()))
+ {
+ WaitForSingleObject(x->thread, INFINITE);
+ CloseHandle(x->thread);
+ }
+ if (res) *res = x->val;
+ free(x);
+
+ return 0;
}
-# define PHJ(x, p) _ecore_thread_win32_join(x, (void**)(&(p)))
-# define PHA(x) TerminateThread(x->thread, 0)
+# define PHJ(x, p) _ecore_thread_win32_join(x, (void **)(&(p)))
+# define PHA(x) TerminateThread(x->thread, 0)
-# define LK(x) HANDLE x
-# define LKI(x) x = CreateMutex(NULL, FALSE, NULL)
-# define LKD(x) CloseHandle(x)
-# define LKL(x) WaitForSingleObject(x, INFINITE)
-# define LKU(x) ReleaseMutex(x)
+# define LK(x) HANDLE x
+# define LKI(x) x = CreateMutex(NULL, FALSE, NULL)
+# define LKD(x) CloseHandle(x)
+# define LKL(x) WaitForSingleObject(x, INFINITE)
+# define LKU(x) ReleaseMutex(x)
typedef struct
{
- HANDLE semaphore;
- LONG threads_count;
- CRITICAL_SECTION threads_count_lock;
+ HANDLE semaphore;
+ LONG threads_count;
+ CRITICAL_SECTION threads_count_lock;
} win32_cond;
-# define CD(x) win32_cond *x
-
-# define CDI(x) \
- do { \
- x = (win32_cond *)calloc(1, sizeof(win32_cond)); \
- if (x) \
- { \
- x->semaphore = CreateSemaphore(NULL, 0, 0x7fffffff, NULL); \
- if (x->semaphore) \
- InitializeCriticalSection(&x->threads_count_lock); \
- else \
- { \
- free(x); \
- x = NULL; \
- } \
- } \
- } while (0)
-
-# define CDD(x) \
- do { \
- CloseHandle(x->semaphore); \
- free(x); \
- x = NULL; \
- } while (0)
-
-# define CDB(x) \
-do { \
- EnterCriticalSection(&x->threads_count_lock); \
- if (x->threads_count > 0) \
- ReleaseSemaphore(x->semaphore, x->threads_count, NULL); \
- LeaveCriticalSection (&x->threads_count_lock); \
- } while (0)
-
-int _ecore_thread_win32_cond_timedwait(win32_cond *c, HANDLE *external_mutex, struct timeval *t)
+# define CD(x) win32_cond * x
+
+# define CDI(x) \
+ do { \
+ x = (win32_cond *)calloc(1, sizeof(win32_cond)); \
+ if (x) \
+ { \
+ x->semaphore = CreateSemaphore(NULL, 0, 0x7fffffff, NULL); \
+ if (x->semaphore) \
+ InitializeCriticalSection(&x->threads_count_lock); \
+ else \
+ { \
+ free(x); \
+ x = NULL; \
+ } \
+ } \
+ } while (0)
+
+# define CDD(x) \
+ do { \
+ CloseHandle(x->semaphore); \
+ free(x); \
+ x = NULL; \
+ } while (0)
+
+# define CDB(x) \
+ do { \
+ EnterCriticalSection(&x->threads_count_lock); \
+ if (x->threads_count > 0) \
+ ReleaseSemaphore(x->semaphore, x->threads_count, NULL); \
+ LeaveCriticalSection (&x->threads_count_lock); \
+ } while (0)
+
+int
+_ecore_thread_win32_cond_timedwait(win32_cond *c,
+ HANDLE *external_mutex,
+ struct timeval *t)
{
- DWORD res;
- DWORD val = t->tv_sec * 1000 + (t->tv_usec / 1000);
- LKL(external_mutex);
- EnterCriticalSection (&c->threads_count_lock);
- c->threads_count++;
- LeaveCriticalSection (&c->threads_count_lock);
- LKU(external_mutex);
- res = WaitForSingleObject(c->semaphore, val);
- if (res == WAIT_OBJECT_0)
- return 0;
- else
- return -1;
+ DWORD res;
+ DWORD val = t->tv_sec * 1000 + (t->tv_usec / 1000);
+ LKL(external_mutex);
+ EnterCriticalSection (&c->threads_count_lock);
+ c->threads_count++;
+ LeaveCriticalSection (&c->threads_count_lock);
+ LKU(external_mutex);
+ res = WaitForSingleObject(c->semaphore, val);
+ if (res == WAIT_OBJECT_0)
+ return 0;
+ else
+ return -1;
}
+
# define CDW(x, y, t) _ecore_thread_win32_cond_timedwait(x, y, t)
typedef struct
{
- LONG readers_count;
- LONG writers_count;
- int readers;
- int writers;
- LK(mutex);
- CD(cond_read);
- CD(cond_write);
+ LONG readers_count;
+ LONG writers_count;
+ int readers;
+ int writers;
+ LK(mutex);
+ CD(cond_read);
+ CD(cond_write);
} win32_rwl;
-# define LRWK(x) win32_rwl *x
-# define LRWKI(x) \
- do { \
- x = (win32_rwl *)calloc(1, sizeof(win32_rwl)); \
- if (x) \
- { \
- LKI(x->mutex); \
- if (x->mutex) \
- { \
- CDI(x->cond_read); \
- if (x->cond_read) \
- { \
- CDI(x->cond_write); \
- if (!x->cond_write) \
- { \
- CDD(x->cond_read); \
- LKD(x->mutex); \
- free(x); \
- x = NULL; \
- } \
- } \
- else \
- { \
- LKD(x->mutex); \
- free(x); \
- x = NULL; \
- } \
- } \
- else \
- { \
- free(x); \
- x = NULL; \
- } \
- } \
- } while (0)
-
-# define LRWKD(x) \
- do { \
- LKU(x->mutex); \
- LKD(x->mutex); \
- CDD(x->cond_write); \
- CDD(x->cond_read); \
- free(x); \
- } while (0)
-# define LRWKWL(x) \
- do { \
- DWORD res; \
- LKU(x->mutex); \
- if (x->writers || x->readers > 0) \
- { \
- x->writers_count++; \
- while (x->writers || x->readers > 0) \
- { \
- EnterCriticalSection(&x->cond_write->threads_count_lock); \
- x->cond_read->threads_count++; \
- LeaveCriticalSection(&x->cond_write->threads_count_lock); \
- res = WaitForSingleObject(x->cond_write->semaphore, INFINITE); \
- if (res != WAIT_OBJECT_0) break; \
- } \
- x->writers_count--; \
- } \
- if (res == 0) x->writers_count = 1; \
- LKU(x->mutex); \
- } while (0)
-# define LRWKRL(x) \
- do { \
- DWORD res; \
- LKL(x->mutex); \
- if (x->writers) \
- { \
- x->readers_count++; \
- while (x->writers) \
- { \
- EnterCriticalSection(&x->cond_write->threads_count_lock); \
- x->cond_read->threads_count++; \
- LeaveCriticalSection(&x->cond_write->threads_count_lock); \
- res = WaitForSingleObject(x->cond_write->semaphore, INFINITE); \
- if (res != WAIT_OBJECT_0) break; \
- } \
- x->readers_count--; \
- } \
- if (res == 0) \
- x->readers++; \
- LKU(x->mutex); \
- } while (0)
-# define LRWKU(x) \
- do { \
- LKL(x->mutex); \
- if (x->writers) \
- { \
- x->writers = 0; \
- if (x->readers_count == 1) \
- { \
- EnterCriticalSection(&x->cond_read->threads_count_lock); \
- if (x->cond_read->threads_count > 0) \
- ReleaseSemaphore(x->cond_read->semaphore, 1, 0); \
- LeaveCriticalSection(&x->cond_read->threads_count_lock); \
- } \
- else if (x->readers_count > 0) \
- CDB(x->cond_read); \
- else if (x->writers_count > 0) \
- { \
- EnterCriticalSection (&x->cond_write->threads_count_lock); \
- if (x->cond_write->threads_count > 0) \
- ReleaseSemaphore(x->cond_write->semaphore, 1, 0); \
- LeaveCriticalSection (&x->cond_write->threads_count_lock); \
- } \
- } \
- else if (x->readers > 0) \
- { \
- x->readers--; \
- if (x->readers == 0 && x->writers_count > 0) \
- { \
- EnterCriticalSection (&x->cond_write->threads_count_lock); \
- if (x->cond_write->threads_count > 0) \
- ReleaseSemaphore(x->cond_write->semaphore, 1, 0); \
- LeaveCriticalSection (&x->cond_write->threads_count_lock); \
- } \
- } \
- LKU(x->mutex); \
- } while (0)
+# define LRWK(x) win32_rwl * x
+# define LRWKI(x) \
+ do { \
+ x = (win32_rwl *)calloc(1, sizeof(win32_rwl)); \
+ if (x) \
+ { \
+ LKI(x->mutex); \
+ if (x->mutex) \
+ { \
+ CDI(x->cond_read); \
+ if (x->cond_read) \
+ { \
+ CDI(x->cond_write); \
+ if (!x->cond_write) \
+ { \
+ CDD(x->cond_read); \
+ LKD(x->mutex); \
+ free(x); \
+ x = NULL; \
+ } \
+ } \
+ else \
+ { \
+ LKD(x->mutex); \
+ free(x); \
+ x = NULL; \
+ } \
+ } \
+ else \
+ { \
+ free(x); \
+ x = NULL; \
+ } \
+ } \
+ } while (0)
+
+# define LRWKD(x) \
+ do { \
+ LKU(x->mutex); \
+ LKD(x->mutex); \
+ CDD(x->cond_write); \
+ CDD(x->cond_read); \
+ free(x); \
+ } while (0)
+# define LRWKWL(x) \
+ do { \
+ DWORD res; \
+ LKU(x->mutex); \
+ if (x->writers || x->readers > 0) \
+ { \
+ x->writers_count++; \
+ while (x->writers || x->readers > 0) \
+ { \
+ EnterCriticalSection(&x->cond_write->threads_count_lock); \
+ x->cond_read->threads_count++; \
+ LeaveCriticalSection(&x->cond_write->threads_count_lock); \
+ res = WaitForSingleObject(x->cond_write->semaphore, INFINITE); \
+ if (res != WAIT_OBJECT_0) break; \
+ } \
+ x->writers_count--; \
+ } \
+ if (res == 0) x->writers_count = 1; \
+ LKU(x->mutex); \
+ } while (0)
+# define LRWKRL(x) \
+ do { \
+ DWORD res; \
+ LKL(x->mutex); \
+ if (x->writers) \
+ { \
+ x->readers_count++; \
+ while (x->writers) \
+ { \
+ EnterCriticalSection(&x->cond_write->threads_count_lock); \
+ x->cond_read->threads_count++; \
+ LeaveCriticalSection(&x->cond_write->threads_count_lock); \
+ res = WaitForSingleObject(x->cond_write->semaphore, INFINITE); \
+ if (res != WAIT_OBJECT_0) break; \
+ } \
+ x->readers_count--; \
+ } \
+ if (res == 0) \
+ x->readers++; \
+ LKU(x->mutex); \
+ } while (0)
+# define LRWKU(x) \
+ do { \
+ LKL(x->mutex); \
+ if (x->writers) \
+ { \
+ x->writers = 0; \
+ if (x->readers_count == 1) \
+ { \
+ EnterCriticalSection(&x->cond_read->threads_count_lock); \
+ if (x->cond_read->threads_count > 0) \
+ ReleaseSemaphore(x->cond_read->semaphore, 1, 0); \
+ LeaveCriticalSection(&x->cond_read->threads_count_lock); \
+ } \
+ else if (x->readers_count > 0) \
+ CDB(x->cond_read); \
+ else if (x->writers_count > 0) \
+ { \
+ EnterCriticalSection (&x->cond_write->threads_count_lock); \
+ if (x->cond_write->threads_count > 0) \
+ ReleaseSemaphore(x->cond_write->semaphore, 1, 0); \
+ LeaveCriticalSection (&x->cond_write->threads_count_lock); \
+ } \
+ } \
+ else if (x->readers > 0) \
+ { \
+ x->readers--; \
+ if (x->readers == 0 && x->writers_count > 0) \
+ { \
+ EnterCriticalSection (&x->cond_write->threads_count_lock); \
+ if (x->cond_write->threads_count > 0) \
+ ReleaseSemaphore(x->cond_write->semaphore, 1, 0); \
+ LeaveCriticalSection (&x->cond_write->threads_count_lock); \
+ } \
+ } \
+ LKU(x->mutex); \
+ } while (0)
# endif
#endif
typedef struct _Ecore_Pthread_Worker Ecore_Pthread_Worker;
-typedef struct _Ecore_Pthread Ecore_Pthread;
-typedef struct _Ecore_Thread_Data Ecore_Thread_Data;
+typedef struct _Ecore_Pthread Ecore_Pthread;
+typedef struct _Ecore_Thread_Data Ecore_Thread_Data;
struct _Ecore_Thread_Data
{
- void *data;
+ void *data;
Eina_Free_Cb cb;
};
struct _Ecore_Pthread_Worker
{
union {
- struct {
+ struct
+ {
Ecore_Thread_Cb func_blocking;
} short_run;
- struct {
- Ecore_Thread_Cb func_heavy;
+ struct
+ {
+ Ecore_Thread_Cb func_heavy;
Ecore_Thread_Notify_Cb func_notify;
- Ecore_Pipe *notify;
+ Ecore_Pipe *notify;
- Ecore_Pipe *direct_pipe;
- Ecore_Pthread_Worker *direct_worker;
+ Ecore_Pipe *direct_pipe;
+ Ecore_Pthread_Worker *direct_worker;
- int send;
- int received;
+ int send;
+ int received;
} feedback_run;
} u;
Ecore_Thread_Cb func_cancel;
Ecore_Thread_Cb func_end;
#ifdef EFL_HAVE_THREADS
- PH(self);
- Eina_Hash *hash;
- CD(cond);
- LK(mutex);
+ PH(self);
+ Eina_Hash *hash;
+ CD(cond);
+ LK(mutex);
#endif
- const void *data;
+ const void *data;
- Eina_Bool cancel : 1;
- Eina_Bool feedback_run : 1;
- Eina_Bool kill : 1;
- Eina_Bool reschedule : 1;
- Eina_Bool no_queue : 1;
+ Eina_Bool cancel : 1;
+ Eina_Bool feedback_run : 1;
+ Eina_Bool kill : 1;
+ Eina_Bool reschedule : 1;
+ Eina_Bool no_queue : 1;
};
#ifdef EFL_HAVE_THREADS
struct _Ecore_Pthread_Data
{
Ecore_Pthread_Worker *death_job;
- Ecore_Pipe *p;
- void *data;
- PH(thread);
+ Ecore_Pipe *p;
+ void *data;
+ PH(thread);
};
#endif
-
static int _ecore_thread_count_max = 0;
static int ECORE_THREAD_PIPE_DEL = 0;
static Eina_Array *_ecore_thread_pipe = NULL;
#ifdef EFL_HAVE_THREADS
-static void _ecore_thread_handler(void *data __UNUSED__, void *buffer, unsigned int nbyte);
+static void _ecore_thread_handler(void *data __UNUSED__,
+ void *buffer,
+ unsigned int nbyte);
-static Ecore_Pipe*
+static Ecore_Pipe *
_ecore_thread_pipe_get(void)
{
if (eina_array_count_get(_ecore_thread_pipe) > 0)
static Eina_Trash *_ecore_thread_worker_trash = NULL;
static int _ecore_thread_worker_count = 0;
-static void *_ecore_thread_worker(Ecore_Pthread_Data *pth);
+static void *_ecore_thread_worker(Ecore_Pthread_Data *pth);
static Ecore_Pthread_Worker *_ecore_thread_worker_new(void);
-static PH(get_main_loop_thread)(void)
+static PH(get_main_loop_thread) (void)
{
- static PH(main_loop_thread);
- static pid_t main_loop_pid;
- pid_t pid = getpid();
-
- if (pid != main_loop_pid)
- {
- main_loop_pid = pid;
- main_loop_thread = PHS();
- have_main_loop_thread = 1;
- }
-
- return main_loop_thread;
+ static PH(main_loop_thread);
+ static pid_t main_loop_pid;
+ pid_t pid = getpid();
+
+ if (pid != main_loop_pid)
+ {
+ main_loop_pid = pid;
+ main_loop_thread = PHS();
+ have_main_loop_thread = 1;
+ }
+
+ return main_loop_thread;
}
static void
if (_ecore_thread_worker_count > (_ecore_thread_count_max + 1) * 16)
{
free(worker);
- return ;
+ return;
}
eina_trash_push(&_ecore_thread_worker_trash, worker);
}
static void
-_ecore_thread_pipe_free(void *data __UNUSED__, void *event)
+_ecore_thread_pipe_free(void *data __UNUSED__,
+ void *event)
{
Ecore_Pipe *p = event;
}
static Eina_Bool
-_ecore_thread_pipe_del(void *data __UNUSED__, int type __UNUSED__, void *event __UNUSED__)
+_ecore_thread_pipe_del(void *data __UNUSED__,
+ int type __UNUSED__,
+ void *event __UNUSED__)
{
/* This is a hack to delay pipe destruction until we are out of its internal loop. */
- return ECORE_CALLBACK_CANCEL;
+ return ECORE_CALLBACK_CANCEL;
}
static void
-_ecore_thread_end(Ecore_Pthread_Data *pth, Ecore_Thread *work)
+_ecore_thread_end(Ecore_Pthread_Data *pth,
+ Ecore_Thread *work)
{
- Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *) work;
+ Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)work;
Ecore_Pipe *p;
if (!worker->feedback_run || (worker->feedback_run && !worker->no_queue))
_ecore_thread_count--;
if (PHJ(pth->thread, p) != 0)
- return ;
+ return;
if (eina_list_count(_ecore_pending_job_threads) > 0
- && (unsigned int) _ecore_thread_count < eina_list_count(_ecore_pending_job_threads)
+ && (unsigned int)_ecore_thread_count < eina_list_count(_ecore_pending_job_threads)
&& _ecore_thread_count < _ecore_thread_count_max)
{
/* One more thread should be created. */
- INF("spawning threads because of still pending jobs.");
+ INF("spawning threads because of still pending jobs.");
- pth->death_job = _ecore_thread_worker_new();
- if (!pth->p || !pth->death_job) goto end;
+ pth->death_job = _ecore_thread_worker_new();
+ if (!pth->p || !pth->death_job) goto end;
- eina_threads_init();
+ eina_threads_init();
- if (PHC(pth->thread, _ecore_thread_worker, pth) == 0)
- {
- _ecore_thread_count++;
- return ;
- }
+ if (PHC(pth->thread, _ecore_thread_worker, pth) == 0)
+ {
+ _ecore_thread_count++;
+ return;
+ }
- eina_threads_shutdown();
+ eina_threads_shutdown();
- end:
- if (pth->death_job) _ecore_thread_worker_free(pth->death_job);
+end:
+ if (pth->death_job) _ecore_thread_worker_free(pth->death_job);
}
_ecore_active_job_threads = eina_list_remove(_ecore_active_job_threads, pth);
if (work->cancel)
{
if (work->func_cancel)
- work->func_cancel((void *) work->data, (Ecore_Thread *) work);
+ work->func_cancel((void *)work->data, (Ecore_Thread *)work);
}
else
{
if (work->func_end)
- work->func_end((void *) work->data, (Ecore_Thread *) work);
+ work->func_end((void *)work->data, (Ecore_Thread *)work);
}
if (work->feedback_run)
}
static void
-_ecore_thread_handler(void *data __UNUSED__, void *buffer, unsigned int nbyte)
+_ecore_thread_handler(void *data __UNUSED__,
+ void *buffer,
+ unsigned int nbyte)
{
Ecore_Pthread_Worker *work;
- if (nbyte != sizeof (Ecore_Pthread_Worker *)) return ;
+ if (nbyte != sizeof (Ecore_Pthread_Worker *)) return;
work = *(Ecore_Pthread_Worker **)buffer;
if (work->u.feedback_run.send != work->u.feedback_run.received)
{
work->kill = EINA_TRUE;
- return ;
+ return;
}
}
}
static void
-_ecore_notify_handler(void *data, void *buffer, unsigned int nbyte)
+_ecore_notify_handler(void *data,
+ void *buffer,
+ unsigned int nbyte)
{
Ecore_Pthread_Worker *work = data;
void *user_data;
- if (nbyte != sizeof (Ecore_Pthread_Worker *)) return ;
+ if (nbyte != sizeof (Ecore_Pthread_Worker *)) return;
user_data = *(void **)buffer;
work->u.feedback_run.received++;
if (work->u.feedback_run.func_notify)
- work->u.feedback_run.func_notify((void *) work->data, (Ecore_Thread *) work, user_data);
+ work->u.feedback_run.func_notify((void *)work->data, (Ecore_Thread *)work, user_data);
/* Force reading all notify event before killing the thread */
if (work->kill && work->u.feedback_run.send == work->u.feedback_run.received)
LKU(_ecore_pending_job_threads_mutex);
if (!work->cancel)
- work->u.short_run.func_blocking((void *) work->data, (Ecore_Thread*) work);
+ work->u.short_run.func_blocking((void *)work->data, (Ecore_Thread *)work);
if (work->reschedule)
{
}
static void
-_ecore_feedback_job(Ecore_Pipe *end_pipe, PH(thread))
+_ecore_feedback_job(Ecore_Pipe *end_pipe,
+ PH(thread))
{
Ecore_Pthread_Worker *work;
work->self = thread;
if (!work->cancel)
- work->u.feedback_run.func_heavy((void *) work->data, (Ecore_Thread *) work);
+ work->u.feedback_run.func_heavy((void *)work->data, (Ecore_Thread *)work);
if (work->reschedule)
{
pth->thread = PHS();
work->self = pth->thread;
- work->u.feedback_run.func_heavy((void *) work->data, (Ecore_Thread *) work);
+ work->u.feedback_run.func_heavy((void *)work->data, (Ecore_Thread *)work);
ecore_pipe_write(pth->p, &work, sizeof (Ecore_Pthread_Worker *));
work->data = pth;
work->u.short_run.func_blocking = NULL;
- work->func_end = (void *) _ecore_thread_end;
+ work->func_end = (void *)_ecore_thread_end;
work->func_cancel = NULL;
work->cancel = EINA_FALSE;
work->feedback_run = EINA_FALSE;
eina_sched_prio_drop();
- restart:
+restart:
if (_ecore_pending_job_threads) _ecore_short_job(pth->p);
if (_ecore_pending_job_threads_feedback) _ecore_feedback_job(pth->p, pth->thread);
work->data = pth;
work->u.short_run.func_blocking = NULL;
- work->func_end = (void *) _ecore_thread_end;
+ work->func_end = (void *)_ecore_thread_end;
work->func_cancel = NULL;
work->cancel = EINA_FALSE;
work->feedback_run = EINA_FALSE;
_ecore_thread_shutdown(void)
{
/* FIXME: If function are still running in the background, should we kill them ? */
- Ecore_Pipe *p;
- Eina_Array_Iterator it;
- unsigned int i;
+ Ecore_Pipe *p;
+ Eina_Array_Iterator it;
+ unsigned int i;
#ifdef EFL_HAVE_THREADS
- Ecore_Pthread_Worker *work;
- Ecore_Pthread_Data *pth;
-
- LKL(_ecore_pending_job_threads_mutex);
-
- EINA_LIST_FREE(_ecore_pending_job_threads, work)
- {
- if (work->func_cancel)
- work->func_cancel((void *)work->data, (Ecore_Thread *) work);
- free(work);
- }
-
- EINA_LIST_FREE(_ecore_pending_job_threads_feedback, work)
- {
- if (work->func_cancel)
- work->func_cancel((void *)work->data, (Ecore_Thread *) work);
- free(work);
- }
-
- LKU(_ecore_pending_job_threads_mutex);
-
- /* Improve emergency shutdown */
- EINA_LIST_FREE(_ecore_active_job_threads, pth)
- {
- Ecore_Pipe *ep;
-
- PHA(pth->thread);
- PHJ(pth->thread, ep);
-
- ecore_pipe_del(pth->p);
- }
- if (_ecore_thread_global_hash)
- eina_hash_free(_ecore_thread_global_hash);
- _ecore_event_handler_del(del_handler);
- have_main_loop_thread = 0;
- del_handler = NULL;
-
- LKD(_ecore_pending_job_threads_mutex);
- LRWKD(_ecore_thread_global_hash_lock);
- LKD(_ecore_thread_global_hash_mutex);
- CDD(_ecore_thread_global_hash_cond);
+ Ecore_Pthread_Worker *work;
+ Ecore_Pthread_Data *pth;
+
+ LKL(_ecore_pending_job_threads_mutex);
+
+ EINA_LIST_FREE(_ecore_pending_job_threads, work)
+ {
+ if (work->func_cancel)
+ work->func_cancel((void *)work->data, (Ecore_Thread *)work);
+ free(work);
+ }
+
+ EINA_LIST_FREE(_ecore_pending_job_threads_feedback, work)
+ {
+ if (work->func_cancel)
+ work->func_cancel((void *)work->data, (Ecore_Thread *)work);
+ free(work);
+ }
+
+ LKU(_ecore_pending_job_threads_mutex);
+
+ /* Improve emergency shutdown */
+ EINA_LIST_FREE(_ecore_active_job_threads, pth)
+ {
+ Ecore_Pipe *ep;
+
+ PHA(pth->thread);
+ PHJ(pth->thread, ep);
+
+ ecore_pipe_del(pth->p);
+ }
+ if (_ecore_thread_global_hash)
+ eina_hash_free(_ecore_thread_global_hash);
+ _ecore_event_handler_del(del_handler);
+ have_main_loop_thread = 0;
+ del_handler = NULL;
+
+ LKD(_ecore_pending_job_threads_mutex);
+ LRWKD(_ecore_thread_global_hash_lock);
+ LKD(_ecore_thread_global_hash_mutex);
+ CDD(_ecore_thread_global_hash_cond);
#endif
- EINA_ARRAY_ITER_NEXT(_ecore_thread_pipe, i, p, it)
- ecore_pipe_del(p);
+ EINA_ARRAY_ITER_NEXT(_ecore_thread_pipe, i, p, it)
+ ecore_pipe_del(p);
- eina_array_free(_ecore_thread_pipe);
- _ecore_thread_pipe = NULL;
+ eina_array_free(_ecore_thread_pipe);
+ _ecore_thread_pipe = NULL;
}
void
ecore_thread_run(Ecore_Thread_Cb func_blocking,
Ecore_Thread_Cb func_end,
Ecore_Thread_Cb func_cancel,
- const void *data)
+ const void *data)
{
Ecore_Pthread_Worker *work;
#ifdef EFL_HAVE_THREADS
if (!work)
{
if (func_cancel)
- func_cancel((void *) data, NULL);
+ func_cancel((void *)data, NULL);
return NULL;
}
if (_ecore_thread_count == _ecore_thread_count_max)
{
LKU(_ecore_pending_job_threads_mutex);
- return (Ecore_Thread *) work;
+ return (Ecore_Thread *)work;
}
LKU(_ecore_pending_job_threads_mutex);
if (PHC(pth->thread, _ecore_thread_worker, pth) == 0)
{
_ecore_thread_count++;
- return (Ecore_Thread *) work;
+ return (Ecore_Thread *)work;
}
eina_threads_shutdown();
- on_error:
+on_error:
if (pth)
{
if (pth->p) eina_array_push(_ecore_thread_pipe, pth->p);
LKU(_ecore_pending_job_threads_mutex);
if (work->func_cancel)
- work->func_cancel((void *) work->data, (Ecore_Thread *) work);
+ work->func_cancel((void *)work->data, (Ecore_Thread *)work);
free(work);
work = NULL;
}
- return (Ecore_Thread *) work;
+ return (Ecore_Thread *)work;
#else
/*
- If no thread and as we don't want to break app that rely on this
- facility, we will lock the interface until we are done.
+ If no thread and as we don't want to break app that rely on this
+ facility, we will lock the interface until we are done.
*/
do {
- /* Handle reschedule by forcing it here. That would mean locking the app,
- * would be better with an idler, but really to complex for a case where
- * thread should really exist.
- */
- work->reschedule = EINA_FALSE;
-
- func_blocking((void *)data, (Ecore_Thread *) work);
- if (work->cancel == EINA_FALSE) func_end((void *)data, (Ecore_Thread *) work);
- else func_cancel((void *)data, (Ecore_Thread *) work);
+ /* Handle reschedule by forcing it here. That would mean locking the app,
+ * would be better with an idler, but really to complex for a case where
+ * thread should really exist.
+ */
+ work->reschedule = EINA_FALSE;
- } while (work->reschedule == EINA_TRUE);
+ func_blocking((void *)data, (Ecore_Thread *)work);
+ if (work->cancel == EINA_FALSE) func_end((void *)data, (Ecore_Thread *)work);
+ else func_cancel((void *)data, (Ecore_Thread *)work);
+ } while (work->reschedule == EINA_TRUE);
free(work);
if (!work->feedback_run)
EINA_LIST_FOREACH(_ecore_pending_job_threads, l, work)
{
- if ((void *) work == (void *) thread)
+ if ((void *)work == (void *)thread)
{
_ecore_pending_job_threads = eina_list_remove_list(_ecore_pending_job_threads, l);
LKU(_ecore_pending_job_threads_mutex);
if (work->func_cancel)
- work->func_cancel((void *) work->data, (Ecore_Thread *) work);
+ work->func_cancel((void *)work->data, (Ecore_Thread *)work);
free(work);
return EINA_TRUE;
else
EINA_LIST_FOREACH(_ecore_pending_job_threads_feedback, l, work)
{
- if ((void *) work == (void *) thread)
+ if ((void *)work == (void *)thread)
{
_ecore_pending_job_threads_feedback = eina_list_remove_list(_ecore_pending_job_threads_feedback, l);
LKU(_ecore_pending_job_threads_mutex);
if (work->func_cancel)
- work->func_cancel((void *) work->data, (Ecore_Thread *) work);
+ work->func_cancel((void *)work->data, (Ecore_Thread *)work);
free(work);
return EINA_TRUE;
LKU(_ecore_pending_job_threads_mutex);
/* Delay the destruction */
- on_exit:
+on_exit:
((Ecore_Pthread_Worker *)thread)->cancel = EINA_TRUE;
return EINA_FALSE;
#else
EAPI Eina_Bool
ecore_thread_check(Ecore_Thread *thread)
{
- Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *) thread;
+ Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)thread;
if (!worker) return EINA_TRUE;
return worker->cancel;
}
-EAPI Ecore_Thread *ecore_thread_feedback_run(Ecore_Thread_Cb func_heavy,
- Ecore_Thread_Notify_Cb func_notify,
- Ecore_Thread_Cb func_end,
- Ecore_Thread_Cb func_cancel,
- const void *data,
- Eina_Bool try_no_queue)
+EAPI Ecore_Thread *
+ecore_thread_feedback_run(Ecore_Thread_Cb func_heavy,
+ Ecore_Thread_Notify_Cb func_notify,
+ Ecore_Thread_Cb func_end,
+ Ecore_Thread_Cb func_cancel,
+ const void *data,
+ Eina_Bool try_no_queue)
{
-
#ifdef EFL_HAVE_THREADS
Ecore_Pthread_Worker *worker;
Ecore_Pthread_Data *pth = NULL;
worker->u.feedback_run.direct_worker = _ecore_thread_worker_new();
worker->no_queue = EINA_TRUE;
- eina_threads_init();
+ eina_threads_init();
if (PHC(t, _ecore_direct_worker, worker) == 0)
- return (Ecore_Thread *) worker;
+ return (Ecore_Thread *)worker;
- eina_threads_shutdown();
+ eina_threads_shutdown();
}
worker->no_queue = EINA_FALSE;
if (_ecore_thread_count == _ecore_thread_count_max)
{
LKU(_ecore_pending_job_threads_mutex);
- return (Ecore_Thread *) worker;
+ return (Ecore_Thread *)worker;
}
LKU(_ecore_pending_job_threads_mutex);
if (PHC(pth->thread, _ecore_thread_worker, pth) == 0)
{
_ecore_thread_count++;
- return (Ecore_Thread *) worker;
+ return (Ecore_Thread *)worker;
}
eina_threads_shutdown();
- on_error:
+on_error:
if (pth)
{
if (pth->p) eina_array_push(_ecore_thread_pipe, pth->p);
worker);
LKU(_ecore_pending_job_threads_mutex);
- if (func_cancel) func_cancel((void *) data, NULL);
+ if (func_cancel) func_cancel((void *)data, NULL);
if (worker)
{
}
}
- return (Ecore_Thread *) worker;
+ return (Ecore_Thread *)worker;
#else
Ecore_Pthread_Worker worker;
- (void) try_no_queue;
+ (void)try_no_queue;
/*
- If no thread and as we don't want to break app that rely on this
- facility, we will lock the interface until we are done.
+ If no thread and as we don't want to break app that rely on this
+ facility, we will lock the interface until we are done.
*/
worker.u.feedback_run.func_heavy = func_heavy;
worker.u.feedback_run.func_notify = func_notify;
worker.kill = EINA_FALSE;
do {
- worker.reschedule = EINA_FALSE;
+ worker.reschedule = EINA_FALSE;
- func_heavy((void *)data, (Ecore_Thread *) &worker);
+ func_heavy((void *)data, (Ecore_Thread *)&worker);
- if (worker.cancel) func_cancel((void *)data, (Ecore_Thread *) &worker);
- else func_end((void *)data, (Ecore_Thread *) &worker);
- } while (worker.reschedule == EINA_TRUE);
+ if (worker.cancel) func_cancel((void *)data, (Ecore_Thread *)&worker);
+ else func_end((void *)data, (Ecore_Thread *)&worker);
+ } while (worker.reschedule == EINA_TRUE);
return NULL;
#endif
}
EAPI Eina_Bool
-ecore_thread_feedback(Ecore_Thread *thread, const void *data)
+ecore_thread_feedback(Ecore_Thread *thread,
+ const void *data)
{
- Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *) thread;
+ Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)thread;
if (!worker) return EINA_FALSE;
if (!worker->feedback_run) return EINA_FALSE;
return EINA_TRUE;
#else
- worker->u.feedback_run.func_notify((void*) worker->data, thread, (void*) data);
+ worker->u.feedback_run.func_notify((void *)worker->data, thread, (void *)data);
return EINA_TRUE;
#endif
EAPI Eina_Bool
ecore_thread_reschedule(Ecore_Thread *thread)
{
- Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *) thread;
+ Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)thread;
if (!worker) return EINA_FALSE;
}
EAPI Eina_Bool
-ecore_thread_local_data_add(Ecore_Thread *thread, const char *key, void *value, Eina_Free_Cb cb, Eina_Bool direct)
+ecore_thread_local_data_add(Ecore_Thread *thread,
+ const char *key,
+ void *value,
+ Eina_Free_Cb cb,
+ Eina_Bool direct)
{
- Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *) thread;
+ Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)thread;
Ecore_Thread_Data *d;
Eina_Bool ret;
}
EAPI void *
-ecore_thread_local_data_set(Ecore_Thread *thread, const char *key, void *value, Eina_Free_Cb cb)
+ecore_thread_local_data_set(Ecore_Thread *thread,
+ const char *key,
+ void *value,
+ Eina_Free_Cb cb)
{
- Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *) thread;
+ Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)thread;
Ecore_Thread_Data *d, *r;
void *ret;
if ((!thread) || (!key) || (!value))
#endif
}
-
EAPI void *
-ecore_thread_local_data_find(Ecore_Thread *thread, const char *key)
+ecore_thread_local_data_find(Ecore_Thread *thread,
+ const char *key)
{
- Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *) thread;
+ Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)thread;
Ecore_Thread_Data *d;
if ((!thread) || (!key))
}
EAPI Eina_Bool
-ecore_thread_local_data_del(Ecore_Thread *thread, const char *key)
+ecore_thread_local_data_del(Ecore_Thread *thread,
+ const char *key)
{
- Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *) thread;
+ Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *)thread;
if ((!thread) || (!key))
return EINA_FALSE;
#ifdef EFL_HAVE_THREADS
}
EAPI Eina_Bool
-ecore_thread_global_data_add(const char *key, void *value, Eina_Free_Cb cb, Eina_Bool direct)
+ecore_thread_global_data_add(const char *key,
+ void *value,
+ Eina_Free_Cb cb,
+ Eina_Bool direct)
{
Eina_Bool ret;
Ecore_Thread_Data *d;
}
EAPI void *
-ecore_thread_global_data_set(const char *key, void *value, Eina_Free_Cb cb)
+ecore_thread_global_data_set(const char *key,
+ void *value,
+ Eina_Free_Cb cb)
{
Ecore_Thread_Data *d, *r;
void *ret;
#endif
}
-
EAPI void *
ecore_thread_global_data_find(const char *key)
{
}
EAPI void *
-ecore_thread_global_data_wait(const char *key, double seconds)
+ecore_thread_global_data_wait(const char *key,
+ double seconds)
{
double tm = 0;
Ecore_Thread_Data *ret = NULL;
return NULL;
#endif
}
+
/**
* Increase throttle amount
- *
+ *
* This will increase or decrease (if @p amount is positive or negative) the
* amount of "voluntary throttling" ecore will do to its main loop while
* running. This is intended to be used to limit animations and wakeups when
* (which can be retrieved by ecore_throttle_get() ), the more throttling
* takes place. If the current throttle value is 0, then no throttling takes
* place at all.
- *
+ *
* The value represents how long the ecore main loop will sleep (in seconds)
* before it goes into a fully idle state waiting for events, input or
* timing events to wake it up. For example, if the current throttle level
* of time. Of course these events, data and timeouts will be buffered,
* thus not losing anything, simply delaying when they get handled by the
* throttle value.
- *
+ *
* Example:
* @code
* void enter_powersave(void) {
* ecore_throttle_adjust(0.2);
* printf("Now at throttle level: %1.3f\n", ecore_throttle_get());
* }
- *
+ *
* void enter_deep_powersave(void) {
* ecore_throttle_adjust(0.5);
* printf("Now at throttle level: %1.3f\n", ecore_throttle_get());
* }
- *
+ *
* void exit_powersave(void) {
* ecore_throttle_adjust(-0.2);
* printf("Now at throttle level: %1.3f\n", ecore_throttle_get());
* }
- *
+ *
* void exit_deep_powersave(void) {
* ecore_throttle_adjust(-0.5);
* printf("Now at throttle level: %1.3f\n", ecore_throttle_get());
* }
* @endcode
- *
+ *
* @param amount Amount (in seconds) to adjust by
*/
EAPI void
/**
* Get current throttle level
- *
- * This gets the current throttling level, which can be adjusted by
+ *
+ * This gets the current throttling level, which can be adjusted by
* ecore_throttle_adjust(). The value is in seconds. Please see
* ecore_throttle_adjust() for more information.
- *
+ *
* @return The current throttle level
*/
EAPI double
if (throttle_val <= 0) return;
usleep(throttle_val);
}
+
struct timespec t;
if (EINA_UNLIKELY(_ecore_time_clock_id < 0))
- return ecore_time_unix_get();
+ return ecore_time_unix_get();
if (EINA_UNLIKELY(clock_gettime(_ecore_time_clock_id, &t)))
{
#elif defined(HAVE_EVIL)
return evil_time_get();
#elif defined(__APPLE__) && defined(__MACH__)
- return _ecore_time_clock_conversion * (double) mach_absolute_time();
+ return _ecore_time_clock_conversion * (double)mach_absolute_time();
#else
return ecore_time_unix_get();
#endif
* @}
*/
-
/********************** Internal methods ********************************/
/* TODO: Documentation says "All implementations support the system-wide
else if (!clock_gettime(CLOCK_REALTIME, &t))
{
/* may go backwards */
- _ecore_time_clock_id = CLOCK_REALTIME;
- WRN("CLOCK_MONOTONIC not available. Fallback to CLOCK_REALTIME.");
+ _ecore_time_clock_id = CLOCK_REALTIME;
+ WRN("CLOCK_MONOTONIC not available. Fallback to CLOCK_REALTIME.");
}
else
{
kern_return_t err = mach_timebase_info(&info);
if (err == 0)
{
- _ecore_time_clock_conversion = 1e-9 * (double) info.numer / (double) info.denom;
+ _ecore_time_clock_conversion = 1e-9 * (double)info.numer / (double)info.denom;
}
else
{
_ecore_time_loop_time = ecore_time_get();
}
+
# include <string.h>
# include <execinfo.h>
# define ECORE_TIMER_DEBUG_BT_NUM 64
- typedef void (*Ecore_Timer_Bt_Func) ();
+typedef void (*Ecore_Timer_Bt_Func)();
#endif
struct _Ecore_Timer
{
EINA_INLIST;
- ECORE_MAGIC;
- double in;
- double at;
- double pending;
- Ecore_Task_Cb func;
- void *data;
+ ECORE_MAGIC;
+ double in;
+ double at;
+ double pending;
+ Ecore_Task_Cb func;
+ void *data;
#ifdef WANT_ECORE_TIMER_DUMP
Ecore_Timer_Bt_Func timer_bt[ECORE_TIMER_DEBUG_BT_NUM];
int timer_bt_num;
#endif
- int references;
- unsigned char delete_me : 1;
- unsigned char just_added : 1;
- unsigned char frozen : 1;
+ int references;
+ unsigned char delete_me : 1;
+ unsigned char just_added : 1;
+ unsigned char frozen : 1;
};
+static void _ecore_timer_set(Ecore_Timer *timer,
+ double at,
+ double in,
+ Ecore_Task_Cb func,
+ void *data);
+static int _ecore_timer_cmp(const void *d1,
+ const void *d2);
-static void _ecore_timer_set(Ecore_Timer *timer, double at, double in, Ecore_Task_Cb func, void *data);
-static int _ecore_timer_cmp(const void *d1, const void *d2);
-
-static int timers_added = 0;
-static int timers_delete_me = 0;
+static int timers_added = 0;
+static int timers_delete_me = 0;
static Ecore_Timer *timers = NULL;
static Ecore_Timer *timer_current = NULL;
static Ecore_Timer *suspended = NULL;
-static double last_check = 0.0;
-static double precision = 10.0 / 1000000.0;
-
+static double last_check = 0.0;
+static double precision = 10.0 / 1000000.0;
/**
* @addtogroup Ecore_Time_Group
* invalid.
*/
EAPI Ecore_Timer *
-ecore_timer_add(double in, Ecore_Task_Cb func, const void *data)
+ecore_timer_add(double in,
+ Ecore_Task_Cb func,
+ const void *data)
{
double now;
Ecore_Timer *timer = NULL;
now = ecore_time_get();
#ifdef WANT_ECORE_TIMER_DUMP
- timer->timer_bt_num = backtrace((void**) (timer->timer_bt),
+ timer->timer_bt_num = backtrace((void **)(timer->timer_bt),
ECORE_TIMER_DEBUG_BT_NUM);
#endif
* ecore_timer_add() for more details.
*/
EAPI Ecore_Timer *
-ecore_timer_loop_add(double in, Ecore_Task_Cb func, const void *data)
+ecore_timer_loop_add(double in,
+ Ecore_Task_Cb func,
+ const void *data)
{
Ecore_Timer *timer;
* @param in The interval in seconds.
*/
EAPI void
-ecore_timer_interval_set(Ecore_Timer *timer, double in)
+ecore_timer_interval_set(Ecore_Timer *timer,
+ double in)
{
_ecore_lock();
* @param add The dalay to add to the next iteration.
*/
EAPI void
-ecore_timer_delay(Ecore_Timer *timer, double add)
+ecore_timer_delay(Ecore_Timer *timer,
+ double add)
{
if (!ECORE_MAGIC_CHECK(timer, ECORE_MAGIC_TIMER))
{
EAPI double
ecore_timer_pending_get(Ecore_Timer *timer)
{
- double now;
- double ret = 0.0;
+ double now;
+ double ret = 0.0;
_ecore_lock();
if (timer->frozen)
goto unlock;
- timers = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
- suspended = (Ecore_Timer *) eina_inlist_prepend(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer));
+ timers = (Ecore_Timer *)eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
+ suspended = (Ecore_Timer *)eina_inlist_prepend(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer));
now = ecore_time_get();
if (!timer->frozen)
goto unlock;
- suspended = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer));
+ suspended = (Ecore_Timer *)eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer));
now = ecore_time_get();
_ecore_timer_set(timer, timer->pending + now, timer->in, timer->func, timer->data);
char **strings;
int j;
- if (!tm->frozen && !tm->delete_me)
- living_timer++;
+ if (!tm->frozen && !tm->delete_me)
+ living_timer++;
- strings = backtrace_symbols((void**) tm->timer_bt, tm->timer_bt_num);
+ strings = backtrace_symbols((void **)tm->timer_bt, tm->timer_bt_num);
if (tm->timer_bt_num <= 0 || strings == NULL)
- {
- unknow_timer++;
- continue ;
- }
+ {
+ unknow_timer++;
+ continue;
+ }
eina_strbuf_append_printf(result, "*** timer: %f ***\n", tm->in);
if (tm->frozen)
*/
Ecore_Timer *
-_ecore_timer_loop_add(double in, Ecore_Task_Cb func, const void *data)
+_ecore_timer_loop_add(double in,
+ Ecore_Task_Cb func,
+ const void *data)
{
double now;
Ecore_Timer *timer = NULL;
now = ecore_loop_time_get();
#ifdef WANT_ECORE_TIMER_DUMP
- timer->timer_bt_num = backtrace((void**) (timer->timer_bt),
+ timer->timer_bt_num = backtrace((void **)(timer->timer_bt),
ECORE_TIMER_DEBUG_BT_NUM);
#endif
_ecore_timer_set(timer, now + in, in, func, (void *)data);
}
EAPI void
-_ecore_timer_delay(Ecore_Timer *timer, double add)
+_ecore_timer_delay(Ecore_Timer *timer,
+ double add)
{
if (timer->frozen)
{
}
else
{
- timers = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
+ timers = (Ecore_Timer *)eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
_ecore_timer_set(timer, timer->at + add, timer->in, timer->func, timer->data);
}
}
-
void *
_ecore_timer_del(Ecore_Timer *timer)
{
{
void *data = timer->data;
- suspended = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer));
+ suspended = (Ecore_Timer *)eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer));
if (timer->delete_me)
timers_delete_me--;
while ((timer = timers))
{
- timers = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timers));
+ timers = (Ecore_Timer *)eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timers));
ECORE_MAGIC_SET(timer, ECORE_MAGIC_NONE);
free(timer);
}
while ((timer = suspended))
{
- suspended = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(suspended));
+ suspended = (Ecore_Timer *)eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(suspended));
ECORE_MAGIC_SET(timer, ECORE_MAGIC_NONE);
free(timer);
}
int in_use = 0, todo = timers_delete_me, done = 0;
if (!timers_delete_me) return;
- for (l = timers; l;)
+ for (l = timers; l; )
{
Ecore_Timer *timer = l;
- l = (Ecore_Timer *) EINA_INLIST_GET(l)->next;
+ l = (Ecore_Timer *)EINA_INLIST_GET(l)->next;
if (timer->delete_me)
{
if (timer->references)
in_use++;
continue;
}
- timers = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
+ timers = (Ecore_Timer *)eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
ECORE_MAGIC_SET(timer, ECORE_MAGIC_NONE);
free(timer);
timers_delete_me--;
if (timers_delete_me == 0) return;
}
}
- for (l = suspended; l;)
+ for (l = suspended; l; )
{
Ecore_Timer *timer = l;
- l = (Ecore_Timer *) EINA_INLIST_GET(l)->next;
+ l = (Ecore_Timer *)EINA_INLIST_GET(l)->next;
if (timer->delete_me)
{
if (timer->references)
in_use++;
continue;
}
- suspended = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer));
+ suspended = (Ecore_Timer *)eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer));
ECORE_MAGIC_SET(timer, ECORE_MAGIC_NONE);
free(timer);
timers_delete_me--;
Ecore_Timer *timer = timers;
while ((timer) && ((timer->delete_me) || (timer->just_added)))
- timer = (Ecore_Timer *) EINA_INLIST_GET(timer)->next;
+ timer = (Ecore_Timer *)EINA_INLIST_GET(timer)->next;
return timer;
}
static inline Ecore_Timer *
_ecore_timer_after_get(Ecore_Timer *base)
{
- Ecore_Timer *timer = (Ecore_Timer *) EINA_INLIST_GET(base)->next;
+ Ecore_Timer *timer = (Ecore_Timer *)EINA_INLIST_GET(base)->next;
Ecore_Timer *valid_timer = NULL;
double maxtime = base->at + precision;
while ((timer) && (timer->at < maxtime))
{
if (!((timer->delete_me) || (timer->just_added)))
- valid_timer = timer;
- timer = (Ecore_Timer *) EINA_INLIST_GET(timer)->next;
+ valid_timer = timer;
+ timer = (Ecore_Timer *)EINA_INLIST_GET(timer)->next;
}
return valid_timer;
}
static inline void
-_ecore_timer_reschedule(Ecore_Timer *timer, double when)
+_ecore_timer_reschedule(Ecore_Timer *timer,
+ double when)
{
if ((timer->delete_me) || (timer->frozen)) return;
- timers = (Ecore_Timer *) eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
+ timers = (Ecore_Timer *)eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
/* if the timer would have gone off more than 15 seconds ago,
* assume that the system hung and set the timer to go off
_ecore_timer_expired_timers_call(double when)
{
/* call the first expired timer until no expired timers exist */
- while (_ecore_timer_expired_call(when));
+ while (_ecore_timer_expired_call(when)) ;
}
/* assume that we hold the ecore lock when entering this function */
if (!timer_current)
{
/* regular main loop, start from head */
- timer_current = timers;
+ timer_current = timers;
}
else
{
/* recursive main loop, continue from where we were */
- Ecore_Timer *timer_old = timer_current;
- timer_current = (Ecore_Timer *)EINA_INLIST_GET(timer_current)->next;
- _ecore_timer_reschedule(timer_old, when);
+ Ecore_Timer *timer_old = timer_current;
+ timer_current = (Ecore_Timer *)EINA_INLIST_GET(timer_current)->next;
+ _ecore_timer_reschedule(timer_old, when);
}
while (timer_current)
if ((timer->just_added) || (timer->delete_me))
{
- timer_current = (Ecore_Timer*)EINA_INLIST_GET(timer_current)->next;
+ timer_current = (Ecore_Timer *)EINA_INLIST_GET(timer_current)->next;
continue;
}
}
static void
-_ecore_timer_set(Ecore_Timer *timer, double at, double in, Ecore_Task_Cb func, void *data)
+_ecore_timer_set(Ecore_Timer *timer,
+ double at,
+ double in,
+ Ecore_Task_Cb func,
+ void *data)
{
Ecore_Timer *t2;
{
if (timer->at > t2->at)
{
- timers = (Ecore_Timer *) eina_inlist_append_relative(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer), EINA_INLIST_GET(t2));
+ timers = (Ecore_Timer *)eina_inlist_append_relative(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer), EINA_INLIST_GET(t2));
return;
}
}
}
- timers = (Ecore_Timer *) eina_inlist_prepend(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
+ timers = (Ecore_Timer *)eina_inlist_prepend(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
}
static int
-_ecore_timer_cmp(const void *d1, const void *d2)
+_ecore_timer_cmp(const void *d1,
+ const void *d2)
{
const Ecore_Timer *t1 = d1;
const Ecore_Timer *t2 = d2;
- return (int) ((t1->in - t2->in) * 100);
+ return (int)((t1->in - t2->in) * 100);
}
+