sdm: Add DynLib utility for dynamic library lifecycle management.
- Add DynLib utility to automatically unload libraries upon
destruction of the utility object.
CRs-Fixed: 1029997
Change-Id: I4e13ad984949db170498fe1ec5c133fa4a798bdd
diff --git a/sdm/include/utils/sys.h b/sdm/include/utils/sys.h
index ae75967..c06b7f8 100644
--- a/sdm/include/utils/sys.h
+++ b/sdm/include/utils/sys.h
@@ -26,6 +26,7 @@
#define __SYS_H__
#include <sys/eventfd.h>
+#include <dlfcn.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
@@ -75,6 +76,20 @@
static eventfd eventfd_;
};
+class DynLib {
+ public:
+ ~DynLib();
+ bool Open(const char *lib_name);
+ bool Sym(const char *func_name, void **func_ptr);
+ const char * Error() { return ::dlerror(); }
+ operator bool() const { return lib_ != NULL; }
+
+ private:
+ void Close();
+
+ void *lib_ = NULL;
+};
+
} // namespace sdm
#endif // __SYS_H__
diff --git a/sdm/libs/core/color_manager.cpp b/sdm/libs/core/color_manager.cpp
index f24a920..c9792db 100644
--- a/sdm/libs/core/color_manager.cpp
+++ b/sdm/libs/core/color_manager.cpp
@@ -37,7 +37,7 @@
namespace sdm {
-void *ColorManagerProxy::color_lib_ = NULL;
+DynLib ColorManagerProxy::color_lib_;
CreateColorInterface ColorManagerProxy::create_intf_ = NULL;
DestroyColorInterface ColorManagerProxy::destroy_intf_ = NULL;
HWResourceInfo ColorManagerProxy::hw_res_info_;
@@ -79,14 +79,10 @@
DisplayError error = kErrorNone;
// Load color service library and retrieve its entry points.
- color_lib_ = ::dlopen(COLORMGR_LIBRARY_NAME, RTLD_NOW);
- if (color_lib_) {
- *(reinterpret_cast<void **>(&create_intf_)) = ::dlsym(color_lib_, CREATE_COLOR_INTERFACE_NAME);
- *(reinterpret_cast<void **>(&destroy_intf_)) =
- ::dlsym(color_lib_, DESTROY_COLOR_INTERFACE_NAME);
- if (!create_intf_ || !destroy_intf_) {
+ if (color_lib_.Open(COLORMGR_LIBRARY_NAME)) {
+ if (!color_lib_.Sym(CREATE_COLOR_INTERFACE_NAME, reinterpret_cast<void **>(&create_intf_)) ||
+ !color_lib_.Sym(DESTROY_COLOR_INTERFACE_NAME, reinterpret_cast<void **>(&destroy_intf_))) {
DLOGW("Fail to retrieve = %s from %s", CREATE_COLOR_INTERFACE_NAME, COLORMGR_LIBRARY_NAME);
- ::dlclose(color_lib_);
error = kErrorResources;
}
} else {
@@ -100,8 +96,7 @@
}
void ColorManagerProxy::Deinit() {
- if (color_lib_)
- ::dlclose(color_lib_);
+ color_lib_.~DynLib();
}
ColorManagerProxy::ColorManagerProxy(DisplayType type, HWInterface *intf,
diff --git a/sdm/libs/core/color_manager.h b/sdm/libs/core/color_manager.h
index 9f9eb40..728b82f 100644
--- a/sdm/libs/core/color_manager.h
+++ b/sdm/libs/core/color_manager.h
@@ -34,6 +34,7 @@
#include <core/sdm_types.h>
#include <utils/locker.h>
#include <private/color_interface.h>
+#include <utils/sys.h>
#include <utils/debug.h>
#include "hw_interface.h"
@@ -78,7 +79,7 @@
const HWPanelInfo &info);
private:
- static void *color_lib_;
+ static DynLib color_lib_;
static CreateColorInterface create_intf_;
static DestroyColorInterface destroy_intf_;
static HWResourceInfo hw_res_info_;
diff --git a/sdm/libs/core/core_impl.cpp b/sdm/libs/core/core_impl.cpp
index 82f578e..da85c9e 100644
--- a/sdm/libs/core/core_impl.cpp
+++ b/sdm/libs/core/core_impl.cpp
@@ -48,28 +48,22 @@
DisplayError error = kErrorNone;
// Try to load extension library & get handle to its interface.
- extension_lib_ = ::dlopen(EXTENSION_LIBRARY_NAME, RTLD_NOW);
- if (extension_lib_) {
- void **create_sym = reinterpret_cast<void **>(&create_extension_intf_);
- void **destroy_sym = reinterpret_cast<void **>(&destroy_extension_intf_);
-
- *create_sym = ::dlsym(extension_lib_, CREATE_EXTENSION_INTERFACE_NAME);
- *destroy_sym = ::dlsym(extension_lib_, DESTROY_EXTENSION_INTERFACE_NAME);
-
- if (!create_extension_intf_ || !destroy_extension_intf_) {
- DLOGE("Unable to load symbols, error = %s", ::dlerror());
- ::dlclose(extension_lib_);
+ if (extension_lib_.Open(EXTENSION_LIBRARY_NAME)) {
+ if (!extension_lib_.Sym(CREATE_EXTENSION_INTERFACE_NAME,
+ reinterpret_cast<void **>(&create_extension_intf_)) ||
+ !extension_lib_.Sym(DESTROY_EXTENSION_INTERFACE_NAME,
+ reinterpret_cast<void **>(&destroy_extension_intf_))) {
+ DLOGE("Unable to load symbols, error = %s", extension_lib_.Error());
return kErrorUndefined;
}
error = create_extension_intf_(EXTENSION_VERSION_TAG, &extension_intf_);
if (error != kErrorNone) {
- DLOGE("Unable to create interface, error = %s", ::dlerror());
- ::dlclose(extension_lib_);
+ DLOGE("Unable to create interface");
return error;
}
} else {
- DLOGW("Unable to load = %s, error = %s", EXTENSION_LIBRARY_NAME, ::dlerror());
+ DLOGW("Unable to load = %s, error = %s", EXTENSION_LIBRARY_NAME, extension_lib_.Error());
}
error = HWInfoInterface::Create(&hw_info_intf_);
@@ -118,11 +112,6 @@
delete hw_resource_;
}
- if (extension_lib_) {
- destroy_extension_intf_(extension_intf_);
- ::dlclose(extension_lib_);
- }
-
return error;
}
@@ -142,11 +131,6 @@
delete hw_resource_;
}
- if (extension_lib_) {
- destroy_extension_intf_(extension_intf_);
- ::dlclose(extension_lib_);
- }
-
return kErrorNone;
}
diff --git a/sdm/libs/core/core_impl.h b/sdm/libs/core/core_impl.h
index 97e8655..2d0e2d2 100644
--- a/sdm/libs/core/core_impl.h
+++ b/sdm/libs/core/core_impl.h
@@ -29,6 +29,7 @@
#include <private/extension_interface.h>
#include <private/color_interface.h>
#include <utils/locker.h>
+#include <utils/sys.h>
#include "hw_interface.h"
#include "comp_manager.h"
@@ -68,7 +69,7 @@
CompManager comp_mgr_;
HWInfoInterface *hw_info_intf_ = NULL;
RotatorInterface *rotator_intf_ = NULL;
- void *extension_lib_ = NULL;
+ DynLib extension_lib_;
ExtensionInterface *extension_intf_ = NULL;
CreateExtensionInterface create_extension_intf_ = NULL;
DestroyExtensionInterface destroy_extension_intf_ = NULL;
diff --git a/sdm/libs/core/fb/hw_info.cpp b/sdm/libs/core/fb/hw_info.cpp
index 9dbb1c8..601d597 100644
--- a/sdm/libs/core/fb/hw_info.cpp
+++ b/sdm/libs/core/fb/hw_info.cpp
@@ -300,11 +300,9 @@
}
// Disable destination scalar count to 0 if extension library is not present
- void *extension_lib = ::dlopen("libsdmextension.so", RTLD_NOW);
- if (!extension_lib) {
+ DynLib extension_lib;
+ if (!extension_lib.Open("libsdmextension.so")) {
hw_resource->hw_dest_scalar_info.count = 0;
- } else {
- ::dlclose(extension_lib);
}
DLOGI("SDE Version = %d, SDE Revision = %x, RGB = %d, VIG = %d, DMA = %d, Cursor = %d",
diff --git a/sdm/libs/hwc/cpuhint.cpp b/sdm/libs/hwc/cpuhint.cpp
index ccf55bf..551fa24 100644
--- a/sdm/libs/hwc/cpuhint.cpp
+++ b/sdm/libs/hwc/cpuhint.cpp
@@ -38,13 +38,6 @@
namespace sdm {
-CPUHint::~CPUHint() {
- if (lib_handle_) {
- dlclose(lib_handle_);
- lib_handle_ = NULL;
- }
-}
-
DisplayError CPUHint::Init(HWCDebugHandler *debug_handler) {
char path[PROPERTY_VALUE_MAX];
if (debug_handler->GetProperty("ro.vendor.extension_library", path) != kErrorNone) {
@@ -61,19 +54,17 @@
DLOGI("CPU Hint Pre-enable Window %d", pre_enable_window);
pre_enable_window_ = pre_enable_window;
- lib_handle_ = dlopen(path, RTLD_NOW);
- if (lib_handle_) {
- *(reinterpret_cast<void **>(&fn_lock_acquire_)) = dlsym(lib_handle_, "perf_lock_acq");
- *(reinterpret_cast<void **>(&fn_lock_release_)) = dlsym(lib_handle_, "perf_lock_rel");
- if (!fn_lock_acquire_ || !fn_lock_release_) {
+ if (vendor_ext_lib_.Open(path)) {
+ if (!vendor_ext_lib_.Sym("perf_lock_acq", reinterpret_cast<void **>(&fn_lock_acquire_)) ||
+ !vendor_ext_lib_.Sym("perf_lock_rel", reinterpret_cast<void **>(&fn_lock_release_))) {
DLOGW("Failed to load symbols for Vendor Extension Library");
return kErrorNotSupported;
}
DLOGI("Successfully Loaded Vendor Extension Library symbols");
enabled_ = true;
} else {
- DLOGW("Failed to open %s : %s", path, dlerror());
+ DLOGW("Failed to open %s : %s", path, vendor_ext_lib_.Error());
}
return kErrorNone;
diff --git a/sdm/libs/hwc/cpuhint.h b/sdm/libs/hwc/cpuhint.h
index a4a7758..e758763 100644
--- a/sdm/libs/hwc/cpuhint.h
+++ b/sdm/libs/hwc/cpuhint.h
@@ -31,6 +31,7 @@
#define __CPUHINT_H__
#include <core/sdm_types.h>
+#include <utils/sys.h>
namespace sdm {
@@ -38,7 +39,6 @@
class CPUHint {
public:
- ~CPUHint();
DisplayError Init(HWCDebugHandler *debug_handler);
void Set();
void Reset();
@@ -51,7 +51,7 @@
int frame_countdown_ = 0;
int lock_handle_ = 0;
bool lock_acquired_ = false;
- void *lib_handle_ = NULL;
+ DynLib vendor_ext_lib_;
int (*fn_lock_acquire_)(int handle, int duration, int *hints, int num_args) = NULL;
int (*fn_lock_release_)(int value) = NULL;
};
diff --git a/sdm/libs/hwc/hwc_color_manager.cpp b/sdm/libs/hwc/hwc_color_manager.cpp
index 7c12ec0..8e11fce 100644
--- a/sdm/libs/hwc/hwc_color_manager.cpp
+++ b/sdm/libs/hwc/hwc_color_manager.cpp
@@ -92,15 +92,12 @@
HWCColorManager *color_mgr = new HWCColorManager();
if (color_mgr) {
- void *&color_lib = color_mgr->color_apis_lib_;
// Load display API interface library. And retrieve color API function tables.
- color_lib = ::dlopen(DISPLAY_API_INTERFACE_LIBRARY_NAME, RTLD_NOW);
- if (color_lib) {
- color_mgr->color_apis_ = ::dlsym(color_lib, DISPLAY_API_FUNC_TABLES);
- if (!color_mgr->color_apis_) {
+ DynLib &color_apis_lib = color_mgr->color_apis_lib_;
+ if (color_apis_lib.Open(DISPLAY_API_INTERFACE_LIBRARY_NAME)) {
+ if (!color_apis_lib.Sym(DISPLAY_API_FUNC_TABLES, &color_mgr->color_apis_)) {
DLOGE("Fail to retrieve = %s from %s", DISPLAY_API_FUNC_TABLES,
DISPLAY_API_INTERFACE_LIBRARY_NAME);
- ::dlclose(color_lib);
delete color_mgr;
return NULL;
}
@@ -112,18 +109,14 @@
DLOGI("Successfully loaded %s", DISPLAY_API_INTERFACE_LIBRARY_NAME);
// Load diagclient library and invokes its entry point to pass in display APIs.
- void *&diag_lib = color_mgr->diag_client_lib_;
- diag_lib = ::dlopen(QDCM_DIAG_CLIENT_LIBRARY_NAME, RTLD_NOW);
- if (diag_lib) {
- *(reinterpret_cast<void **>(&color_mgr->qdcm_diag_init_)) =
- ::dlsym(diag_lib, INIT_QDCM_DIAG_CLIENT_NAME);
- *(reinterpret_cast<void **>(&color_mgr->qdcm_diag_deinit_)) =
- ::dlsym(diag_lib, DEINIT_QDCM_DIAG_CLIENT_NAME);
-
- if (!color_mgr->qdcm_diag_init_ || !color_mgr->qdcm_diag_deinit_) {
+ DynLib &diag_client_lib = color_mgr->diag_client_lib_;
+ if (diag_client_lib.Open(QDCM_DIAG_CLIENT_LIBRARY_NAME)) {
+ if (!diag_client_lib.Sym(INIT_QDCM_DIAG_CLIENT_NAME,
+ reinterpret_cast<void **>(&color_mgr->qdcm_diag_init_)) ||
+ !diag_client_lib.Sym(DEINIT_QDCM_DIAG_CLIENT_NAME,
+ reinterpret_cast<void **>(&color_mgr->qdcm_diag_deinit_))) {
DLOGE("Fail to retrieve = %s from %s", INIT_QDCM_DIAG_CLIENT_NAME,
QDCM_DIAG_CLIENT_LIBRARY_NAME);
- ::dlclose(diag_lib);
} else {
// invoke Diag Client entry point to initialize.
color_mgr->qdcm_diag_init_(color_mgr->color_apis_);
@@ -152,12 +145,6 @@
if (qdcm_diag_deinit_) {
qdcm_diag_deinit_();
}
- if (diag_client_lib_) {
- ::dlclose(diag_client_lib_);
- }
- if (color_apis_lib_) {
- ::dlclose(color_apis_lib_);
- }
delete this;
}
diff --git a/sdm/libs/hwc/hwc_color_manager.h b/sdm/libs/hwc/hwc_color_manager.h
index 2541e21..981b14a 100644
--- a/sdm/libs/hwc/hwc_color_manager.h
+++ b/sdm/libs/hwc/hwc_color_manager.h
@@ -36,6 +36,7 @@
#include <binder/BinderService.h>
#include <core/sdm_types.h>
#include <utils/locker.h>
+#include <utils/sys.h>
namespace sdm {
@@ -125,8 +126,8 @@
static uint32_t Get8BitsARGBColorValue(const PPColorFillParams ¶ms);
private:
- void *color_apis_lib_ = NULL;
- void *diag_client_lib_ = NULL;
+ DynLib color_apis_lib_;
+ DynLib diag_client_lib_;
void *color_apis_ = NULL;
QDCMDiagInit qdcm_diag_init_ = NULL;
QDCMDiagDeInit qdcm_diag_deinit_ = NULL;
diff --git a/sdm/libs/hwc2/hwc_color_manager.cpp b/sdm/libs/hwc2/hwc_color_manager.cpp
index 89b4918..3075cbb 100644
--- a/sdm/libs/hwc2/hwc_color_manager.cpp
+++ b/sdm/libs/hwc2/hwc_color_manager.cpp
@@ -92,15 +92,12 @@
HWCColorManager *color_mgr = new HWCColorManager();
if (color_mgr) {
- void *&color_lib = color_mgr->color_apis_lib_;
// Load display API interface library. And retrieve color API function tables.
- color_lib = ::dlopen(DISPLAY_API_INTERFACE_LIBRARY_NAME, RTLD_NOW);
- if (color_lib) {
- color_mgr->color_apis_ = ::dlsym(color_lib, DISPLAY_API_FUNC_TABLES);
- if (!color_mgr->color_apis_) {
+ DynLib &color_apis_lib = color_mgr->color_apis_lib_;
+ if (color_apis_lib.Open(DISPLAY_API_INTERFACE_LIBRARY_NAME)) {
+ if (!color_apis_lib.Sym(DISPLAY_API_FUNC_TABLES, &color_mgr->color_apis_)) {
DLOGE("Fail to retrieve = %s from %s", DISPLAY_API_FUNC_TABLES,
DISPLAY_API_INTERFACE_LIBRARY_NAME);
- ::dlclose(color_lib);
delete color_mgr;
return NULL;
}
@@ -112,18 +109,14 @@
DLOGI("Successfully loaded %s", DISPLAY_API_INTERFACE_LIBRARY_NAME);
// Load diagclient library and invokes its entry point to pass in display APIs.
- void *&diag_lib = color_mgr->diag_client_lib_;
- diag_lib = ::dlopen(QDCM_DIAG_CLIENT_LIBRARY_NAME, RTLD_NOW);
- if (diag_lib) {
- *(reinterpret_cast<void **>(&color_mgr->qdcm_diag_init_)) =
- ::dlsym(diag_lib, INIT_QDCM_DIAG_CLIENT_NAME);
- *(reinterpret_cast<void **>(&color_mgr->qdcm_diag_deinit_)) =
- ::dlsym(diag_lib, DEINIT_QDCM_DIAG_CLIENT_NAME);
-
- if (!color_mgr->qdcm_diag_init_ || !color_mgr->qdcm_diag_deinit_) {
+ DynLib &diag_client_lib = color_mgr->diag_client_lib_;
+ if (diag_client_lib.Open(QDCM_DIAG_CLIENT_LIBRARY_NAME)) {
+ if (!diag_client_lib.Sym(INIT_QDCM_DIAG_CLIENT_NAME,
+ reinterpret_cast<void **>(&color_mgr->qdcm_diag_init_)) ||
+ !diag_client_lib.Sym(DEINIT_QDCM_DIAG_CLIENT_NAME,
+ reinterpret_cast<void **>(&color_mgr->qdcm_diag_deinit_))) {
DLOGE("Fail to retrieve = %s from %s", INIT_QDCM_DIAG_CLIENT_NAME,
QDCM_DIAG_CLIENT_LIBRARY_NAME);
- ::dlclose(diag_lib);
} else {
// invoke Diag Client entry point to initialize.
color_mgr->qdcm_diag_init_(color_mgr->color_apis_);
@@ -152,12 +145,6 @@
if (qdcm_diag_deinit_) {
qdcm_diag_deinit_();
}
- if (diag_client_lib_) {
- ::dlclose(diag_client_lib_);
- }
- if (color_apis_lib_) {
- ::dlclose(color_apis_lib_);
- }
delete this;
}
diff --git a/sdm/libs/utils/sys.cpp b/sdm/libs/utils/sys.cpp
index 6dddcfb..0ce524e 100644
--- a/sdm/libs/utils/sys.cpp
+++ b/sdm/libs/utils/sys.cpp
@@ -62,5 +62,33 @@
#endif // SDM_VIRTUAL_DRIVER
+DynLib::~DynLib() {
+ Close();
+}
+
+bool DynLib::Open(const char *lib_name) {
+ Close();
+ lib_ = ::dlopen(lib_name, RTLD_NOW);
+
+ return (*this);
+}
+
+bool DynLib::Sym(const char *func_name, void **func_ptr) {
+ if (lib_) {
+ *func_ptr = ::dlsym(lib_, func_name);
+ } else {
+ *func_ptr = NULL;
+ }
+
+ return (*func_ptr != NULL);
+}
+
+void DynLib::Close() {
+ if (lib_) {
+ ::dlclose(lib_);
+ lib_ = NULL;
+ }
+}
+
} // namespace sdm