From 4598f6ade76e5da0b8464854d42b30ce946675e8 Mon Sep 17 00:00:00 2001 From: barbieri Date: Fri, 4 Sep 2009 00:53:19 +0000 Subject: [PATCH] eina_safety_checks_init() All these individual init functions are getting messy, some modules lack them and it's easy to get inconsistent. Safety check needs error and log, but these need safety checks as well, some modules (lalloc, rbtree and others) use safety checks but provide no _init(). I want to know if we really gain something to init individual modules. It should not be that expensive as init should not allocate heavy resources and the recommendation is to call eina_init() so most users will do that anyway. If people agree I'll unmark all *_init() as EAPI and make them private to eina lib. git-svn-id: http://svn.enlightenment.org/svn/e/trunk/eina@42214 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/include/eina_safety_checks.h | 65 ++++++++++++++++++++++++++++++++++++++++ src/lib/Makefile.am | 3 +- src/lib/eina_array.c | 8 +++++ src/lib/eina_convert.c | 9 ++++++ src/lib/eina_counter.c | 14 ++++++++- src/lib/eina_error.c | 32 ++++++++++++-------- src/lib/eina_hash.c | 24 +++++++++++---- src/lib/eina_list.c | 8 +++++ src/lib/eina_log.c | 17 ++++++++--- src/lib/eina_main.c | 32 ++++++++++++++------ src/lib/eina_mempool.c | 11 ++++++- src/lib/eina_module.c | 9 ++++++ src/lib/eina_rectangle.c | 8 +++++ src/lib/eina_stringshare.c | 8 +++++ 14 files changed, 214 insertions(+), 34 deletions(-) diff --git a/src/include/eina_safety_checks.h b/src/include/eina_safety_checks.h index 7b3d80c..5081677 100644 --- a/src/include/eina_safety_checks.h +++ b/src/include/eina_safety_checks.h @@ -19,8 +19,63 @@ #ifndef EINA_SAFETY_CHECKS_H_ #define EINA_SAFETY_CHECKS_H_ +/** + * @addtogroup Eina_Tools_Group Tools + * + * @{ + */ + +/** + * @defgroup Eina_Safety_Checks_Group Safety Checks + * + * @warning @c eina_safety_checks.h should only be included by source + * files, after all other includes and before the source file + * specific includes. By source file specific includes we + * mean those that define the functions that are being + * checked. The reason for such complexity is the trick to + * avoid compiler optimizations. If compilers are told that + * some given function will never receive @c NULL + * (EINA_ARG_NONNULL(), then compiler will emit a warning if + * it detects so (good!) but will remove any checks for that + * condition as it believes it will never happen, removing + * all safety checks! By including @c eina_safety_checks.h it + * will redefine EINA_ARG_NONNULL() to void and compiler + * warning will not be emitted, but checks will be there. The + * files already processed with the old macro + * EINA_ARG_NONNULL() will still work and emit the warnings. + * + * + * @code + * + * // all these files will emit warning from EINA_ARG_NONNULL() + * #include // third party headers + * #include + * #include // eina own header + * + * #include + * // all these files below will NOT emit warning from EINA_ARG_NONNULL(), + * // but this is required to have the functions defined there to be checked + * // for NULL pointers + * #include "my_functions1.h" + * #include "my_functions2.h" + * + * @endcode + * + * @{ + */ + #include "eina_config.h" +#include "eina_error.h" + +EAPI int eina_safety_checks_init(void); +EAPI int eina_safety_checks_shutdown(void); + +/** + * @var EINA_ERROR_SAFETY_FAILED + * Error identifier corresponding to safety check failure. + */ +EAPI extern Eina_Error EINA_ERROR_SAFETY_FAILED; #ifdef EINA_SAFETY_CHECKS @@ -31,6 +86,7 @@ { \ if (EINA_UNLIKELY((exp) == NULL)) \ { \ + eina_error_set(EINA_ERROR_SAFETY_FAILED); \ EINA_LOG_ERR("%s", "safety check failed: " #exp " == NULL"); \ return; \ } \ @@ -42,6 +98,7 @@ { \ if (EINA_UNLIKELY((exp) == NULL)) \ { \ + eina_error_set(EINA_ERROR_SAFETY_FAILED); \ EINA_LOG_ERR("%s", "safety check failed: " #exp " == NULL"); \ return (val); \ } \ @@ -53,6 +110,7 @@ { \ if (EINA_UNLIKELY(exp)) \ { \ + eina_error_set(EINA_ERROR_SAFETY_FAILED); \ EINA_LOG_ERR("%s", "safety check failed: " #exp " is true"); \ return; \ } \ @@ -64,6 +122,7 @@ { \ if (EINA_UNLIKELY(exp)) \ { \ + eina_error_set(EINA_ERROR_SAFETY_FAILED); \ EINA_LOG_ERR("%s", "safety check failed: " #exp " is true"); \ return val; \ } \ @@ -75,6 +134,7 @@ { \ if (EINA_UNLIKELY(!(exp))) \ { \ + eina_error_set(EINA_ERROR_SAFETY_FAILED); \ EINA_LOG_ERR("%s", "safety check failed: " #exp " is false"); \ return; \ } \ @@ -86,6 +146,7 @@ { \ if (EINA_UNLIKELY(!(exp))) \ { \ + eina_error_set(EINA_ERROR_SAFETY_FAILED); \ EINA_LOG_ERR("%s", "safety check failed: " #exp " is false"); \ return val; \ } \ @@ -121,3 +182,7 @@ #endif /* safety checks macros */ #endif /* EINA_SAFETY_CHECKS_H_ */ + +/** + * @} + */ diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 8bd09a4..809cf2e 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -34,7 +34,8 @@ eina_rectangle.c \ eina_stringshare.c \ eina_cpu.c \ eina_tiler.c \ -eina_hamster.c +eina_hamster.c \ +eina_safety_checks.c if EINA_STATIC_BUILD_CHAINED_POOL diff --git a/src/lib/eina_array.c b/src/lib/eina_array.c index 007f091..16560b1 100644 --- a/src/lib/eina_array.c +++ b/src/lib/eina_array.c @@ -375,6 +375,13 @@ eina_array_init(void) return 0; } + if (!eina_safety_checks_init()) + { + fprintf(stderr, "Could not initialize eina safety checks.\n"); + eina_error_shutdown(); + return 0; + } + if (!eina_magic_string_init()) { EINA_ERROR_PERR("ERROR: Could not initialize eina magic string module.\n"); @@ -421,6 +428,7 @@ eina_array_shutdown(void) if (!_eina_array_init_count) { eina_magic_string_shutdown(); + eina_safety_checks_shutdown(); eina_error_shutdown(); } diff --git a/src/lib/eina_convert.c b/src/lib/eina_convert.c index 1469710..d7ffab0 100644 --- a/src/lib/eina_convert.c +++ b/src/lib/eina_convert.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "eina_config.h" #include "eina_safety_checks.h" @@ -222,6 +223,13 @@ eina_convert_init(void) EINA_ERROR_CONVERT_P_NOT_FOUND = eina_error_msg_register("Error during string convertion to float, First 'p' was not found."); EINA_ERROR_CONVERT_OUTRUN_STRING_LENGTH = eina_error_msg_register("Error outrun string limit during convertion string convertion to float."); + if (!eina_safety_checks_init()) + { + fprintf(stderr, "Could not initialize eina safety checks.\n"); + eina_error_shutdown(); + return 0; + } + init_out: return _eina_convert_init_count; } @@ -243,6 +251,7 @@ eina_convert_shutdown(void) if (_eina_convert_init_count > 0) goto shutdown_out; + eina_safety_checks_shutdown(); eina_error_shutdown(); shutdown_out: diff --git a/src/lib/eina_counter.c b/src/lib/eina_counter.c index e12036b..5539be7 100644 --- a/src/lib/eina_counter.c +++ b/src/lib/eina_counter.c @@ -268,6 +268,14 @@ eina_counter_init(void) return 0; } #endif /* _WIN2 */ + + + if (!eina_safety_checks_init()) + { + fprintf(stderr, "Could not initialize eina safety checks.\n"); + eina_error_shutdown(); + return 0; + } } return _eina_counter_init_count; @@ -292,7 +300,11 @@ eina_counter_shutdown(void) { _eina_counter_init_count--; - if (_eina_counter_init_count == 0) eina_error_shutdown(); + if (_eina_counter_init_count == 0) + { + eina_error_shutdown(); + eina_safety_checks_shutdown(); + } return _eina_counter_init_count; } diff --git a/src/lib/eina_error.c b/src/lib/eina_error.c index 38d355d..c439353 100644 --- a/src/lib/eina_error.c +++ b/src/lib/eina_error.c @@ -525,18 +525,25 @@ EAPI Eina_Error EINA_ERROR_OUT_OF_MEMORY = 0; */ EAPI int eina_error_init(void) { - if (!_eina_error_init_count) - { - char *level; - /* TODO register the eina's basic errors */ - if ((level = getenv("EINA_ERROR_LEVEL"))) - { - _error_level = atoi(level); - } - EINA_ERROR_OUT_OF_MEMORY = eina_error_msg_register("Out of memory"); - } - /* get all the modules */ - return ++_eina_error_init_count; + const char *level; + + _eina_error_init_count++; + if (_eina_error_init_count != 1) + return _eina_error_init_count; + + /* TODO register the eina's basic errors */ + if ((level = getenv("EINA_ERROR_LEVEL"))) + _error_level = atoi(level); + + EINA_ERROR_OUT_OF_MEMORY = eina_error_msg_register("Out of memory"); + + if (!eina_safety_checks_init()) + { + fprintf(stderr, "Could not initialize eina safety checks.\n"); + _eina_error_init_count = 0; + return 0; + } + return 1; } /** @@ -569,6 +576,7 @@ EAPI int eina_error_shutdown(void) free(tmp); } _error_list_count = 0; + eina_safety_checks_shutdown(); } return _eina_error_init_count; } diff --git a/src/lib/eina_hash.c b/src/lib/eina_hash.c index f6572ca..426337b 100644 --- a/src/lib/eina_hash.c +++ b/src/lib/eina_hash.c @@ -658,11 +658,20 @@ EAPI int eina_hash_init(void) { if (!_eina_hash_init_count) - if (!eina_error_init()) - { - fprintf(stderr, "Could not initialize eina error module\n"); - return 0; - } + { + if (!eina_error_init()) + { + fprintf(stderr, "Could not initialize eina error module\n"); + return 0; + } + + if (!eina_safety_checks_init()) + { + fprintf(stderr, "Could not initialize eina safety checks.\n"); + eina_error_shutdown(); + return 0; + } + } return ++_eina_hash_init_count; } @@ -682,7 +691,10 @@ EAPI int eina_hash_shutdown(void) { if (_eina_hash_init_count == 1) - eina_error_shutdown(); + { + eina_safety_checks_shutdown(); + eina_error_shutdown(); + } return --_eina_hash_init_count; } diff --git a/src/lib/eina_list.c b/src/lib/eina_list.c index fd38dab..60be26d 100644 --- a/src/lib/eina_list.c +++ b/src/lib/eina_list.c @@ -468,6 +468,13 @@ eina_list_init(void) return 0; } + if (!eina_safety_checks_init()) + { + fprintf(stderr, "Could not initialize eina safety checks.\n"); + eina_error_shutdown(); + return 0; + } + if (!eina_magic_string_init()) { EINA_ERROR_PERR("ERROR: Could not initialize eina magic string module.\n"); @@ -551,6 +558,7 @@ eina_list_shutdown(void) eina_mempool_shutdown(); eina_magic_string_shutdown(); + eina_safety_checks_shutdown(); eina_error_shutdown(); } diff --git a/src/lib/eina_log.c b/src/lib/eina_log.c index 00d4489..f2e0c71 100644 --- a/src/lib/eina_log.c +++ b/src/lib/eina_log.c @@ -663,10 +663,11 @@ EAPI int EINA_LOG_DOMAIN_GLOBAL = 0; EAPI int eina_log_init(void) { - char *level; - char *tmp; + const char *level, *tmp; - if (_eina_log_init_count) return ++_eina_log_init_count; + _eina_log_init_count++; + if (_eina_log_init_count != 1) + return _eina_log_init_count; assert((sizeof(_names)/sizeof(_names[0])) == EINA_LOG_LEVELS); assert((sizeof(_colors)/sizeof(_colors[0])) == EINA_LOG_LEVELS + 1); @@ -695,13 +696,21 @@ eina_log_init(void) if (EINA_LOG_DOMAIN_GLOBAL < 0) { fprintf(stderr, "Failed to create global logging domain.\n"); + _eina_log_init_count = 0; return 0; } // Parse pending domains passed through EINA_LOG_LEVELS eina_log_domain_parse_pendings(); - return ++_eina_log_init_count; + if (!eina_safety_checks_init()) + { + fprintf(stderr, "Could not initialize eina safety checks.\n"); + eina_log_shutdown(); /* zero _eina_log_init_count and free stuff */ + return 0; + } + + return 1; } /** diff --git a/src/lib/eina_main.c b/src/lib/eina_main.c index 7b75337..c5a8e14 100644 --- a/src/lib/eina_main.c +++ b/src/lib/eina_main.c @@ -26,6 +26,7 @@ #include "eina_types.h" #include "eina_main.h" #include "eina_error.h" +#include "eina_safety_checks.h" #include "eina_log.h" #include "eina_hash.h" #include "eina_stringshare.h" @@ -79,6 +80,8 @@ static int _eina_main_count = 0; * (in that order): * * @li eina_error_init() + * @li eina_log_init() + * @li eina_safety_checks_init() * @li eina_hash_init() * @li eina_stringshare_init() * @li eina_list_init() @@ -108,6 +111,12 @@ eina_init(void) goto log_init_error; } + if (!eina_safety_checks_init()) + { + EINA_ERROR_PERR("Could not initialize eina safety checks module.\n"); + goto safety_checks_init_error; + } + if (!eina_hash_init()) { EINA_ERROR_PERR("Could not initialize eina hash module.\n"); @@ -168,6 +177,8 @@ eina_init(void) eina_hash_shutdown(); hash_init_error: eina_log_shutdown(); + safety_checks_init_error: + eina_safety_checks_shutdown(); log_init_error: eina_error_shutdown(); @@ -185,15 +196,17 @@ eina_init(void) * it shut down all the Eina modules. The list of shut down functions * that are called are (in that order): * - * @li eina_rectangle_init() - * @li eina_magic_string_init() - * @li eina_benchmark_init() - * @li eina_counter_init() - * @li eina_array_init() - * @li eina_list_init() - * @li eina_stringshare_init() - * @li eina_hash_init() - * @li eina_error_init() + * @li eina_rectangle_shutdown() + * @li eina_magic_string_shutdown() + * @li eina_benchmark_shutdown() + * @li eina_counter_shutdown() + * @li eina_array_shutdown() + * @li eina_list_shutdown() + * @li eina_stringshare_shutdown() + * @li eina_hash_shutdown() + * @li eina_safety_checks_shutdown() + * @li eina_log_shutdown() + * @li eina_error_shutdown() * * Once this function succeeds (that is, @c 0 is returned), you must * not call any of the Eina function anymore. You must call @@ -212,6 +225,7 @@ eina_shutdown(void) eina_list_shutdown(); eina_stringshare_shutdown(); eina_hash_shutdown(); + eina_safety_checks_shutdown(); eina_log_shutdown(); eina_error_shutdown(); diff --git a/src/lib/eina_mempool.c b/src/lib/eina_mempool.c index 5e2b1b7..bae4a35 100644 --- a/src/lib/eina_mempool.c +++ b/src/lib/eina_mempool.c @@ -137,10 +137,16 @@ eina_mempool_init(void) { char *path; + if (!eina_safety_checks_init()) + { + fprintf(stderr, "Could not initialize eina safety checks.\n"); + return 0; + } + if (!eina_hash_init()) { fprintf(stderr, "Could not initialize eina hash module.\n"); - return 0; + goto hash_init_error; } if (!eina_module_init()) { @@ -196,6 +202,8 @@ eina_mempool_init(void) eina_module_shutdown(); module_init_error: eina_hash_shutdown(); + hash_init_error: + eina_safety_checks_shutdown(); return 0; @@ -234,6 +242,7 @@ eina_mempool_shutdown(void) eina_hash_free(_backends); eina_hash_shutdown(); + eina_safety_checks_shutdown(); return 0; } diff --git a/src/lib/eina_module.c b/src/lib/eina_module.c index e7699a4..6c8a7b6 100644 --- a/src/lib/eina_module.c +++ b/src/lib/eina_module.c @@ -215,6 +215,13 @@ eina_module_init(void) return 0; } + if (!eina_safety_checks_init()) + { + EINA_LOG_ERR("Could not initialize eina safety checks."); + eina_log_shutdown(); + return 0; + } + EINA_MODULE_LOG_DOM = eina_log_domain_register ("eina_module", EINA_LOG_COLOR_DEFAULT); if (EINA_MODULE_LOG_DOM < 0) @@ -265,6 +272,8 @@ eina_module_shutdown(void) * delete the list of modules here */ + eina_safety_checks_shutdown(); + eina_log_domain_unregister(EINA_MODULE_LOG_DOM); EINA_MODULE_LOG_DOM = -1; eina_log_shutdown(); diff --git a/src/lib/eina_rectangle.c b/src/lib/eina_rectangle.c index d624c1d..6505eb4 100644 --- a/src/lib/eina_rectangle.c +++ b/src/lib/eina_rectangle.c @@ -245,6 +245,11 @@ eina_rectangle_init(void) EINA_ERROR_PERR("Could not initialize eina error module.\n"); return 0; } + if (!eina_safety_checks_init()) + { + fprintf(stderr, "Could not initialize eina safety checks.\n"); + goto safety_checks_init_error; + } if (!eina_mempool_init()) { EINA_ERROR_PERR("Could not initialize eina mempool module.\n"); @@ -286,6 +291,8 @@ eina_rectangle_init(void) list_init_error: eina_mempool_shutdown(); mempool_init_error: + eina_safety_checks_shutdown(); + safety_checks_init_error: eina_error_shutdown(); return 0; @@ -310,6 +317,7 @@ eina_rectangle_shutdown(void) eina_mempool_del(_eina_rectangle_mp); eina_mempool_shutdown(); + eina_safety_checks_shutdown(); eina_error_shutdown(); return 0; diff --git a/src/lib/eina_stringshare.c b/src/lib/eina_stringshare.c index 8decc09..ef2a41b 100644 --- a/src/lib/eina_stringshare.c +++ b/src/lib/eina_stringshare.c @@ -829,6 +829,13 @@ eina_stringshare_init(void) return 0; } + if (!eina_safety_checks_init()) + { + fprintf(stderr, "Could not initialize eina safety checks.\n"); + eina_error_shutdown(); + return 0; + } + if (!eina_magic_string_init()) { EINA_ERROR_PERR("ERROR: Could not initialize eina magic string module.\n"); @@ -883,6 +890,7 @@ eina_stringshare_shutdown(void) _eina_stringshare_population_shutdown(); _eina_stringshare_small_shutdown(); eina_magic_string_shutdown(); + eina_safety_checks_shutdown(); eina_error_shutdown(); } -- 2.7.4