
OpenHarmony轻量系统服务管理|samgr_lite功能详解(四)
本文继续分析samgr_lite的函数实现。文件位于distributedschedule_samgr_lite\samgr\source\samgr_lite.c
·
往期知识点记录:
- 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总
- OpenHarmony轻量系统服务管理-samgr主要接口思维导图(1)
- OpenHarmony轻量系统服务管理-samgr主要接口思维导图(2)
- OpenHarmony轻量系统服务管理-samgr:common赏析及实现
- OpenHarmony轻量系统服务管理-samgr:iunknown赏析
- OpenHarmony轻量系统服务管理-samgr:iunknown实现分析
- OpenHarmony轻量系统服务管理samgr-message赏析
- OpenHarmony轻量系统服务管理samgr-message实现分析(1)
- OpenHarmony轻量系统服务管理samgr-message实现分析(2)
- OpenHarmony轻量系统服务管理samgr-service赏析
- OpenHarmony轻量系统服务管理samgr-samgr_lite赏析
- OpenHarmony轻量系统服务管理samgr-feature赏析及实现
- OpenHarmony轻量系统服务管理samgr-service实现分析(1)
- OpenHarmony轻量系统服务管理samgr-service实现分析(2)
- OpenHarmony轻量系统服务管理samgr-task_manager赏析及实现(1)
- OpenHarmony轻量系统服务管理samgr-task_manager赏析及实现(2)
- OpenHarmony轻量系统服务管理|samgr_lite功能详解(一)
- OpenHarmony轻量系统服务管理|samgr_lite功能详解(二)
- OpenHarmony轻量系统服务管理|samgr_lite功能详解(三)
- OpenHarmony轻量系统服务管理|samgr_lite功能详解(四)
- 持续更新中……
本文继续分析samgr_lite的函数实现。文件位于distributedschedule_samgr_lite\samgr\source\samgr_lite.c
函数实现分析
添加任务池
/*
函数功能:为服务绑定任务池
函数参数:@service:ServiceImpl对象
@cfg:任务池配置
@name:service的name
函数描述:任务池的绑定分为三种,根据服务的任务类型选择不同的方案。
首先进行任务配置的优先级检查,防止出现非法值,导致共享任务池数组越界
然后根据服务任务类型绑定不同的任务池,分为一下三种方案:
1.SHARED_TASK:按照当前任务配置cfg的优先级来确定应该绑定到sharedPool中的哪一个任务池
2.SPECIFIED_TASK:在services的集合中查找是否存在与指定的任务配置cfg相同的任务池,若存在则绑定,若不存在则进入SINGLE_TASK
3.SINGLE_TASK:根据任务配置cfg创建新的任务池
*/
static void AddTaskPool(ServiceImpl *service, TaskConfig *cfg, const char *name)
{
//如果当前service已分配taskpool,则返回
if (service->taskPool != NULL) {
return;
}
//未分配taskpoll,进行分配
if (cfg->priority < PRI_LOW || cfg->priority >= PRI_BUTT) {
//参数不合法,记录日志
HILOG_ERROR(HILOG_MODULE_SAMGR, "The %s service pri(%d) is out of range!", name, cfg->priority);
//更新优先级为最低级
cfg->priority = PRI_LOW;
}
//判断任务类型
switch (cfg->taskFlags) {
case SHARED_TASK: {
//根据服务的优先级共享任务
int pos = (int)cfg->priority / PROPERTY_STEP;//优先级与步长的结果正好对应到1,2,3,4
SamgrLiteImpl *samgr = GetImplement();
//若为NULL,则创建一个默认配置的任务池
if (samgr->sharedPool[pos] == NULL) {
TaskConfig shareCfg = DEFAULT_TASK_CFG(pos);
/*
函数功能:创建一个任务池和相应的队列
函数参数:@1:service的任务配置,包括任务优先级、堆栈大小、队列大小、任务类型和共享任务ID
@2:队列名称
@3:维护的线程ID数组大小
*/
samgr->sharedPool[pos] = SAMGR_CreateFixedTaskPool(&shareCfg, name, DEFAULT_SIZE);
}
//给service配置任务池
service->taskPool = samgr->sharedPool[pos];
//引用对应的任务池,增加任务池的引用计数
if (SAMGR_ReferenceTaskPool(service->taskPool) == NULL) {
//任务池为NULL或者任务池的引用已达到上限。
HILOG_ERROR(HILOG_MODULE_SAMGR, "shared task:%p pri:%d ref is full", service->taskPool, cfg->priority);
samgr->sharedPool[pos] = NULL;
}
}
break;
case SPECIFIED_TASK:
//由多个服务共享的指定任务
//查找是否存在与cfg配置相同的任务池,即多个服务共享同一个任务池
service->taskPool = GetSpecifiedTaskPool(cfg);
if (service->taskPool != NULL) {
//若找到,则结束switch,若未找到则进入SINGLE_TASK
break;
}
case SINGLE_TASK:
//服务独占的任务
//根据当前的任务配置,创建一个新的任务池
service->taskPool = SAMGR_CreateFixedTaskPool(cfg, name, SINGLE_SIZE);
break;
default:
break;
}
if (service->taskPool == NULL) {
//记录错误日志
HILOG_ERROR(HILOG_MODULE_SAMGR, "Service<name:%s, flag:%d> create taskPool failed!", name, cfg->taskFlags);
}
}
发送启动请求
/*
函数功能:发送与启动相关的消息
函数参数:@msgId:消息类型
@msgValue:消息值
函数描述:BOOTSTRAP_SERVICE服务向消息队列发送消息,消息包含消息类型和消息值
*/
static int32 SendBootRequest(int msgId, uint32 msgValue)
{
/*
①获取name为BOOTSTRAP_SERVICE的serviceImpl对象
②根据serviceImpl和feature返回相应的identity
*/
Identity id = DEFAULT_GetFeatureId(GetService(BOOTSTRAP_SERVICE), NULL);
//构建消息request
Request request = {msgId, 0, NULL, msgValue};
/*
函数功能:将请求放入消息队列中
函数参数:@1:标识服务或特性的ID
@2:消息
@3:消息处理函数
函数返回:成功 返回EC_SUCCESS,失败 返回EC_INVALID or EC_BUSBUSY
*/
return SAMGR_SendRequest(&id, &request, (Handler)SAMGR_Bootstrap);
}
处理初始化的请求消息
//处理消息的函数,负责服务的初始化
static void HandleInitRequest(const Request *request, const Response *response)
{
//从消息中获取serviceImpl对象
ServiceImpl *serviceImpl = (ServiceImpl *)request->data;
if (serviceImpl == NULL) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "Init service Request:<%d,%d>, Response:<%p,%d>!",
request->msgId, request->msgValue, response->data, response->len);
return;
}
//记录 处理的最新的一条消息的时间戳
uint32 lastTime = serviceImpl->ops.timestamp;
//初始化ServiceImpl,并初始化ServiceImpl的features中所有的FeatureImpl
DEFAULT_Initialize(serviceImpl);
//获取最新的时间戳
serviceImpl->ops.timestamp = SAMGR_GetProcessTime();
//更新为闲置状态
serviceImpl->inited = SVC_IDLE;
HILOG_INFO(HILOG_MODULE_SAMGR, "Init service %s <time: %ums> success!",
serviceImpl->service->GetName(serviceImpl->service), serviceImpl->ops.timestamp - lastTime);
//判断是否对所有服务都进行了初始化
int32 err = InitCompleted();
if (err != EC_SUCCESS) {
HILOG_INFO(HILOG_MODULE_SAMGR, "Goto next boot step return code:%d", err);
}
}
初始化指定服务
//初始化单个service
static void InitializeSingleService(ServiceImpl *service)
{
//若service绑定的任务池为NULL,则直接进行初始化
if (service->taskPool == NULL) {
DEFAULT_Initialize(service);
return;
}
//已绑定任务池,则向消息队列发送初始化服务的请求
//构建ID信息
Identity identity = {service->serviceId, INVALID_INDEX, service->taskPool->queueId};
//构建消息,将service作为数据段
Request request = {0, 0, service, 0};
uint32 *ref = NULL;
//向特性线程发送调用者的请求和响应。直接调用HandleInitRequest来处理请求和响应,而不使用消息处理函数。
(void)SAMGR_SendSharedDirectRequest(&identity, &request, NULL, &ref, HandleInitRequest);
}
查找指定任务配置的任务池
/*
函数功能:查找指定任务配置的任务池
函数返回:查找成功返回该任务池,查找失败返回NULL
函数描述:遍历samgr中维护的服务,查找与指定任务配置相同的服务。
若找到相同任务配置的服务,则判断绑定的任务池是否为NULL。!=NULL时,增加任务池的引用数并返回它,==NULL时返回NULL。
若未找到相同任务配置的服务,则返回NULL。
*/
static TaskPool *GetSpecifiedTaskPool(TaskConfig *config)
{
//获取samgr对象
SamgrLiteImpl *samgr = GetImplement();
//获取service集合
Vector *services = &(samgr->services);
MUTEX_Lock(samgr->mutex);
//获取services中ServiceImpl的个数
int16 serviceNum = VECTOR_Size(services);
int i;
//遍历所有服务的任务配置
for (i = 0; i < serviceNum; ++i) {
//获取服务实例
ServiceImpl *impl = VECTOR_At(services, i);
if (impl == NULL) {
continue;
}
//获取任务配置
TaskConfig cfg = impl->service->GetTaskConfig(impl->service);
//寻找ServiceImpl中的任务配置与当前指定的config相同的service
if (memcmp(&cfg, config, sizeof(TaskConfig)) != 0) {
continue;
}
//若匹配到,但绑定的任务池为NULL,则结束循环
if (impl->taskPool == NULL) {
break;
}
//绑定的任务池不为NULL,增加该任务池的引用数并返回它
TaskPool *taskPool = SAMGR_ReferenceTaskPool(impl->taskPool);
if (taskPool != NULL) {
MUTEX_Unlock(samgr->mutex);
return taskPool;
}
}
MUTEX_Unlock(samgr->mutex);
return NULL;
}
samgr_lite部分的函数终于分析完毕。
写在最后
如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
- 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
- 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
- 想要获取更多完整鸿蒙最新学习资源,请看下图提示:
更多推荐
所有评论(0)