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-07-28 10:53:01 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(
      19              :     CallbackMapT& callbackMap, std::recursive_mutex& mutex, 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(
      40              :     CallbackMapT& callbackMap, std::recursive_mutex& mutex, aclRegisterCallbackType type,
      41              :     const NotifyInvokerT& notifyInvoker)
      42              : {
      43          238 :     std::lock_guard<std::recursive_mutex> lock(mutex);
      44          238 :     const auto range = callbackMap.equal_range(type);
      45          244 :     for (auto it = range.first; it != range.second; ++it) {
      46           20 :         const aclError ret = notifyInvoker(it->second);
      47           20 :         if (ret != ACL_SUCCESS) {
      48           14 :             return ret;
      49              :         }
      50              :     }
      51          224 :     return ACL_SUCCESS;
      52          238 : }
      53              : } // namespace
      54              : 
      55          283 : InitCallbackManager& InitCallbackManager::GetInstance()
      56              : {
      57              :     // 单例模式上下文不做判空和捕获异常,内存分配失败这种极端情况让程序正常终止,比引入更复杂的错误处理逻辑更合理
      58              :     // 这里单例在堆上申请且内存不显式释放,是考虑到so卸载顺序的问题,延长单例的生命周期确保不引入异常
      59          283 :     static InitCallbackManager* instance = new InitCallbackManager();
      60          283 :     return *instance;
      61              : }
      62              : 
      63            1 : InitCallbackManager::InitCallbackManager() {}
      64              : 
      65           18 : aclError InitCallbackManager::RegInitCallback(aclRegisterCallbackType type, aclInitCallbackFunc cbFunc, void* userData)
      66              : {
      67           18 :     if (cbFunc == nullptr) {
      68            1 :         return ACL_ERROR_INVALID_PARAM;
      69              :     }
      70           17 :     std::lock_guard<std::recursive_mutex> lock(mutex_);
      71           17 :     if (type != ACL_REG_TYPE_OTHER && initCallbackMap_.count(type) != 0U) {
      72            2 :         return ACL_ERROR_INTERNAL_ERROR;
      73              :     }
      74           15 :     initCallbackMap_.insert({type, {cbFunc, userData}});
      75              :     // 已经初始化的情况下,需要立即执行
      76           15 :     if (GetAclInitFlag()) {
      77            4 :         auto& configData = GetConfigPathStr();
      78            4 :         (void)cbFunc(configData.c_str(), configData.size(), userData);
      79              :     }
      80           15 :     return ACL_SUCCESS;
      81           17 : }
      82              : 
      83           10 : aclError InitCallbackManager::UnRegInitCallback(aclRegisterCallbackType type, aclInitCallbackFunc cbFunc)
      84              : {
      85           10 :     return UnregisterCallbackImpl(initCallbackMap_, mutex_, type, cbFunc);
      86              : }
      87              : 
      88          120 : aclError InitCallbackManager::NotifyInitCallback(aclRegisterCallbackType type, const char* configStr, size_t len)
      89              : {
      90          240 :     return NotifyCallbackImpl(
      91          240 :         initCallbackMap_, mutex_, type, [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(
      97              :     aclRegisterCallbackType type, aclFinalizeCallbackFunc cbFunc, 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          236 :     return NotifyCallbackImpl(
     118          236 :         finalizeCallbackMap_, mutex_, type, [](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