diff --git a/uhdf2/hdi.gni b/uhdf2/hdi.gni index 58681031b12231ca496f00ce7e8072c4f6ef08d7..d620918f67a88a007b778e3c5f27f3aeb551f7a1 100755 --- a/uhdf2/hdi.gni +++ b/uhdf2/hdi.gni @@ -50,9 +50,7 @@ template("hdi") { config("hdi_public_config") { include_dirs = [ - "$hdf_uhdf_path/include/hdi", "$hdf_uhdf_path/include/host", - "$hdf_uhdf_path/ipc/include", "${files_info.root_package_dir}", "${files_info.version_dir}", ] @@ -121,9 +119,10 @@ template("hdi") { public_configs = [ ":hdi_public_config" ] - deps = [ + deps = [ "$hdi_gen" ] + + public_deps = [ "$hdf_uhdf_path/hdi:libhdi", - "$hdi_gen", "//drivers/adapter/uhdf2/ipc:libhdf_ipc_adapter", "//drivers/adapter/uhdf2/utils:libhdf_utils", ] @@ -164,9 +163,10 @@ template("hdi") { public_configs = [ ":hdi_public_config" ] - deps = [ + deps = [ "$hdi_gen" ] + + public_deps = [ "$hdf_uhdf_path/hdi:libhdi", - "$hdi_gen", "//drivers/adapter/uhdf2/ipc:libhdf_ipc_adapter", "//drivers/adapter/uhdf2/utils:libhdf_utils", ] diff --git a/uhdf2/hdi/src/hdi_support.cpp b/uhdf2/hdi/src/hdi_support.cpp index fae506acae094d36722ee865faea0de7278d2cdc..91d8fca7d9b7e9d5f0beee45b42b13501fb3fd66 100644 --- a/uhdf2/hdi/src/hdi_support.cpp +++ b/uhdf2/hdi/src/hdi_support.cpp @@ -15,6 +15,7 @@ #include "hdi_support.h" #include +#include #include #include #include @@ -33,37 +34,76 @@ #endif namespace { -constexpr int VERSION_SIZE = 2; -constexpr size_t INTERFACE_SIZE = 5; -constexpr size_t INTERFACE_VERSION_INDEX = 3; -constexpr size_t INTERFACE_NAME_INDEX = 2; +constexpr size_t INTERFACE_MATCH_RESIZE = 4; +constexpr size_t INTERFACE_VERSION_MAJOR_INDEX = 1; +constexpr size_t INTERFACE_VERSION_MINOR_INDEX = 2; +constexpr size_t INTERFACE_NAME_INDEX = 3; +static const std::regex reInfDesc("[a-zA-Z_][a-zA-Z0-9_]*(?:\\.[a-zA-Z_][a-zA-Z0-9_]*)*\\." + "[V|v]([0-9]+)_([0-9]+)\\." + "([a-zA-Z_][a-zA-Z0-9_]*)"); } // namespace -static int ParseInterface( - const std::string &fullName, std::string &interface, uint32_t &versionMajor, uint32_t &versionMinor) +static int32_t ParseInterface(const std::string &fullName, std::string &interface, uint32_t &versionMajor, + uint32_t &versionMinor) { - std::vector spInfo; - OHOS::SplitStr(fullName, ".", spInfo, false, true); - if (spInfo.size() != INTERFACE_SIZE) { - HDF_LOGE("invlid interface format"); + std::smatch result; + if (!std::regex_match(fullName, result, reInfDesc)) { + HDF_LOGE("invalid format of interface descriptor '%{public}s'", fullName.c_str()); return HDF_FAILURE; } - interface = spInfo[INTERFACE_NAME_INDEX]; - int ret = sscanf_s(spInfo[INTERFACE_VERSION_INDEX].data(), "V%u_%u", &versionMajor, &versionMinor); - if (ret != VERSION_SIZE) { - HDF_LOGE("failed to get interface version\n"); + if (result.size() < INTERFACE_MATCH_RESIZE) { + HDF_LOGE("failed to parse interface descriptor '%{public}s'", fullName.c_str()); + return HDF_FAILURE; + } + + versionMajor = std::stoul(result[INTERFACE_VERSION_MAJOR_INDEX]); + versionMinor = std::stoul(result[INTERFACE_VERSION_MINOR_INDEX]); + std::string interfaceName = result[INTERFACE_NAME_INDEX]; + + interface = interfaceName[0] == 'I' ? interfaceName.substr(1) : interfaceName; + if (interface.empty()) { + HDF_LOGE("failed to get invalid interface name"); return HDF_FAILURE; } return HDF_SUCCESS; } +static std::string TransFileName(const std::string& interfaceName) +{ + if (interfaceName.empty()) { + return interfaceName; + } + + std::string result; + for (size_t i = 0; i < interfaceName.size(); i++) { + char c = interfaceName[i]; + if (std::isupper(c) != 0) { + if (i > 1) { + result += '_'; + } + result += std::tolower(c); + } else { + result += c; + } + } + return result; +} + +/* + * interface descriptor name: ohos.hdi.sample.v1_0.IFoo + * interface: Foo + * versionMajor: 1 + * versionMinor: 0 + * library name: libfoo_service_1.0.z.so + * method name: FooImplGetInstance + */ void *LoadHdiImpl(const char *fullIfName) { char path[PATH_MAX + 1] = {0}; char resolvedPath[PATH_MAX + 1] = {0}; - // interface name like "OHOS.HDI.Sample.V1_0.IFoo", the last two are version and interface name + // interface descriptor name like "ohos.hdi.sample.v1_0.IFoo", the last two are version and interface base name if (fullIfName == nullptr) { HDF_LOGE("fullIfName is nullptr"); return nullptr; @@ -78,9 +118,10 @@ void *LoadHdiImpl(const char *fullIfName) HDF_LOGE("failed to parse hdi interface info"); return nullptr; } - // hdi implement name like libsample_service_1.0.z.so + + // hdi implement name like libfoo_service_1.0.z.so if (snprintf_s(path, sizeof(path), sizeof(path) - 1, "%s/lib%s_service_%u.%u.z.so", HDI_SO_PATH, - OHOS::LowerStr(interfaceName).data(), versionMajor, versionMinor) < 0) { + TransFileName(interfaceName).data(), versionMajor, versionMinor) < 0) { HDF_LOGE("%{public}s snprintf_s failed", __func__); return nullptr; } diff --git a/uhdf2/hdi/src/object_collector.cpp b/uhdf2/hdi/src/object_collector.cpp index 8b99b84998c208e2357f6d7a2f2a91bdc1ea028e..7e1c69acfeef2c05f3eca95346b6293999836c85 100644 --- a/uhdf2/hdi/src/object_collector.cpp +++ b/uhdf2/hdi/src/object_collector.cpp @@ -18,6 +18,7 @@ #include "hdf_base.h" #include "hdf_log.h" +#include "osal_time.h" using namespace OHOS::HDI; @@ -67,15 +68,23 @@ OHOS::sptr ObjectCollector::NewObject( OHOS::sptr ObjectCollector::GetOrNewObject( const OHOS::sptr &interface, const std::u16string &interfaceName) { - std::lock_guard lock(mutex_); - + mutex_.lock(); +RETRY: auto it = interfaceObjectCollector_.find(interface.GetRefPtr()); if (it != interfaceObjectCollector_.end()) { + if (it->second->GetSptrRefCount() == 0) { + // may object is releasing, yield to sync + mutex_.unlock(); + OsalMSleep(1); + mutex_.lock(); + goto RETRY; + } + mutex_.unlock(); return it->second; } sptr object = NewObjectLocked(interface, interfaceName); interfaceObjectCollector_[interface.GetRefPtr()] = object.GetRefPtr(); - + mutex_.unlock(); return object; }