#include <dlfcn.h>
#include <dlog.h>
+#include <glib-object.h>
+
#include "common.h"
#include "hal-api-conf.h"
#endif
static enum hal_abi_version g_platform_curr_abi_version;
+G_LOCK_DEFINE_STATIC(hal_common_lock);
EXPORT
const char *hal_common_get_backend_library_name(enum hal_module module)
const char *library_name, *symbol_name;
int ret = 0;
+ /* 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 TIZEN_ERROR_INVALID_PARAMETER;
+ }
+
+ G_LOCK(hal_common_lock);
+
info = _hal_api_conf_get_module_info(module);
if (info == NULL) {
_E("Failed to get HAL module(%d) information\n", module);
goto err;
}
- /* Load module */
- library_name = hal_common_get_backend_library_name(module);
- if (!library_name) {
- _E("%s: Failed to get backend library name\n",
- info->module_name);
- return TIZEN_ERROR_INVALID_PARAMETER;
- }
+ if (info->usage_count == 0) {
+ /*
+ * Load HAL backend library at first loading time
+ * when usage_count is 0.
+ */
+ library_name = hal_common_get_backend_library_name(module);
+ if (!library_name) {
+ _E("%s: Failed to get backend library name\n",
+ info->module_name);
+ ret = TIZEN_ERROR_INVALID_PARAMETER;
+ goto err;
+ }
- handle = dlopen(library_name, RTLD_LAZY);
- if (!handle) {
- _E("%s: Failed to load shared library (%s)\n",
- info->module_name, dlerror());
- return TIZEN_ERROR_INVALID_PARAMETER;
- }
+ handle = dlopen(library_name, RTLD_LAZY);
+ if (!handle) {
+ _E("%s: Failed to load shared library (%s)\n",
+ info->module_name, dlerror());
+ ret = TIZEN_ERROR_INVALID_PARAMETER;
+ goto err;
+ }
- symbol_name = hal_common_get_backend_symbol_name(module);
- if (!symbol_name) {
- _E("%s: Failed to get backend symbol name\n",
- info->module_name);
- ret = TIZEN_ERROR_INVALID_PARAMETER;
- goto err;
- }
+ symbol_name = hal_common_get_backend_symbol_name(module);
+ if (!symbol_name) {
+ _E("%s: Failed to get backend symbol name\n",
+ info->module_name);
+ ret = TIZEN_ERROR_INVALID_PARAMETER;
+ goto err_dlclose;
+ }
- backend = dlsym(handle, symbol_name);
- if (!backend) {
- _E("%s: Failed to find backend data (%s)\n",
- info->module_name, dlerror());
- ret = TIZEN_ERROR_INVALID_PARAMETER;
- goto err;
+ backend = dlsym(handle, symbol_name);
+ if (!backend) {
+ _E("%s: Failed to find backend data (%s)\n",
+ info->module_name, dlerror());
+ ret = TIZEN_ERROR_INVALID_PARAMETER;
+ goto err_dlclose;
+ }
+
+ info->library_backend = backend;
+ info->library_handle = handle;
+ } else {
+ /*
+ * Re-use the already loaded HAL backend instance
+ * when usage_count is larger than 0.
+ */
+ backend = info->library_backend;
}
/* Check HAL ABI Version */
_E("%s: Failed to check ABI version\n",
info->module_name);
ret = TIZEN_ERROR_INVALID_PARAMETER;
- goto err;
+ goto err_dlclose;
}
/* Get the backend module data */
_E("%s: hal_backend->init() is NULL\n",
info->module_name);
ret = TIZEN_ERROR_INVALID_PARAMETER;
- goto err;
+ goto err_dlclose;
}
ret = backend->init(data);
_E("%s: Failed to initialize backend: name(%s)/vendor(%s)\n",
info->module_name, backend->name, backend->vendor);
ret = TIZEN_ERROR_INVALID_PARAMETER;
- goto err;
+ goto err_dlclose;
}
- info->library_backend = backend;
- info->library_handle = handle;
-
_I("%s: Get HAL backend: name(%s)/vendor(%s)\n",
info->module_name, backend->name, backend->vendor);
+ info->usage_count++;
+
+ G_UNLOCK(hal_common_lock);
return TIZEN_ERROR_NONE;
-err:
+
+err_dlclose:
dlclose(handle);
+err:
+ G_UNLOCK(hal_common_lock);
return ret;
}
return TIZEN_ERROR_INVALID_PARAMETER;
}
+ G_LOCK(hal_common_lock);
+
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;
}
backend = info->library_backend;
handle = info->library_handle;
- if (!backend) {
+ if (!backend || info->usage_count == 0) {
_I("%s: Already fully put for HAL module\n", info->module_name);
- return TIZEN_ERROR_NONE;
+ ret = TIZEN_ERROR_NONE;
+ goto out;
+ }
+
+ info->usage_count--;
+ if (info->usage_count > 0) {
+ ret = TIZEN_ERROR_NONE;
+ goto out;
}
if (backend->exit) {
if (ret < 0) {
_E("%s: Failed to exit backend: name(%s)/vendor(%s)\n",
info->module_name, backend->name, backend->vendor);
- return TIZEN_ERROR_INVALID_PARAMETER;
+ ret = TIZEN_ERROR_INVALID_PARAMETER;
+ goto out;
}
}
info->library_backend = NULL;
info->library_handle = NULL;
- return TIZEN_ERROR_NONE;
+out:
+ G_UNLOCK(hal_common_lock);
+ return ret;
}
EXPORT