and these
[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 #include <stdio.h>
20
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
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 static Eina_Version _version = { VMAJ, VMIN, VMIC, VREV };
55 EAPI Eina_Version *eina_version = &_version;
56
57 /*============================================================================*
58 *                                  Local                                     *
59 *============================================================================*/
60
61 /**
62  * @cond LOCAL
63  */
64
65 static int _eina_main_count = 0;
66 #ifdef EFL_HAVE_THREADS
67 static int _eina_main_thread_count = 0;
68 #endif
69 static int _eina_log_dom = -1;
70
71 #ifdef ERR
72 #undef ERR
73 #endif
74 #define ERR(...) EINA_LOG_DOM_ERR(_eina_log_dom, __VA_ARGS__)
75
76 #ifdef DBG
77 #undef DBG
78 #endif
79 #define DBG(...) EINA_LOG_DOM_DBG(_eina_log_dom, __VA_ARGS__)
80
81 #ifdef EFL_HAVE_THREADS
82 static Eina_Bool _threads_activated = EINA_FALSE;
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 #undef S
127
128 struct eina_desc_setup
129 {
130    const char *name;
131    Eina_Bool (*init)(void);
132    Eina_Bool (*shutdown)(void);
133 };
134
135 static const struct eina_desc_setup _eina_desc_setup[] = {
136 #define S(x) {# x, eina_ ## x ## _init, eina_ ## x ## _shutdown}
137    /* log is a special case as it needs printf */
138    S(error),
139    S(safety_checks),
140    S(magic_string),
141    S(iterator),
142    S(accessor),
143    S(array),
144    S(module),
145    S(mempool),
146    S(list),
147    S(binshare),
148    S(stringshare),
149    S(ustringshare),
150    S(matrixsparse),
151    S(convert),
152    S(counter),
153    S(benchmark),
154    S(rectangle),
155    S(strbuf),
156    S(ustrbuf),
157    S(quadtree)
158 #undef S
159 };
160 static const size_t _eina_desc_setup_len = sizeof(_eina_desc_setup) /
161    sizeof(_eina_desc_setup[0]);
162
163 static void
164 _eina_shutdown_from_desc(const struct eina_desc_setup *itr)
165 {
166    for (itr--; itr >= _eina_desc_setup; itr--)
167      {
168         if (!itr->shutdown())
169            ERR("Problems shutting down eina module '%s', ignored.", itr->name);
170      }
171
172    eina_log_domain_unregister(_eina_log_dom);
173    _eina_log_dom = -1;
174    eina_log_shutdown();
175 }
176
177 /**
178  * @endcond
179  */
180
181 /*============================================================================*
182 *                                 Global                                     *
183 *============================================================================*/
184
185 /*============================================================================*
186 *                                   API                                      *
187 *============================================================================*/
188
189 /**
190  * @addtogroup Eina_Main_Group Main
191  *
192  * @brief These functions provide general initialisation and shut down
193  * functions.
194  *
195  * @{
196  */
197
198 /**
199  * @brief Initialize the Eina library.
200  *
201  * @return 1 or greater on success, 0 on error.
202  *
203  * This function sets up all the eina modules. It returns 0 on
204  * failure (that is, when one of the module fails to initialize),
205  * otherwise it returns the number of times it has already been
206  * called.
207  *
208  * When Eina is not used anymore, call eina_shutdown() to shut down
209  * the Eina library.
210  */
211 EAPI int
212 eina_init(void)
213 {
214    const struct eina_desc_setup *itr, *itr_end;
215
216    if (EINA_LIKELY(_eina_main_count > 0))
217       return ++_eina_main_count;
218
219    if (!eina_log_init())
220      {
221         fprintf(stderr, "Could not initialize eina logging system.\n");
222         return 0;
223      }
224
225    _eina_log_dom = eina_log_domain_register("eina", EINA_LOG_COLOR_DEFAULT);
226    if (_eina_log_dom < 0)
227      {
228         EINA_LOG_ERR("Could not register log domain: eina");
229         eina_log_shutdown();
230         return 0;
231      }
232
233    itr = _eina_desc_setup;
234    itr_end = itr + _eina_desc_setup_len;
235    for (; itr < itr_end; itr++)
236      {
237         if (!itr->init())
238           {
239              ERR("Could not initialize eina module '%s'.", itr->name);
240              _eina_shutdown_from_desc(itr);
241              return 0;
242           }
243      }
244
245    _eina_main_count = 1;
246    return 1;
247 }
248
249 /**
250  * @brief Shut down the Eina library.
251  *
252  * @return 0 when all the modules is completely shut down, 1 or
253  * greater otherwise.
254  *
255  * This function shuts down the Eina library. It returns 0 when it has
256  * been called the same number of times than eina_init(). In that case
257  * it shut down all the Eina modules.
258  *
259  * Once this function succeeds (that is, @c 0 is returned), you must
260  * not call any of the Eina function anymore. You must call
261  * eina_init() again to use the Eina functions again.
262  */
263 EAPI int
264 eina_shutdown(void)
265 {
266    _eina_main_count--;
267    if (EINA_UNLIKELY(_eina_main_count == 0))
268              _eina_shutdown_from_desc(_eina_desc_setup + _eina_desc_setup_len);
269
270    return _eina_main_count;
271 }
272
273
274 /**
275  * @brief Initialize the mutexs of the Eina library.
276  *
277  * @return 1 or greater on success, 0 on error.
278  *
279  * This function sets up all the mutexs in all eina modules. It returns 0 on
280  * failure (that is, when one of the module fails to initialize),
281  * otherwise it returns the number of times it has already been
282  * called.
283  *
284  * When the mutexs are not used anymore, call eina_thread_shutdown() to shut down
285  * the mutexs.
286  */
287 EAPI int
288 eina_threads_init(void)
289 {
290 #ifdef EFL_HAVE_THREADS
291    int ret;
292
293 # ifdef EFL_HAVE_WIN32_THREADS
294    if (!_mutex)
295       _mutex = CreateMutex(NULL, FALSE, NULL);
296
297    if (!_mutex)
298       return 0;
299
300 # endif
301
302    LOCK();
303    ++_eina_main_thread_count;
304    ret = _eina_main_thread_count;
305
306    if(_eina_main_thread_count > 1)
307      {
308         UNLOCK();
309         return ret;
310      }
311
312    eina_share_common_threads_init();
313    eina_log_threads_init();
314    _threads_activated = EINA_TRUE;
315
316    return ret;
317 #else
318    return 0;
319 #endif
320 }
321
322 /**
323  * @brief Shut down mutexs in the Eina library.
324  *
325  * @return 0 when all mutexs are completely shut down, 1 or
326  * greater otherwise.
327  *
328  * This function shuts down the mutexs in the Eina library. It returns 0 when it has
329  * been called the same number of times than eina_thread_init(). In that case
330  * it shut down all the mutexs.
331  *
332  * Once this function succeeds (that is, @c 0 is returned), you must
333  * not call any of the Eina function in a thread anymore. You must call
334  * eina_thread_init() again to use the Eina functions in a thread again.
335  */
336 EAPI int
337 eina_threads_shutdown(void)
338 {
339 #ifdef EFL_HAVE_THREADS
340    int ret;
341
342    LOCK();
343    ret = --_eina_main_thread_count;
344    if(_eina_main_thread_count > 0)
345      {
346         UNLOCK();
347         return ret;
348      }
349
350    eina_share_common_threads_shutdown();
351    eina_log_threads_shutdown();
352
353    _threads_activated = EINA_FALSE;
354
355    UNLOCK_FORCE();
356
357 # ifdef EFL_HAVE_WIN32_THREADS
358    if (_mutex)
359       CloseHandle(_mutex);
360
361 # endif
362
363    return ret;
364 #else
365    return 0;
366 #endif
367 }
368
369 /**
370  * @}
371  */