函数实现详解
相关代码位于distributedschedule_samgr_lite\samgr_server\source\samgr_server.c。
SamgrServer消息处理函数
//SamgrServer服务的消息处理函数,当前只实现了MSG_CLEAN,用于删除对应的ListNode
static BOOL MessageHandle(Service *service, Request *request)
{
SamgrServer *server = (SamgrServer *)service;
switch (request->msgId) {
case MSG_CLEAN: //消息ID为清除
MUTEX_Lock(server->mtx);
//根据pid删除对应的ListNode,并更新maps
SASTORA_ClearByPid(&server->store, request->msgValue);
MUTEX_Unlock(server->mtx);
break;
default:
break;
}
return TRUE;
}
获取服务的默认配置
//获取服务的任务配置,此时返回的是默认的任务配置
static TaskConfig GetTaskConfig(Service *service)
{
(void)service;
//默认的任务配置
TaskConfig config = {LEVEL_HIGH, PRI_BUTT - 1, 0x400, 20, SINGLE_TASK}; // Cannot use PRI_BUTT directly, so minus 1
return config;
}
资源请求处理函数
//根据不同的资源类型调用不同的处理函数
static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply)
{
//获取SamgrServer对象
SamgrServer *server = GET_OBJECT(iProxy, SamgrServer, iUnknown);
//读取一个uint32的值,赋给resource,即资源类型
int32 resource = IpcIoPopUint32(req);
//读取一个uint32的值,赋给option,即操作类型
int32 option = IpcIoPopUint32(req);
//参数检查,参数不合法则返回EC_INVALID
if (server == NULL || resource >= RES_BUTT || resource < 0 || g_functions[resource] == NULL) {
HILOG_ERROR(HILOG_MODULE_SAMGR, "Invalid Msg<%d, %d, %d>", resource, option, funcId);
return EC_INVALID;
}
//根据资源类型调用不同的处理函数
return g_functions[resource](server, option, origin, req, reply);
}
DD一下:欢迎大家关注公众号<程序猿百晓生>,可以了解到一下知识点。
1.OpenHarmony开发基础
2.OpenHarmony北向开发环境搭建
3.鸿蒙南向开发环境的搭建
4.鸿蒙生态应用开发白皮书V2.0 & V3.0
5.鸿蒙开发面试真题(含参考答案)
6.TypeScript入门学习手册
7.OpenHarmony 经典面试题(含参考答案)
8.OpenHarmony设备开发入门【最新版】
9.沉浸式剖析OpenHarmony源代码
10.系统定制指南
11.【OpenHarmony】Uboot 驱动加载流程
12.OpenHarmony构建系统--GN与子系统、部件、模块详解
13.ohos开机init启动流程
14.鸿蒙版性能优化指南
.......
处理资源类型为endpoint的消息
/*
函数功能:处理endpoint类型的消息,注册endpoint
函数参数:@server:SamgrServer对象
@option:操作类型
@origin:请求数据
@req:请求IO
@reply:响应IO
函数返回:成功 返回EC_SUCCESS,失败 返回EC_FAILURE
函数描述:处理资源类型为RES_ENDPOINT和操作类型为OP_POST的请求消息,将其他进程的endpoint信息注册到satore中。
首先从请求消息中获取待注册的endpoint所属的进程ID号,然后在satore中查询是否存在注册记录。
若存在,则将pid对应的PidHandle对象的handle作为响应数据发送给请求者。
若不存在,则创建新的PidHandle对象保存待注册的endpoint的信息,然后添加到satore中。同样,将handle作为响应数据发送给请求者。
*/
static int ProcEndpoint(SamgrServer *server, int32 option, void *origin, IpcIo *req, IpcIo *reply)
{
if (option != OP_POST) {
//若操作类型不为POST,则消息有误。发送响应消息,值为INVALID_INDEX
IpcIoPushUint32(reply, (uint32)INVALID_INDEX);
return EC_FAILURE;
}
//获取origin中记录的发送者processID值,processID由内核填充
pid_t pid = GetCallingPid(origin);
PidHandle handle;
MUTEX_Lock(server->mtx);
//根据进程ID在store的maps中查找对应的PidHandle,由handle返回,并返回其对应的下标
int index = SASTORA_FindHandleByPid(&g_server.store, pid, &handle);
if (index == INVALID_INDEX) {
//返回的下标无效,则没找到该对象,需要创建它
//初始化地址
SvcIdentity identity = {(uint32)INVALID_INDEX, (uint32)INVALID_INDEX, (uint32)INVALID_INDEX};
//GetCallingTid()用于获取origin的taskID,即获取发送者的任务ID,这个值是由内核填充的
//根据taskID生成发送者的serviceHandle,赋值给identity的handle
(void)GenServiceHandle(&identity, GetCallingTid(origin));
#ifdef __LINUX__
BinderAcquire(g_server.samgr->context, identity.handle);//该函数在当前版本中暂未实现
#endif
//重新构建handle对象
//发送者的进程ID
handle.pid = pid;
//返回origin的userID,即发送者的用户ID
handle.uid = GetCallingUid(origin);
//发送者的服务handle
handle.handle = identity.handle;
handle.deadId = INVALID_INDEX;
//将指定的PidHandle对象保存在satore中
(void)SASTORA_SaveHandleByPid(&server->store, handle);
//解除死亡的回调函数
(void)UnregisterDeathCallback(identity, handle.deadId);
//再次注册死亡的回调函数
(void)RegisterDeathCallback(server->samgr->context, identity, OnEndpointExit, (void*)((uintptr_t)pid),
&handle.deadId);
}
MUTEX_Unlock(server->mtx);
//将handle.handle的值当作响应消息发送给请求者
IpcIoPushUint32(reply, handle.handle);
HILOG_INFO(HILOG_MODULE_SAMGR, "Register Endpoint<%d, %d, %d>", handle.pid, handle.handle, handle.deadId);
return EC_SUCCESS;
}
处理资源类型为feature的消息
//feature处理函数,根据option类型调用不同的处理函数
static int ProcFeature(SamgrServer *server, int32 option, void *origin, IpcIo *req, IpcIo *reply)
{
//option必须是OP_PUT或者OP_GET
if (option != OP_PUT && option != OP_GET) {
//操作不符合,发送响应,值为EC_INVALID
IpcIoPushInt32(reply, EC_INVALID);
return EC_INVALID;
}
if (g_server.ipcAuth == NULL) {
//获取服务名为 PERMISSION_SERVICE 且功能名为 IPCAUTH 的API接口
g_server.ipcAuth = GetIpcAuthInterface();
}
if (g_server.ipcAuth == NULL) {
//获取接口失败,则响应EC_NOINIT
IpcIoPushInt32(reply, EC_NOINIT);
return EC_NOINIT;
}
int ret = EC_SUCCESS;
//定义一个无效的通信地址
SvcIdentity identity = {INVALID_INDEX, INVALID_INDEX, INVALID_INDEX};
if (option == OP_PUT) {
//操作类型为PUT,调用PUT处理函数,向SamgrServer注册feature
ret = ProcPutFeature(server, origin, req, reply, &identity);
}
if (ret != EC_SUCCESS) {
return ret;
}
if (option == OP_GET) {
//操作类型为GET,调用GET处理函数,向SamgrServer查询指定服务名和功能名的IPC通信地址SvcIdentity
ret = ProcGetFeature(server, origin, req, reply, &identity);
//将结果响应给请求者
IpcIoPushInt32(reply, ret);
if (ret == EC_SUCCESS) {
//若操作成功,将identity响应给请求者
IpcIoPushSvc(reply, &identity);
}
}
return ret;
}