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