LCOV - code coverage report
Current view: top level - acl/aclrt_impl - init_callback_manager.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 98.4 % 61 60
Test Date: 2026-08-06 15:29:52 Functions: 100.0 % 14 14

            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              : 
      11              : #include "init_callback_manager.h"
      12              : #include "acl/acl_base.h"
      13              : #include "acl_rt_impl_base.h"
      14              : 
      15              : namespace acl {
      16              : namespace {
      17              : template <typename CallbackMapT, typename CallbackFuncT>
      18           24 : aclError UnregisterCallbackImpl(CallbackMapT &callbackMap, std::recursive_mutex &mutex,
      19              :                                 aclRegisterCallbackType type, CallbackFuncT cbFunc)
      20              : {
      21           24 :     if (cbFunc == nullptr) {
      22            0 :         return ACL_ERROR_INVALID_PARAM;
      23              :     }
      24           24 :     std::lock_guard<std::recursive_mutex> lock(mutex);
      25           24 :     if (callbackMap.count(type) == 0U) {
      26            6 :         return ACL_ERROR_INTERNAL_ERROR;
      27              :     }
      28           18 :     const auto range = callbackMap.equal_range(type);
      29           20 :     for (auto it = range.first; it != range.second; ++it) {
      30           18 :         if (it->second.first == cbFunc) {
      31           16 :             (void)callbackMap.erase(it);
      32           16 :             return ACL_SUCCESS;
      33              :         }
      34              :     }
      35            2 :     return ACL_ERROR_INTERNAL_ERROR;
      36           24 : }
      37              : 
      38              : template <typename CallbackMapT, typename NotifyInvokerT>
      39          238 : aclError NotifyCallbackImpl(CallbackMapT &callbackMap, std::recursive_mutex &mutex,
      40              :                             aclRegisterCallbackType type, const NotifyInvokerT &notifyInvoker)
      41              : {
      42          238 :     std::lock_guard<std::recursive_mutex> lock(mutex);
      43          238 :     const auto range = callbackMap.equal_range(type);
      44          244 :     for (auto it = range.first; it != range.second; ++it) {
      45           20 :         const aclError ret = notifyInvoker(it->second);
      46           20 :         if (ret != ACL_SUCCESS) {
      47           14 :             return ret;
      48              :         }
      49              :     }
      50          224 :     return ACL_SUCCESS;
      51          238 : }
      52              : }  // namespace
      53              : 
      54          283 : InitCallbackManager &InitCallbackManager::GetInstance()
      55              : {
      56              :     // 单例模式上下文不做判空和捕获异常,内存分配失败这种极端情况让程序正常终止,比引入更复杂的错误处理逻辑更合理
      57              :     // 这里单例在堆上申请且内存不显式释放,是考虑到so卸载顺序的问题,延长单例的生命周期确保不引入异常
      58          283 :     static InitCallbackManager *instance = new InitCallbackManager();
      59          283 :     return *instance;
      60              : }
      61              : 
      62            1 : InitCallbackManager::InitCallbackManager(){}
      63              : 
      64           18 : aclError InitCallbackManager::RegInitCallback(aclRegisterCallbackType type, aclInitCallbackFunc cbFunc, void *userData)
      65              : {
      66           18 :     if (cbFunc == nullptr) {
      67            1 :         return ACL_ERROR_INVALID_PARAM;
      68              :     }
      69           17 :     std::lock_guard<std::recursive_mutex> lock(mutex_);
      70           17 :     if (type != ACL_REG_TYPE_OTHER && initCallbackMap_.count(type) != 0U) {
      71            2 :         return ACL_ERROR_INTERNAL_ERROR;
      72              :     }
      73           15 :     initCallbackMap_.insert({type, {cbFunc, userData}});
      74              :     // 已经初始化的情况下,需要立即执行
      75           15 :     if (GetAclInitFlag()) {
      76            4 :         auto &configData = GetConfigPathStr();
      77            4 :         (void)cbFunc(configData.c_str(), configData.size(), userData);
      78              :     }
      79           15 :     return ACL_SUCCESS;
      80           17 : }
      81              : 
      82           10 : aclError InitCallbackManager::UnRegInitCallback(aclRegisterCallbackType type, aclInitCallbackFunc cbFunc)
      83              : {
      84           10 :     return UnregisterCallbackImpl(initCallbackMap_, mutex_, type, cbFunc);
      85              : }
      86              : 
      87          120 : aclError InitCallbackManager::NotifyInitCallback(aclRegisterCallbackType type,
      88              :                                                  const char *configStr, size_t len)
      89              : {
      90          240 :     return NotifyCallbackImpl(initCallbackMap_, mutex_, type,
      91          240 :         [configStr, len](const std::pair<aclInitCallbackFunc, void *> &callbackEntry) {
      92           10 :             return callbackEntry.first(configStr, len, callbackEntry.second);
      93          240 :         });
      94              : }
      95              : 
      96           20 : aclError InitCallbackManager::RegFinalizeCallback(aclRegisterCallbackType type, aclFinalizeCallbackFunc cbFunc,
      97              :     void *userData)
      98              : {
      99           20 :     if (cbFunc == nullptr) {
     100            1 :         return ACL_ERROR_INVALID_PARAM;
     101              :     }
     102           19 :     std::lock_guard<std::recursive_mutex> lock(mutex_);
     103           19 :     if (type != ACL_REG_TYPE_OTHER && finalizeCallbackMap_.count(type) != 0U) {
     104            2 :         return ACL_ERROR_INTERNAL_ERROR;
     105              :     }
     106           17 :     finalizeCallbackMap_.insert({type, {cbFunc, userData}});
     107           17 :     return ACL_SUCCESS;
     108           19 : }
     109              : 
     110           14 : aclError InitCallbackManager::UnRegFinalizeCallback(aclRegisterCallbackType type, aclFinalizeCallbackFunc cbFunc)
     111              : {
     112           14 :     return UnregisterCallbackImpl(finalizeCallbackMap_, mutex_, type, cbFunc);
     113              : }
     114              : 
     115          118 : aclError InitCallbackManager::NotifyFinalizeCallback(aclRegisterCallbackType type)
     116              : {
     117          118 :     return NotifyCallbackImpl(finalizeCallbackMap_, mutex_, type,
     118          118 :         [](const std::pair<aclFinalizeCallbackFunc, void *> &callbackEntry) {
     119           10 :             return callbackEntry.first(callbackEntry.second);
     120          236 :         });
     121              : }
     122              : }  // namespace acl
        

Generated by: LCOV version 2.0-1