diff options
author | Cedric Bail <cedric.bail@samsung.com> | 2013-05-30 15:42:56 +0900 |
---|---|---|
committer | Cedric Bail <cedric.bail@samsung.com> | 2013-06-04 11:20:25 +0900 |
commit | 4d15a0f50f8680de22ea6ced009d666e9ae6be3f (patch) | |
tree | a497ff66fea181eb533357e7c46bda444681ba2b /src/lib/evas/canvas/evas_async_events.c | |
parent | b52a380a5f3e198c25b27e540315268c75e6d6cf (diff) |
evas: add infra to block the main loop from evas.
PS: later on, I think we should just move evas to use Ecore infra
directly to create jobs and sync with the main loop.
Diffstat (limited to 'src/lib/evas/canvas/evas_async_events.c')
-rw-r--r-- | src/lib/evas/canvas/evas_async_events.c | 142 |
1 files changed, 141 insertions, 1 deletions
diff --git a/src/lib/evas/canvas/evas_async_events.c b/src/lib/evas/canvas/evas_async_events.c index 2bab528..c6e9c0e 100644 --- a/src/lib/evas/canvas/evas_async_events.c +++ b/src/lib/evas/canvas/evas_async_events.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include "evas_private.h" | 12 | #include "evas_private.h" |
13 | 13 | ||
14 | typedef struct _Evas_Event_Async Evas_Event_Async; | 14 | typedef struct _Evas_Event_Async Evas_Event_Async; |
15 | |||
16 | struct _Evas_Event_Async | 15 | struct _Evas_Event_Async |
17 | { | 16 | { |
18 | const void *target; | 17 | const void *target; |
@@ -21,6 +20,28 @@ struct _Evas_Event_Async | |||
21 | Evas_Callback_Type type; | 20 | Evas_Callback_Type type; |
22 | }; | 21 | }; |
23 | 22 | ||
23 | typedef struct _Evas_Safe_Call Evas_Safe_Call; | ||
24 | struct _Evas_Safe_Call | ||
25 | { | ||
26 | Eina_Condition c; | ||
27 | Eina_Lock m; | ||
28 | |||
29 | int current_id; | ||
30 | }; | ||
31 | |||
32 | static Eina_Lock _thread_mutex; | ||
33 | static Eina_Condition _thread_cond; | ||
34 | |||
35 | static Eina_Lock _thread_feedback_mutex; | ||
36 | static Eina_Condition _thread_feedback_cond; | ||
37 | |||
38 | static int _thread_loop = 0; | ||
39 | |||
40 | static Eina_Lock _thread_id_lock; | ||
41 | static int _thread_id = -1; | ||
42 | static int _thread_id_max = 0; | ||
43 | static int _thread_id_update = 0; | ||
44 | |||
24 | static int _fd_write = -1; | 45 | static int _fd_write = -1; |
25 | static int _fd_read = -1; | 46 | static int _fd_read = -1; |
26 | static pid_t _fd_pid = 0; | 47 | static pid_t _fd_pid = 0; |
@@ -81,6 +102,14 @@ evas_async_events_init(void) | |||
81 | eina_lock_new(&async_lock); | 102 | eina_lock_new(&async_lock); |
82 | eina_inarray_step_set(&async_queue, sizeof (Eina_Inarray), sizeof (Evas_Event_Async), 16); | 103 | eina_inarray_step_set(&async_queue, sizeof (Eina_Inarray), sizeof (Evas_Event_Async), 16); |
83 | 104 | ||
105 | eina_lock_new(&_thread_mutex); | ||
106 | eina_condition_new(&_thread_cond, &_thread_mutex); | ||
107 | |||
108 | eina_lock_new(&_thread_feedback_mutex); | ||
109 | eina_condition_new(&_thread_feedback_cond, &_thread_feedback_mutex); | ||
110 | |||
111 | eina_lock_new(&_thread_id_lock); | ||
112 | |||
84 | return _init_evas_event; | 113 | return _init_evas_event; |
85 | } | 114 | } |
86 | 115 | ||
@@ -90,6 +119,12 @@ evas_async_events_shutdown(void) | |||
90 | _init_evas_event--; | 119 | _init_evas_event--; |
91 | if (_init_evas_event > 0) return _init_evas_event; | 120 | if (_init_evas_event > 0) return _init_evas_event; |
92 | 121 | ||
122 | eina_condition_free(&_thread_cond); | ||
123 | eina_lock_free(&_thread_mutex); | ||
124 | eina_condition_free(&_thread_feedback_cond); | ||
125 | eina_lock_free(&_thread_feedback_mutex); | ||
126 | eina_lock_free(&_thread_id_lock); | ||
127 | |||
93 | eina_lock_free(&async_lock); | 128 | eina_lock_free(&async_lock); |
94 | eina_inarray_flush(&async_queue); | 129 | eina_inarray_flush(&async_queue); |
95 | free(async_queue_cache); | 130 | free(async_queue_cache); |
@@ -284,3 +319,108 @@ evas_async_events_put(const void *target, Evas_Callback_Type type, void *event_i | |||
284 | 319 | ||
285 | return ret; | 320 | return ret; |
286 | } | 321 | } |
322 | |||
323 | static void | ||
324 | _evas_thread_main_loop_lock(void *target EINA_UNUSED, | ||
325 | Evas_Callback_Type type EINA_UNUSED, | ||
326 | void *event_info) | ||
327 | { | ||
328 | Evas_Safe_Call *call = event_info; | ||
329 | |||
330 | eina_lock_take(&_thread_mutex); | ||
331 | |||
332 | eina_lock_take(&call->m); | ||
333 | _thread_id = call->current_id; | ||
334 | eina_condition_broadcast(&call->c); | ||
335 | eina_lock_release(&call->m); | ||
336 | |||
337 | while (_thread_id_update != _thread_id) | ||
338 | eina_condition_wait(&_thread_cond); | ||
339 | eina_lock_release(&_thread_mutex); | ||
340 | |||
341 | eina_main_loop_define(); | ||
342 | |||
343 | eina_lock_take(&_thread_feedback_mutex); | ||
344 | |||
345 | _thread_id = -1; | ||
346 | |||
347 | eina_condition_broadcast(&_thread_feedback_cond); | ||
348 | eina_lock_release(&_thread_feedback_mutex); | ||
349 | |||
350 | eina_condition_free(&call->c); | ||
351 | eina_lock_free(&call->m); | ||
352 | free(call); | ||
353 | } | ||
354 | |||
355 | EAPI int | ||
356 | evas_thread_main_loop_begin(void) | ||
357 | { | ||
358 | Evas_Safe_Call *order; | ||
359 | |||
360 | if (eina_main_loop_is()) | ||
361 | { | ||
362 | return ++_thread_loop; | ||
363 | } | ||
364 | |||
365 | order = malloc(sizeof (Evas_Safe_Call)); | ||
366 | if (!order) return -1; | ||
367 | |||
368 | eina_lock_take(&_thread_id_lock); | ||
369 | order->current_id = ++_thread_id_max; | ||
370 | if (order->current_id < 0) | ||
371 | { | ||
372 | _thread_id_max = 0; | ||
373 | order->current_id = ++_thread_id_max; | ||
374 | } | ||
375 | eina_lock_release(&_thread_id_lock); | ||
376 | |||
377 | eina_lock_new(&order->m); | ||
378 | eina_condition_new(&order->c, &order->m); | ||
379 | |||
380 | evas_async_events_put(NULL, 0, order, _evas_thread_main_loop_lock); | ||
381 | |||
382 | eina_lock_take(&order->m); | ||
383 | while (order->current_id != _thread_id) | ||
384 | eina_condition_wait(&order->c); | ||
385 | eina_lock_release(&order->m); | ||
386 | |||
387 | eina_main_loop_define(); | ||
388 | |||
389 | _thread_loop = 1; | ||
390 | |||
391 | return _thread_loop; | ||
392 | } | ||
393 | |||
394 | EAPI int | ||
395 | evas_thread_main_loop_end(void) | ||
396 | { | ||
397 | int current_id; | ||
398 | |||
399 | if (_thread_loop == 0) | ||
400 | abort(); | ||
401 | |||
402 | /* until we unlock the main loop, this thread has the main loop id */ | ||
403 | if (!eina_main_loop_is()) | ||
404 | { | ||
405 | ERR("Not in a locked thread !"); | ||
406 | return -1; | ||
407 | } | ||
408 | |||
409 | _thread_loop--; | ||
410 | if (_thread_loop > 0) | ||
411 | return _thread_loop; | ||
412 | |||
413 | current_id = _thread_id; | ||
414 | |||
415 | eina_lock_take(&_thread_mutex); | ||
416 | _thread_id_update = _thread_id; | ||
417 | eina_condition_broadcast(&_thread_cond); | ||
418 | eina_lock_release(&_thread_mutex); | ||
419 | |||
420 | eina_lock_take(&_thread_feedback_mutex); | ||
421 | while (current_id == _thread_id && _thread_id != -1) | ||
422 | eina_condition_wait(&_thread_feedback_cond); | ||
423 | eina_lock_release(&_thread_feedback_mutex); | ||
424 | |||
425 | return 0; | ||
426 | } | ||