summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorUlisses Furquim <ulisses@profusion.mobi>2013-01-06 02:01:53 +0000
committerUlisses Furquim <ulisses@profusion.mobi>2013-01-06 02:01:53 +0000
commitd53f43abaf440d2356c91fa809ad636daa176d7f (patch)
treee16d367848cd150f5c16e525128e07ff8841735a /src
parent7904f59248e0bce31d0807e4581c1839e1caf6e0 (diff)
evas/common/thread_render: fix queue cache handling
Fixed queue cache handling to let enqueue and process happen at the same time, even though this is not our use case yet. This also solves a race with the assignment of cache variables outside the queue lock and remembers to free the cache when shutting down. SVN revision: 82296
Diffstat (limited to 'src')
-rw-r--r--src/lib/evas/common/evas_thread_render.c42
1 files changed, 19 insertions, 23 deletions
diff --git a/src/lib/evas/common/evas_thread_render.c b/src/lib/evas/common/evas_thread_render.c
index 9c434c29e2..40964ba7ec 100644
--- a/src/lib/evas/common/evas_thread_render.c
+++ b/src/lib/evas/common/evas_thread_render.c
@@ -7,9 +7,8 @@ static Eina_Condition evas_thread_queue_condition;
7static Eina_Lock evas_thread_queue_lock; 7static Eina_Lock evas_thread_queue_lock;
8static Eina_Bool evas_thread_queue_ready = EINA_FALSE; 8static Eina_Bool evas_thread_queue_ready = EINA_FALSE;
9static Eina_Inarray evas_thread_queue; 9static Eina_Inarray evas_thread_queue;
10
11static Evas_Thread_Command *evas_thread_queue_cache = NULL; 10static Evas_Thread_Command *evas_thread_queue_cache = NULL;
12static int evas_thread_queue_cache_max = 0; 11static unsigned int evas_thread_queue_cache_max = 0;
13 12
14static volatile int evas_thread_exited = 0; 13static volatile int evas_thread_exited = 0;
15static Eina_Bool exit_thread = EINA_FALSE; 14static Eina_Bool exit_thread = EINA_FALSE;
@@ -22,15 +21,6 @@ evas_thread_queue_append(Evas_Thread_Command_Cb cb, void *data, Eina_Bool do_flu
22 21
23 eina_lock_take(&evas_thread_queue_lock); 22 eina_lock_take(&evas_thread_queue_lock);
24 23
25 if (evas_thread_queue.members == NULL)
26 {
27 evas_thread_queue.members = evas_thread_queue_cache;
28 evas_thread_queue.len = 0;
29 evas_thread_queue.max = evas_thread_queue_cache_max;
30 evas_thread_queue_cache = NULL;
31 evas_thread_queue_cache_max = 0;
32 }
33
34 cmd = eina_inarray_grow(&evas_thread_queue, 1); 24 cmd = eina_inarray_grow(&evas_thread_queue, 1);
35 if (cmd) 25 if (cmd)
36 { 26 {
@@ -40,6 +30,7 @@ evas_thread_queue_append(Evas_Thread_Command_Cb cb, void *data, Eina_Bool do_flu
40 else 30 else
41 { 31 {
42 ERR("Out of memory allocating thread command."); 32 ERR("Out of memory allocating thread command.");
33 goto out;
43 } 34 }
44 35
45 if (do_flush) 36 if (do_flush)
@@ -48,6 +39,7 @@ evas_thread_queue_append(Evas_Thread_Command_Cb cb, void *data, Eina_Bool do_flu
48 eina_condition_signal(&evas_thread_queue_condition); 39 eina_condition_signal(&evas_thread_queue_condition);
49 } 40 }
50 41
42out:
51 eina_lock_release(&evas_thread_queue_lock); 43 eina_lock_release(&evas_thread_queue_lock);
52} 44}
53 45
@@ -68,10 +60,8 @@ evas_thread_worker_func(void *data EINA_UNUSED, Eina_Thread thread EINA_UNUSED)
68{ 60{
69 while (1) 61 while (1)
70 { 62 {
71 Evas_Thread_Command *head;
72 Evas_Thread_Command *cmd; 63 Evas_Thread_Command *cmd;
73 int len; 64 unsigned int len, max;
74 int max;
75 65
76 eina_lock_take(&evas_thread_queue_lock); 66 eina_lock_take(&evas_thread_queue_lock);
77 67
@@ -88,20 +78,28 @@ evas_thread_worker_func(void *data EINA_UNUSED, Eina_Thread thread EINA_UNUSED)
88 if (!eina_inarray_count(&evas_thread_queue)) 78 if (!eina_inarray_count(&evas_thread_queue))
89 { 79 {
90 ERR("Signaled to find an empty queue. BUG!"); 80 ERR("Signaled to find an empty queue. BUG!");
81 evas_thread_queue_ready = EINA_FALSE;
91 eina_lock_release(&evas_thread_queue_lock); 82 eina_lock_release(&evas_thread_queue_lock);
92 continue; 83 continue;
93 } 84 }
94 85
95 head = evas_thread_queue.members; 86 cmd = evas_thread_queue.members;
96 evas_thread_queue.members = NULL; 87 evas_thread_queue.members = evas_thread_queue_cache;
97 max = evas_thread_queue.max; evas_thread_queue.max = 0; 88 evas_thread_queue_cache = cmd;
98 len = evas_thread_queue.len; evas_thread_queue.len = 0; 89
99 90 max = evas_thread_queue.max;
91 evas_thread_queue.max = evas_thread_queue_cache_max;
92 evas_thread_queue_cache_max = max;
93
94 len = evas_thread_queue.len;
95 evas_thread_queue.len = 0;
96
100 evas_thread_queue_ready = EINA_FALSE; 97 evas_thread_queue_ready = EINA_FALSE;
101 98
102 eina_lock_release(&evas_thread_queue_lock); 99 eina_lock_release(&evas_thread_queue_lock);
103 100
104 cmd = head; 101 DBG("Evas render thread command queue length: %u", len);
102
105 while (len) 103 while (len)
106 { 104 {
107 assert(cmd->cb); 105 assert(cmd->cb);
@@ -111,9 +109,6 @@ evas_thread_worker_func(void *data EINA_UNUSED, Eina_Thread thread EINA_UNUSED)
111 cmd++; 109 cmd++;
112 len--; 110 len--;
113 } 111 }
114
115 evas_thread_queue_cache = head;
116 evas_thread_queue_cache_max = max;
117 } 112 }
118 113
119out: 114out:
@@ -163,6 +158,7 @@ evas_thread_shutdown(void)
163 eina_condition_free(&evas_thread_queue_condition); 158 eina_condition_free(&evas_thread_queue_condition);
164 159
165 eina_inarray_flush(&evas_thread_queue); 160 eina_inarray_flush(&evas_thread_queue);
161 free(evas_thread_queue_cache);
166 162
167 eina_threads_shutdown(); 163 eina_threads_shutdown();
168} 164}