当前位置: 首页 > news >正文

CEF框架中的一些宏定义(二):CEF_CURRENTLY_ON

CEF_CURRENTLY_ON

前面有一篇分析进程和线程的文章提到过:
CEF线程模型与初始化过程详解

在Browser进程中在CEF框架中,很多代码都需要由这个browser的主线程来执行,宏定义CEF_CURRENTLY_ON就是用于这个判断的。

这个宏定义及其相关的宏定义在thread_util.h中定义:

#define CEF_UIT content::BrowserThread::UI
#define CEF_IOT content::BrowserThread::IO#define CEF_CURRENTLY_ON(id) content::BrowserThread::CurrentlyOn(id)
#define CEF_CURRENTLY_ON_UIT() CEF_CURRENTLY_ON(CEF_UIT)
#define CEF_CURRENTLY_ON_IOT() CEF_CURRENTLY_ON(CEF_IOT)#define 
(id) DCHECK(CEF_CURRENTLY_ON(id))
#define CEF_REQUIRE_UIT() CEF_REQUIRE(CEF_UIT)
#define CEF_REQUIRE_IOT() CEF_REQUIRE(CEF_IOT)#define CEF_REQUIRE_RETURN(id, var)              \if (!CEF_CURRENTLY_ON(id)) {                   \DCHECK(false) << "called on invalid thread"; \return var;                                  \}
#define CEF_REQUIRE_UIT_RETURN(var) CEF_REQUIRE_RETURN(CEF_UIT, var)
#define CEF_REQUIRE_IOT_RETURN(var) CEF_REQUIRE_RETURN(CEF_IOT, var)#define CEF_REQUIRE_RETURN_VOID(id)              \if (!CEF_CURRENTLY_ON(id)) {                   \DCHECK(false) << "called on invalid thread"; \return;                                      \}
#define CEF_REQUIRE_UIT_RETURN_VOID() CEF_REQUIRE_RETURN_VOID(CEF_UIT)
#define CEF_REQUIRE_IOT_RETURN_VOID() CEF_REQUIRE_RETURN_VOID(CEF_IOT)

CEF_UIT & CEF_IOT

这个宏定义就是获取content::BrowserThread::UI,这个定义在chrome的源码content/public/browser/browser_thread.h中,是一个枚举类型:

  enum ID {// The main thread in the browser. It stops running tasks during shutdown// and is never joined.UI,// This is the thread that processes non-blocking I/O, i.e. IPC and network.// Blocking I/O should happen in base::ThreadPool. It is joined on shutdown// (and thus any task posted to it may block shutdown).//// The name is admittedly confusing, as the IO thread is not for blocking// I/O like calling base::File::Read. "The highly responsive, non-blocking// I/O thread for IPC" is more accurate but too long for an enum name. See// docs/transcripts/wuwt-e08-processes.md at 44:20 for more history.IO,// NOTE: do not add new threads here. Instead you should just use// base::ThreadPool::Create*TaskRunner to run tasks on the base::ThreadPool.// This identifier does not represent a thread.  Instead it counts the// number of well-known threads.  Insert new well-known threads before this// identifier.ID_COUNT};

CEF_CURRENTLY_ON

这个宏定义直接定义成了chrome源码中的content::BrowserThread::CurrentlyOn,这个函数同样存在于content/public/browser/browser_thread.h中:

函数定义在content/browser/browser_thread_impl.cc中:

// static
bool BrowserThread::CurrentlyOn(ID identifier) {DCHECK_GE(identifier, 0);DCHECK_LT(identifier, ID_COUNT);BrowserThreadGlobals& globals = GetBrowserThreadGlobals();// Thread-safe since |globals.task_runners| is read-only after being// initialized from main thread (which happens before //content and embedders// are kicked off and enabled to call the BrowserThread API from other// threads).return globals.task_runners[identifier] &&globals.task_runners[identifier]->RunsTasksInCurrentSequence();
}
  • DCHECK_GE和DCHECK_LT就是对这个ID进行断言判断,需要大于0,小于进程数
  • task_runners是chrome里面的任务runner,可以参考CEF线程模型与初始化过程详解。
  • 这个函数就是判断线程ID是否相同。
  • CEF_REQUIRE宏定义就是配合DCHECK一起使用。

CEF_TASK_RUNNER && CEF_POST_TASK

在CEF线程模型与初始化过程详解提到了chrome的基本线程模型,任何任务都是需要通过POST一个runner来执行的,在cef框架中也用到了chrome源码中的几个任务处理宏定义:CEF_TASK_RUNNER 和 CEF_POST_TASK。

template <int id, std::enable_if_t<id == CEF_UIT, bool> = true>
auto CEF_TASK_RUNNER() {return content::GetUIThreadTaskRunner({});
}
template <int id, std::enable_if_t<id == CEF_IOT, bool> = true>
auto CEF_TASK_RUNNER() {return content::GetIOThreadTaskRunner({});
}#define CEF_POST_TASK(id, task) CEF_TASK_RUNNER<id>()->PostTask(FROM_HERE, task)

这个宏定义简单来说,就是通过模板定义,在CEF_POST_TASK宏传入的id为UI或者IOT的时候,获得对应的TaskRunner,然后把task任务发送过去。

相关文章:

  • JavaEE进阶(6)SpringBoot 配置文件(作用、格式、properties配置文件说明、yml配置文件说明、验证码案例)
  • 【计算机网络】第三章·数据链路层(三)
  • 前端面试——关于this指向问题?
  • 使用Spring Boot和Tess4J实现本地与远程图片的文字识别
  • SVN 常用命令汇总(2024)
  • 上位机图像处理和嵌入式模块部署(自定义算法)
  • React16源码: React中commit阶段的commitRoot的主流程源码实现
  • 单片机学习笔记---矩阵键盘
  • 源 “MySQL 5.7 Community Server“ 的 GPG 密钥已安装,但是不适用于此软件包。请检查源的公钥 URL 是否配置正确。
  • [UI5 常用控件] 03.Icon, Avatar,Image
  • 数据验证方法补充ValidationRule
  • 《动手学深度学习(PyTorch版)》笔记2
  • Ubuntu20.04安装cuda12.11
  • 当一个json存在id 和_id 的时候,使用JSONObject.parseObject进行序列号操作,映射错误
  • HCIA学习作业二
  • [译]如何构建服务器端web组件,为何要构建?
  • bootstrap创建登录注册页面
  • IDEA 插件开发入门教程
  • node-glob通配符
  • pdf文件如何在线转换为jpg图片
  • SQL 难点解决:记录的引用
  • Vue 重置组件到初始状态
  • 闭包--闭包之tab栏切换(四)
  • 从 Android Sample ApiDemos 中学习 android.animation API 的用法
  • 从0到1:PostCSS 插件开发最佳实践
  • 高程读书笔记 第六章 面向对象程序设计
  • 个人博客开发系列:评论功能之GitHub账号OAuth授权
  • 给github项目添加CI badge
  • 基于Volley网络库实现加载多种网络图片(包括GIF动态图片、圆形图片、普通图片)...
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 前端技术周刊 2019-01-14:客户端存储
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 思考 CSS 架构
  • 通信类
  • 携程小程序初体验
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • 运行时添加log4j2的appender
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • 说说我为什么看好Spring Cloud Alibaba
  • ​Z时代时尚SUV新宠:起亚赛图斯值不值得年轻人买?
  • #if和#ifdef区别
  • #pragam once 和 #ifndef 预编译头
  • (04)odoo视图操作
  • (八)Flask之app.route装饰器函数的参数
  • (附源码)计算机毕业设计SSM疫情居家隔离服务系统
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (教学思路 C#之类三)方法参数类型(ref、out、parmas)
  • (四)库存超卖案例实战——优化redis分布式锁
  • (淘宝无限适配)手机端rem布局详解(转载非原创)
  • (转)Scala的“=”符号简介
  • .halo勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .htaccess配置常用技巧
  • .h头文件 .lib动态链接库文件 .dll 动态链接库
  • .Net程序帮助文档制作
  • .NET中 MVC 工厂模式浅析