LCOV - code coverage report
Current view: top level - adcore/component - adx_server_manager.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 94.3 % 367 346
Test Date: 2026-08-12 11:04:53 Functions: 96.6 % 29 28

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : #include "adx_server_manager.h"
      11              : #include "log/adx_log.h"
      12              : #include "memory_utils.h"
      13              : #include "device/adx_hdc_device.h"
      14              : #include "hdc_api.h"
      15              : #include "adcore_api.h"
      16              : namespace Adx {
      17              : namespace {
      18              : constexpr uint32_t RECONNECT_TIMES = 3U;
      19              : constexpr uint32_t MAX_PROCESS_DRAIN_TIMEOUT = 5000U; // max 5s to wait the process threads over
      20              : } // namespace
      21              : 
      22           27 : AdxServerManager::AdxServerManager() noexcept
      23           27 :     : pid_(0),
      24           27 :       loadMode_(0),
      25           27 :       deviceId_(-1),
      26           27 :       type_(OptType::NR_COMM),
      27           54 :       info_(""),
      28           27 :       epoll_(nullptr),
      29           27 :       handleQue_(DEFAULT_EPOLL_HANDLE_QUEUE_SIZE),
      30           27 :       linkNum_(0),
      31           81 :       processingNum_(0)
      32              : {
      33           27 :     servers_.clear();
      34           27 : }
      35              : 
      36            2 : AdxServerManager::AdxServerManager(int32_t loadMode, int32_t deviceId) noexcept
      37            2 :     : pid_(0),
      38            2 :       loadMode_(loadMode),
      39            2 :       deviceId_(deviceId),
      40            2 :       type_(OptType::NR_COMM),
      41            4 :       info_(""),
      42            2 :       epoll_(nullptr),
      43            2 :       handleQue_(DEFAULT_EPOLL_HANDLE_QUEUE_SIZE),
      44            2 :       linkNum_(0),
      45            6 :       processingNum_(0)
      46              : {
      47            2 :     servers_.clear();
      48            2 : }
      49              : 
      50           29 : AdxServerManager::~AdxServerManager() { (void)Exit(); }
      51              : 
      52           20 : bool AdxServerManager::RegisterEpoll(std::unique_ptr<AdxEpoll>& epoll)
      53              : {
      54           20 :     if (epoll == nullptr) {
      55            1 :         IDE_LOGE("register epoll input error");
      56            1 :         return false;
      57              :     }
      58              : 
      59           19 :     if (epoll_ == nullptr) {
      60           19 :         epoll_ = std::move(epoll);
      61           19 :         return true;
      62              :     }
      63              : 
      64            0 :     return false;
      65              : }
      66              : 
      67           24 : bool AdxServerManager::RegisterCommOpt(std::unique_ptr<AdxCommOpt>& opt, const std::string& info)
      68              : {
      69           24 :     if (opt == nullptr) {
      70            5 :         IDE_LOGE("register commopt input error");
      71            5 :         return false;
      72              :     }
      73              : 
      74           19 :     info_ = info;
      75           19 :     type_ = opt->GetOptType();
      76           19 :     return AdxCommOptManager::Instance().CommOptsRegister(opt);
      77              : }
      78              : 
      79           25 : bool AdxServerManager::ServerInit(const std::map<std::string, std::string>& info)
      80              : {
      81              :     EpollEvent event;
      82           25 :     if (epoll_ == nullptr || type_ == OptType::NR_COMM || info.empty()) {
      83            7 :         IDE_LOGE("server init failed for epoll not register");
      84            7 :         return false;
      85              :     }
      86              : 
      87           18 :     CommHandle handle = AdxCommOptManager::Instance().OpenServer(type_, info);
      88           18 :     if (handle.session == ADX_OPT_INVALID_HANDLE) {
      89            0 :         return false;
      90              :     }
      91              : 
      92           18 :     event.events = ADX_EPOLL_CONN_IN;
      93           18 :     event.data = handle.session;
      94           18 :     if (epoll_->EpollCreate(DEFAULT_EPOLL_SIZE) == IDE_DAEMON_ERROR) {
      95            0 :         IDE_LOGE("create epoll failed");
      96            0 :         (void)AdxCommOptManager::Instance().CloseServer(handle);
      97            0 :         return false;
      98              :     }
      99              : 
     100           18 :     if (epoll_->EpollAdd(handle.session, event) != IDE_DAEMON_OK) {
     101            1 :         IDE_LOGE("epoll add listen event failed");
     102            1 :         (void)AdxCommOptManager::Instance().CloseServer(handle);
     103            1 :         return false;
     104              :     }
     105              : 
     106           17 :     auto it = info.find(OPT_DEVICE_KEY);
     107           17 :     if (it != info.end()) {
     108           17 :         servers_[it->second] = handle.session;
     109              :     }
     110           17 :     IDE_LOGI("create server info");
     111           17 :     return true;
     112              : }
     113              : 
     114           26 : bool AdxServerManager::ServerUnInit(OptHandle epHandle)
     115              : {
     116              :     EpollEvent event;
     117           26 :     if (epoll_ == nullptr || epHandle == ADX_OPT_INVALID_HANDLE) {
     118            2 :         IDE_LOGE("server uninit failed for epoll not register");
     119            2 :         return false;
     120              :     }
     121           24 :     event.events = ADX_EPOLL_CONN_IN;
     122           24 :     event.data = epHandle;
     123           24 :     if (epoll_->EpollDel(epHandle, event) == IDE_DAEMON_ERROR) {
     124            5 :         IDE_LOGE("epoll del listen event failed");
     125            5 :         return false;
     126              :     }
     127              : 
     128           19 :     CommHandle handle = {type_, epHandle, NR_COMPONENTS, -1, nullptr};
     129           19 :     if (AdxCommOptManager::Instance().CloseServer(handle) != IDE_DAEMON_OK) {
     130            1 :         IDE_LOGE("close server failed");
     131            1 :         return false;
     132              :     }
     133              : 
     134           18 :     return true;
     135              : }
     136              : 
     137           15 : bool AdxServerManager::ComponentAdd(std::unique_ptr<AdxComponent>& comp)
     138              : {
     139           15 :     if (comp == nullptr) {
     140            2 :         IDE_LOGE("add component input error");
     141            2 :         return false;
     142              :     }
     143              : 
     144           13 :     const ComponentType type = comp->GetType();
     145           13 :     std::lock_guard<std::mutex> lck(compMtx_);
     146           13 :     auto it = compMap_.find(type);
     147           13 :     if (it != compMap_.end()) {
     148            1 :         return false;
     149              :     }
     150           12 :     IDE_LOGI("server manager add component (%d)", static_cast<int32_t>(type));
     151           12 :     compMap_[type] = std::shared_ptr<AdxComponent>(std::move(comp));
     152           12 :     return true;
     153           13 : }
     154              : 
     155            3 : bool AdxServerManager::ComponentErase(ComponentType type)
     156              : {
     157            3 :     std::lock_guard<std::mutex> lck(compMtx_);
     158            3 :     auto it = compMap_.find(type);
     159            3 :     if (it == compMap_.end()) {
     160            1 :         return false;
     161              :     }
     162            2 :     IDE_LOGI("server manager erase component (%d)", type);
     163            2 :     (void)compMap_.erase(type);
     164            2 :     return (compMap_.count(type) == 0);
     165            3 : }
     166              : 
     167            5 : std::shared_ptr<AdxComponent> AdxServerManager::GetComponent(ComponentType type) const
     168              : {
     169            5 :     std::lock_guard<std::mutex> lck(compMtx_);
     170            5 :     auto it = compMap_.find(type);
     171           10 :     return (it == compMap_.end()) ? nullptr : it->second;
     172            5 : }
     173              : 
     174           10 : bool AdxServerManager::ComponentInit() const
     175              : {
     176           10 :     if (epoll_ == nullptr) {
     177            1 :         return false;
     178              :     }
     179              : 
     180              :     // Snapshot under lock, call Init() outside to avoid re-entering compMtx_(eg: LibLoadServerInit)
     181            9 :     std::vector<std::shared_ptr<AdxComponent>> snapshot;
     182              :     {
     183            9 :         std::lock_guard<std::mutex> lck(compMtx_);
     184            9 :         snapshot.reserve(compMap_.size());
     185           18 :         for (const auto& item : compMap_) {
     186            9 :             snapshot.push_back(item.second);
     187              :         }
     188            9 :     }
     189           18 :     for (auto& component : snapshot) {
     190            9 :         (void)component->Init();
     191              :     }
     192            9 :     IDE_LOGI("server manager components init successfully");
     193            9 :     return true;
     194            9 : }
     195              : 
     196            9 : void AdxServerManager::HandleConnectEvent(CommHandle handle)
     197              : {
     198            9 :     CommHandle conHandle = AdxCommOptManager::Instance().Accept(handle);
     199            9 :     if (conHandle.session == ADX_OPT_INVALID_HANDLE) {
     200            0 :         return;
     201              :     }
     202            9 :     handleQue_.Push(conHandle.session);
     203            9 :     IDE_LOGD("handle queue push: %lx", conHandle.session);
     204              :     mmUserBlock_t funcBlock;
     205            9 :     funcBlock.procFunc = AdxServerManager::ThreadProcess;
     206            9 :     funcBlock.pulArg = this;
     207            9 :     mmThread tid = 0;
     208              :     {
     209            9 :         std::lock_guard<std::mutex> lck(processMtx_);
     210            9 :         ++processingNum_;
     211            9 :     }
     212            9 :     int32_t ret = Thread::CreateDetachTask(tid, funcBlock);
     213            9 :     if (ret != EN_OK) {
     214              :         {
     215            1 :             std::lock_guard<std::mutex> lck(processMtx_);
     216            1 :             --processingNum_;
     217            1 :             processCv_.notify_all();
     218            1 :         }
     219            1 :         EpollHandle epHandle = ADX_INVALID_HANDLE;
     220            1 :         if (handleQue_.Pop(epHandle) == true) {
     221            1 :             IDE_LOGD("handle queue pop: %lx", epHandle);
     222            1 :             CommHandle curHandle{type_, epHandle, NR_COMPONENTS, -1, nullptr};
     223            1 :             (void)AdxCommOptManager::Instance().Close(curHandle);
     224              :         }
     225            1 :         char errBuf[MAX_ERRSTR_LEN + 1] = {0};
     226            1 :         IDE_LOGE(
     227              :             "create component process thread failed, strerror is %s",
     228              :             mmGetErrorFormatMessage(mmGetErrorCode(), errBuf, MAX_ERRSTR_LEN));
     229              :     }
     230              : }
     231           10 : bool AdxServerManager::ComponentWaitEvent()
     232              : {
     233           10 :     IDE_CTRL_VALUE_FAILED(epoll_ != nullptr, return false, "epoll_ check failed, nullptr");
     234            9 :     const int32_t epollSize = epoll_->EpollGetSize();
     235            9 :     std::vector<EpollEvent> events(epollSize);
     236         1161 :     for (int32_t i = 0; i < epollSize; i++) {
     237         1152 :         events[i].data = 0;
     238         1152 :         events[i].events = 0;
     239              :     }
     240            9 :     IDE_RUN_LOGI("Run Server(%d) Process", static_cast<int32_t>(type_));
     241            9 :     waitOver_ = false;
     242           27 :     while (!IsQuit()) {
     243            9 :         TimerProcess();
     244            9 :         int32_t handles = epoll_->EpollWait(events, epollSize, DEFAULT_EPOLL_TIMEOUT);
     245           36 :         for (int32_t i = 0; i < handles && i < epollSize; i++) {
     246           27 :             IDE_LOGI("sock EpollWait accept event %d", handles);
     247           27 :             if ((events[i].events & ADX_EPOLL_CONN_IN) != 0) {
     248            9 :                 IDE_LOGI("sock connect EpollWait event %d", handles);
     249            9 :                 CommHandle handle = {type_, events[i].data, NR_COMPONENTS, -1, nullptr};
     250            9 :                 HandleConnectEvent(handle);
     251           18 :             } else if ((events[i].events & ADX_EPOLL_DATA_IN) != 0) {
     252            0 :                 IDE_LOGI("data in");
     253           18 :             } else if ((events[i].events & ADX_EPOLL_HANG_UP) != 0) {
     254            0 :                 IDE_LOGW("hang up state");
     255              :             } else {
     256           18 :                 IDE_LOGW("other epoll state");
     257           18 :                 epoll_->EpollErrorHandle();
     258              :             }
     259              :         }
     260            9 :         if (handles < 0) {
     261            0 :             epoll_->EpollErrorHandle();
     262              :         }
     263              :     }
     264              : 
     265            9 :     waitOver_ = true;
     266            9 :     return true;
     267            9 : }
     268              : 
     269            9 : void AdxServerManager::Run()
     270              : {
     271            9 :     pid_ = mmGetPid();
     272            9 :     if (ComponentWaitEvent()) {
     273            9 :         IDE_RUN_LOGI("server manager stop");
     274              :     }
     275            9 : }
     276              : 
     277            8 : IdeThreadArg AdxServerManager::ThreadProcess(IdeThreadArg arg)
     278              : {
     279            8 :     if (arg == nullptr) {
     280            0 :         return nullptr;
     281              :     }
     282            8 :     auto runnable = reinterpret_cast<AdxServerManager*>(arg);
     283            8 :     (void)mmSetCurrentThreadName("adx_component_process");
     284            8 :     runnable->ComponentProcess();
     285            8 :     return nullptr;
     286              : }
     287              : 
     288            8 : void AdxServerManager::ComponentProcess()
     289              : {
     290            8 :     const std::shared_ptr<void> processGuard(nullptr, [this](void*) {
     291            8 :         std::lock_guard<std::mutex> lck(this->processMtx_);
     292            8 :         --this->processingNum_;
     293            8 :         this->processCv_.notify_all();
     294           16 :     });
     295              : 
     296            8 :     EpollHandle epHandle = ADX_INVALID_HANDLE;
     297            8 :     IDE_LOGI("process new connect");
     298            8 :     if (handleQue_.Pop(epHandle) == false) {
     299            0 :         return;
     300              :     }
     301            8 :     IDE_LOGD("handle queue pop: %lx", epHandle);
     302              : 
     303            8 :     if (epHandle == ADX_INVALID_HANDLE) {
     304            0 :         IDE_LOGE("server run process handle invalid");
     305            0 :         return;
     306              :     }
     307              : 
     308            8 :     AdxCommHandle handle = static_cast<AdxCommHandle>(IdeXmalloc(sizeof(CommHandle)));
     309            8 :     IDE_CTRL_VALUE_FAILED(handle != nullptr, return, "malloc handle failed.");
     310            8 :     handle->type = type_;
     311            8 :     handle->session = epHandle;
     312            8 :     handle->comp = ComponentType::NR_COMPONENTS;
     313            8 :     handle->timeout = 0;
     314            8 :     handle->client = nullptr;
     315            8 :     ComponentType comp = ComponentType::NR_COMPONENTS;
     316            8 :     bool ret = SubComponentProcess(*handle, comp);
     317            8 :     if (((comp != ComponentType::COMPONENT_LOG_BACKHAUL) && (comp != ComponentType::COMPONENT_TRACE) &&
     318            8 :          (comp != ComponentType::COMPONENT_SYS_REPORT) && (comp != ComponentType::COMPONENT_FILE_REPORT) &&
     319            8 :          (comp != ComponentType::COMPONENT_CPU_DETECT)) ||
     320            0 :         !ret) {
     321            8 :         (void)AdxCommOptManager::Instance().Close(*handle);
     322            8 :         handle->session = ADX_OPT_INVALID_HANDLE;
     323            8 :         IDE_XFREE_AND_SET_NULL(handle);
     324              :     }
     325            8 : }
     326              : 
     327            8 : bool AdxServerManager::SubComponentProcess(CommHandle& handle, ComponentType& comp)
     328              : {
     329            8 :     MsgProto* req = nullptr;
     330            8 :     int32_t length = 0;
     331              : 
     332              :     int32_t ret =
     333            8 :         AdxCommOptManager::Instance().Read(handle, reinterpret_cast<IdeRecvBuffT>(&req), length, COMM_OPT_NOBLOCK);
     334            8 :     if (ret == IDE_DAEMON_ERROR || req == nullptr || length <= 0) {
     335            1 :         IDE_LOGE("receive request failed ret %d, length(%d bytes)", ret, length);
     336            1 :         return false;
     337              :     }
     338              : 
     339            7 :     SharedPtr<MsgProto> msgPtr(req, IdeXfree);
     340            7 :     req = nullptr;
     341            7 :     if (msgPtr->sliceLen + sizeof(MsgProto) != (uint32_t)length) {
     342            1 :         IDE_LOGE("receive request package(%u bytes) length(%d bytes) exception", msgPtr->sliceLen, length);
     343            1 :         return false;
     344              :     }
     345              : 
     346            6 :     HDC_SESSION session = reinterpret_cast<HDC_SESSION>(handle.session);
     347            6 :     int32_t devId = -1;
     348            6 :     ret = IdeGetDevIdBySession(session, &devId);
     349            6 :     if (ret != IDE_DAEMON_OK || devId < 0 || devId > UINT16_MAX) {
     350            1 :         IDE_LOGE("get dev id by session fail, ret=%d", ret);
     351            1 :         return false;
     352              :     }
     353            5 :     msgPtr->devId = static_cast<uint16_t>(devId);
     354              : 
     355            5 :     IDE_LOGI("commopt type(%d), request type(%u), device id(%d)", static_cast<int32_t>(type_), msgPtr->reqType, devId);
     356            5 :     return DispatchComponent(handle, msgPtr, session, comp);
     357            7 : }
     358              : 
     359            5 : bool AdxServerManager::DispatchComponent(
     360              :     CommHandle& handle, SharedPtr<MsgProto>& msgPtr, HDC_SESSION session, ComponentType& comp)
     361              : {
     362            5 :     comp = GetComponentTypeByReqType(static_cast<CmdClassT>(msgPtr->reqType));
     363              :     // hold a reference of the component, it keeps alive until this process is over
     364            5 :     const std::shared_ptr<AdxComponent> component = GetComponent(comp);
     365            5 :     if (component == nullptr) {
     366            1 :         IDE_LOGE("Unable to find the corresponding component type(%d)", static_cast<int32_t>(comp));
     367            1 :         return false;
     368              :     }
     369              : 
     370            4 :     handle.comp = comp;
     371            4 :     if (handle.comp == ComponentType::COMPONENT_GETD_FILE || handle.comp == COMPONENT_LOG_LEVEL) {
     372            4 :         std::lock_guard<std::mutex> lck(linkMtx_);
     373            4 :         if (IsLinkOverload(session)) {
     374            3 :             return false;
     375              :         }
     376            1 :         linkNum_++;
     377            4 :     }
     378            1 :     std::string compInfo = component->GetInfo();
     379            1 :     IDE_LOGI("begin to process [%s] component", compInfo.c_str());
     380            1 :     if (component->Process(handle, msgPtr) != IDE_DAEMON_OK) {
     381            0 :         IDE_LOGE("end of processing [%s] component failed, req->type: %u", compInfo.c_str(), msgPtr->reqType);
     382              :     } else {
     383            1 :         IDE_LOGI("end of processing [%s] component successfully", compInfo.c_str());
     384              :     }
     385            1 :     if (handle.comp == ComponentType::COMPONENT_GETD_FILE || handle.comp == COMPONENT_LOG_LEVEL) {
     386            1 :         std::lock_guard<std::mutex> lck(linkMtx_);
     387            1 :         linkNum_--;
     388            1 :     }
     389            1 :     return true;
     390            5 : }
     391              : 
     392            5 : ComponentType AdxServerManager::GetComponentTypeByReqType(CmdClassT cmdType) const
     393              : {
     394            5 :     ComponentType cmptType = ComponentType::NR_COMPONENTS;
     395            5 :     for (uint32_t i = 0; i < ARRAY_LEN(g_componentsInfo, AdxComponentMap); i++) {
     396            5 :         if (cmdType == g_componentsInfo[i].cmdType) {
     397            5 :             cmptType = g_componentsInfo[i].cmptType;
     398            5 :             break;
     399              :         }
     400              :     }
     401            5 :     return cmptType;
     402              : }
     403              : 
     404           14 : void AdxServerManager::TimerProcess()
     405              : {
     406           14 :     std::vector<std::string> devLogIds;
     407           14 :     SharedPtr<AdxDevice> device = AdxCommOptManager::Instance().GetDevice(type_);
     408           14 :     if (device == nullptr) {
     409            0 :         return;
     410              :     }
     411              : 
     412              :     // initialize the devices on the first time(AdxCommOptManager is singleton object)
     413              :     // create HDC server on th enable device
     414           14 :     device->GetAllEnableDevices(loadMode_, deviceId_, devLogIds);
     415           14 :     std::map<std::string, std::string> info;
     416           14 :     info[OPT_SERVICE_KEY] = info_;
     417              : 
     418           14 :     std::lock_guard<std::mutex> lck(serverMtx_);
     419           28 :     for (const auto& deviceId : devLogIds) {
     420              :         // filter the device that created HDC server(or not the specified device)
     421           14 :         if (servers_.find(deviceId) != servers_.end() || !(deviceId_ == -1 || std::to_string(deviceId_) == deviceId)) {
     422           12 :             continue;
     423              :         }
     424              : 
     425            5 :         IDE_LOGI("device up %s", deviceId.c_str());
     426            5 :         info[OPT_DEVICE_KEY] = deviceId;
     427            5 :         if (ServerInit(info)) {
     428            1 :             faultyDevices_.erase(deviceId);
     429            1 :             continue;
     430              :         }
     431              : 
     432              :         // record retry times of connection for the faulty device
     433            4 :         auto faultDevice = faultyDevices_.find(deviceId);
     434            4 :         if (faultDevice == faultyDevices_.end()) {
     435            2 :             faultyDevices_[deviceId] = 1;
     436            2 :             continue;
     437              :         }
     438            2 :         ++(faultDevice->second);
     439            2 :         if (faultDevice->second >= RECONNECT_TIMES) {
     440            1 :             faultyDevices_.erase(faultDevice);
     441              :             // set the device to disable if connection is timeout
     442            1 :             device->DisableNotify(deviceId);
     443              :         }
     444              :     }
     445              : 
     446           14 :     device->GetDisableDevices(devLogIds);
     447           15 :     for (const auto& deviceId : devLogIds) {
     448            1 :         auto server = servers_.find(deviceId);
     449            1 :         if (server == servers_.end()) {
     450            1 :             continue;
     451              :         }
     452            0 :         IDE_LOGI("device suspend %s", deviceId.c_str());
     453            0 :         if (ServerUnInit(server->second)) {
     454            0 :             servers_.erase(server);
     455              :         }
     456              :     }
     457           14 :     serverInittedFlag_ = true;
     458           14 :     AdxCommOptManager::Instance().Timer(type_);
     459           14 : }
     460              : 
     461           84 : int32_t AdxServerManager::Exit()
     462              : {
     463           84 :     serverInittedFlag_ = false;
     464           84 :     if (pid_ == mmGetPid()) { // not fork
     465              :         // Stop the manager thread: Terminate stops accepting new client sessions
     466           10 :         Terminate();
     467              :         // Confirm the thread exited
     468           10 :         while (!waitOver_) {
     469            0 :             mmSleep(DEFAULT_EPOLL_TIMEOUT);
     470              :         }
     471              :     }
     472              : 
     473              :     // Stop the components: UnInit stops processing new client sessions,
     474              :     // then Terminate closes blocking client sessions
     475           84 :     std::vector<std::shared_ptr<AdxComponent>> stopSnapshot;
     476              :     {
     477           84 :         std::lock_guard<std::mutex> lck(compMtx_);
     478           84 :         stopSnapshot.reserve(compMap_.size());
     479           94 :         for (auto& item : compMap_) {
     480           10 :             stopSnapshot.push_back(item.second);
     481              :         }
     482           84 :     }
     483           94 :     for (auto& component : stopSnapshot) {
     484           10 :         (void)component->UnInit();
     485           10 :         (void)component->Terminate();
     486              :     }
     487              : 
     488              :     // Wait the client session threads over, they are still using the components and the sessions
     489           84 :     WaitProcessDrained();
     490              : 
     491              :     // Finalize the servers(delete epoll and close the listening handle)
     492           84 :     int32_t serverRet = IDE_DAEMON_OK;
     493              :     {
     494           84 :         std::lock_guard<std::mutex> lck(serverMtx_);
     495           84 :         auto it = servers_.begin();
     496          103 :         while (it != servers_.end()) {
     497           19 :             if (ServerUnInit(it->second)) {
     498           16 :                 it = servers_.erase(it);
     499              :             } else {
     500            3 :                 serverRet = IDE_DAEMON_ERROR;
     501            3 :                 ++it;
     502              :             }
     503              :         }
     504           84 :     }
     505           84 :     if (serverRet != IDE_DAEMON_OK) {
     506            3 :         return serverRet;
     507              :     }
     508              : 
     509              :     // Clear the registered components. shared_ptr(not unique_ptr) is required here: on drain
     510              :     // timeout the straggler thread still holds its reference and destroys the component itself
     511              :     {
     512           81 :         std::lock_guard<std::mutex> lck(compMtx_);
     513           81 :         compMap_.clear();
     514           81 :     }
     515              : 
     516           81 :     if (epoll_ != nullptr) {
     517           18 :         if (epoll_->EpollDestroy() != IDE_DAEMON_OK) {
     518            1 :             return IDE_DAEMON_ERROR;
     519              :         }
     520           17 :         epoll_ = nullptr;
     521              :     }
     522           80 :     return IDE_DAEMON_OK;
     523           84 : }
     524              : 
     525           84 : void AdxServerManager::WaitProcessDrained()
     526              : {
     527           84 :     std::unique_lock<std::mutex> lck(processMtx_);
     528           84 :     if (!processCv_.wait_for(lck, std::chrono::milliseconds(MAX_PROCESS_DRAIN_TIMEOUT), [this]() {
     529           84 :             return this->processingNum_ == 0U;
     530              :         })) {
     531            0 :         IDE_LOGW(
     532              :             "still have %u component process threads running after waiting %ums", processingNum_,
     533              :             MAX_PROCESS_DRAIN_TIMEOUT);
     534              :     }
     535           84 : }
     536              : 
     537            9 : void AdxServerManager::SetMode(int32_t loadMode) { loadMode_ = loadMode; }
     538              : 
     539            9 : void AdxServerManager::SetDeviceId(int32_t deviceId) { deviceId_ = deviceId; }
     540              : 
     541            2 : bool AdxServerManager::IsLinkOverload(HDC_SESSION session) const
     542              : {
     543            2 :     const int32_t maxLinkNum = 16; // limit max links num is 16 at the same time
     544            2 :     if (linkNum_ >= maxLinkNum) {
     545            1 :         int32_t pid = -1;
     546            1 :         (void)IdeGetPidBySession(session, &pid);
     547            1 :         IDE_LOGE("server manager overload, pid: %d.", pid);
     548            1 :         return true;
     549              :     }
     550            1 :     return false;
     551              : }
     552              : 
     553           49 : bool AdxServerManager::WaitServerInitted() const
     554              : {
     555              :     // 最大等待60s,等待serverInittedFlag_为true,每等待一轮等待时间增加1毫秒
     556           49 :     const int32_t maxRetryTimes = 346; // 60s (1 + 2 + ... + 346)ms
     557           49 :     int32_t retryTime = 1;
     558        16609 :     while (retryTime < maxRetryTimes) {
     559        16561 :         if (serverInittedFlag_) {
     560            1 :             IDE_LOGI("The server is initialized after waiting %d times.", retryTime);
     561            1 :             return true;
     562              :         }
     563        16560 :         mmSleep(retryTime);
     564        16560 :         retryTime++;
     565              :     }
     566              : 
     567           48 :     if (retryTime >= maxRetryTimes) {
     568           48 :         IDE_LOGW("The server is not initialized after waiting %d times.", retryTime);
     569              :     }
     570              : 
     571           48 :     return false;
     572              : }
     573              : } // namespace Adx
        

Generated by: LCOV version 2.0-1