diff options
Diffstat (limited to 'libraries/evas/src/lib/cache/evas_preload.c')
-rw-r--r-- | libraries/evas/src/lib/cache/evas_preload.c | 266 |
1 files changed, 0 insertions, 266 deletions
diff --git a/libraries/evas/src/lib/cache/evas_preload.c b/libraries/evas/src/lib/cache/evas_preload.c deleted file mode 100644 index 5eebaed..0000000 --- a/libraries/evas/src/lib/cache/evas_preload.c +++ /dev/null | |||
@@ -1,266 +0,0 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | #ifdef HAVE_EVIL | ||
6 | # include <Evil.h> | ||
7 | #endif | ||
8 | |||
9 | #ifdef BUILD_ASYNC_PRELOAD | ||
10 | # include <pthread.h> | ||
11 | # ifdef __linux__ | ||
12 | # include <sys/syscall.h> | ||
13 | # endif | ||
14 | #endif | ||
15 | |||
16 | #include "evas_common.h" | ||
17 | #include "evas_private.h" | ||
18 | #include "Evas.h" | ||
19 | |||
20 | #ifdef BUILD_ASYNC_PRELOAD | ||
21 | |||
22 | static int _threads_max = 0; | ||
23 | |||
24 | typedef struct _Evas_Preload_Pthread_Worker Evas_Preload_Pthread_Worker; | ||
25 | typedef struct _Evas_Preload_Pthread_Data Evas_Preload_Pthread_Data; | ||
26 | |||
27 | typedef void (*_evas_preload_pthread_func)(void *data); | ||
28 | |||
29 | struct _Evas_Preload_Pthread_Worker | ||
30 | { | ||
31 | EINA_INLIST; | ||
32 | |||
33 | _evas_preload_pthread_func func_heavy; | ||
34 | _evas_preload_pthread_func func_end; | ||
35 | _evas_preload_pthread_func func_cancel; | ||
36 | void *data; | ||
37 | Eina_Bool cancel : 1; | ||
38 | }; | ||
39 | |||
40 | struct _Evas_Preload_Pthread_Data | ||
41 | { | ||
42 | pthread_t thread; | ||
43 | }; | ||
44 | |||
45 | static int _threads_count = 0; | ||
46 | static Evas_Preload_Pthread_Worker *_workers = NULL; | ||
47 | |||
48 | static LK(_mutex); | ||
49 | |||
50 | static void | ||
51 | _evas_preload_thread_end(void *data) | ||
52 | { | ||
53 | Evas_Preload_Pthread_Data *pth = data; | ||
54 | Evas_Preload_Pthread_Data *p = NULL; | ||
55 | |||
56 | if (pthread_join(pth->thread, (void **)&p) == 0) free(p); | ||
57 | else return; | ||
58 | eina_threads_shutdown(); | ||
59 | } | ||
60 | |||
61 | static void | ||
62 | _evas_preload_thread_done(void *target __UNUSED__, Evas_Callback_Type type __UNUSED__, void *event_info) | ||
63 | { | ||
64 | Evas_Preload_Pthread_Worker *work = event_info; | ||
65 | if (work->cancel) | ||
66 | { | ||
67 | if (work->func_cancel) work->func_cancel(work->data); | ||
68 | } | ||
69 | else | ||
70 | work->func_end(work->data); | ||
71 | |||
72 | free(work); | ||
73 | } | ||
74 | |||
75 | static void * | ||
76 | _evas_preload_thread_worker(void *data) | ||
77 | { | ||
78 | Evas_Preload_Pthread_Data *pth = data; | ||
79 | Evas_Preload_Pthread_Worker *work; | ||
80 | |||
81 | eina_sched_prio_drop(); | ||
82 | pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); | ||
83 | pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); | ||
84 | on_error: | ||
85 | for (;;) | ||
86 | { | ||
87 | LKL(_mutex); | ||
88 | if (!_workers) | ||
89 | { | ||
90 | LKU(_mutex); | ||
91 | break; | ||
92 | } | ||
93 | |||
94 | work = _workers; | ||
95 | _workers = EINA_INLIST_CONTAINER_GET(eina_inlist_remove(EINA_INLIST_GET(_workers), | ||
96 | EINA_INLIST_GET(_workers)), | ||
97 | Evas_Preload_Pthread_Worker); | ||
98 | LKU(_mutex); | ||
99 | |||
100 | if (work->func_heavy) work->func_heavy(work->data); | ||
101 | evas_async_events_put(pth, 0, work, _evas_preload_thread_done); | ||
102 | } | ||
103 | |||
104 | LKL(_mutex); | ||
105 | if (_workers) | ||
106 | { | ||
107 | LKU(_mutex); | ||
108 | goto on_error; | ||
109 | } | ||
110 | _threads_count--; | ||
111 | LKU(_mutex); | ||
112 | |||
113 | // dummy worker to wake things up | ||
114 | work = malloc(sizeof(Evas_Preload_Pthread_Worker)); | ||
115 | if (!work) return NULL; | ||
116 | |||
117 | work->data = pth; | ||
118 | work->func_heavy = NULL; | ||
119 | work->func_end = (_evas_preload_pthread_func) _evas_preload_thread_end; | ||
120 | work->func_cancel = NULL; | ||
121 | work->cancel = EINA_FALSE; | ||
122 | |||
123 | evas_async_events_put(pth, 0, work, _evas_preload_thread_done); | ||
124 | return pth; | ||
125 | } | ||
126 | #endif | ||
127 | |||
128 | void | ||
129 | _evas_preload_thread_init(void) | ||
130 | { | ||
131 | #ifdef BUILD_ASYNC_PRELOAD | ||
132 | _threads_max = eina_cpu_count(); | ||
133 | if (_threads_max < 1) _threads_max = 1; | ||
134 | |||
135 | LKI(_mutex); | ||
136 | #endif | ||
137 | } | ||
138 | |||
139 | void | ||
140 | _evas_preload_thread_shutdown(void) | ||
141 | { | ||
142 | /* FIXME: If function are still running in the background, should we kill them ? */ | ||
143 | #ifdef BUILD_ASYNC_PRELOAD | ||
144 | Evas_Preload_Pthread_Worker *work; | ||
145 | |||
146 | /* Force processing of async events. */ | ||
147 | evas_async_events_process(); | ||
148 | LKL(_mutex); | ||
149 | while (_workers) | ||
150 | { | ||
151 | work = _workers; | ||
152 | _workers = EINA_INLIST_CONTAINER_GET(eina_inlist_remove(EINA_INLIST_GET(_workers), | ||
153 | EINA_INLIST_GET(_workers)), | ||
154 | Evas_Preload_Pthread_Worker); | ||
155 | if (work->func_cancel) work->func_cancel(work->data); | ||
156 | free(work); | ||
157 | } | ||
158 | LKU(_mutex); | ||
159 | |||
160 | LKD(_mutex); | ||
161 | #endif | ||
162 | } | ||
163 | |||
164 | Evas_Preload_Pthread * | ||
165 | evas_preload_thread_run(void (*func_heavy) (void *data), | ||
166 | void (*func_end) (void *data), | ||
167 | void (*func_cancel) (void *data), | ||
168 | const void *data) | ||
169 | { | ||
170 | #ifdef BUILD_ASYNC_PRELOAD | ||
171 | Evas_Preload_Pthread_Worker *work; | ||
172 | Evas_Preload_Pthread_Data *pth; | ||
173 | |||
174 | work = malloc(sizeof(Evas_Preload_Pthread_Worker)); | ||
175 | if (!work) | ||
176 | { | ||
177 | func_cancel((void *)data); | ||
178 | return NULL; | ||
179 | } | ||
180 | |||
181 | work->func_heavy = func_heavy; | ||
182 | work->func_end = func_end; | ||
183 | work->func_cancel = func_cancel; | ||
184 | work->cancel = EINA_FALSE; | ||
185 | work->data = (void *)data; | ||
186 | |||
187 | LKL(_mutex); | ||
188 | _workers = (Evas_Preload_Pthread_Worker *)eina_inlist_append(EINA_INLIST_GET(_workers), EINA_INLIST_GET(work)); | ||
189 | if (_threads_count == _threads_max) | ||
190 | { | ||
191 | LKU(_mutex); | ||
192 | return (Evas_Preload_Pthread *)work; | ||
193 | } | ||
194 | LKU(_mutex); | ||
195 | |||
196 | /* One more thread could be created. */ | ||
197 | pth = malloc(sizeof(Evas_Preload_Pthread_Data)); | ||
198 | if (!pth) goto on_error; | ||
199 | |||
200 | eina_threads_init(); | ||
201 | |||
202 | if (pthread_create(&pth->thread, NULL, _evas_preload_thread_worker, pth) == 0) | ||
203 | { | ||
204 | LKL(_mutex); | ||
205 | _threads_count++; | ||
206 | LKU(_mutex); | ||
207 | return (Evas_Preload_Pthread*)work; | ||
208 | } | ||
209 | |||
210 | eina_threads_shutdown(); | ||
211 | |||
212 | on_error: | ||
213 | LKL(_mutex); | ||
214 | if (_threads_count == 0) | ||
215 | { | ||
216 | LKU(_mutex); | ||
217 | if (work->func_cancel) work->func_cancel(work->data); | ||
218 | free(work); | ||
219 | return NULL; | ||
220 | } | ||
221 | LKU(_mutex); | ||
222 | return NULL; | ||
223 | #else | ||
224 | /* | ||
225 | If no thread and as we don't want to break app that rely on this | ||
226 | facility, we will lock the interface until we are done. | ||
227 | */ | ||
228 | (void)func_cancel; | ||
229 | func_heavy((void *)data); | ||
230 | func_end((void *)data); | ||
231 | return (void *)1; | ||
232 | #endif | ||
233 | } | ||
234 | |||
235 | Eina_Bool | ||
236 | evas_preload_thread_cancel(Evas_Preload_Pthread *thread) | ||
237 | { | ||
238 | #ifdef BUILD_ASYNC_PRELOAD | ||
239 | Evas_Preload_Pthread_Worker *work; | ||
240 | |||
241 | if (!thread) return EINA_TRUE; | ||
242 | LKL(_mutex); | ||
243 | EINA_INLIST_FOREACH(_workers, work) | ||
244 | { | ||
245 | if (work == (Evas_Preload_Pthread_Worker *)thread) | ||
246 | { | ||
247 | _workers = EINA_INLIST_CONTAINER_GET(eina_inlist_remove(EINA_INLIST_GET(_workers), | ||
248 | EINA_INLIST_GET(work)), | ||
249 | Evas_Preload_Pthread_Worker); | ||
250 | LKU(_mutex); | ||
251 | if (work->func_cancel) work->func_cancel(work->data); | ||
252 | free(work); | ||
253 | return EINA_TRUE; | ||
254 | } | ||
255 | } | ||
256 | LKU(_mutex); | ||
257 | |||
258 | /* Delay the destruction */ | ||
259 | work = (Evas_Preload_Pthread_Worker *)thread; | ||
260 | work->cancel = EINA_TRUE; | ||
261 | return EINA_FALSE; | ||
262 | #else | ||
263 | (void) thread; | ||
264 | return EINA_TRUE; | ||
265 | #endif | ||
266 | } | ||