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

往期知识点记录:

函数实现详解

本文将对samgr_server部分的最后系列函数实现进行分析。相关函数代码位于distributedschedule_samgr_lite\samgr_server\source\samgr_server.c

endpoint退出时的回调函数
//endpoint退出时,进行收尾工作
static int OnEndpointExit(const IpcContext *context, void* ipcMsg, IpcIo* data, void* argv)
{
    (void)data;
    if (ipcMsg != NULL) {
        //回收资源
        FreeBuffer(context, ipcMsg);
    }
    //获取pid
    pid_t pid = (pid_t)((uintptr_t)argv);
    Request request = {0};
    //消息类型为清除
    request.msgId = MSG_CLEAN;
    //消息值为进程ID
    request.msgValue = pid;
    //重试次数
    int retry = RETRY_TIMES;
    int ret = EC_INVALID;
    while (retry > 0) {//若消息发送不成功,可以最多重试RETRY_TIMES次,保证系统的可靠性
        //将构建的资源回收请求消息放入g_server绑定的消息队列中
        //触发store中资源清理的操作
        ret = SAMGR_SendRequest(&g_server.identity, &request, NULL);
        if (ret == EC_SUCCESS) {
            break;
        }
        sleep(RETRY_INTERVAL);
        --retry;
    }
#ifdef __LINUX__
    PidHandle handle;
    //根据pid在store中查找对应的PidHandle,由handle返回,并返回其对应的下标
    int err = SASTORA_FindHandleByPid(&g_server.store, pid, &handle);
    if (err != INVALID_INDEX) {
        //释放
        BinderRelease(context, handle.handle);
    }
#endif
    HILOG_ERROR(HILOG_MODULE_SAMGR, "IPC pid<%d> exit! send clean request retry(%d), ret(%d)!", pid, retry, ret);
    return EC_SUCCESS;
}
获取cJSON对象
//读取指定文件路径下的json文件,解析为cJSON对象返回
static cJSON *GetJsonStream()
{
    //json文件的路径
    const char *path = "/etc/system_capability.json";
    struct stat fileInfo;
    int32_t size = 0;
    if (stat(path, &fileInfo) != 0 || (size = fileInfo.st_size) == 0) {
        return NULL;
    }
    //以只读的方式打开
    int32_t fp = open(path, O_RDONLY, S_IRUSR);
    if (fp < 0) {
        return NULL;
    }
    //申请内存
    char *json = (char *)SAMGR_Malloc(size * sizeof(char));
    if (json == NULL) {
        close(fp);
        return NULL;
    }
    //读取文件中的数据
    if (read(fp, json, size * sizeof(char)) != size * sizeof(char)) {
        SAMGR_Free(json);
        close(fp);
        return NULL;
    }
    close(fp);
    //解析json数据
    cJSON *root = cJSON_Parse(json);
    //回收资源
    SAMGR_Free(json);
    json = NULL;
    return root;
}
读取并解析本地文件中的syscap
/*
    函数功能:从本地文件中解析syscap信息
    函数描述:解析指定路径下json格式的文件,文件中描述了SysCap的信息,将内部所有的SysCap添加到sysCapabilitys中
*/
static void ParseSysCap(void)
{
    //读取json格式的文件,返回cJSON对象
    cJSON *root = GetJsonStream();
    if (root == NULL) {
        HILOG_ERROR(HILOG_MODULE_SAMGR, "ParseSysCap GetJsonStream failed!");
        return;
    }
    //返回root->child->string与字符串‘systemCapability’相同的对象
    cJSON *sysCaps = cJSON_GetObjectItem(root, "systemCapability");
    //判断(sysCaps->type & 0xFF) == cJSON_Array的bool值
    if (!cJSON_IsArray(sysCaps)) {
        //若不是cJSON_Array
        //则删除这个cJSON
        cJSON_Delete(root);
        HILOG_ERROR(HILOG_MODULE_SAMGR, "ParseSysCap format failed!");
        return;
    }
    //获取sysCaps的大小
    int32_t size = cJSON_GetArraySize(sysCaps);
    int32_t sysCapNum = 0;
    for (int32_t i = 0; i < size; i++) {
        if (sysCapNum >= MAX_SYSCAP_NUM) {
            //防止sysCapNum超出最大限制
            HILOG_ERROR(HILOG_MODULE_SAMGR, "ParseSycCapMap system capability exceed");
            break;
        }
        //获取指定下标的item
        cJSON *item = cJSON_GetArrayItem(sysCaps, i);
        //判断(item->type & 0xFF) == cJSON_Object是否成立
        if (!cJSON_IsObject(item)) {
            continue;
        }
        //返回item->child->string与字符串‘name’相同的对象,内部包含syscap的name
        cJSON *name = cJSON_GetObjectItem(item, "name");
        //返回item->child->string与字符串‘register-on-startup’相同的对象,标识是否注册
        cJSON *isRegister = cJSON_GetObjectItem(item, "register-on-startup");
        if (!cJSON_IsString(name) || !cJSON_IsBool(isRegister)) {
            //若name不是字符串或isRegister不是布尔值,则跳出本次循环
            continue;
        }
        //获取name->valuestring值,即syscap的name
        char *nameStr = cJSON_GetStringValue(name);
        //根据nameStr查询对应的syscap
        if (VECTOR_FindByKey(&(g_server.sysCapabilitys), nameStr) != INVALID_INDEX) {
            //已存在,不允许重复注册
            HILOG_WARN(HILOG_MODULE_SAMGR, "Duplicate system capability %s register!", nameStr);
            continue;
        }
        //指定的syscap不存在
        //申请资源,创建SysCapImpl实例
        SysCapImpl *impl = (SysCapImpl *)SAMGR_Malloc(sizeof(SysCapImpl));
        if (impl == NULL) {
            continue;
        }
        //字符串的拷贝,将获取的syscap的name拷贝到impl实例中
        if (strcpy_s(impl->name, sizeof(impl->name), cJSON_GetStringValue(name)) != EC_SUCCESS) {
            SAMGR_Free(impl);
            continue;
        }
        //判断(isRegister->type & 0xff) == cJSON_True,结果赋给isRegister,标识是否注册该系统能力
        impl->isRegister = cJSON_IsTrue(isRegister);
        //将封装的SysCapImpl添加到sysCapabilitys中
        if (VECTOR_Add(&(g_server.sysCapabilitys), impl) == INVALID_INDEX) {
            SAMGR_Free(impl);
            HILOG_ERROR(HILOG_MODULE_SAMGR, "system capability %s register failed!", impl->name);
            continue;
        }
        sysCapNum++;
    }
    //回收资源
    cJSON_Delete(root);
}

写在最后

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值