diff options
Diffstat (limited to 'libraries/eina/src/lib/eina_main.c')
-rw-r--r-- | libraries/eina/src/lib/eina_main.c | 440 |
1 files changed, 0 insertions, 440 deletions
diff --git a/libraries/eina/src/lib/eina_main.c b/libraries/eina/src/lib/eina_main.c deleted file mode 100644 index f233929..0000000 --- a/libraries/eina/src/lib/eina_main.c +++ /dev/null | |||
@@ -1,440 +0,0 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2008 Cedric Bail | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifdef HAVE_CONFIG_H | ||
20 | # include "config.h" | ||
21 | #endif | ||
22 | |||
23 | #include <stdio.h> | ||
24 | |||
25 | #ifdef EFL_HAVE_WIN32_THREADS | ||
26 | # define WIN32_LEAN_AND_MEAN | ||
27 | # include <windows.h> | ||
28 | # undef WIN32_LEAN_AND_MEAN | ||
29 | #endif | ||
30 | |||
31 | #ifdef EFL_HAVE_THREADS | ||
32 | # ifdef HAVE_SYS_TYPES_H | ||
33 | # include <sys/types.h> | ||
34 | # endif | ||
35 | # ifdef HAVE_UNISTD_H | ||
36 | # include <unistd.h> | ||
37 | # endif | ||
38 | #endif | ||
39 | |||
40 | #ifdef HAVE_MCHECK | ||
41 | # ifdef HAVE_MTRACE | ||
42 | # define MT 1 | ||
43 | # endif | ||
44 | #endif | ||
45 | |||
46 | #ifdef MT | ||
47 | #include <mcheck.h> | ||
48 | #endif | ||
49 | |||
50 | #include "eina_lock.h" | ||
51 | #include "eina_config.h" | ||
52 | #include "eina_private.h" | ||
53 | #include "eina_types.h" | ||
54 | #include "eina_main.h" | ||
55 | #include "eina_error.h" | ||
56 | #include "eina_log.h" | ||
57 | #include "eina_hash.h" | ||
58 | #include "eina_binshare.h" | ||
59 | #include "eina_stringshare.h" | ||
60 | #include "eina_ustringshare.h" | ||
61 | #include "eina_list.h" | ||
62 | #include "eina_matrixsparse.h" | ||
63 | #include "eina_array.h" | ||
64 | #include "eina_counter.h" | ||
65 | #include "eina_benchmark.h" | ||
66 | #include "eina_magic.h" | ||
67 | #include "eina_rectangle.h" | ||
68 | #include "eina_safety_checks.h" | ||
69 | #include "eina_inlist.h" | ||
70 | #include "eina_inarray.h" | ||
71 | #include "eina_value.h" | ||
72 | #include "eina_model.h" | ||
73 | |||
74 | /*============================================================================* | ||
75 | * Local * | ||
76 | *============================================================================*/ | ||
77 | |||
78 | /** | ||
79 | * @cond LOCAL | ||
80 | */ | ||
81 | |||
82 | static Eina_Version _version = { VMAJ, VMIN, VMIC, VREV }; | ||
83 | |||
84 | static int _eina_main_count = 0; | ||
85 | #ifdef EFL_HAVE_THREADS | ||
86 | static int _eina_main_thread_count = 0; | ||
87 | #endif | ||
88 | static int _eina_log_dom = -1; | ||
89 | |||
90 | #ifdef ERR | ||
91 | #undef ERR | ||
92 | #endif | ||
93 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_log_dom, __VA_ARGS__) | ||
94 | |||
95 | #ifdef DBG | ||
96 | #undef DBG | ||
97 | #endif | ||
98 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_log_dom, __VA_ARGS__) | ||
99 | |||
100 | EAPI Eina_Bool _eina_threads_activated = EINA_FALSE; | ||
101 | EAPI Eina_Error EINA_ERROR_NOT_MAIN_LOOP = 0; | ||
102 | |||
103 | static const char EINA_ERROR_NOT_MAIN_LOOP_STR[] = "Main loop thread check failed."; | ||
104 | |||
105 | #ifdef EFL_HAVE_THREADS | ||
106 | # ifdef _WIN32 | ||
107 | EAPI DWORD _eina_main_loop; | ||
108 | # else | ||
109 | EAPI pthread_t _eina_main_loop; | ||
110 | # endif | ||
111 | static pid_t _eina_pid; | ||
112 | #endif | ||
113 | |||
114 | #ifdef MT | ||
115 | static int _mt_enabled = 0; | ||
116 | #endif | ||
117 | |||
118 | #ifdef EFL_HAVE_THREADS | ||
119 | EAPI int _eina_threads_debug = 0; | ||
120 | # if !defined(_WIN32_WCE) && !defined(_WIN32) | ||
121 | EAPI pthread_mutex_t _eina_tracking_lock; | ||
122 | EAPI Eina_Inlist *_eina_tracking = NULL; | ||
123 | # endif | ||
124 | #endif | ||
125 | |||
126 | /* place module init/shutdown functions here to avoid other modules | ||
127 | * calling them by mistake. | ||
128 | */ | ||
129 | #define S(x) extern Eina_Bool eina_ ## x ## _init(void); \ | ||
130 | extern Eina_Bool eina_ ## x ## _shutdown(void) | ||
131 | S(log); | ||
132 | S(error); | ||
133 | S(safety_checks); | ||
134 | S(magic_string); | ||
135 | S(iterator); | ||
136 | S(accessor); | ||
137 | S(inarray); | ||
138 | S(array); | ||
139 | S(module); | ||
140 | S(mempool); | ||
141 | S(list); | ||
142 | S(binshare); | ||
143 | S(stringshare); | ||
144 | S(ustringshare); | ||
145 | S(matrixsparse); | ||
146 | S(convert); | ||
147 | S(counter); | ||
148 | S(benchmark); | ||
149 | S(rectangle); | ||
150 | S(strbuf); | ||
151 | S(ustrbuf); | ||
152 | S(quadtree); | ||
153 | S(simple_xml); | ||
154 | S(file); | ||
155 | S(prefix); | ||
156 | S(value); | ||
157 | S(model); | ||
158 | #undef S | ||
159 | |||
160 | struct eina_desc_setup | ||
161 | { | ||
162 | const char *name; | ||
163 | Eina_Bool (*init)(void); | ||
164 | Eina_Bool (*shutdown)(void); | ||
165 | }; | ||
166 | |||
167 | static const struct eina_desc_setup _eina_desc_setup[] = { | ||
168 | #define S(x) {# x, eina_ ## x ## _init, eina_ ## x ## _shutdown} | ||
169 | /* log is a special case as it needs printf */ | ||
170 | S(stringshare), | ||
171 | S(error), | ||
172 | S(safety_checks), | ||
173 | S(magic_string), | ||
174 | S(iterator), | ||
175 | S(accessor), | ||
176 | S(inarray), | ||
177 | S(array), | ||
178 | S(module), | ||
179 | S(mempool), | ||
180 | S(list), | ||
181 | S(binshare), | ||
182 | S(ustringshare), | ||
183 | S(matrixsparse), | ||
184 | S(convert), | ||
185 | S(counter), | ||
186 | S(benchmark), | ||
187 | S(rectangle), | ||
188 | S(strbuf), | ||
189 | S(ustrbuf), | ||
190 | S(quadtree), | ||
191 | S(simple_xml), | ||
192 | S(file), | ||
193 | S(prefix), | ||
194 | S(value), | ||
195 | S(model) | ||
196 | #undef S | ||
197 | }; | ||
198 | static const size_t _eina_desc_setup_len = sizeof(_eina_desc_setup) / | ||
199 | sizeof(_eina_desc_setup[0]); | ||
200 | |||
201 | static void | ||
202 | _eina_shutdown_from_desc(const struct eina_desc_setup *itr) | ||
203 | { | ||
204 | for (itr--; itr >= _eina_desc_setup; itr--) | ||
205 | { | ||
206 | if (!itr->shutdown()) | ||
207 | ERR("Problems shutting down eina module '%s', ignored.", itr->name); | ||
208 | } | ||
209 | |||
210 | eina_log_domain_unregister(_eina_log_dom); | ||
211 | _eina_log_dom = -1; | ||
212 | eina_log_shutdown(); | ||
213 | } | ||
214 | |||
215 | /** | ||
216 | * @endcond | ||
217 | */ | ||
218 | |||
219 | /*============================================================================* | ||
220 | * Global * | ||
221 | *============================================================================*/ | ||
222 | |||
223 | |||
224 | /*============================================================================* | ||
225 | * API * | ||
226 | *============================================================================*/ | ||
227 | |||
228 | /** | ||
229 | * @var eina_version | ||
230 | * @brief Eina version (defined at configuration time) | ||
231 | */ | ||
232 | EAPI Eina_Version *eina_version = &_version; | ||
233 | |||
234 | EAPI int | ||
235 | eina_init(void) | ||
236 | { | ||
237 | const struct eina_desc_setup *itr, *itr_end; | ||
238 | |||
239 | if (EINA_LIKELY(_eina_main_count > 0)) | ||
240 | return ++_eina_main_count; | ||
241 | |||
242 | #ifdef MT | ||
243 | if ((getenv("EINA_MTRACE")) && (getenv("MALLOC_TRACE"))) | ||
244 | { | ||
245 | _mt_enabled = 1; | ||
246 | mtrace(); | ||
247 | } | ||
248 | #endif | ||
249 | |||
250 | if (!eina_log_init()) | ||
251 | { | ||
252 | fprintf(stderr, "Could not initialize eina logging system.\n"); | ||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | _eina_log_dom = eina_log_domain_register("eina", EINA_LOG_COLOR_DEFAULT); | ||
257 | if (_eina_log_dom < 0) | ||
258 | { | ||
259 | EINA_LOG_ERR("Could not register log domain: eina"); | ||
260 | eina_log_shutdown(); | ||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | EINA_ERROR_NOT_MAIN_LOOP = eina_error_msg_static_register( | ||
265 | EINA_ERROR_NOT_MAIN_LOOP_STR); | ||
266 | |||
267 | #ifdef EFL_HAVE_THREADS | ||
268 | # ifdef _WIN32 | ||
269 | _eina_main_loop = GetCurrentThreadId(); | ||
270 | # else | ||
271 | _eina_main_loop = pthread_self(); | ||
272 | # endif | ||
273 | _eina_pid = getpid(); | ||
274 | #endif | ||
275 | |||
276 | #ifdef EINA_HAVE_DEBUG_THREADS | ||
277 | pthread_mutex_init(&_eina_tracking_lock, NULL); | ||
278 | |||
279 | if (getenv("EINA_DEBUG_THREADS")) | ||
280 | _eina_threads_debug = atoi(getenv("EINA_DEBUG_THREADS")); | ||
281 | #endif | ||
282 | |||
283 | itr = _eina_desc_setup; | ||
284 | itr_end = itr + _eina_desc_setup_len; | ||
285 | for (; itr < itr_end; itr++) | ||
286 | { | ||
287 | if (!itr->init()) | ||
288 | { | ||
289 | ERR("Could not initialize eina module '%s'.", itr->name); | ||
290 | _eina_shutdown_from_desc(itr); | ||
291 | return 0; | ||
292 | } | ||
293 | } | ||
294 | |||
295 | _eina_main_count = 1; | ||
296 | return 1; | ||
297 | } | ||
298 | |||
299 | EAPI int | ||
300 | eina_shutdown(void) | ||
301 | { | ||
302 | _eina_main_count--; | ||
303 | if (EINA_UNLIKELY(_eina_main_count == 0)) | ||
304 | { | ||
305 | _eina_shutdown_from_desc(_eina_desc_setup + _eina_desc_setup_len); | ||
306 | |||
307 | #ifdef EINA_HAVE_DEBUG_THREADS | ||
308 | pthread_mutex_destroy(&_eina_tracking_lock); | ||
309 | #endif | ||
310 | #ifdef MT | ||
311 | if (_mt_enabled) | ||
312 | { | ||
313 | muntrace(); | ||
314 | _mt_enabled = 0; | ||
315 | } | ||
316 | #endif | ||
317 | } | ||
318 | |||
319 | return _eina_main_count; | ||
320 | } | ||
321 | |||
322 | |||
323 | EAPI int | ||
324 | eina_threads_init(void) | ||
325 | { | ||
326 | #ifdef EFL_HAVE_THREADS | ||
327 | int ret; | ||
328 | |||
329 | #ifdef EINA_HAVE_DEBUG_THREADS | ||
330 | assert(pthread_equal(_eina_main_loop, pthread_self())); | ||
331 | #endif | ||
332 | |||
333 | ++_eina_main_thread_count; | ||
334 | ret = _eina_main_thread_count; | ||
335 | |||
336 | if(_eina_main_thread_count > 1) | ||
337 | return ret; | ||
338 | |||
339 | eina_share_common_threads_init(); | ||
340 | eina_log_threads_init(); | ||
341 | _eina_threads_activated = EINA_TRUE; | ||
342 | |||
343 | return ret; | ||
344 | #else | ||
345 | return 0; | ||
346 | #endif | ||
347 | } | ||
348 | |||
349 | EAPI int | ||
350 | eina_threads_shutdown(void) | ||
351 | { | ||
352 | #ifdef EFL_HAVE_THREADS | ||
353 | int ret; | ||
354 | |||
355 | #ifdef EINA_HAVE_DEBUG_THREADS | ||
356 | const Eina_Lock *lk; | ||
357 | |||
358 | assert(pthread_equal(_eina_main_loop, pthread_self())); | ||
359 | assert(_eina_main_thread_count > 0); | ||
360 | #endif | ||
361 | |||
362 | ret = --_eina_main_thread_count; | ||
363 | if(_eina_main_thread_count > 0) | ||
364 | return ret; | ||
365 | |||
366 | #ifdef EINA_HAVE_DEBUG_THREADS | ||
367 | pthread_mutex_lock(&_eina_tracking_lock); | ||
368 | if (_eina_tracking) | ||
369 | { | ||
370 | fprintf(stderr, "*************************\n"); | ||
371 | fprintf(stderr, "* The IMPOSSIBLE HAPPEN *\n"); | ||
372 | fprintf(stderr, "* LOCK STILL TAKEN : *\n"); | ||
373 | fprintf(stderr, "*************************\n"); | ||
374 | EINA_INLIST_FOREACH(_eina_tracking, lk) | ||
375 | eina_lock_debug(lk); | ||
376 | fprintf(stderr, "*************************\n"); | ||
377 | abort(); | ||
378 | } | ||
379 | pthread_mutex_unlock(&_eina_tracking_lock); | ||
380 | #endif | ||
381 | |||
382 | eina_share_common_threads_shutdown(); | ||
383 | eina_log_threads_shutdown(); | ||
384 | |||
385 | _eina_threads_activated = EINA_FALSE; | ||
386 | |||
387 | return ret; | ||
388 | #else | ||
389 | return 0; | ||
390 | #endif | ||
391 | } | ||
392 | |||
393 | EAPI Eina_Bool | ||
394 | eina_main_loop_is(void) | ||
395 | { | ||
396 | #ifdef EFL_HAVE_THREADS | ||
397 | pid_t pid = getpid(); | ||
398 | |||
399 | # ifdef _WIN32 | ||
400 | if (pid != _eina_pid) | ||
401 | { | ||
402 | _eina_pid = pid; | ||
403 | _eina_main_loop = GetCurrentThreadId(); | ||
404 | return EINA_TRUE; | ||
405 | } | ||
406 | if (_eina_main_loop == GetCurrentThreadId()) | ||
407 | return EINA_TRUE; | ||
408 | # else | ||
409 | if (pid != _eina_pid) | ||
410 | { | ||
411 | /* This is in case of a fork, but don't like the solution */ | ||
412 | _eina_pid = pid; | ||
413 | _eina_main_loop = pthread_self(); | ||
414 | return EINA_TRUE; | ||
415 | } | ||
416 | |||
417 | if (pthread_equal(_eina_main_loop, pthread_self())) | ||
418 | return EINA_TRUE; | ||
419 | # endif | ||
420 | #endif | ||
421 | return EINA_FALSE; | ||
422 | } | ||
423 | |||
424 | /** The purpose of this API should not be documented, it is used only by the one who know what they are doing. */ | ||
425 | EAPI void | ||
426 | eina_main_loop_define(void) | ||
427 | { | ||
428 | #ifdef EFL_HAVE_THREADS | ||
429 | _eina_pid = getpid(); | ||
430 | # ifdef _WIN32 | ||
431 | _eina_main_loop = GetCurrentThreadId(); | ||
432 | # else | ||
433 | _eina_main_loop = pthread_self(); | ||
434 | # endif | ||
435 | #endif | ||
436 | } | ||
437 | |||
438 | /** | ||
439 | * @} | ||
440 | */ | ||