EFL Threading example 5

This is the same as EFL Threading example 4 but now uses the ecore_thread infrastructure to have a running worker thread that feeds results back to the mainloop and can easily be cancelled.

This saves some code in the application and makes for fewer problem spots if you forget a mutex.

EFL Threading example 6

//Compile with:
//gcc -o efl_thread_5 efl_thread_5.c -g `pkg-config --cflags --libs elementary`
#include <Elementary.h>
static Ecore_Thread *thr = NULL;
static Evas_Object *win = NULL;
static Evas_Object *rect = NULL;
struct info
{
double x, y;
};
// BEGIN - code running in my custom thread instance
//
static void
th_do(void *data EINA_UNUSED, Ecore_Thread *th)
{
double t = 0.0;
// inside our "do" function for the ecore thread, lets do the real work
for (;;)
{
struct info *inf = malloc(sizeof(struct info));
if (inf)
{
inf->x = 200 + (200 * sin(t));
inf->y = 200 + (200 * cos(t));
// now we have recorded the timepoint we pass it as feedback
// back to the mainloop. it will free it when done
ecore_thread_feedback(th, inf);
}
// and sleep and loop
usleep(1000);
t += 0.02;
// in case someone has asked us to cancel - then cancel this loop
// co-operatively (cancelling is co-operative)
if (ecore_thread_check(th)) break;
}
}
//
// END - code running in my custom thread instance
static void // when mainloop gets feedback from worker
th_feedback(void *data EINA_UNUSED, Ecore_Thread *th EINA_UNUSED, void *msg)
{
struct info *inf = msg;
evas_object_move(rect, inf->x - 50, inf->y - 50);
free(inf);
}
// BONUS (optional): called after th_do returns and has NOT been cancelled
static void th_end(void *data EINA_UNUSED, Ecore_Thread *th EINA_UNUSED) { printf("thread ended\n"); }
// BONUS (optional): called in mainloop AFTER thread has finished cancelling
static void th_cancel(void *data EINA_UNUSED, Ecore_Thread *th EINA_UNUSED) { printf("thread cancelled\n"); }
// just test cancelling the thread worker
static void
down(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
if (thr) ecore_thread_cancel(thr);
thr = NULL;
}
// on window delete - cancel thread then delete window and exit mainloop
static void
del(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
{
if (thr) ecore_thread_cancel(thr);
thr = NULL;
evas_object_del(obj);
elm_exit();
}
EAPI_MAIN int
elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
{
Evas_Object *o;
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
win = elm_win_util_standard_add("efl-thread-5", "EFL Thread 5");
evas_object_smart_callback_add(win, "delete,request", del, NULL);
o = evas_object_rectangle_add(evas_object_evas_get(win));
evas_object_color_set(o, 50, 80, 180, 255);
evas_object_resize(o, 100, 100);
evas_object_show(o);
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, down, NULL);
rect = o;
// explicitly create ecore thread to do some "work on the side" and pass
// in NULL as data ptr to callbacks and true at the end means to actually
// make a new thread and not use the thread pool (there is a thread pool
// with as many thread workers as there are cpu's so this means you do not
// overload the cpu's with more work than you actually have processing
// units *IF* your threads do actually spend their time doing actual
// heavy computation)
thr = ecore_thread_feedback_run(th_do, th_feedback, th_end, th_cancel,
NULL, EINA_TRUE);
evas_object_resize(win, 400, 400);
evas_object_show(win);
elm_run();
if (thr) ecore_thread_cancel(thr);
return 0;
}
ELM_MAIN()
EVAS_CALLBACK_MOUSE_DOWN
@ EVAS_CALLBACK_MOUSE_DOWN
Mouse Button Down Event.
Definition Evas_Common.h:422
Ecore_Thread
struct _Ecore_Thread Ecore_Thread
A handle for threaded jobs.
Definition Ecore_Common.h:1735
ecore_thread_check
Eina_Bool ecore_thread_check(Ecore_Thread *thread)
Checks if a thread is pending cancellation.
Definition ecore_thread.c:892
ecore_thread_feedback
Eina_Bool ecore_thread_feedback(Ecore_Thread *thread, const void *msg_data)
Sends data from the worker thread to the main loop.
Definition ecore_thread.c:1037
ecore_thread_feedback_run
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)
Launches a thread to run a task that can talk back to the main thread.
Definition ecore_thread.c:911
ecore_thread_cancel
Eina_Bool ecore_thread_cancel(Ecore_Thread *thread)
Cancels a running thread.
Definition ecore_thread.c:741
EINA_TRUE
#define EINA_TRUE
boolean value TRUE (numerical value 1)
Definition eina_types.h:539
EINA_UNUSED
#define EINA_UNUSED
Used to indicate that a function parameter is purposely unused.
Definition eina_types.h:339
ELM_MAIN
#define ELM_MAIN()
macro to be used after the elm_main() function
Definition elm_general.h:556
elm_policy_set
Eina_Bool elm_policy_set(unsigned int policy, int value)
Set a new policy's value (for a given policy group/identifier).
Definition elm_main.c:1380
elm_exit
void elm_exit(void)
Ask to exit Elementary's main loop.
Definition elm_main.c:1373
elm_run
void elm_run(void)
Run Elementary's main loop.
Definition elm_main.c:1357
ELM_POLICY_QUIT_LAST_WINDOW_CLOSED
@ ELM_POLICY_QUIT_LAST_WINDOW_CLOSED
quit when the application's last window is closed
Definition elm_general.h:248
ELM_POLICY_QUIT
@ ELM_POLICY_QUIT
under which circumstances the application should quit automatically.
Definition elm_general.h:227
elm_win_util_standard_add
Evas_Object * elm_win_util_standard_add(const char *name, const char *title)
Adds a window object with standard setup.
Definition efl_ui_win.c:9587
Evas
Eo Evas
An opaque handle to an Evas canvas.
Definition Evas_Common.h:163
evas_object_show
EVAS_API void evas_object_show(Evas_Object *eo_obj)
Makes the given Evas object visible.
Definition evas_object_main.c:1814
evas_object_del
EVAS_API void evas_object_del(Evas_Object *obj)
Marks the given Evas object for deletion (when Evas will free its memory).
Definition evas_object_main.c:928
evas_object_color_set
EVAS_API void evas_object_color_set(Evas_Object *obj, int r, int g, int b, int a)
Sets the general/main color of the given Evas object to the given one.
Definition evas_object_main.c:2024
evas_object_event_callback_add
EVAS_API void evas_object_event_callback_add(Evas_Object *eo_obj, Evas_Callback_Type type, Evas_Object_Event_Cb func, const void *data)
Add (register) a callback function to a given Evas object event.
Definition evas_callbacks.c:478
evas_object_move
EVAS_API void evas_object_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
Move the given Evas object to the given location inside its canvas' viewport.
Definition evas_object_main.c:1171
evas_object_evas_get
EVAS_API Evas * evas_object_evas_get(const Eo *eo_obj)
Get the Evas to which this object belongs to.
Definition evas_object_main.c:2662
Evas_Object
Efl_Canvas_Object Evas_Object
An Evas Object handle.
Definition Evas_Common.h:185
evas_object_resize
EVAS_API void evas_object_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
Changes the size of the given Evas object.
Definition evas_object_main.c:1236
evas_object_rectangle_add
EVAS_API Evas_Object * evas_object_rectangle_add(Evas *e)
Adds a rectangle to the given evas.
Definition evas_object_rectangle.c:78
evas_object_smart_callback_add
EVAS_API void evas_object_smart_callback_add(Evas_Object *eo_obj, const char *event, Evas_Smart_Cb func, const void *data)
Add (register) a callback function to the smart event specified by event on the smart object obj.
Definition evas_object_smart.c:1040