OpenHarmony轻量系统服务管理|samgr_lite功能详解(二)

100 篇文章 0 订阅
100 篇文章 1 订阅

往期知识点记录:

本文继续分析samgr_lite的函数实现。文件位于distributedschedule_samgr_lite\samgr\source\samgr_lite.c

函数实现分析

检查服务初始化状态

/*
    函数功能:判断所有服务是否已完成初始化
    函数描述:遍历全局的SamgrLiteImpl对象,查询是否存在未初始化的ServiceImpl对象
             若存在,则samgr初始化未完成。若不存在,则更新samgr的状态
*/
static int32 InitCompleted(void)
{
    SamgrLiteImpl *manager = GetImplement();
    //获取未初始化对象的下标
    int16 pos = GetUninitializedPos();
    //获取vector的大小,即top值
    int16 size = VECTOR_Size(&(manager->services));
    if (pos < size) {
        //pos值小于size,则找到一个未初始化的对象
        return EC_SUCCESS;
    }
    //services中所有对象都已初始化
    //更新samgr的状态
    MUTEX_Lock(manager->mutex);
    if (manager->status == BOOT_SYS_WAIT) {
        //进入启动应用服务阶段
        manager->status = BOOT_APP;
        MUTEX_Unlock(manager->mutex);
        //记录日志
        HILOG_INFO(HILOG_MODULE_SAMGR, "Initialized all core system services!");
        WDT_Reset(WDG_SVC_REG_TIME);
        //发送一条消息,表示核心系统服务已初始化,在pos值之前的服务已初始化,在pos值之后的未初始化
        return SendBootRequest(BOOT_SYS_COMPLETED, pos);
    }
    if (manager->status == BOOT_APP_WAIT) {
        //进入启动动态服务阶段
        manager->status = BOOT_DYNAMIC;
        MUTEX_Unlock(manager->mutex);
        HILOG_INFO(HILOG_MODULE_SAMGR, "Initialized all system and application services!");
        WDT_Reset(WDG_SVC_TEST_TIME);
        //发送一条消息,表示系统和应用层服务已初始化,在pos值之前的服务已初始化,在pos值之后的未初始化
        return SendBootRequest(BOOT_APP_COMPLETED, pos);
    }
    MUTEX_Unlock(manager->mutex);
    WDT_Stop();
    return EC_SUCCESS;
}

初始化所有服务

/*
    函数功能:将所有SVC_INIT状态的serviceImpl进行初始化
    函数参数:@services:vector对象,包含多个ServiceImpl
    详细描述:
        1.遍历所有的serviceImpl,为其中的service绑定合适的任务池并初始化
        2.遍历所有的serviceImpl,启动任务池
*/
static void InitializeAllServices(Vector *services)
{
    //获取服务集合的大小
    int16 size = VECTOR_Size(services);
    int16 i;
    //遍历所有服务实例
    for (i = 0; i < size; ++i) {
        //根据下标返回指定服务实例
        ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(services, i);
        if (serviceImpl == NULL) {
            continue;
        }
        //获取service的任务配置信息
        TaskConfig config = serviceImpl->service->GetTaskConfig(serviceImpl->service);
        //获取service的name
        const char *name = serviceImpl->service->GetName(serviceImpl->service);
        //为serviceImpl绑定指定任务配置的任务池
        AddTaskPool(serviceImpl, &config, name);
        HILOG_INFO(HILOG_MODULE_SAMGR, "Init service:%s TaskPool:%p", name, serviceImpl->taskPool);
        //初始化单个serviceImpl
        InitializeSingleService(serviceImpl);
    }
    //获取samgr全局实例
    SamgrLiteImpl *samgr = GetImplement();
    MUTEX_Lock(samgr->mutex);
    //遍历serviceImpl,启动任务池
    for (i = 0; i < size; ++i) {
        ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(services, i);
        if (serviceImpl == NULL) {
            continue;
        }
        //获取service的name
        const char *name = serviceImpl->service->GetName(serviceImpl->service);
        //启动任务池,向任务池中添加新创建的线程
        SAMGR_StartTaskPool(serviceImpl->taskPool, name);
    }
    MUTEX_Unlock(samgr->mutex);
}

向samgr注册服务

/*
    函数功能:注册服务
    函数描述:向samgr中注册指定的服务,后续需要初始化该服务。
             将service封装为ServiceImpl对象,并加入到SamgrLiteImpl的services中
*/
static BOOL RegisterService(Service *service)
{
    //判断service是否有效
    if (IsInvalidService(service)) {
        return FALSE;
    }
    //获取samgr全局实例
    SamgrLiteImpl *samgr = GetImplement();
    MUTEX_Lock(samgr->mutex);
    //获取指定servicename的ServiceImpl下标
    int16 pos = VECTOR_FindByKey(&(samgr->services), (void *)service->GetName(service));
    if (pos >= 0) {
        //service已存在,直接返回false
        MUTEX_Unlock(samgr->mutex);
        return FALSE;
    }
    if (VECTOR_Num(&(samgr->services)) >= MAX_SERVICE_NUM) {
        //service的数目已达上限,直接返回false
        MUTEX_Unlock(samgr->mutex);
        return FALSE;
    }
    //根据service和status创建一个ServiceImpl的实例
    ServiceImpl *serviceImpl = SAMGR_CreateServiceImpl(service, samgr->status);
    if (serviceImpl == NULL) {
        MUTEX_Unlock(samgr->mutex);
        return FALSE;
    }
    //向samgr->services中添加新的元素,若成功 返回新加入的元素的下标,失败 返回INVALID_INDEX
    serviceImpl->serviceId = VECTOR_Add(&(samgr->services), serviceImpl);
    MUTEX_Unlock(samgr->mutex);
    if (serviceImpl->serviceId == INVALID_INDEX) {
        //serviceImpl注册失败,回收资源
        SAMGR_Free(serviceImpl);
        return FALSE;
    }
    return TRUE;
}

删除samgr中的服务

/*
    函数功能:注销服务
    函数描述:删除samgr中指定的服务,返回被删除的service。
             需要先将内部的动态对象释放,如feature等
*/
static Service *UnregisterService(const char *name)
{
    if (name == NULL) {
        return NULL;
    }
    //获取samgr全局实例
    SamgrLiteImpl *samgr = GetImplement();
    MUTEX_Lock(samgr->mutex);
    //获取samgr中维护的服务集合
    Vector *services = &(samgr->services);
    //在services中根据name查找指定元素,返回下标
    int16 pos = VECTOR_FindByKey(services, (void *)name);
    //获取serviceImpl对象
    ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(services, pos);
    if (serviceImpl == NULL || serviceImpl->defaultApi != NULL || VECTOR_Num(&serviceImpl->features) > 0) {
        //features集合中还存在feature未注销,返回NULL
        MUTEX_Unlock(samgr->mutex);
        return NULL;
    }
    //将services中指定下标pos的元素置为NULL,起到删除作用
    VECTOR_Swap(services, pos, NULL);
    //释放任务池必须在锁中,以保持引用的原子性
    //释放任务池,若引用计数为0,则回收资源
    SAMGR_ReleaseTaskPool(serviceImpl->taskPool);
    MUTEX_Unlock(samgr->mutex);
    Service *service = serviceImpl->service;
    //资源回收,清空features集合内的feature
    VECTOR_Clear(&serviceImpl->features);
    SAMGR_Free(serviceImpl);
    return service;
}

获取服务名


//获取service的name
static const char *GetServiceName(const ServiceImpl *serviceImpl)
{
    if (serviceImpl == NULL) {
        return NULL;
    }
    //调用服务的GetName,获取name
    return serviceImpl->service->GetName(serviceImpl->service);
}

本部分还有许多函数待分析,将在后续的文章进行分析。

写在最后

如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙

  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新学习资源,请看下图提示:
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值