EFL Threading example 1

You can use threads with Elementary (and EFL) but you need to be careful to only use eina or eet calls inside a thread. Other libraries are not totally threadsafe except for some specific ecore calls designed for working from threads like the ecore_pipe_write() and ecore_thread calls.

Below is an example of how to use EFL calls from a native thread you have already created. You have to put the EFL calls inside the critical block between ecore_thread_main_loop_begin() and ecore_thread_main_loop_end() which ensure you gain a lock on the mainloop. Beware that this requires that the thread WAIT to synchronize with the mainloop at the beginning of the critical section. It is highly suggested you use as few of these in your thread as possible and probably put just a single ecore_thread_main_loop_begin() / ecore_thread_main_loop_end() section at the end of the threads calculation or work when it is done and would otherwise exit to sit idle.

For a progression of examples that become more complex and show other ways to use threading with EFL, please see:

EFL Threading example 2

EFL Threading example 3

EFL Threading example 4

EFL Threading example 5

EFL Threading example 6

//Compile with:
//gcc -o efl_thread_1 efl_thread_1.c -g `pkg-config --cflags --libs elementary`
#include <Elementary.h>
#include <pthread.h>
static Evas_Object *win = NULL;
static Evas_Object *rect = NULL;
static pthread_t thread_id;
// BEGIN - code running in my custom pthread instance
//
static void *
my_thread_run(void *arg EINA_UNUSED)
{
double t = 0.0;
for (;;)
{
ecore_thread_main_loop_begin(); // begin critical
{ // indented for illustration of "critical" block
Evas_Coord x, y;
x = 200 + (200 * sin(t));
y = 200 + (200 * cos(t));
evas_object_move(rect, x - 50, y - 50);
}
ecore_thread_main_loop_end(); // end critical
usleep(1000);
t += 0.02;
}
return NULL;
}
//
// END - code running in my custom pthread instance
static void
my_thread_new(void)
{
pthread_attr_t attr;
if (pthread_attr_init(&attr) != 0)
perror("pthread_attr_init");
if (pthread_create(&thread_id, &attr, my_thread_run, NULL) != 0)
perror("pthread_create");
}
// on window delete - cancel thread then delete window and exit mainloop
static void
del(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
exit(0);
}
EAPI_MAIN int
elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
{
win = elm_win_util_standard_add("efl-thread-1", "EFL Thread 1");
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);
rect = o;
// create custom thread to do some "work on the side"
my_thread_new();
evas_object_resize(win, 400, 400);
return 0;
}
EINA_UNUSED
#define EINA_UNUSED
Definition: eina_types.h:321
evas_object_smart_callback_add
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:980
Evas_Object
Efl_Canvas_Object Evas_Object
Definition: Evas_Common.h:180
elm_run
void elm_run(void)
Run Elementary's main loop.
Definition: elm_main.c:1384
ELM_MAIN
#define ELM_MAIN()
macro to be used after the elm_main() function
Definition: elm_general.h:528
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:9199
evas_object_show
void evas_object_show(Evas_Object *eo_obj)
Makes the given Evas object visible.
Definition: evas_object_main.c:1853
ecore_thread_main_loop_begin
EAPI int ecore_thread_main_loop_begin(void)
This function suspends the main loop in a know state.
Definition: ecore.c:685
evas_object_rectangle_add
Evas_Object * evas_object_rectangle_add(Evas *e)
Adds a rectangle to the given evas.
Definition: evas_object_rectangle.c:78
ecore_thread_main_loop_end
EAPI int ecore_thread_main_loop_end(void)
Unlocks the main loop.
Definition: ecore.c:735
Evas_Coord
int Evas_Coord
Type used for coordinates (in pixels, int).
Definition: Evas_Common.h:111
evas_object_color_set
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:2063