diff --git a/adapter/uhdf2/host/test/unittest/devmgr_test.cpp b/adapter/uhdf2/host/test/unittest/devmgr_test.cpp index 2b592a90b11b5236c44bb9d6d4a3151c804f9dd8..549546066f308611457f6a389bc5a75d98512569 100644 --- a/adapter/uhdf2/host/test/unittest/devmgr_test.cpp +++ b/adapter/uhdf2/host/test/unittest/devmgr_test.cpp @@ -108,4 +108,36 @@ HWTEST_F(DevMgrTest, DriverUnLoaderTest, TestSize.Level1) ASSERT_TRUE(sampleService == nullptr); } + +HWTEST_F(DevMgrTest, DriverTest, TestSize.Level1) +{ + ASSERT_TRUE(servmgr != nullptr); + ASSERT_TRUE(devmgr != nullptr); + int ret; + constexpr int loop = 100; + + for (int i = 0; i < loop; i++) { + ret = devmgr->LoadDevice(devmgr, TEST_SERVICE_NAME); + ASSERT_EQ(ret, HDF_SUCCESS); + uint32_t cnt = 0; + struct HdfRemoteService *sampleService = servmgr->GetService(servmgr, TEST_SERVICE_NAME); + while (sampleService == nullptr && cnt < timeout) { + OsalMSleep(waitTime); + sampleService = servmgr->GetService(servmgr, TEST_SERVICE_NAME); + cnt++; + } + ASSERT_TRUE(sampleService != nullptr); + + ret = devmgr->UnloadDevice(devmgr, TEST_SERVICE_NAME); + ASSERT_EQ(ret, HDF_SUCCESS); + cnt = 0; + sampleService = servmgr->GetService(servmgr, TEST_SERVICE_NAME); + while (sampleService != nullptr && cnt < timeout) { + OsalMSleep(waitTime); + sampleService = servmgr->GetService(servmgr, TEST_SERVICE_NAME); + cnt++; + } + ASSERT_TRUE(sampleService == nullptr); + } +} } // namespace OHOS diff --git a/adapter/uhdf2/manager/src/devmgr_service_full.c b/adapter/uhdf2/manager/src/devmgr_service_full.c index 628c277b5c4ddf96ecb09f61e6f4c4dce66d90da..25daa8633fa0638f86a6881792fedbcee2467255 100644 --- a/adapter/uhdf2/manager/src/devmgr_service_full.c +++ b/adapter/uhdf2/manager/src/devmgr_service_full.c @@ -33,11 +33,11 @@ static Map g_hostMap = {0}; static void CleanupDiedHostResources(struct DevHostServiceClnt *hostClnt, struct HdfRemoteService *service) { OsalMutexLock(&hostClnt->hostLock); - hostClnt->hostPid = INVALID_PID; struct DevHostServiceProxy *hostProxy = (struct DevHostServiceProxy *)hostClnt->hostService; if (hostProxy != NULL) { if ((hostProxy->remote != NULL) && ((uintptr_t)hostProxy->remote == (uintptr_t)service)) { HDF_LOGI("%{public}s hostId: %{public}u remove current hostService", __func__, hostClnt->hostId); + hostClnt->hostPid = INVALID_PID; DevHostServiceProxyRecycle(hostProxy); hostClnt->hostService = NULL; HdfSListFlush(&hostClnt->devices, DeviceTokenClntDelete); @@ -90,7 +90,10 @@ static int32_t DevmgrServiceFullHandleDeviceHostDied(struct DevHostServiceClnt * struct IDriverInstaller *installer = DriverInstallerGetInstance(); if (installer != NULL && installer->StartDeviceHost != NULL) { HDF_LOGI("%{public}s:%{public}d", __func__, __LINE__); - hostClnt->hostPid = installer->StartDeviceHost(hostClnt->hostId, hostClnt->hostName, true); + int pid = installer->StartDeviceHost(hostClnt->hostId, hostClnt->hostName, true); + OsalMutexLock(&hostClnt->hostLock); + hostClnt->hostPid = pid; + OsalMutexUnlock(&hostClnt->hostLock); return hostClnt->hostPid; } return INVALID_PID; diff --git a/framework/core/manager/src/devmgr_service.c b/framework/core/manager/src/devmgr_service.c index 54c1fee317352e9081ca486931741d9ee67bc79e..ac221dbb38326ad501ea263f4ac12d75451be381 100644 --- a/framework/core/manager/src/devmgr_service.c +++ b/framework/core/manager/src/devmgr_service.c @@ -19,6 +19,7 @@ #include "osal_time.h" #define HDF_LOG_TAG devmgr_service +#define INVALID_PID (-1) static bool DevmgrServiceDynamicDevInfoFound( const char *svcName, struct DevHostServiceClnt **targetHostClnt, struct HdfDeviceInfo **targetDeviceInfo) @@ -104,11 +105,16 @@ static int DevmgrServiceLoadDevice(struct IDevmgrService *devMgrSvc, const char } dynamic = HdfSListIsEmpty(&hostClnt->unloadDevInfos) && !HdfSListIsEmpty(&hostClnt->dynamicDevInfos); - if (hostClnt->hostPid < 0 && DevmgrServiceStartHostProcess(hostClnt, true, dynamic) != HDF_SUCCESS) { - HDF_LOGW("failed to start device host(%{public}s, %{public}u)", hostClnt->hostName, hostClnt->hostId); - return HDF_FAILURE; - } OsalMutexLock(&hostClnt->hostLock); + if (hostClnt->hostPid < 0) { + OsalMutexUnlock(&hostClnt->hostLock); + if (DevmgrServiceStartHostProcess(hostClnt, true, dynamic) != HDF_SUCCESS) { + HDF_LOGW("failed to start device host(%{public}s, %{public}u)", hostClnt->hostName, hostClnt->hostId); + return HDF_FAILURE; + } + OsalMutexLock(&hostClnt->hostLock); + } + if (hostClnt->hostService == NULL || hostClnt->hostService->AddDevice == NULL) { OsalMutexUnlock(&hostClnt->hostLock); HDF_LOGE("%{public}s load %{public}s failed, hostService is null", __func__, serviceName); @@ -157,17 +163,24 @@ static int DevmgrServiceUnloadDevice(struct IDevmgrService *devMgrSvc, const cha return HDF_FAILURE; } ret = hostClnt->hostService->DelDevice(hostClnt->hostService, deviceInfo->deviceId); - OsalMutexUnlock(&hostClnt->hostLock); if (ret != HDF_SUCCESS) { + OsalMutexUnlock(&hostClnt->hostLock); HDF_LOGI("%{public}s:unload service %{public}s delDevice failed", __func__, serviceName); return ret; } deviceInfo->status = HDF_SERVICE_UNUSABLE; if (!HdfSListIsEmpty(&hostClnt->devices)) { + OsalMutexUnlock(&hostClnt->hostLock); HDF_LOGD("%{public}s host %{public}s devices is not empty", __func__, hostClnt->hostName); return HDF_SUCCESS; } - return DevmgrServiceStopHost(hostClnt); + hostClnt->hostPid = INVALID_PID; + hostClnt->hostService = NULL; // old hostService will be recycled in CleanupDiedHostResources + HdfSListFlush(&hostClnt->devices, DeviceTokenClntDelete); + OsalMutexUnlock(&hostClnt->hostLock); + ret = DevmgrServiceStopHost(hostClnt); + + return ret; } int32_t DevmgrServiceLoadLeftDriver(struct DevmgrService *devMgrSvc)