OpenHarmony轻量系统服务管理samgr-message实现分析(2)

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

往期知识点记录:

接着上文继续分析message中的函数实现。

消息资源回收操作

/*
    函数功能:释放exchange对象的成员所指向的内存
    函数描述:释放exchange对象的成员所指向的内存分为两步,首先处理exchange->sharedRef指向的内存。
            若更新引用数后,指向的值不大于0,则释放exchange->sharedRef指向的内存。否则不释放。
            其次处理exchange->request.data和exchange->response.data指向的内存。
            若更新后的引用数==0,则释放它两指向的内存,否则不释放。
*/
int32 SAMGR_FreeMsg(Exchange *exchange)
{
    if (!FreeReference(exchange)) {
        //exchange对象引用数不为0,不能释放
        return EC_SUCCESS;
    }
    //exchange对象引用数不大于0
    //释放request.data占用的空间
    if (exchange->request.len > 0) {
        SAMGR_Free(exchange->request.data);
        exchange->request.data = NULL;
    }
    //释放response.data占用的空间
    if (exchange->response.len > 0) {
        SAMGR_Free(exchange->response.data);
        exchange->response.data = NULL;
    }
    return EC_SUCCESS;
}

消息广播操作

/*
    函数功能:向多个服务或特性发送请求以节省内存。用于为Broadcast服务发布主题,以广播消息。
    函数参数:@identity:服务或特性ID
             @request:请求
             @token:引用计数
             @handler:处理响应的函数
    函数返回:成功返回共享引用计数,失败返回NULL
*/
uint32 *SAMGR_SendSharedRequest(const Identity *identity, const Request *request, uint32 *token, Handler handler)
{
    //参数检查
    if (identity == NULL || request == NULL) {
        return NULL;
    }
    //初始化exchange对象
    Exchange exchange = {*identity, *request, {NULL, 0}, MSG_NON, handler, token};
    exchange.type = (handler == NULL) ? MSG_NON : MSG_CON;
    exchange.id.queueId = NULL;
    //将共享的exchange对象发送到identity->queueId队列中
    int32 err = SharedSend(identity->queueId, &exchange, 0);
    if (err != EC_SUCCESS) {
        //发送失败,更新exchange的引用
        HILOG_ERROR(HILOG_MODULE_SAMGR, "SharedSend [%p] failed(%d)!", identity->queueId, err);
        (void)FreeReference(&exchange);
    }
    //返回引用计数
    return exchange.sharedRef;
}

消息处理函数

//发送消息类型为MSG_DIRECT的exchange对象,直接调用处理程序来处理请求和响应,而不使用消息处理函数。
int32 SAMGR_SendSharedDirectRequest(const Identity *id, const Request *req, const Response *resp, uint32 **ref,
                                    Handler handler)
{
    //参数检查
    if (handler == NULL || ref == NULL) {
        return EC_INVALID;
    }
    //初始化
    Exchange exchange = {0};
    //配置请求和响应消息
    if (req != NULL) {
        exchange.request = *req;
    }
    if (resp != NULL) {
        exchange.response = *resp;
    }
    //响应处理函数
    exchange.handler = handler;
    //引用
    exchange.sharedRef = *ref;
    //类型为MSG_DIRECT
    exchange.type = MSG_DIRECT;
    exchange.id = *id;//身份标识
    exchange.id.queueId = NULL;
    //将exchange对象发送到指定队列中
    int32 err = SharedSend(id->queueId, &exchange, 0);
    if (err != EC_SUCCESS) {
        //错误日志
        HILOG_ERROR(HILOG_MODULE_SAMGR, "SharedSend [%p] failed(%d)!", id->queueId, err);
        (void)FreeReference(&exchange);
    }
    *ref = exchange.sharedRef;//更新引用
    return err;
}

消息响应函数

//将exchange对象发送到指定Identity所绑定的消息队列
int32 SAMGR_SendResponseByIdentity(const Identity *id, const Request *request, const Response *response)
{
    //参数检查
    if (request == NULL || id == NULL) {
        return EC_INVALID;
    }
    //获取exchange对象
    Exchange *exchange = GET_OBJECT(request, Exchange, request);
    if (exchange->type == MSG_NON) {
        return EC_INVALID;
    }
    //指定消息队列
    exchange->id.queueId = id->queueId;
    //调用SAMGR_SendResponse()发送响应
    return SAMGR_SendResponse(request, response);
}

发送消息,本质上是将消息对象放入队列中

//将exchange对象发送到指定消息队列中,并更新引用计数
static int32 SharedSend(MQueueId queueId, Exchange *exchange, int initRef)
{
    //如果msg数据和响应是NULL,直接进行入队操作,不需要共享
    if ((exchange->request.data == NULL || exchange->request.len <= 0) &&
        (exchange->response.data == NULL || exchange->response.len <= 0)) {
        return QUEUE_Put(queueId, exchange, 0, DONT_WAIT);//入队,非阻塞
    }
    //加锁,更新引用计数
    MUTEX_GlobalLock();
    if (exchange->sharedRef == NULL) {
        //分配内存
        exchange->sharedRef = (uint32*)SAMGR_Malloc(sizeof(uint32));
        if (exchange->sharedRef == NULL) {
            //内存分配失败,解锁并返回EC_NOMEMORY
            MUTEX_GlobalUnlock();
            return EC_NOMEMORY;
        }
        *(exchange->sharedRef) = initRef;
    }
    (*(exchange->sharedRef))++;
    MUTEX_GlobalUnlock();
    return QUEUE_Put(queueId, exchange, 0, DONT_WAIT);//入队,非阻塞
}

释放引用计数操作

/*
    函数功能:更新exchange对象的引用数
    函数返回:true表示需要释放exchange的资源,false表示不能释放
    函数描述:更新exchange对象的引用数,若引用数不大于0,则释放sharedRef指向的内存空间,并指向NULL。然后返回true,表示可以释放exchange对象
             若引用数大于0,则返回false,表示不能释放exchange对象,还有其他对象引用它。
*/
static BOOL FreeReference(Exchange *exchange)
{
    //参数检查
    if (exchange == NULL) {
        return FALSE;
    }
    BOOL needFree = TRUE;
    //检查引用数
    MUTEX_GlobalLock();
    if (exchange->sharedRef != NULL) {
        if (*(exchange->sharedRef) > 0) {
            //更新引用数,引用减一
            (*(exchange->sharedRef))--;
        }
        if (*(exchange->sharedRef) > 0) {
            //若引用数大于0,则当前对象被其他对象引用,不能释放
            needFree = FALSE;
        }
    }
    MUTEX_GlobalUnlock();
    //如果needFree为TRUE,则释放sharedRef内存
    if (needFree) {
        SAMGR_Free(exchange->sharedRef);
        exchange->sharedRef = NULL;
    }
    return needFree;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值