diff options
author | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
---|---|---|
committer | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
commit | dd7595a3475407a7fa96a97393bae8c5220e8762 (patch) | |
tree | e341e911d7eb911a51684a7412ef7f7c7605d28e /libraries/eina/src/lib/eina_main.c | |
parent | Add the skeleton. (diff) | |
download | SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.zip SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.gz SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.bz2 SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.xz |
Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje.
Note that embryo wont be used, but I'm not sure yet if you can build edje without it.
Diffstat (limited to 'libraries/eina/src/lib/eina_main.c')
-rw-r--r-- | libraries/eina/src/lib/eina_main.c | 431 |
1 files changed, 431 insertions, 0 deletions
diff --git a/libraries/eina/src/lib/eina_main.c b/libraries/eina/src/lib/eina_main.c new file mode 100644 index 0000000..8727f83 --- /dev/null +++ b/libraries/eina/src/lib/eina_main.c | |||
@@ -0,0 +1,431 @@ | |||
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 | |||
71 | /*============================================================================* | ||
72 | * Local * | ||
73 | *============================================================================*/ | ||
74 | |||
75 | /** | ||
76 | * @cond LOCAL | ||
77 | */ | ||
78 | |||
79 | static Eina_Version _version = { VMAJ, VMIN, VMIC, VREV }; | ||
80 | |||
81 | static int _eina_main_count = 0; | ||
82 | #ifdef EFL_HAVE_THREADS | ||
83 | static int _eina_main_thread_count = 0; | ||
84 | #endif | ||
85 | static int _eina_log_dom = -1; | ||
86 | |||
87 | #ifdef ERR | ||
88 | #undef ERR | ||
89 | #endif | ||
90 | #define ERR(...) EINA_LOG_DOM_ERR(_eina_log_dom, __VA_ARGS__) | ||
91 | |||
92 | #ifdef DBG | ||
93 | #undef DBG | ||
94 | #endif | ||
95 | #define DBG(...) EINA_LOG_DOM_DBG(_eina_log_dom, __VA_ARGS__) | ||
96 | |||
97 | EAPI Eina_Bool _eina_threads_activated = EINA_FALSE; | ||
98 | EAPI Eina_Error EINA_ERROR_NOT_MAIN_LOOP = 0; | ||
99 | |||
100 | static const char EINA_ERROR_NOT_MAIN_LOOP_STR[] = "Main loop thread check failed."; | ||
101 | |||
102 | #ifdef EFL_HAVE_THREADS | ||
103 | # ifdef _WIN32 | ||
104 | EAPI DWORD _eina_main_loop; | ||
105 | # else | ||
106 | EAPI pthread_t _eina_main_loop; | ||
107 | # endif | ||
108 | static pid_t _eina_pid; | ||
109 | #endif | ||
110 | |||
111 | #ifdef MT | ||
112 | static int _mt_enabled = 0; | ||
113 | #endif | ||
114 | |||
115 | #ifdef EFL_HAVE_THREADS | ||
116 | EAPI int _eina_threads_debug = 0; | ||
117 | # if !defined(_WIN32_WCE) && !defined(_WIN32) | ||
118 | EAPI pthread_mutex_t _eina_tracking_lock; | ||
119 | EAPI Eina_Inlist *_eina_tracking = NULL; | ||
120 | # endif | ||
121 | #endif | ||
122 | |||
123 | /* place module init/shutdown functions here to avoid other modules | ||
124 | * calling them by mistake. | ||
125 | */ | ||
126 | #define S(x) extern Eina_Bool eina_ ## x ## _init(void); \ | ||
127 | extern Eina_Bool eina_ ## x ## _shutdown(void) | ||
128 | S(log); | ||
129 | S(error); | ||
130 | S(safety_checks); | ||
131 | S(magic_string); | ||
132 | S(iterator); | ||
133 | S(accessor); | ||
134 | S(array); | ||
135 | S(module); | ||
136 | S(mempool); | ||
137 | S(list); | ||
138 | S(binshare); | ||
139 | S(stringshare); | ||
140 | S(ustringshare); | ||
141 | S(matrixsparse); | ||
142 | S(convert); | ||
143 | S(counter); | ||
144 | S(benchmark); | ||
145 | S(rectangle); | ||
146 | S(strbuf); | ||
147 | S(ustrbuf); | ||
148 | S(quadtree); | ||
149 | S(simple_xml); | ||
150 | S(file); | ||
151 | S(prefix); | ||
152 | #undef S | ||
153 | |||
154 | struct eina_desc_setup | ||
155 | { | ||
156 | const char *name; | ||
157 | Eina_Bool (*init)(void); | ||
158 | Eina_Bool (*shutdown)(void); | ||
159 | }; | ||
160 | |||
161 | static const struct eina_desc_setup _eina_desc_setup[] = { | ||
162 | #define S(x) {# x, eina_ ## x ## _init, eina_ ## x ## _shutdown} | ||
163 | /* log is a special case as it needs printf */ | ||
164 | S(error), | ||
165 | S(safety_checks), | ||
166 | S(magic_string), | ||
167 | S(iterator), | ||
168 | S(accessor), | ||
169 | S(array), | ||
170 | S(module), | ||
171 | S(mempool), | ||
172 | S(list), | ||
173 | S(binshare), | ||
174 | S(stringshare), | ||
175 | S(ustringshare), | ||
176 | S(matrixsparse), | ||
177 | S(convert), | ||
178 | S(counter), | ||
179 | S(benchmark), | ||
180 | S(rectangle), | ||
181 | S(strbuf), | ||
182 | S(ustrbuf), | ||
183 | S(quadtree), | ||
184 | S(simple_xml), | ||
185 | S(file), | ||
186 | S(prefix) | ||
187 | #undef S | ||
188 | }; | ||
189 | static const size_t _eina_desc_setup_len = sizeof(_eina_desc_setup) / | ||
190 | sizeof(_eina_desc_setup[0]); | ||
191 | |||
192 | static void | ||
193 | _eina_shutdown_from_desc(const struct eina_desc_setup *itr) | ||
194 | { | ||
195 | for (itr--; itr >= _eina_desc_setup; itr--) | ||
196 | { | ||
197 | if (!itr->shutdown()) | ||
198 | ERR("Problems shutting down eina module '%s', ignored.", itr->name); | ||
199 | } | ||
200 | |||
201 | eina_log_domain_unregister(_eina_log_dom); | ||
202 | _eina_log_dom = -1; | ||
203 | eina_log_shutdown(); | ||
204 | } | ||
205 | |||
206 | /** | ||
207 | * @endcond | ||
208 | */ | ||
209 | |||
210 | /*============================================================================* | ||
211 | * Global * | ||
212 | *============================================================================*/ | ||
213 | |||
214 | |||
215 | /*============================================================================* | ||
216 | * API * | ||
217 | *============================================================================*/ | ||
218 | |||
219 | /** | ||
220 | * @var eina_version | ||
221 | * @brief Eina version (defined at configuration time) | ||
222 | */ | ||
223 | EAPI Eina_Version *eina_version = &_version; | ||
224 | |||
225 | EAPI int | ||
226 | eina_init(void) | ||
227 | { | ||
228 | const struct eina_desc_setup *itr, *itr_end; | ||
229 | |||
230 | if (EINA_LIKELY(_eina_main_count > 0)) | ||
231 | return ++_eina_main_count; | ||
232 | |||
233 | #ifdef MT | ||
234 | if ((getenv("EINA_MTRACE")) && (getenv("MALLOC_TRACE"))) | ||
235 | { | ||
236 | _mt_enabled = 1; | ||
237 | mtrace(); | ||
238 | } | ||
239 | #endif | ||
240 | |||
241 | if (!eina_log_init()) | ||
242 | { | ||
243 | fprintf(stderr, "Could not initialize eina logging system.\n"); | ||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | _eina_log_dom = eina_log_domain_register("eina", EINA_LOG_COLOR_DEFAULT); | ||
248 | if (_eina_log_dom < 0) | ||
249 | { | ||
250 | EINA_LOG_ERR("Could not register log domain: eina"); | ||
251 | eina_log_shutdown(); | ||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | EINA_ERROR_NOT_MAIN_LOOP = eina_error_msg_static_register( | ||
256 | EINA_ERROR_NOT_MAIN_LOOP_STR); | ||
257 | |||
258 | #ifdef EFL_HAVE_THREADS | ||
259 | # ifdef _WIN32 | ||
260 | _eina_main_loop = GetCurrentThreadId(); | ||
261 | # else | ||
262 | _eina_main_loop = pthread_self(); | ||
263 | # endif | ||
264 | _eina_pid = getpid(); | ||
265 | #endif | ||
266 | |||
267 | #ifdef EINA_HAVE_DEBUG_THREADS | ||
268 | pthread_mutex_init(&_eina_tracking_lock, NULL); | ||
269 | |||
270 | if (getenv("EINA_DEBUG_THREADS")) | ||
271 | _eina_threads_debug = atoi(getenv("EINA_DEBUG_THREADS")); | ||
272 | #endif | ||
273 | |||
274 | itr = _eina_desc_setup; | ||
275 | itr_end = itr + _eina_desc_setup_len; | ||
276 | for (; itr < itr_end; itr++) | ||
277 | { | ||
278 | if (!itr->init()) | ||
279 | { | ||
280 | ERR("Could not initialize eina module '%s'.", itr->name); | ||
281 | _eina_shutdown_from_desc(itr); | ||
282 | return 0; | ||
283 | } | ||
284 | } | ||
285 | |||
286 | _eina_main_count = 1; | ||
287 | return 1; | ||
288 | } | ||
289 | |||
290 | EAPI int | ||
291 | eina_shutdown(void) | ||
292 | { | ||
293 | _eina_main_count--; | ||
294 | if (EINA_UNLIKELY(_eina_main_count == 0)) | ||
295 | { | ||
296 | _eina_shutdown_from_desc(_eina_desc_setup + _eina_desc_setup_len); | ||
297 | |||
298 | #ifdef EINA_HAVE_DEBUG_THREADS | ||
299 | pthread_mutex_destroy(&_eina_tracking_lock); | ||
300 | #endif | ||
301 | #ifdef MT | ||
302 | if (_mt_enabled) | ||
303 | { | ||
304 | muntrace(); | ||
305 | _mt_enabled = 0; | ||
306 | } | ||
307 | #endif | ||
308 | } | ||
309 | |||
310 | return _eina_main_count; | ||
311 | } | ||
312 | |||
313 | |||
314 | EAPI int | ||
315 | eina_threads_init(void) | ||
316 | { | ||
317 | #ifdef EFL_HAVE_THREADS | ||
318 | int ret; | ||
319 | |||
320 | #ifdef EINA_HAVE_DEBUG_THREADS | ||
321 | assert(pthread_equal(_eina_main_loop, pthread_self())); | ||
322 | #endif | ||
323 | |||
324 | ++_eina_main_thread_count; | ||
325 | ret = _eina_main_thread_count; | ||
326 | |||
327 | if(_eina_main_thread_count > 1) | ||
328 | return ret; | ||
329 | |||
330 | eina_share_common_threads_init(); | ||
331 | eina_log_threads_init(); | ||
332 | _eina_threads_activated = EINA_TRUE; | ||
333 | |||
334 | return ret; | ||
335 | #else | ||
336 | return 0; | ||
337 | #endif | ||
338 | } | ||
339 | |||
340 | EAPI int | ||
341 | eina_threads_shutdown(void) | ||
342 | { | ||
343 | #ifdef EFL_HAVE_THREADS | ||
344 | int ret; | ||
345 | |||
346 | #ifdef EINA_HAVE_DEBUG_THREADS | ||
347 | const Eina_Lock *lk; | ||
348 | |||
349 | assert(pthread_equal(_eina_main_loop, pthread_self())); | ||
350 | assert(_eina_main_thread_count > 0); | ||
351 | #endif | ||
352 | |||
353 | ret = --_eina_main_thread_count; | ||
354 | if(_eina_main_thread_count > 0) | ||
355 | return ret; | ||
356 | |||
357 | #ifdef EINA_HAVE_DEBUG_THREADS | ||
358 | pthread_mutex_lock(&_eina_tracking_lock); | ||
359 | if (_eina_tracking) | ||
360 | { | ||
361 | fprintf(stderr, "*************************\n"); | ||
362 | fprintf(stderr, "* The IMPOSSIBLE HAPPEN *\n"); | ||
363 | fprintf(stderr, "* LOCK STILL TAKEN : *\n"); | ||
364 | fprintf(stderr, "*************************\n"); | ||
365 | EINA_INLIST_FOREACH(_eina_tracking, lk) | ||
366 | eina_lock_debug(lk); | ||
367 | fprintf(stderr, "*************************\n"); | ||
368 | abort(); | ||
369 | } | ||
370 | pthread_mutex_unlock(&_eina_tracking_lock); | ||
371 | #endif | ||
372 | |||
373 | eina_share_common_threads_shutdown(); | ||
374 | eina_log_threads_shutdown(); | ||
375 | |||
376 | _eina_threads_activated = EINA_FALSE; | ||
377 | |||
378 | return ret; | ||
379 | #else | ||
380 | return 0; | ||
381 | #endif | ||
382 | } | ||
383 | |||
384 | EAPI Eina_Bool | ||
385 | eina_main_loop_is(void) | ||
386 | { | ||
387 | #ifdef EFL_HAVE_THREADS | ||
388 | pid_t pid = getpid(); | ||
389 | |||
390 | # ifdef _WIN32 | ||
391 | if (pid != _eina_pid) | ||
392 | { | ||
393 | _eina_pid = pid; | ||
394 | _eina_main_loop = GetCurrentThreadId(); | ||
395 | return EINA_TRUE; | ||
396 | } | ||
397 | if (_eina_main_loop == GetCurrentThreadId()) | ||
398 | return EINA_TRUE; | ||
399 | # else | ||
400 | if (pid != _eina_pid) | ||
401 | { | ||
402 | /* This is in case of a fork, but don't like the solution */ | ||
403 | _eina_pid = pid; | ||
404 | _eina_main_loop = pthread_self(); | ||
405 | return EINA_TRUE; | ||
406 | } | ||
407 | |||
408 | if (pthread_equal(_eina_main_loop, pthread_self())) | ||
409 | return EINA_TRUE; | ||
410 | # endif | ||
411 | #endif | ||
412 | return EINA_FALSE; | ||
413 | } | ||
414 | |||
415 | /** The purpose of this API should not be documented, it is used only by the one who know what they are doing. */ | ||
416 | EAPI void | ||
417 | eina_main_loop_define(void) | ||
418 | { | ||
419 | #ifdef EFL_HAVE_THREADS | ||
420 | _eina_pid = getpid(); | ||
421 | # ifdef _WIN32 | ||
422 | _eina_main_loop = GetCurrentThreadId(); | ||
423 | # else | ||
424 | _eina_main_loop = pthread_self(); | ||
425 | # endif | ||
426 | #endif | ||
427 | } | ||
428 | |||
429 | /** | ||
430 | * @} | ||
431 | */ | ||