LCOV - code coverage report
Current view: top level - adcore/component - adx_server_manager.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 93.8 % 324 304
Test Date: 2026-07-28 10:54:24 Functions: 96.0 % 25 24

            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              : }
      20              : 
      21           24 : AdxServerManager::AdxServerManager() noexcept
      22           24 :     : waitOver_(true),
      23           24 :       pid_(0),
      24           24 :       loadMode_(0),
      25           24 :       deviceId_(-1),
      26           24 :       type_(OptType::NR_COMM),
      27           24 :       info_(""),
      28           24 :       epoll_(nullptr),
      29           24 :       handleQue_(DEFAULT_EPOLL_HANDLE_QUEUE_SIZE),
      30           24 :       linkNum_(0),
      31           72 :       serverInittedFlag_(false)
      32              : {
      33           24 :     servers_.clear();
      34           24 : }
      35              : 
      36            2 : AdxServerManager::AdxServerManager(int32_t loadMode, int32_t deviceId) noexcept
      37            2 :     : waitOver_(true),
      38            2 :       pid_(0),
      39            2 :       loadMode_(loadMode),
      40            2 :       deviceId_(deviceId),
      41            2 :       type_(OptType::NR_COMM),
      42            2 :       info_(""),
      43            2 :       epoll_(nullptr),
      44            2 :       handleQue_(DEFAULT_EPOLL_HANDLE_QUEUE_SIZE),
      45            2 :       linkNum_(0),
      46            6 :       serverInittedFlag_(false)
      47              : {
      48            2 :     servers_.clear();
      49            2 : }
      50              : 
      51           26 : AdxServerManager::~AdxServerManager()
      52              : {
      53           26 :     (void)Exit();
      54           26 : }
      55              : 
      56           17 : bool AdxServerManager::RegisterEpoll(std::unique_ptr<AdxEpoll> &epoll)
      57              : {
      58           17 :     if (epoll == nullptr) {
      59            1 :         IDE_LOGE("register epoll input error");
      60            1 :         return false;
      61              :     }
      62              : 
      63           16 :     if (epoll_ == nullptr) {
      64           16 :         epoll_ = std::move(epoll);
      65           16 :         return true;
      66              :     }
      67              : 
      68            0 :     return false;
      69              : }
      70              : 
      71           21 : bool AdxServerManager::RegisterCommOpt(std::unique_ptr<AdxCommOpt> &opt,
      72              :     const std::string &info)
      73              : {
      74           21 :     if (opt == nullptr) {
      75            5 :         IDE_LOGE("register commopt input error");
      76            5 :         return false;
      77              :     }
      78              : 
      79           16 :     info_ = info;
      80           16 :     type_ = opt->GetOptType();
      81           16 :     return AdxCommOptManager::Instance().CommOptsRegister(opt);
      82              : }
      83              : 
      84           22 : bool AdxServerManager::ServerInit(const std::map<std::string, std::string> &info)
      85              : {
      86              :     EpollEvent event;
      87           22 :     if (epoll_ == nullptr || type_ == OptType::NR_COMM || info.empty()) {
      88            7 :         IDE_LOGE("server init failed for epoll not register");
      89            7 :         return false;
      90              :     }
      91              : 
      92           15 :     CommHandle handle = AdxCommOptManager::Instance().OpenServer(type_, info);
      93           15 :     if (handle.session == ADX_OPT_INVALID_HANDLE) {
      94            0 :         return false;
      95              :     }
      96              : 
      97           15 :     event.events = ADX_EPOLL_CONN_IN;
      98           15 :     event.data = handle.session;
      99           15 :     if (epoll_->EpollCreate(DEFAULT_EPOLL_SIZE) == IDE_DAEMON_ERROR) {
     100            0 :         IDE_LOGE("create epoll failed");
     101            0 :         (void)AdxCommOptManager::Instance().CloseServer(handle);
     102            0 :         return false;
     103              :     }
     104              : 
     105           15 :     if (epoll_->EpollAdd(handle.session, event) != IDE_DAEMON_OK) {
     106            1 :         IDE_LOGE("epoll add listen event failed");
     107            1 :         (void)AdxCommOptManager::Instance().CloseServer(handle);
     108            1 :         return false;
     109              :     }
     110              : 
     111           14 :     auto it = info.find(OPT_DEVICE_KEY);
     112           14 :     if (it != info.end()) {
     113           14 :         servers_[it->second] = handle.session;
     114              :     }
     115           14 :     IDE_LOGI("create server info");
     116           14 :     return true;
     117              : }
     118              : 
     119           21 : bool AdxServerManager::ServerUnInit(OptHandle epHandle)
     120              : {
     121              :     EpollEvent event;
     122           21 :     if (epoll_ == nullptr || epHandle == ADX_OPT_INVALID_HANDLE) {
     123            2 :         IDE_LOGE("server uninit failed for epoll not register");
     124            2 :         return false;
     125              :     }
     126           19 :     event.events = ADX_EPOLL_CONN_IN;
     127           19 :     event.data = epHandle;
     128           19 :     if (epoll_->EpollDel(epHandle, event) == IDE_DAEMON_ERROR) {
     129            2 :         IDE_LOGE("epoll del listen event failed");
     130            2 :         return false;
     131              :     }
     132              : 
     133           17 :     CommHandle handle = {type_, epHandle, NR_COMPONENTS, -1, nullptr};
     134           17 :     if (AdxCommOptManager::Instance().CloseServer(handle) != IDE_DAEMON_OK) {
     135            1 :         IDE_LOGE("close server failed");
     136            1 :         return false;
     137              :     }
     138              : 
     139           16 :     return true;
     140              : }
     141              : 
     142           15 : bool AdxServerManager::ComponentAdd(std::unique_ptr<AdxComponent> &comp)
     143              : {
     144           15 :     if (comp == nullptr) {
     145            2 :         IDE_LOGE("add component input error");
     146            2 :         return false;
     147              :     }
     148              : 
     149           13 :     auto it = compMap_.find(comp->GetType());
     150           13 :     if (it != compMap_.end()) {
     151            1 :         return false;
     152              :     }
     153           12 :     IDE_LOGI("server manager add component (%d)", static_cast<int32_t>(comp->GetType()));
     154           12 :     compMap_[comp->GetType()] = std::move(comp);
     155           12 :     return true;
     156              : }
     157              : 
     158            3 : bool AdxServerManager::ComponentErase(ComponentType type)
     159              : {
     160            3 :     auto it = compMap_.find(type);
     161            3 :     if (it == compMap_.end()) {
     162            1 :         return false;
     163              :     }
     164            2 :     IDE_LOGI("server manager erase component (%d)", type);
     165            2 :     (void)compMap_.erase(type);
     166            2 :     return (compMap_.count(type) == 0);
     167              : }
     168              : 
     169           10 : bool AdxServerManager::ComponentInit() const
     170              : {
     171           10 :     if (epoll_ == nullptr) {
     172            1 :         return false;
     173              :     }
     174              : 
     175            9 :     auto it = compMap_.begin();
     176           18 :     while (it != compMap_.end()) {
     177            9 :         (void)it->second->Init();
     178            9 :         it++;
     179              :     }
     180            9 :     IDE_LOGI("server manager components init successfully");
     181            9 :     return true;
     182              : }
     183              : 
     184            9 : void AdxServerManager::HandleConnectEvent(CommHandle handle)
     185              : {
     186            9 :     CommHandle conHandle = AdxCommOptManager::Instance().Accept(handle);
     187            9 :     if (conHandle.session == ADX_OPT_INVALID_HANDLE) {
     188            0 :         return;
     189              :     }
     190            9 :     handleQue_.Push(conHandle.session);
     191            9 :     IDE_LOGD("handle queue push: %lx", conHandle.session);
     192              :     mmUserBlock_t funcBlock;
     193            9 :     funcBlock.procFunc = AdxServerManager::ThreadProcess;
     194            9 :     funcBlock.pulArg = this;
     195            9 :     mmThread tid = 0;
     196            9 :     int32_t ret = Thread::CreateDetachTask(tid, funcBlock);
     197            9 :     if (ret != EN_OK) {
     198            1 :         EpollHandle epHandle = ADX_INVALID_HANDLE;
     199            1 :         if (handleQue_.Pop(epHandle) == true) {
     200            1 :             IDE_LOGD("handle queue pop: %lx", epHandle);
     201            1 :             CommHandle curHandle {type_, epHandle, NR_COMPONENTS, -1, nullptr};
     202            1 :             (void)AdxCommOptManager::Instance().Close(curHandle);
     203              :         }
     204            1 :         char errBuf[MAX_ERRSTR_LEN + 1] = {0};
     205            1 :         IDE_LOGE("create component process thread failed, strerror is %s",
     206              :                  mmGetErrorFormatMessage(mmGetErrorCode(), errBuf, MAX_ERRSTR_LEN));
     207              :     }
     208              : }
     209           10 : bool AdxServerManager::ComponentWaitEvent()
     210              : {
     211           10 :     IDE_CTRL_VALUE_FAILED(epoll_ != nullptr, return false, "epoll_ check failed, nullptr");
     212            9 :     const int32_t epollSize = epoll_->EpollGetSize();
     213            9 :     std::vector<EpollEvent> events(epollSize);
     214         1161 :     for (int32_t i = 0; i < epollSize; i++) {
     215         1152 :         events[i].data = 0;
     216         1152 :         events[i].events = 0;
     217              :     }
     218            9 :     IDE_RUN_LOGI("Run Server(%d) Process", static_cast<int32_t>(type_));
     219            9 :     waitOver_ = false;
     220           27 :     while (!IsQuit()) {
     221            9 :         TimerProcess();
     222            9 :         int32_t handles = epoll_->EpollWait(events, epollSize, DEFAULT_EPOLL_TIMEOUT);
     223           36 :         for (int32_t i = 0; i < handles && i < epollSize; i++) {
     224           27 :             IDE_LOGI("sock EpollWait accept event %d", handles);
     225           27 :             if ((events[i].events & ADX_EPOLL_CONN_IN) != 0) {
     226            9 :                 IDE_LOGI("sock connect EpollWait event %d", handles);
     227            9 :                 CommHandle handle = {type_, events[i].data, NR_COMPONENTS, -1, nullptr};
     228            9 :                 HandleConnectEvent(handle);
     229           18 :             } else if ((events[i].events & ADX_EPOLL_DATA_IN) != 0) {
     230            0 :                 IDE_LOGI("data in");
     231           18 :             } else if ((events[i].events & ADX_EPOLL_HANG_UP) != 0) {
     232            0 :                 IDE_LOGW("hang up state");
     233              :             } else {
     234           18 :                 IDE_LOGW("other epoll state");
     235           18 :                 epoll_->EpollErrorHandle();
     236              :             }
     237              :         }
     238            9 :         if (handles < 0) {
     239            0 :             epoll_->EpollErrorHandle();
     240              :         }
     241              :     }
     242              : 
     243            9 :     waitOver_ = true;
     244            9 :     return true;
     245            9 : }
     246              : 
     247            9 : void AdxServerManager::Run()
     248              : {
     249            9 :     pid_ = mmGetPid();
     250            9 :     if (ComponentWaitEvent()) {
     251            9 :         IDE_RUN_LOGI("server manager stop");
     252              :     }
     253            9 : }
     254              : 
     255            8 : IdeThreadArg AdxServerManager::ThreadProcess(IdeThreadArg arg)
     256              : {
     257            8 :     if (arg == nullptr) {
     258            0 :         return nullptr;
     259              :     }
     260            8 :     auto runnable = reinterpret_cast<AdxServerManager *>(arg);
     261            8 :     (void)mmSetCurrentThreadName("adx_component_process");
     262            8 :     runnable->ComponentProcess();
     263            8 :     return nullptr;
     264              : }
     265              : 
     266            8 : void AdxServerManager::ComponentProcess()
     267              : {
     268            8 :     EpollHandle epHandle = ADX_INVALID_HANDLE;
     269            8 :     IDE_LOGI("process new connect");
     270            8 :     if (handleQue_.Pop(epHandle) == false) {
     271            0 :         return;
     272              :     }
     273            8 :     IDE_LOGD("handle queue pop: %lx", epHandle);
     274              : 
     275            8 :     if (epHandle == ADX_INVALID_HANDLE) {
     276            0 :         IDE_LOGE("server run process handle invalid");
     277            0 :         return;
     278              :     }
     279              : 
     280            8 :     AdxCommHandle handle = static_cast<AdxCommHandle>(IdeXmalloc(sizeof(CommHandle)));
     281            8 :     IDE_CTRL_VALUE_FAILED(handle != nullptr, return, "malloc handle failed.");
     282            8 :     handle->type = type_;
     283            8 :     handle->session = epHandle;
     284            8 :     handle->comp = ComponentType::NR_COMPONENTS;
     285            8 :     handle->timeout = 0;
     286            8 :     handle->client = nullptr;
     287            8 :     ComponentType comp = ComponentType::NR_COMPONENTS;
     288            8 :     bool ret = SubComponentProcess(*handle, comp);
     289            8 :     if (((comp != ComponentType::COMPONENT_LOG_BACKHAUL) && (comp != ComponentType::COMPONENT_TRACE) &&
     290            8 :         (comp != ComponentType::COMPONENT_SYS_REPORT) && (comp != ComponentType::COMPONENT_FILE_REPORT) &&
     291            8 :         (comp != ComponentType::COMPONENT_CPU_DETECT)) || !ret) {
     292            8 :         (void)AdxCommOptManager::Instance().Close(*handle);
     293            8 :         handle->session = ADX_OPT_INVALID_HANDLE;
     294            8 :         IDE_XFREE_AND_SET_NULL(handle);
     295              :     }
     296              : }
     297              : 
     298            8 : bool AdxServerManager::SubComponentProcess(CommHandle &handle, ComponentType &comp)
     299              : {
     300            8 :     MsgProto *req = nullptr;
     301            8 :     int32_t length = 0;
     302              : 
     303            8 :     int32_t ret = AdxCommOptManager::Instance().Read(handle, reinterpret_cast<IdeRecvBuffT>(&req), length,
     304              :         COMM_OPT_NOBLOCK);
     305            8 :     if (ret == IDE_DAEMON_ERROR || req == nullptr || length <= 0) {
     306            1 :         IDE_LOGE("receive request failed ret %d, length(%d bytes)", ret, length);
     307            1 :         return false;
     308              :     }
     309              : 
     310            7 :     SharedPtr<MsgProto> msgPtr(req, IdeXfree);
     311            7 :     req = nullptr;
     312            7 :     if (msgPtr->sliceLen + sizeof(MsgProto) != (uint32_t)length) {
     313            1 :         IDE_LOGE("receive request package(%u bytes) length(%d bytes) exception", msgPtr->sliceLen, length);
     314            1 :         return false;
     315              :     }
     316              : 
     317            6 :     HDC_SESSION session = reinterpret_cast<HDC_SESSION>(handle.session);
     318            6 :     int32_t devId = -1;
     319            6 :     ret = IdeGetDevIdBySession(session, &devId);
     320            6 :     if (ret != IDE_DAEMON_OK || devId < 0 || devId > UINT16_MAX) {
     321            1 :         IDE_LOGE("get dev id by session fail, ret=%d", ret);
     322            1 :         return false;
     323              :     }
     324            5 :     msgPtr->devId = static_cast<uint16_t>(devId);
     325              : 
     326            5 :     IDE_LOGI("commopt type(%d), request type(%u), device id(%d)", static_cast<int32_t>(type_), msgPtr->reqType, devId);
     327            5 :     return DispatchComponent(handle, msgPtr, session, comp);
     328            7 : }
     329              : 
     330            5 : bool AdxServerManager::DispatchComponent(CommHandle &handle, SharedPtr<MsgProto> &msgPtr, HDC_SESSION session,
     331              :     ComponentType &comp)
     332              : {
     333            5 :     comp = GetComponentTypeByReqType(static_cast<CmdClassT>(msgPtr->reqType));
     334            5 :     auto it = compMap_.find(comp);
     335            5 :     if (it == compMap_.end()) {
     336            1 :         IDE_LOGE("Unable to find the corresponding component type(%d)", static_cast<int32_t>(comp));
     337            1 :         return false;
     338              :     }
     339              : 
     340            4 :     handle.comp = comp;
     341            4 :     if (handle.comp == ComponentType::COMPONENT_GETD_FILE || handle.comp == COMPONENT_LOG_LEVEL) {
     342            4 :         std::lock_guard<std::mutex> lck(linkMtx_);
     343            4 :         if (IsLinkOverload(session)) {
     344            3 :             return false;
     345              :         }
     346            1 :         linkNum_++;
     347            4 :     }
     348            1 :     std::string compInfo = it->second->GetInfo();
     349            1 :     IDE_LOGI("begin to process [%s] component", compInfo.c_str());
     350            1 :     if (it->second->Process(handle, msgPtr) != IDE_DAEMON_OK) {
     351            0 :         IDE_LOGE("end of processing [%s] component failed, req->type: %u", compInfo.c_str(), msgPtr->reqType);
     352              :     } else {
     353            1 :         IDE_LOGI("end of processing [%s] component successfully", compInfo.c_str());
     354              :     }
     355            1 :     if (handle.comp == ComponentType::COMPONENT_GETD_FILE || handle.comp == COMPONENT_LOG_LEVEL) {
     356            1 :         std::lock_guard<std::mutex> lck(linkMtx_);
     357            1 :         linkNum_--;
     358            1 :     }
     359            1 :     return true;
     360            1 : }
     361              : 
     362            5 : ComponentType AdxServerManager::GetComponentTypeByReqType(CmdClassT cmdType) const
     363              : {
     364            5 :     ComponentType cmptType = ComponentType::NR_COMPONENTS;
     365            5 :     for (uint32_t i = 0; i < ARRAY_LEN(g_componentsInfo, AdxComponentMap); i++) {
     366            5 :         if (cmdType == g_componentsInfo[i].cmdType) {
     367            5 :             cmptType = g_componentsInfo[i].cmptType;
     368            5 :             break;
     369              :         }
     370              :     }
     371            5 :     return cmptType;
     372              : }
     373              : 
     374           14 : void AdxServerManager::TimerProcess()
     375              : {
     376           14 :     std::vector<std::string> devLogIds;
     377           14 :     SharedPtr<AdxDevice> device = AdxCommOptManager::Instance().GetDevice(type_);
     378           14 :     if (device == nullptr) {
     379            0 :         return;
     380              :     }
     381              : 
     382              :     // initialize the devices on the first time(AdxCommOptManager is singleton object)
     383              :     // create HDC server on th enable device
     384           14 :     device->GetAllEnableDevices(loadMode_, deviceId_, devLogIds);
     385           14 :     std::map<std::string, std::string> info;
     386           14 :     info[OPT_SERVICE_KEY] = info_;
     387           28 :     for (const auto& deviceId : devLogIds) {
     388           14 :         auto server = servers_.find(deviceId);
     389              :         // filter the device that created HDC server(or not the specified device)
     390           14 :         if (server != servers_.end() || !(deviceId_ == -1 || std::to_string(deviceId_) == deviceId)) {
     391           12 :             continue;
     392              :         }
     393              : 
     394            5 :         IDE_LOGI("device up %s", deviceId.c_str());
     395            5 :         info[OPT_DEVICE_KEY] = deviceId;
     396            5 :         if (ServerInit(info)) {
     397            1 :             faultyDevices_.erase(deviceId);
     398            1 :             continue;
     399              :         }
     400              : 
     401              :         // record retry times of connection for the faulty device
     402            4 :         auto faultDevice = faultyDevices_.find(deviceId);
     403            4 :         if (faultDevice == faultyDevices_.end()) {
     404            2 :             faultyDevices_[deviceId] = 1;
     405            2 :             continue;
     406              :         }
     407            2 :         ++(faultDevice->second);
     408            2 :         if (faultDevice->second >= RECONNECT_TIMES) {
     409            1 :             faultyDevices_.erase(faultDevice);
     410              :             // set the device to disable if connection is timeout
     411            1 :             device->DisableNotify(deviceId);
     412              :         }
     413              :     }
     414              : 
     415           14 :     device->GetDisableDevices(devLogIds);
     416           15 :     for (const auto& deviceId : devLogIds) {
     417            1 :         auto server = servers_.find(deviceId);
     418            1 :         if (server == servers_.end()) {
     419            1 :             continue;
     420              :         }
     421            0 :         IDE_LOGI("device suspend %s", deviceId.c_str());
     422            0 :         if (ServerUnInit(server->second)) {
     423            0 :             servers_.erase(server);
     424              :         }
     425              :     }
     426           14 :     serverInittedFlag_ = true;
     427           14 :     AdxCommOptManager::Instance().Timer(type_);
     428           14 : }
     429              : 
     430           77 : int32_t AdxServerManager::Exit()
     431              : {
     432           77 :     serverInittedFlag_ = false;
     433           77 :     if (pid_ == mmGetPid()) { // not fork
     434           10 :         Terminate();
     435              :         // wait epoll wait timeout
     436           10 :         while (!waitOver_) {
     437            0 :             mmSleep(DEFAULT_EPOLL_TIMEOUT);
     438              :         }
     439              :     }
     440              : 
     441              :     // terminate the running components before close servers(close client sessions)
     442           87 :     for (auto& component : compMap_) {
     443           10 :         (void)component.second->Terminate();
     444              :     }
     445              : 
     446              :     // finalize the servers(delete epoll and close session)
     447           91 :     for (auto& server : servers_) {
     448           14 :         if (!ServerUnInit(server.second)) {
     449            0 :             return IDE_DAEMON_ERROR;
     450              :         }
     451              :     }
     452           77 :     servers_.clear();
     453              : 
     454              :     // finalize the components
     455           87 :     for (auto& component : compMap_) {
     456           10 :         (void)component.second->UnInit();
     457              :     }
     458              :     // make sure no longer use it in ComponentProcess/SubComponentProcess
     459           77 :     compMap_.clear();
     460              : 
     461           77 :     if (epoll_ != nullptr) {
     462           16 :         if (epoll_->EpollDestroy() != IDE_DAEMON_OK) {
     463            1 :             return IDE_DAEMON_ERROR;
     464              :         }
     465           15 :         epoll_ = nullptr;
     466              :     }
     467           76 :     return IDE_DAEMON_OK;
     468              : }
     469              : 
     470            9 : void AdxServerManager::SetMode(int32_t loadMode)
     471              : {
     472            9 :     loadMode_ = loadMode;
     473            9 : }
     474              : 
     475            9 : void AdxServerManager::SetDeviceId(int32_t deviceId)
     476              : {
     477            9 :     deviceId_ = deviceId;
     478            9 : }
     479              : 
     480            2 : bool AdxServerManager::IsLinkOverload(HDC_SESSION session) const
     481              : {
     482            2 :     const int32_t maxLinkNum = 16; // limit max links num is 16 at the same time
     483            2 :     if (linkNum_ >= maxLinkNum) {
     484            1 :         int32_t pid = -1;
     485            1 :         (void)IdeGetPidBySession(session, &pid);
     486            1 :         IDE_LOGE("server manager overload, pid: %d.", pid);
     487            1 :         return true;
     488              :     }
     489            1 :     return false;
     490              : }
     491              : 
     492           49 : bool AdxServerManager::WaitServerInitted() const
     493              : {
     494              :     // 最大等待60s,等待serverInittedFlag_为true,每等待一轮等待时间增加1毫秒
     495           49 :     const int32_t maxRetryTimes = 346; // 60s (1 + 2 + ... + 346)ms
     496           49 :     int32_t retryTime = 1;
     497        16609 :     while (retryTime < maxRetryTimes) {
     498        16561 :         if (serverInittedFlag_) {
     499            1 :             IDE_LOGI("The server is initialized after waiting %d times.", retryTime);
     500            1 :             return true;
     501              :         }
     502        16560 :         mmSleep(retryTime);
     503        16560 :         retryTime++;
     504              :     }
     505              : 
     506           48 :     if (retryTime >= maxRetryTimes) {
     507           48 :         IDE_LOGW("The server is not initialized after waiting %d times.", retryTime);
     508              :     }
     509              : 
     510           48 :     return false;
     511              : }
     512              : }
        

Generated by: LCOV version 2.0-1