前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Chromium】Base库的AtExitManager

【Chromium】Base库的AtExitManager

原创
作者头像
lealc
修改2024-04-19 18:06:33
790
修改2024-04-19 18:06:33
举报
文章被收录于专栏:Chromium学习Chromium学习

源码

先附上可用于学习的开源代码:Base库

喜欢可以帮忙Star一下

前言

编译:参考Base库即可

环境:Visual Studio 2022 - 17.8.3 + v143 + 10.0.22621.0 + C++17

AtExitManager

这个类提供了类似于 CRT 的 atexit() 的功能,但我们可以控制回调函数的执行时间。在 Windows 下,对于 DLL,它们在一个非常糟糕的时机和加载器锁定下发生。这个功能主要被 base::Singleton 使用。

退出执行注册任务的线程是构建AtExitManager实例的线程

使用方法很简单。在 main() 或 WinMain() 的早期范围内,在栈上创建一个 AtExitManager 对象:

代码语言:C++
复制
int main(...) { 
? base::AtExitManager exit_manager;
}

当 exit_manager 对象超出范围时,所有注册的回调函数和单例析构函数都将被调用。

源码解析

老规矩先上源码和对其的注释:

代码语言:C++
复制
class BASE_EXPORT AtExitManager {
public:
??? typedef void (AtExitCallbackType)(void);

??? AtExitManager();

??? // 析构函数调用所有已注册的回调函数。在此之后不要尝试注册更多的回调函数。
??? ~AtExitManager();

??? // 注册指定的函数在退出时调用。回调函数的原型为 void func(void*)。
??? static void RegisterCallback(AtExitCallbackType func, void* param);

??? // 注册指定的任务在退出时调用。
??? static void RegisterTask(base::OnceClosure task);

??? // 按照 LIFO 的顺序调用使用 RegisterCallback 注册的函数。在调用此函数后仍然可以注册新的回调函数。
??? static void ProcessCallbacksNow();

??? // 禁用所有已注册的退出回调。仅在单进程模式下使用。
??? static void DisableAllAtExitManagers();

protected:
??? // 此构造函数允许即使已存在 AtExitManager 实例,也可以创建该实例。这仅用于测试!
??? // AtExitManager 保存在全局堆栈上,并在销毁时将其移除。这允许您遮盖另一个 
AtExitManager。
??? explicit AtExitManager(bool shadow);

private:
??? base::Lock lock_;

??? base::stackbase::OnceClosure stack_ GUARDED_BY(lock_);

#if DCHECK_IS_ON()
??? bool processing_callbacks_ GUARDED_BY(lock_) = false;
#endif

??? // 允许遮盖的管理器堆栈。
??? AtExitManager* const next_manager_;

??? DISALLOW_COPY_AND_ASSIGN(AtExitManager);
};

注意:

1、从源码可知,AtExitManager注册的函数只能是下面这种

代码语言:C++
复制
void func(void*)

2、注册任务也是如此

代码语言:C++
复制
int g_test_counter_1 = 0;
void ExpectParamIsCounter(void* param) {? 
? EXPECT_EQ(&g_test_counter_1, param);
} 

base::AtExitManager::RegisterTask(
? ? ? base::BindOnce(&ExpectParamIsCounter, &g_test_counter_1));

示例代码

代码语言:C++
复制
void AtExitTask(void* param) {
??? L_TRACE(L"%s %d", __FUNCTIONW__, *static_cast<int*>(param));
}

base::AtExitManager at_exit;
int i = 1;
at_exit.RegisterCallback(&AtExitTask, &i);
at_exit.RegisterCallback(&AtExitTask, &i);
at_exit.ProcessCallbacksNow();

整个AtExitManager实现比较简单,感兴趣可以自行实现试试看

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 源码
  • 前言
  • AtExitManager
  • 源码解析
  • 示例代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档

http://www.vxiaotou.com