Now when you want to have a thread do some work, send back results to the mainloop and continue running but the mainloop controls when the thread should stop working, you need some extra flags.

This is an example of how you might use ecore\+\_\+main\+\_\+loop\+\_\+thread\+\_\+safe\+\_\+call\+\_\+async() and pthreads to do this.

\hyperlink{efl_thread_5}{E\+FL Threading example 5}

\hyperlink{efl_thread_6}{E\+FL Threading example 6}


\begin{DoxyCodeInclude}
\textcolor{comment}{//Compile with:}
\textcolor{comment}{//gcc -o efl\_thread\_4 efl\_thread\_4.c -g `pkg-config --cflags --libs elementary`}
\textcolor{preprocessor}{#include <Elementary.h>}
\textcolor{preprocessor}{#include <pthread.h>}

\textcolor{keyword}{static} Evas\_Object *win = NULL;
\textcolor{keyword}{static} Evas\_Object *rect = NULL;

\textcolor{keyword}{struct }info
\{
   \textcolor{keywordtype}{double} x, y;
\};

\textcolor{keyword}{static} \textcolor{keywordtype}{void} my\_thread\_mainloop\_code(\textcolor{keywordtype}{void} *data);

\textcolor{keyword}{static} pthread\_t thread\_id;
\textcolor{keyword}{static} pthread\_mutex\_t th\_lock;
\textcolor{keyword}{static} \textcolor{keywordtype}{int} th\_exit = 0;

\textcolor{comment}{// BEGIN - code running in my custom pthread instance}
\textcolor{comment}{//}
\textcolor{keyword}{static} \textcolor{keywordtype}{void} *
my\_thread\_run(\textcolor{keywordtype}{void} *arg)
\{
   \textcolor{keywordtype}{double} t = 0.0;

   \textcolor{comment}{// inside the pthread function lets loop forever incrementing a time point}
   \textcolor{keywordflow}{for} (;;)
     \{
        \textcolor{keyword}{struct }info *inf = malloc(\textcolor{keyword}{sizeof}(\textcolor{keyword}{struct} info));
        \textcolor{keywordtype}{int} do\_exit;

        \textcolor{keywordflow}{if} (inf)
          \{
             inf->x = 200 + (200 * sin(t));
             inf->y = 200 + (200 * cos(t));
             \textcolor{comment}{// now call a function in the mainloop and pass it our allocated}
             \textcolor{comment}{// data that it will free when it gets it}
             ecore\_main\_loop\_thread\_safe\_call\_async
                (my\_thread\_mainloop\_code, inf);
          \}
        \textcolor{comment}{// and sleep and loop}
        usleep(1000);
        t += 0.02;
        \textcolor{comment}{// in case someone has asked us to cancel - then cancel this loop}
        \textcolor{comment}{// co-operatively (cancelling is co-operative)}
        pthread\_mutex\_lock(&th\_lock);
        do\_exit = th\_exit;
        pthread\_mutex\_unlock(&th\_lock);
        \textcolor{keywordflow}{if} (do\_exit) \textcolor{keywordflow}{break};
     \}
   \textcolor{keywordflow}{return} NULL;
\}
\textcolor{comment}{//}
\textcolor{comment}{// END - code running in my custom pthread instance}

\textcolor{keyword}{static} \textcolor{keywordtype}{void}
my\_thread\_new(\textcolor{keywordtype}{void})
\{
   pthread\_attr\_t attr;

   pthread\_mutex\_init(&th\_lock, NULL);
   \textcolor{keywordflow}{if} (pthread\_attr\_init(&attr) != 0)
     perror(\textcolor{stringliteral}{"pthread\_attr\_init"});
   \textcolor{keywordflow}{if} (pthread\_create(&thread\_id, &attr, my\_thread\_run, NULL) != 0)
     perror(\textcolor{stringliteral}{"pthread\_create"});
\}

\textcolor{keyword}{static} \textcolor{keywordtype}{void}
my\_thread\_mainloop\_code(\textcolor{keywordtype}{void} *data)
\{
   \textcolor{keyword}{struct }info *inf = data;
   evas\_object\_move(rect, inf->x - 50, inf->y - 50);
   free(inf);
\}

\textcolor{comment}{// just test cancelling the thread}
\textcolor{keyword}{static} \textcolor{keywordtype}{void}
down(\textcolor{keywordtype}{void} *data, Evas *e, Evas\_Object *obj, \textcolor{keywordtype}{void} *event\_info)
\{
   pthread\_mutex\_lock(&th\_lock);
   th\_exit = 1;
   pthread\_mutex\_unlock(&th\_lock);
\}

\textcolor{comment}{// on window delete - cancel thread then delete window and exit mainloop}
\textcolor{keyword}{static} \textcolor{keywordtype}{void}
del(\textcolor{keywordtype}{void} *data, Evas\_Object *obj, \textcolor{keywordtype}{void} *event\_info)
\{
   pthread\_mutex\_lock(&th\_lock);
   th\_exit = 1;
   pthread\_mutex\_unlock(&th\_lock);
   evas\_object\_del(obj);
   elm_exit();
\}

EAPI\_MAIN \textcolor{keywordtype}{int}
elm\_main(\textcolor{keywordtype}{int} argc, \textcolor{keywordtype}{char} **argv)
\{
   Evas\_Object *o;

   elm_policy_set(ELM\_POLICY\_QUIT, ELM\_POLICY\_QUIT\_LAST\_WINDOW\_CLOSED);

   win = elm_win_util_standard_add(\textcolor{stringliteral}{"efl-thread-4"}, \textcolor{stringliteral}{"EFL Thread 4"});
   evas\_object\_smart\_callback\_add(win, \textcolor{stringliteral}{"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);
   \textcolor{comment}{// new in the examples - we have a mouse down on the blue box cancel}
   \textcolor{comment}{// the thread}
   evas\_object\_event\_callback\_add(o, EVAS\_CALLBACK\_MOUSE\_DOWN, down, NULL);
   rect = o;

   \textcolor{comment}{// create custom thread to do some "work on the side"}
   my\_thread\_new();

   evas\_object\_resize(win, 400, 400);
   evas\_object\_show(win);

   elm_run();
   pthread\_mutex\_lock(&th\_lock);
   th\_exit = 1;
   pthread\_mutex\_unlock(&th\_lock);

   \textcolor{keywordflow}{return} 0;
\}
ELM_MAIN()
\end{DoxyCodeInclude}
 