halpai: Add support of reference count for hal_common_(get|put)_backend function 02/252802/4
authorChanwoo Choi <cw00.choi@samsung.com>
Tue, 2 Feb 2021 10:09:58 +0000 (19:09 +0900)
committerChanwoo Choi <cw00.choi@samsung.com>
Mon, 8 Feb 2021 05:59:19 +0000 (14:59 +0900)
Some HAL module need to call hal_common_(get|put)_backend() funcions at
multiple points at the same time. So that have to support this
requirement by using the reference count. When touching the reference
count, uses the mutex in order to keep the data integrity.

Change-Id: I2c3a662f21d1c56c7b5b077c7a3f155bf47fd792
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
src/common.h
src/hal-api-common.c

index 55b28ff..f19e56c 100644 (file)
@@ -55,6 +55,8 @@ struct hal_abi_version_match {
 };
 
 struct __hal_module_info {
+       int usage_count;
+
        enum hal_group group;
        enum hal_module module;
        enum hal_license license;
index 6492aae..be66273 100644 (file)
@@ -22,6 +22,8 @@
 #include <dlfcn.h>
 #include <dlog.h>
 
+#include <glib-object.h>
+
 #include "common.h"
 #include "hal-api-conf.h"
 
@@ -30,6 +32,7 @@
 #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)
@@ -96,6 +99,14 @@ int hal_common_get_backend(enum hal_module module, void **data)
        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);
@@ -103,35 +114,51 @@ int hal_common_get_backend(enum hal_module module, void **data)
                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 */
@@ -140,7 +167,7 @@ int hal_common_get_backend(enum hal_module module, void **data)
                _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 */
@@ -148,7 +175,7 @@ int hal_common_get_backend(enum hal_module module, void **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);
@@ -156,18 +183,21 @@ int hal_common_get_backend(enum hal_module module, void **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;
 }
 
@@ -185,18 +215,28 @@ int hal_common_put_backend(enum hal_module module, void *data)
                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) {
@@ -204,7 +244,8 @@ int hal_common_put_backend(enum hal_module module, void *data)
                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;
                }
        }
 
@@ -217,7 +258,9 @@ int hal_common_put_backend(enum hal_module module, void *data)
        info->library_backend = NULL;
        info->library_handle = NULL;
 
-       return TIZEN_ERROR_NONE;
+out:
+       G_UNLOCK(hal_common_lock);
+       return ret;
 }
 
 EXPORT