2 * gcc -o ecore_thread_example ecore_thread_example.c `pkg-config --cflags --libs ecore`
8 #include <Ecore_Getopt.h>
12 Ecore_Thread *thread_3;
16 Eina_Condition condition;
29 } Feedback_Thread_Data;
38 _local_data_free(void *data)
40 Thread_Data *td = data;
43 EINA_LIST_FREE(td->list, str)
45 printf("Freeing string: %s\n", str);
52 _short_job(void *data, Ecore_Thread *th)
57 td = ecore_thread_local_data_find(th, "data");
60 td = calloc(1, sizeof(Thread_Data));
63 ecore_thread_cancel(th);
66 ecore_thread_local_data_add(th, "data", td, _local_data_free,
70 for (i = 0; i < 10; i++)
74 if (ecore_thread_check(th))
76 ecore_thread_local_data_del(th, "data");
80 snprintf(buf, sizeof(buf), "Thread %p: String number %d", th, i);
81 td->list = eina_list_append(td->list, strdup(buf));
87 _feedback_job(void *data, Ecore_Thread *th)
91 Feedback_Thread_Data *ftd = NULL;
95 count = (int)ecore_thread_global_data_find("count");
96 for (i = 0; i < count; i++)
99 snprintf(buf, sizeof(buf), "data%d", i);
100 ftd = ecore_thread_global_data_find(buf);
103 if (eina_lock_take_try(&ftd->mutex))
111 dir = opendir(ftd->base);
115 msg = calloc(1, sizeof(App_Msg));
118 while (time(NULL) < t + 2)
120 struct dirent entry, *result;
122 if (readdir_r(dir, &entry, &result))
127 if (strlen(result->d_name) >= 10)
128 msg->list = eina_list_append(msg->list,
129 strdup(result->d_name));
133 ecore_thread_feedback(th, msg);
136 ecore_thread_global_data_del(ftd->name);
139 eina_lock_release(&ftd->mutex);
140 eina_lock_free(&ftd->mutex);
142 ecore_thread_reschedule(th);
146 _out_of_pool_job(void *data, Ecore_Thread *th)
154 eina_condition_wait(&ad->condition);
155 msgs = ad->msgs_received;
156 eina_lock_release(&ad->mutex);
157 if (msgs == ad->max_msgs)
159 msg = calloc(1, sizeof(App_Msg));
161 ecore_thread_feedback(th, msg);
170 int active, pending_total, pending_feedback, pending_short, available;
172 active = ecore_thread_active_get();
173 pending_total = ecore_thread_pending_total_get();
174 pending_feedback = ecore_thread_pending_feedback_get();
175 pending_short = ecore_thread_pending_get();
176 available = ecore_thread_available_get();
178 printf("Status:\n\t* Active threads: %d\n"
179 "\t* Available threads: %d\n"
180 "\t* Pending short jobs: %d\n"
181 "\t* Pending feedback jobs: %d\n"
182 "\t* Pending total: %d\n", active, available, pending_short,
183 pending_feedback, pending_total);
187 _feedback_job_msg_cb(void *data, Ecore_Thread *th, void *msg_data)
190 App_Msg *msg = msg_data;
195 ecore_main_loop_quit();
203 printf("Received an empty list from thread %p\n", th);
207 printf("Received %d elements from threads %p (printing first 5):\n",
208 eina_list_count(msg->list), th);
209 EINA_LIST_FREE(msg->list, str)
212 printf("\t%s\n", str);
218 eina_lock_take(&ad->mutex);
220 eina_condition_signal(&ad->condition);
221 eina_lock_release(&ad->mutex);
227 _thread_end_cb(void *data, Ecore_Thread *th)
231 printf("Normal termination for thread %p.\n", th);
232 if (th == ad->thread_3)
237 _thread_cancel_cb(void *data, Ecore_Thread *th)
241 printf("Thread %p got cancelled.\n", th);
242 if (th == ad->thread_3)
247 _cancel_timer_cb(void *data)
251 if (ad->thread_3 && !ecore_thread_check(ad->thread_3))
252 ecore_thread_cancel(ad->thread_3);
258 _status_timer_cb(void *data)
265 static const Ecore_Getopt optdesc = {
266 "ecore_thread_example",
269 "(C) 2011 Enlightenment",
271 "Example program for Ecore_Thread",
274 ECORE_GETOPT_STORE_INT('t', "threads", "Max number of threads to run"),
275 ECORE_GETOPT_STORE_INT('m', "msgs", "Max number of messages to receive"),
276 ECORE_GETOPT_APPEND_METAVAR('p', "path", "Add path for feedback job",
277 "STRING", ECORE_GETOPT_TYPE_STR),
278 ECORE_GETOPT_HELP('h', "help"),
279 ECORE_GETOPT_SENTINEL
284 main(int argc, char *argv[])
286 int i, max_threads = 0, max_msgs = 0;
287 Eina_Bool opt_quit = EINA_FALSE;
288 Eina_List *path_list = NULL;
290 Ecore_Getopt_Value values[] = {
291 ECORE_GETOPT_VALUE_INT(max_threads),
292 ECORE_GETOPT_VALUE_INT(max_msgs),
293 ECORE_GETOPT_VALUE_LIST(path_list),
294 ECORE_GETOPT_VALUE_BOOL(opt_quit),
295 ECORE_GETOPT_VALUE_NONE
300 i = ecore_thread_max_get();
301 printf("Initial max threads: %d\n", i);
303 memset(&appdata, 0, sizeof(App_Data));
304 appdata.max_msgs = 1;
306 if (ecore_getopt_parse(&optdesc, values, argc, argv) < 0)
308 printf("Argument parsing failed\n");
317 ecore_thread_max_set(max_threads);
318 printf("Max threads: %d\n", ecore_thread_max_get());
321 appdata.max_msgs = max_msgs;
325 Feedback_Thread_Data *ftd;
326 ecore_thread_global_data_add("count", (void *)3, NULL, EINA_FALSE);
327 ftd = calloc(1, sizeof(Feedback_Thread_Data));
328 ftd->name = strdup("data0");
329 ftd->base = strdup("/usr/bin");
330 eina_lock_new(&ftd->mutex);
331 ecore_thread_global_data_add(ftd->name, ftd, NULL, EINA_TRUE);
332 ftd = calloc(1, sizeof(Feedback_Thread_Data));
333 ftd->name = strdup("data1");
334 ftd->base = strdup("/usr/lib");
335 eina_lock_new(&ftd->mutex);
336 ecore_thread_global_data_add(ftd->name, ftd, NULL, EINA_TRUE);
337 ftd = calloc(1, sizeof(Feedback_Thread_Data));
338 ftd->name = strdup("data2");
339 ftd->base = strdup("/usr/share");
340 eina_lock_new(&ftd->mutex);
341 ecore_thread_global_data_add(ftd->name, ftd, NULL, EINA_TRUE);
345 Feedback_Thread_Data *ftd;
347 ecore_thread_global_data_add("count",
348 (void *)eina_list_count(path_list), NULL,
351 EINA_LIST_FREE(path_list, str)
354 snprintf(buf, sizeof(buf), "data%d", i);
355 ftd = calloc(1, sizeof(Feedback_Thread_Data));
356 ftd->name = strdup(buf);
357 ftd->base = strdup(str);
358 eina_lock_new(&ftd->mutex);
359 ecore_thread_global_data_add(ftd->name, ftd, NULL, EINA_TRUE);
365 eina_lock_new(&appdata.mutex);
366 eina_condition_new(&appdata.condition, &appdata.mutex);
368 ecore_thread_feedback_run(_out_of_pool_job, _feedback_job_msg_cb, NULL,
369 NULL, &appdata, EINA_TRUE);
371 ecore_thread_run(_short_job, _thread_end_cb, _thread_cancel_cb, &appdata);
372 ecore_thread_feedback_run(_feedback_job, _feedback_job_msg_cb,
373 _thread_end_cb, _thread_cancel_cb, &appdata,
375 appdata.thread_3 = ecore_thread_run(_short_job, _thread_end_cb,
376 _thread_cancel_cb, &appdata);
377 ecore_thread_feedback_run(_feedback_job, _feedback_job_msg_cb,
378 _thread_end_cb, _thread_cancel_cb, &appdata,
381 ecore_timer_add(1.0, _cancel_timer_cb, &appdata);
382 ecore_timer_add(2.0, _status_timer_cb, NULL);
386 ecore_main_loop_begin();
388 eina_condition_free(&appdata.condition);
389 eina_lock_free(&appdata.mutex);