halapi: Replace destructor with reference count method to free memory 93/253193/4
authorChanwoo Choi <cw00.choi@samsung.com>
Thu, 4 Feb 2021 06:53:40 +0000 (15:53 +0900)
committerChanwoo Choi <cw00.choi@samsung.com>
Mon, 8 Feb 2021 07:11:08 +0000 (16:11 +0900)
Instead of destructor method to free the memory, use the reference count
method to free the memory in order to support multi-thread environment.

So that define the _hal_api_conf_(init|exit)() functions to control
the reference count. These functions either get the resources from hal-api.json
or put the resources according to the reference count.
- _hal_api_conf_init() increments the reference count
- _hal_api_conf_exit() decrements the reference count

hal_common_get_backend() and hal_common_put_backend() functions should
be called pairly in order to free the resources of hal-api.json.

[Detailed use-case of _hal_api_conf_init() and _hal_api_conf_ext()]
hal_common_get_backend()
_hal_api_conf_init()
/* codes */

hal_common_put_backend()
/* codes */
_hal_api_conf_exit()

hal_common_get_backend_library_name()
_hal_api_conf_init()
/* codes */
_hal_api_conf_exit()

hal_common_get_backend_symbol_name()
_hal_api_conf_init()
/* codes */
_hal_api_conf_exit()

hal_common_check_backend_abi_version()
_hal_api_conf_init()
/* codes */
_hal_api_conf_exit()

And change the prototype of hal_common_get_backend_library_name,
hal_common_get_backend_symbol_name as following:
- int hal_common_get_backend_library_name(enum hal_module module, char *name, int size);
- int hal_common_get_backend_symbol_name(enum hal_module module, char *name, int size);

Change-Id: If663b87244cc680d94568818d4358a7b91fb071e
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
haltests/src/test_hal.cc
include/hal-common.h
src/hal-api-common.c
src/hal-api-conf.c
src/hal-api-conf.h

index a73e484..ddadc56 100644 (file)
@@ -28,6 +28,8 @@
 #include "../../src/hal-api-conf.h"
 #include "../../src/common.h"
 
+#define MAX_BUFF       128
+
 using namespace std;
 
 
@@ -45,11 +47,15 @@ class CommonHaltest : public testing::Test {
 };
 
 TEST(CommonHaltest, test_symbol_name_invalid_module) {
-  const char *ret_unknown = hal_common_get_backend_symbol_name(HAL_MODULE_UNKNOWN);
-  EXPECT_TRUE(ret_unknown == nullptr);
+  char ret_unknown[MAX_BUFF] = {0, };
+  char ret_end[MAX_BUFF] = {0, };
+  int ret;
 
-  const char *ret_end = hal_common_get_backend_symbol_name(HAL_MODULE_END);
-  EXPECT_TRUE(ret_end == nullptr);
+  ret = hal_common_get_backend_symbol_name(HAL_MODULE_UNKNOWN, ret_unknown, MAX_BUFF);
+  EXPECT_TRUE(ret != TIZEN_ERROR_NONE);
+
+  ret = hal_common_get_backend_symbol_name(HAL_MODULE_UNKNOWN, ret_end, MAX_BUFF);
+  EXPECT_TRUE(ret != TIZEN_ERROR_NONE);
 }
 
 TEST(CommonHaltest, test_check_backend_abi_version_invalid_parameter) {
@@ -69,8 +75,9 @@ TEST(CommonHaltest, test_check_backend_abi_version_invalid_parameter) {
 }
 
 TEST(CommonHaltest, get_backend_library_name_unknown) {
-  const char *ret = hal_common_get_backend_library_name(HAL_MODULE_UNKNOWN);
-  EXPECT_TRUE(ret == nullptr);
+  char ret_name[MAX_BUFF] = {0, };
+  int ret = hal_common_get_backend_library_name(HAL_MODULE_UNKNOWN, ret_name, MAX_BUFF);
+  EXPECT_TRUE(ret != TIZEN_ERROR_NONE);
 }
 
 class HalInfo {
@@ -117,10 +124,10 @@ INSTANTIATE_TEST_CASE_P(CommonHaltest,
   ),
 
   HalInfo(HAL_MODULE_COREGL, HAL_GROUP_GRAPHICS, HAL_LICENSE_UNKNOWN,
-    "HAL_MODULE_COREGL", nullptr, nullptr, nullptr, {}),
+    "HAL_MODULE_COREGL", "", "", "", {}),
 
   HalInfo(HAL_MODULE_INPUT, HAL_GROUP_GRAPHICS, HAL_LICENSE_MIT,
-    "HAL_MODULE_INPUT", nullptr, nullptr, nullptr, {}),
+    "HAL_MODULE_INPUT", "", "", "", {}),
 
   HalInfo(HAL_MODULE_AUDIO, HAL_GROUP_MULTIMEDIA, HAL_LICENSE_APACHE_2_0,
     "HAL_MODULE_AUDIO", "/hal/lib/libhal-backend-audio.so",
@@ -150,13 +157,13 @@ INSTANTIATE_TEST_CASE_P(CommonHaltest,
   ),
 
   HalInfo(HAL_MODULE_CODEC, HAL_GROUP_MULTIMEDIA, HAL_LICENSE_APACHE_2_0,
-    "HAL_MODULE_CODEC", nullptr, nullptr, nullptr, {}),
+    "HAL_MODULE_CODEC", "", "", "", {}),
 
   HalInfo(HAL_MODULE_USB_AUDIO, HAL_GROUP_MULTIMEDIA, HAL_LICENSE_APACHE_2_0,
-    "HAL_MODULE_USB_AUDIO", nullptr, nullptr, nullptr, {}),
+    "HAL_MODULE_USB_AUDIO", "", "", "", {}),
 
   HalInfo(HAL_MODULE_ALSAUCM, HAL_GROUP_MULTIMEDIA, HAL_LICENSE_APACHE_2_0,
-    "HAL_MODULE_ALSAUCM", nullptr, nullptr, nullptr, {}),
+    "HAL_MODULE_ALSAUCM", "", "", "", {}),
 
   HalInfo(HAL_MODULE_BLUETOOTH, HAL_GROUP_CONNECTIVITY, HAL_LICENSE_APACHE_2_0,
     "HAL_MODULE_BLUETOOTH", "/hal/lib/libhal-backend-bluetooth.so",
@@ -177,7 +184,7 @@ INSTANTIATE_TEST_CASE_P(CommonHaltest,
   ),
 
   HalInfo(HAL_MODULE_NAN, HAL_GROUP_CONNECTIVITY, HAL_LICENSE_APACHE_2_0,
-    "HAL_MODULE_NAN", nullptr, nullptr, nullptr, {}),
+    "HAL_MODULE_NAN", "", "", "", {}),
 
   HalInfo(HAL_MODULE_NFC, HAL_GROUP_CONNECTIVITY, HAL_LICENSE_APACHE_2_0,
     "HAL_MODULE_NFC", "/hal/lib/libhal-backend-nfc.so",
@@ -207,10 +214,10 @@ INSTANTIATE_TEST_CASE_P(CommonHaltest,
   ),
 
   HalInfo(HAL_MODULE_MTP, HAL_GROUP_CONNECTIVITY, HAL_LICENSE_APACHE_2_0,
-    "HAL_MODULE_MTP", nullptr, nullptr, nullptr, {}),
+    "HAL_MODULE_MTP", "", "", "", {}),
 
   HalInfo(HAL_MODULE_TELEPHONY, HAL_GROUP_TELEPHONY, HAL_LICENSE_APACHE_2_0,
-    "HAL_MODULE_TELEPHONY", nullptr, nullptr, nullptr, {}),
+    "HAL_MODULE_TELEPHONY", "", "", "", {}),
 
   HalInfo(HAL_MODULE_LOCATION, HAL_GROUP_LOCATION, HAL_LICENSE_APACHE_2_0,
     "HAL_MODULE_LOCATION", "/hal/lib/libhal-backend-location.so",
@@ -222,7 +229,7 @@ INSTANTIATE_TEST_CASE_P(CommonHaltest,
   ),
 
   HalInfo(HAL_MODULE_COMMON, HAL_GROUP_SYSTEM, HAL_LICENSE_APACHE_2_0,
-    "HAL_MODULE_COMMON", nullptr, nullptr, nullptr, {}),
+    "HAL_MODULE_COMMON", "", "", "", {}),
 
   HalInfo(HAL_MODULE_POWER, HAL_GROUP_SYSTEM, HAL_LICENSE_APACHE_2_0,
     "HAL_MODULE_POWER", "/hal/lib/libhal-backend-power.so",
@@ -243,7 +250,7 @@ INSTANTIATE_TEST_CASE_P(CommonHaltest,
   ),
 
   HalInfo(HAL_MODULE_PERIPHERAL, HAL_GROUP_SYSTEM, HAL_LICENSE_APACHE_2_0,
-    "HAL_MODULE_PERIPHERAL", nullptr, nullptr, nullptr, {}),
+    "HAL_MODULE_PERIPHERAL", "", "", "", {}),
 
   HalInfo(HAL_MODULE_DEVICE_BATTERY, HAL_GROUP_SYSTEM, HAL_LICENSE_APACHE_2_0,
     "HAL_MODULE_DEVICE_BATTERY", "/hal/lib/libhal-backend-device-battery.so",
@@ -346,11 +353,12 @@ INSTANTIATE_TEST_CASE_P(CommonHaltest,
 ));
 
 TEST_P(HalInfoMatchedTest, get_backend_library_name) {
-  const char *ret_library_name;
-
+  char ret_library_name[MAX_BUFF] = {0, };
+  int ret;
   auto info = GetParam();
 
-  ret_library_name = hal_common_get_backend_library_name(info.module_);
+  ret = hal_common_get_backend_library_name(info.module_, ret_library_name, MAX_BUFF);
+  EXPECT_TRUE(ret == TIZEN_ERROR_NONE);
 #if defined(__aarch64__)
   EXPECT_STREQ(info.library_name_64bit_, ret_library_name) << "module name is " << info.module_name_;
 #else
@@ -359,11 +367,12 @@ TEST_P(HalInfoMatchedTest, get_backend_library_name) {
 }
 
 TEST_P(HalInfoMatchedTest, test_symbol_name_module_matching) {
-  const char *ret_symbol_name = NULL;
-
+  char ret_symbol_name[MAX_BUFF] = {0, };
+  int ret;
   auto info = GetParam();
 
-  ret_symbol_name = hal_common_get_backend_symbol_name(info.module_);
+  ret = hal_common_get_backend_symbol_name(info.module_, ret_symbol_name, MAX_BUFF);
+  EXPECT_TRUE(ret == TIZEN_ERROR_NONE);
   EXPECT_STREQ(ret_symbol_name, info.symbol_name_) << "module name is " << info.module_name_;
 }
 
@@ -372,11 +381,11 @@ TEST_P(HalInfoMatchedTest, test_group_module_matching) {
 
   auto result_info = GetParam();
 
+  _hal_api_conf_init();
   info = _hal_api_conf_get_module_info(result_info.module_);
   ASSERT_TRUE(info != nullptr) << "module name is " << result_info.module_name_;
   EXPECT_EQ(info->group, result_info.group_) << "module name is " << result_info.module_name_;
-
-  _destroy_module_info(info);
+  _hal_api_conf_exit();
 }
 
 TEST_P(HalInfoMatchedTest, test_license_module_matching) {
@@ -384,11 +393,11 @@ TEST_P(HalInfoMatchedTest, test_license_module_matching) {
 
   auto result_info = GetParam();
 
+  _hal_api_conf_init();
   info = _hal_api_conf_get_module_info(result_info.module_);
   ASSERT_TRUE(info != nullptr) << "module name is " << result_info.module_name_;
   EXPECT_EQ(info->license, result_info.license_) << "module name is " << result_info.module_name_;
-
-  _destroy_module_info(info);
+  _hal_api_conf_exit();
 }
 
 TEST_P(HalInfoMatchedTest, test_module_name_matching) {
@@ -396,18 +405,18 @@ TEST_P(HalInfoMatchedTest, test_module_name_matching) {
 
   auto result_info = GetParam();
 
+  _hal_api_conf_init();
   info = _hal_api_conf_get_module_info(result_info.module_);
   ASSERT_TRUE(info != nullptr) << "module name is " << result_info.module_name_;
   EXPECT_STREQ(info->module_name, result_info.module_name_) << "module name is " << result_info.module_name_;
-
-  _destroy_module_info(info);
+  _hal_api_conf_exit();
 }
 
 TEST_P(HalInfoMatchedTest, test_check_backend_abi_version) {
   struct __hal_module_info *info = NULL;
-
-
   auto result_info = GetParam();
+
+  _hal_api_conf_init();
   info = _hal_api_conf_get_module_info(result_info.module_);
   ASSERT_TRUE(info != nullptr);
 
@@ -422,4 +431,5 @@ TEST_P(HalInfoMatchedTest, test_check_backend_abi_version) {
     EXPECT_EQ(meta_versions[i].platform_abi_version, tmp_version.platform_abi_version) << "module name is " << result_info.module_name_;;
     EXPECT_EQ(meta_versions[i].backend_min_abi_version, tmp_version.backend_min_abi_version) << "module name is " << result_info.module_name_;;
   }
+  _hal_api_conf_exit();
 }
index c270279..99ed3d2 100644 (file)
@@ -166,18 +166,20 @@ static const char *const hal_module_string[] = {
 /**
  * @brief Get the backend library name according to the type of HAL module
  * @param[in] HAL module id among enum hal_moudle
- * @return @c backend library name on success and don't need to be freed
- *         due to the global variable, otherwise NULL.
+ * @param[out] Backend Library name of HAL module
+ * @param[in] Arrary size of name[]
+ * @return @c 0 on success, otherwise a negative error value
  */
-const char *hal_common_get_backend_library_name(enum hal_module module);
+int hal_common_get_backend_library_name(enum hal_module module, char *name, int size);
 
 /**
  * @brief Get the backend symbol name according to the type of HAL module
  * @param[in] HAL module id among enum hal_moudle
- * @return @c backend library name on success and don't need to be freed
- *         due to the global variable, otherwise NULL.
+ * @param[out] Backend symbol name of HAL module
+ * @param[in] Arrary size of name[]
+ * @return @c 0 on success, otherwise a negative error value
  */
-const char *hal_common_get_backend_symbol_name(enum hal_module module);
+int hal_common_get_backend_symbol_name(enum hal_module module, char *name, int size);
 
 /**
  * @brief Get the backend data according to the type of HAL module
index be66273..a59bb52 100644 (file)
 static enum hal_abi_version g_platform_curr_abi_version;
 G_LOCK_DEFINE_STATIC(hal_common_lock);
 
+
+static const char* get_backend_library_name(struct __hal_module_info *info)
+{
+       if (!info)
+               return NULL;
+
+#if defined(__aarch64__)
+       return info->library_name_64bit;
+#else
+       return info->library_name;
+#endif
+}
+
 EXPORT
-const char *hal_common_get_backend_library_name(enum hal_module module)
+int hal_common_get_backend_library_name(enum hal_module module, char *name, int size)
 {
-       char *library_name;
+       const char *library_name = NULL;
        struct __hal_module_info *info = NULL;
+       int ret;
+       int len_library_name;
 
        /* Check parameter whether is valid or not */
        if (module <= HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END) {
                _E("Invalid parameter of HAL module (%d)\n", module);
-               return NULL;
+               return TIZEN_ERROR_INVALID_PARAMETER;
        }
 
+       if (_hal_api_conf_init())
+               return TIZEN_ERROR_UNKNOWN;
+
        info = _hal_api_conf_get_module_info(module);
        if (info == NULL) {
                _E("Failed to get HAL module(%d) information\n", module);
-               return NULL;
+               ret = TIZEN_ERROR_UNKNOWN;
+               goto out;
        }
 
-#if defined(__aarch64__)
-       library_name = info->library_name_64bit;
-#else
-       library_name = info->library_name;
-#endif
-
+       library_name = get_backend_library_name(info);
        if (!library_name) {
                _E("%s backend library name is NULL\n", info->module_name);
-               return NULL;
+               ret = TIZEN_ERROR_NONE;
+               goto out;
+       }
+
+       len_library_name = strlen(library_name);
+       if (!name || (len_library_name + 1 > size)) {
+               ret = TIZEN_ERROR_UNKNOWN;
+               name = NULL;
+               goto out;
        }
-       return library_name;
+       strncpy(name, library_name, len_library_name);
+       name[len_library_name] = '\0';
+
+       ret = TIZEN_ERROR_NONE;
+out:
+       _hal_api_conf_exit();
+
+       return ret;
 }
 
 EXPORT
-const char *hal_common_get_backend_symbol_name(enum hal_module module)
+int hal_common_get_backend_symbol_name(enum hal_module module, char *name, int size)
 {
        struct __hal_module_info *info = NULL;
+       char *symbol_name = NULL;
+       int ret;
+       int len_symbol_name;
 
        /* Check parameter whether is valid or not */
        if (module <= HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END) {
                _E("Invalid paramer of HAL module (%d)\n", module);
-               return NULL;
+               return TIZEN_ERROR_INVALID_PARAMETER;
        }
 
+       if (_hal_api_conf_init())
+               return TIZEN_ERROR_UNKNOWN;
+
        info = _hal_api_conf_get_module_info(module);
        if (info == NULL) {
                _E("Failed to get HAL module(%d) information\n", module);
-               return NULL;
+               ret = TIZEN_ERROR_UNKNOWN;
+               goto out;
+       }
+       symbol_name = info->symbol_name;
+       if (!symbol_name) {
+               _E("%s backend symbol name is NULL\n", info->module_name);
+               ret = TIZEN_ERROR_NONE;
+               goto out;
        }
 
-       if (!info->symbol_name) {
-               _E("%s backend library name is NULL\n", info->module_name);
-               return NULL;
+       len_symbol_name = strlen(symbol_name);
+       if (!name || (len_symbol_name + 1 > size)) {
+               ret = TIZEN_ERROR_UNKNOWN;
+               name = NULL;
+               goto out;
        }
+       strncpy(name, symbol_name, len_symbol_name);
+       name[len_symbol_name] = '\0';
 
-       return info->symbol_name;
+       ret = TIZEN_ERROR_NONE;
+out:
+       _hal_api_conf_exit();
+
+       return ret;
 }
 
 EXPORT
@@ -107,6 +157,9 @@ int hal_common_get_backend(enum hal_module module, void **data)
 
        G_LOCK(hal_common_lock);
 
+       if (_hal_api_conf_init())
+               return TIZEN_ERROR_UNKNOWN;
+
        info = _hal_api_conf_get_module_info(module);
        if (info == NULL) {
                _E("Failed to get HAL module(%d) information\n", module);
@@ -119,7 +172,7 @@ int hal_common_get_backend(enum hal_module module, void **data)
                 * Load HAL backend library at first loading time
                 * when usage_count is 0.
                 */
-               library_name = hal_common_get_backend_library_name(module);
+               library_name = get_backend_library_name(info);
                if (!library_name) {
                        _E("%s: Failed to get backend library name\n",
                                        info->module_name);
@@ -135,7 +188,7 @@ int hal_common_get_backend(enum hal_module module, void **data)
                        goto err;
                }
 
-               symbol_name = hal_common_get_backend_symbol_name(module);
+               symbol_name = info->symbol_name;
                if (!symbol_name) {
                        _E("%s: Failed to get backend symbol name\n",
                                        info->module_name);
@@ -195,6 +248,7 @@ int hal_common_get_backend(enum hal_module module, void **data)
        return TIZEN_ERROR_NONE;
 
 err_dlclose:
+       _hal_api_conf_exit();
        dlclose(handle);
 err:
        G_UNLOCK(hal_common_lock);
@@ -258,6 +312,10 @@ int hal_common_put_backend(enum hal_module module, void *data)
        info->library_backend = NULL;
        info->library_handle = NULL;
 
+       _hal_api_conf_exit();
+
+       ret = TIZEN_ERROR_NONE;
+
 out:
        G_UNLOCK(hal_common_lock);
        return ret;
@@ -269,6 +327,7 @@ int hal_common_check_backend_abi_version(enum hal_module module,
 {
        struct __hal_module_info *info = NULL;
        int i;
+       int ret;
 
        /* Check parameter whether is valid or not */
        if (module <= HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END) {
@@ -283,23 +342,29 @@ int hal_common_check_backend_abi_version(enum hal_module module,
                return TIZEN_ERROR_INVALID_PARAMETER;
        }
 
+       if (_hal_api_conf_init())
+               return TIZEN_ERROR_UNKNOWN;
+
        info = _hal_api_conf_get_module_info(module);
        if (info == NULL) {
                _E("Failed to get HAL module(%d) information\n", module);
-               return TIZEN_ERROR_UNKNOWN;
+               ret = TIZEN_ERROR_UNKNOWN;
+               goto out;
        }
 
        /* Check abi_version whether is supported or not */
        if (!info->hal_api) {
                _E("%s: Doesn't support HAL API\n", info->module_name);
-               return TIZEN_ERROR_INVALID_PARAMETER;
+               ret = TIZEN_ERROR_INVALID_PARAMETER;
+               goto out;
        }
 
        if (!info->num_abi_versions
                        || !info->abi_versions) {
                _E("%s: Doesn't have the ABI version information\n",
                                                info->module_name);
-               return TIZEN_ERROR_INVALID_PARAMETER;
+               ret = TIZEN_ERROR_INVALID_PARAMETER;
+               goto out;
        }
 
        g_platform_curr_abi_version = _hal_api_conf_get_platform_abi_version();
@@ -314,12 +379,15 @@ int hal_common_check_backend_abi_version(enum hal_module module,
                        data->backend_min_abi_version >= HAL_ABI_VERSION_END) {
                        _E("%s: abi_versions[%d].backend_min_abi_version(%d) is invalid\n",
                                info->module_name, i, data->backend_min_abi_version);
-                       return TIZEN_ERROR_INVALID_PARAMETER;
+                       ret = TIZEN_ERROR_INVALID_PARAMETER;
+                       goto out;
                }
 
                if (abi_version <= data->platform_abi_version
-                               && abi_version >= data->backend_min_abi_version)
-                       return TIZEN_ERROR_NONE;
+                               && abi_version >= data->backend_min_abi_version) {
+                       ret = TIZEN_ERROR_NONE;
+                       goto out;
+               }
 
                _E("%s: \'%s\' doesn't support \'%s\'\n",
                                info->module_name,
@@ -330,6 +398,9 @@ int hal_common_check_backend_abi_version(enum hal_module module,
                                hal_abi_version_str[data->backend_min_abi_version],
                                hal_abi_version_str[data->platform_abi_version]);
        }
+       ret = TIZEN_ERROR_INVALID_PARAMETER;
 
-       return TIZEN_ERROR_INVALID_PARAMETER;
+out:
+       _hal_api_conf_exit();
+       return ret;
 }
index 0b4f5d8..9b8480b 100644 (file)
@@ -34,22 +34,7 @@ static JsonObject *_root_object = NULL;
 
 static GHashTable *_module_hash = NULL;
 
-static bool _initialized = false;
-
-void __attribute__ ((destructor)) _destroy_configuration(void);
-
-void _destroy_configuration(void)
-{
-       if (_parser)
-               g_object_unref(_parser);
-
-       if (_module_hash) {
-               g_hash_table_remove_all(_module_hash);
-               g_hash_table_unref(_module_hash);
-       }
-
-       _initialized = false;
-}
+static int _usage_count = 0;
 
 static enum hal_abi_version __convert_abi_version_str_to_enum(const char *abi_version) {
        int version;
@@ -120,43 +105,6 @@ do { \
        }
 }
 
-static bool __init_configuration(void)
-{
-       JsonNode *root_node = NULL;
-       GError *error = NULL;
-       gboolean result;
-
-       if (_initialized)
-               return _initialized;
-
-       _parser = json_parser_new();
-       result = json_parser_load_from_file(_parser, HAL_CONFIGURATION_PATH, &error);
-       if (result == FALSE) {
-               _E("Failed to parsing json configuration file : %s\n", error->message);
-               goto err;
-       }
-
-       root_node = json_parser_get_root(_parser);
-       if (JSON_NODE_HOLDS_OBJECT(root_node) == FALSE) {
-               _E("There is no object in root node\n");
-               goto err;
-       }
-
-       _root_object = json_node_get_object(root_node);
-       _module_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, _destroy_module_info);
-
-       _initialized = true;
-
-       return _initialized;
-
-err:
-       if (error)
-               g_error_free(error);
-       _destroy_configuration();
-
-       return _initialized;
-}
-
 static struct __hal_module_info *__create_hal_module_info(enum hal_module module, JsonObject *object)
 {
        struct __hal_module_info *info;
@@ -233,13 +181,9 @@ struct __hal_module_info* _hal_api_conf_get_module_info(enum hal_module module)
        GList *iter_list;
        const char *group_name = NULL;
        const char *module_name = NULL;
-       bool ret_initialized;
 
-       ret_initialized = __init_configuration();
-       if (ret_initialized == false) {
-               _E("Failed to parse json information\n");
-               goto ret;
-       }
+       if (!_root_object || !_module_hash)
+               return NULL;
 
        info = (struct __hal_module_info*)g_hash_table_lookup(_module_hash, GINT_TO_POINTER(module));
        if (info != NULL)
@@ -277,14 +221,71 @@ enum hal_abi_version _hal_api_conf_get_platform_abi_version(void)
        if (_platform_abi_version != HAL_ABI_VERSION_END)
                return _platform_abi_version;
 
-       ret_initialized = __init_configuration();
-       if (ret_initialized == false) {
-               _E("Failed to parser json file\n");
+       if (!_root_object || !_module_hash)
                return HAL_ABI_VERSION_UNKNOWN;
-       }
 
        abi_version = json_object_get_string_member(_root_object, "PLATFORM_ABI_VERSION");
        _platform_abi_version = __convert_abi_version_str_to_enum(abi_version);
 
        return _platform_abi_version;
 }
+
+__attribute__ ((visibility("default")))
+int _hal_api_conf_init(void)
+{
+       JsonNode *root_node = NULL;
+       GError *error = NULL;
+       gboolean result;
+
+       if (_usage_count++ > 0)
+               return 0;
+
+       _parser = json_parser_new();
+       result = json_parser_load_from_file(_parser, HAL_CONFIGURATION_PATH, &error);
+       if (result == FALSE) {
+               _E("Failed to parsing json configuration file : %s\n", error->message);
+               goto err;
+       }
+
+       root_node = json_parser_get_root(_parser);
+       if (JSON_NODE_HOLDS_OBJECT(root_node) == FALSE) {
+               _E("There is no object in root node\n");
+               goto err;
+       }
+
+       _root_object = json_node_get_object(root_node);
+       _module_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, _destroy_module_info);
+
+       return 0;
+
+err:
+       _usage_count--;
+
+       if (error)
+               g_error_free(error);
+       if (_parser)
+               g_object_unref(_parser);
+
+       if (_module_hash) {
+               g_hash_table_remove_all(_module_hash);
+               g_hash_table_unref(_module_hash);
+       }
+
+       return -EINVAL;
+}
+
+__attribute__ ((visibility("default")))
+void _hal_api_conf_exit(void)
+{
+       _usage_count--;
+       if (_usage_count != 0)
+               return;
+
+       if (_parser)
+               g_object_unref(_parser);
+
+       if (_module_hash) {
+               g_hash_table_remove_all(_module_hash);
+               g_hash_table_unref(_module_hash);
+       }
+}
index 4920483..f0d0cfd 100644 (file)
@@ -30,6 +30,9 @@ extern "C" {
 
 #define HAL_CONFIGURATION_PATH tzplatform_mkpath(TZ_SYS_RO_ETC, "hal/hal-api.json")
 
+int _hal_api_conf_init(void);
+void _hal_api_conf_exit(void);
+
 struct __hal_module_info *_hal_api_conf_get_module_info(enum hal_module module);
 
 enum hal_abi_version _hal_api_conf_get_platform_abi_version(void);