aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/eina/src/lib/eina_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/eina/src/lib/eina_main.c')
-rw-r--r--libraries/eina/src/lib/eina_main.c440
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
82static Eina_Version _version = { VMAJ, VMIN, VMIC, VREV };
83
84static int _eina_main_count = 0;
85#ifdef EFL_HAVE_THREADS
86static int _eina_main_thread_count = 0;
87#endif
88static 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
100EAPI Eina_Bool _eina_threads_activated = EINA_FALSE;
101EAPI Eina_Error EINA_ERROR_NOT_MAIN_LOOP = 0;
102
103static const char EINA_ERROR_NOT_MAIN_LOOP_STR[] = "Main loop thread check failed.";
104
105#ifdef EFL_HAVE_THREADS
106# ifdef _WIN32
107EAPI DWORD _eina_main_loop;
108# else
109EAPI pthread_t _eina_main_loop;
110# endif
111static pid_t _eina_pid;
112#endif
113
114#ifdef MT
115static int _mt_enabled = 0;
116#endif
117
118#ifdef EFL_HAVE_THREADS
119EAPI int _eina_threads_debug = 0;
120# if !defined(_WIN32_WCE) && !defined(_WIN32)
121EAPI pthread_mutex_t _eina_tracking_lock;
122EAPI 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
160struct eina_desc_setup
161{
162 const char *name;
163 Eina_Bool (*init)(void);
164 Eina_Bool (*shutdown)(void);
165};
166
167static 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};
198static const size_t _eina_desc_setup_len = sizeof(_eina_desc_setup) /
199 sizeof(_eina_desc_setup[0]);
200
201static 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 */
232EAPI Eina_Version *eina_version = &_version;
233
234EAPI int
235eina_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
299EAPI int
300eina_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
323EAPI int
324eina_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
349EAPI int
350eina_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
393EAPI Eina_Bool
394eina_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. */
425EAPI void
426eina_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 */