eina: add Eina_Simple_Xml parser by Gustavo.
[profile/ivi/eina.git] / src / lib / eina_main.c
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_POSIX_THREADS
26 # include <pthread.h>
27 #endif
28
29 #ifdef EFL_HAVE_WIN32_THREADS
30 # define WIN32_LEAN_AND_MEAN
31 # include <windows.h>
32 # undef WIN32_LEAN_AND_MEAN
33 #endif
34
35 #include "eina_config.h"
36 #include "eina_private.h"
37 #include "eina_types.h"
38 #include "eina_main.h"
39 #include "eina_error.h"
40 #include "eina_log.h"
41 #include "eina_hash.h"
42 #include "eina_binshare.h"
43 #include "eina_stringshare.h"
44 #include "eina_ustringshare.h"
45 #include "eina_list.h"
46 #include "eina_matrixsparse.h"
47 #include "eina_array.h"
48 #include "eina_counter.h"
49 #include "eina_benchmark.h"
50 #include "eina_magic.h"
51 #include "eina_rectangle.h"
52 #include "eina_safety_checks.h"
53
54 /*============================================================================*
55 *                                  Local                                     *
56 *============================================================================*/
57
58 /**
59  * @cond LOCAL
60  */
61
62 static Eina_Version _version = { VMAJ, VMIN, VMIC, VREV };
63
64 static int _eina_main_count = 0;
65 #ifdef EFL_HAVE_THREADS
66 static int _eina_main_thread_count = 0;
67 #endif
68 static int _eina_log_dom = -1;
69
70 #ifdef ERR
71 #undef ERR
72 #endif
73 #define ERR(...) EINA_LOG_DOM_ERR(_eina_log_dom, __VA_ARGS__)
74
75 #ifdef DBG
76 #undef DBG
77 #endif
78 #define DBG(...) EINA_LOG_DOM_DBG(_eina_log_dom, __VA_ARGS__)
79
80 Eina_Bool _threads_activated = EINA_FALSE;
81
82 #ifdef EFL_HAVE_THREADS
83 # ifdef EFL_HAVE_POSIX_THREADS
84 static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER;
85 #  define LOCK() if(_threads_activated) pthread_mutex_lock(&_mutex)
86 #  define UNLOCK() if(_threads_activated) pthread_mutex_unlock(&_mutex)
87 #  define UNLOCK_FORCE() pthread_mutex_unlock(&_mutex)
88 # else /* EFL_HAVE_WIN32_THREADS */
89 static HANDLE _mutex = NULL;
90 #  define LOCK() if(_threads_activated) WaitForSingleObject(_mutex, INFINITE)
91 #  define UNLOCK() if(_threads_activated) ReleaseMutex(_mutex)
92 #  define UNLOCK_FORCE() ReleaseMutex(_mutex)
93 # endif
94 #else
95 # define LOCK() do {} while (0)
96 # define UNLOCK() do {} while (0)
97 # define UNLOCK_FORCE() do {} while (0)
98 #endif
99
100 /* place module init/shutdown functions here to avoid other modules
101  * calling them by mistake.
102  */
103 #define S(x) extern Eina_Bool eina_ ## x ## _init(void); \
104    extern Eina_Bool eina_ ## x ## _shutdown(void)
105    S(log);
106    S(error);
107    S(safety_checks);
108    S(magic_string);
109    S(iterator);
110    S(accessor);
111    S(array);
112    S(module);
113    S(mempool);
114    S(list);
115    S(binshare);
116    S(stringshare);
117    S(ustringshare);
118    S(matrixsparse);
119    S(convert);
120    S(counter);
121    S(benchmark);
122    S(rectangle);
123    S(strbuf);
124    S(ustrbuf);
125    S(quadtree);
126    S(simple_xml);
127 #undef S
128
129 struct eina_desc_setup
130 {
131    const char *name;
132    Eina_Bool (*init)(void);
133    Eina_Bool (*shutdown)(void);
134 };
135
136 static const struct eina_desc_setup _eina_desc_setup[] = {
137 #define S(x) {# x, eina_ ## x ## _init, eina_ ## x ## _shutdown}
138    /* log is a special case as it needs printf */
139    S(error),
140    S(safety_checks),
141    S(magic_string),
142    S(iterator),
143    S(accessor),
144    S(array),
145    S(module),
146    S(mempool),
147    S(list),
148    S(binshare),
149    S(stringshare),
150    S(ustringshare),
151    S(matrixsparse),
152    S(convert),
153    S(counter),
154    S(benchmark),
155    S(rectangle),
156    S(strbuf),
157    S(ustrbuf),
158    S(quadtree),
159    S(simple_xml)
160 #undef S
161 };
162 static const size_t _eina_desc_setup_len = sizeof(_eina_desc_setup) /
163    sizeof(_eina_desc_setup[0]);
164
165 static void
166 _eina_shutdown_from_desc(const struct eina_desc_setup *itr)
167 {
168    for (itr--; itr >= _eina_desc_setup; itr--)
169      {
170         if (!itr->shutdown())
171            ERR("Problems shutting down eina module '%s', ignored.", itr->name);
172      }
173
174    eina_log_domain_unregister(_eina_log_dom);
175    _eina_log_dom = -1;
176    eina_log_shutdown();
177 }
178
179 /**
180  * @endcond
181  */
182
183 /*============================================================================*
184 *                                 Global                                     *
185 *============================================================================*/
186
187
188 /*============================================================================*
189 *                                   API                                      *
190 *============================================================================*/
191
192 /**
193  * @addtogroup Eina_Main_Group Main
194  *
195  * @brief These functions provide general initialisation and shut down
196  * functions.
197  *
198  * @{
199  */
200
201 /**
202  * @var eina_version
203  * @brief Eina version (defined at configuration time)
204  */
205 EAPI Eina_Version *eina_version = &_version;
206
207 /**
208  * @brief Initialize the Eina library.
209  *
210  * @return 1 or greater on success, 0 on error.
211  *
212  * This function sets up all the eina modules. It returns 0 on
213  * failure (that is, when one of the module fails to initialize),
214  * otherwise it returns the number of times it has already been
215  * called.
216  *
217  * When Eina is not used anymore, call eina_shutdown() to shut down
218  * the Eina library.
219  */
220 EAPI int
221 eina_init(void)
222 {
223    const struct eina_desc_setup *itr, *itr_end;
224
225    if (EINA_LIKELY(_eina_main_count > 0))
226       return ++_eina_main_count;
227
228    if (!eina_log_init())
229      {
230         fprintf(stderr, "Could not initialize eina logging system.\n");
231         return 0;
232      }
233
234    _eina_log_dom = eina_log_domain_register("eina", EINA_LOG_COLOR_DEFAULT);
235    if (_eina_log_dom < 0)
236      {
237         EINA_LOG_ERR("Could not register log domain: eina");
238         eina_log_shutdown();
239         return 0;
240      }
241
242    itr = _eina_desc_setup;
243    itr_end = itr + _eina_desc_setup_len;
244    for (; itr < itr_end; itr++)
245      {
246         if (!itr->init())
247           {
248              ERR("Could not initialize eina module '%s'.", itr->name);
249              _eina_shutdown_from_desc(itr);
250              return 0;
251           }
252      }
253
254    _eina_main_count = 1;
255    return 1;
256 }
257
258 /**
259  * @brief Shut down the Eina library.
260  *
261  * @return 0 when all the modules is completely shut down, 1 or
262  * greater otherwise.
263  *
264  * This function shuts down the Eina library. It returns 0 when it has
265  * been called the same number of times than eina_init(). In that case
266  * it shut down all the Eina modules.
267  *
268  * Once this function succeeds (that is, @c 0 is returned), you must
269  * not call any of the Eina function anymore. You must call
270  * eina_init() again to use the Eina functions again.
271  */
272 EAPI int
273 eina_shutdown(void)
274 {
275    _eina_main_count--;
276    if (EINA_UNLIKELY(_eina_main_count == 0))
277              _eina_shutdown_from_desc(_eina_desc_setup + _eina_desc_setup_len);
278
279    return _eina_main_count;
280 }
281
282
283 /**
284  * @brief Initialize the mutexes of the Eina library.
285  *
286  * @return 1 or greater on success, 0 on error.
287  *
288  * This function sets up all the mutexes in all eina modules. It returns 0 on
289  * failure (that is, when one of the module fails to initialize),
290  * otherwise it returns the number of times it has already been
291  * called.
292  *
293  * When the mutexes are not used anymore, call eina_threads_shutdown() to shut down
294  * the mutexes.
295  */
296 EAPI int
297 eina_threads_init(void)
298 {
299 #ifdef EFL_HAVE_THREADS
300    int ret;
301
302 # ifdef EFL_HAVE_WIN32_THREADS
303    if (!_mutex)
304       _mutex = CreateMutex(NULL, FALSE, NULL);
305
306    if (!_mutex)
307       return 0;
308
309 # endif
310
311    LOCK();
312    ++_eina_main_thread_count;
313    ret = _eina_main_thread_count;
314
315    if(_eina_main_thread_count > 1)
316      {
317         UNLOCK();
318         return ret;
319      }
320
321    eina_share_common_threads_init();
322    eina_log_threads_init();
323    _threads_activated = EINA_TRUE;
324
325    return ret;
326 #else
327    return 0;
328 #endif
329 }
330
331 /**
332  * @brief Shut down mutexes in the Eina library.
333  *
334  * @return 0 when all mutexes are completely shut down, 1 or
335  * greater otherwise.
336  *
337  * This function shuts down the mutexes in the Eina library. It returns 0 when it has
338  * been called the same number of times than eina_threads_init(). In that case
339  * it shut down all the mutexes.
340  *
341  * Once this function succeeds (that is, @c 0 is returned), you must
342  * not call any of the Eina function in a thread anymore. You must call
343  * eina_threads_init() again to use the Eina functions in a thread again.
344  */
345 EAPI int
346 eina_threads_shutdown(void)
347 {
348 #ifdef EFL_HAVE_THREADS
349    int ret;
350
351    LOCK();
352    ret = --_eina_main_thread_count;
353    if(_eina_main_thread_count > 0)
354      {
355         UNLOCK();
356         return ret;
357      }
358
359    eina_share_common_threads_shutdown();
360    eina_log_threads_shutdown();
361
362    _threads_activated = EINA_FALSE;
363
364    UNLOCK_FORCE();
365
366 # ifdef EFL_HAVE_WIN32_THREADS
367    if (_mutex)
368       CloseHandle(_mutex);
369
370 # endif
371
372    return ret;
373 #else
374    return 0;
375 #endif
376 }
377
378 /**
379  * @}
380  */