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