鸿蒙源码分析(五十五)

pub_sub_implement.c和其相关头文件分析

文件功能:
文件路径:

一、头文件pub_sub_implement.h

头文件主要是一些结构体和共用体的定义

//MessageId德定义
enum MessageID {
    
    
    MSG_PUBLISH = 1,
    MSG_BUTT
};

typedef struct PubSubImplement {
    
    
    INHERIT_IUNKNOWNENTRY(PubSubInterface);  //一个接口
    PubSubFeature *feature;  //特征信息
} PubSubImplement;

二、源文件pub_sub_implement.c

//函数声明

static PubSubImplement g_pubSubImplement = {
    
    
    DEFAULT_IUNKNOWN_ENTRY_BEGIN,
    .subscriber.AddTopic = AddTopic,
    .subscriber.Subscribe = Subscribe,
    .subscriber.ModifyConsumer = ModifyConsumer,
    .subscriber.Unsubscribe = Unsubscribe,
    .provider.Publish = Publish,
    DEFAULT_IUNKNOWN_ENTRY_END,
    .feature = NULL
};
PubSubImplement *BCE_CreateInstance(Feature *feature)
{
    
    
    g_pubSubImplement.feature = (PubSubFeature *)feature;
    return &g_pubSubImplement;
}

//根据传入的topic添加一个主题
static int AddTopic(IUnknown *iUnknown, const Topic *topic)
{
    
    
    if (iUnknown == NULL || topic == NULL) {
    
    
        return EC_INVALID;
        //检查传入的参数是否为空
    }

    PubSubImplement *broadcast = GET_OBJECT(iUnknown, PubSubImplement, iUnknown);
    //调用一个宏定义函数
    if (broadcast->feature == NULL || broadcast->feature->GetRelation == NULL) {
    
    
        return EC_FAILURE;
        //检查broadcast德属性值是否为空
    }
    //执行GetRelation函数进行关联broadcast->feature和topic
    if (broadcast->feature->GetRelation(broadcast->feature, topic) != NULL) {
    
    
        return EC_FAILURE;
    }

    Relation *head = &broadcast->feature->relations;
    Relation *newRelation = (Relation *)SAMGR_Malloc(sizeof(Relation));
    //定义一个新的Relation并申请相关空间
    if (newRelation == NULL) {
    
    
        return EC_NOMEMORY;
    }
    newRelation->topic = *topic;
    newRelation->callbacks.consumer = NULL;
    UtilsListInit(&newRelation->callbacks.node);

    MUTEX_Lock(broadcast->feature->mutex);//操作前对该对象进行加锁
    UtilsListAdd(&head->node, &(newRelation->node));
    //在链表中添加一个新的节点
    MUTEX_Unlock(broadcast->feature->mutex);//释放锁
    return EC_SUCCESS;
}

static int Subscribe(IUnknown *iUnknown, const Topic *topic, Consumer *consumer)
{
    
    
    if (iUnknown == NULL || topic == NULL || consumer == NULL) {
    
    
        return EC_INVALID;
    }
    //先检查参数
    PubSubImplement *broadcast = GET_OBJECT(iUnknown, PubSubImplement, iUnknown);
    //获取对象德一个宏定义函数
    if (broadcast->feature == NULL || broadcast->feature->GetRelation == NULL) {
    
    
        return EC_FAILURE;
    }
    //检查broadcast德属性值是否为空
    Relation *relation = broadcast->feature->GetRelation(broadcast->feature, topic);
    //关系的关联
    if (relation == NULL) {
    
    
        return EC_FAILURE;
    }
    //执行相关操作前对对象进行申请加锁
    MUTEX_Lock(broadcast->feature->mutex);
    ConsumerNode *item = NULL;
    UTILS_DL_LIST_FOR_EACH_ENTRY(item, &relation->callbacks.node, ConsumerNode, node) {
    
    
    //遍历整个链表,找到item->consumer和传入consumer一样的,就释放锁然后返回
        if (item->consumer->Equal(item->consumer, consumer)) {
    
    
            MUTEX_Unlock(broadcast->feature->mutex);
            return EC_ALREADY_SUBSCRIBED;
        }
    }
    MUTEX_Unlock(broadcast->feature->mutex);
    //链表遍历结束也释放锁
    ConsumerNode *consumerNode = (ConsumerNode *)SAMGR_Malloc(sizeof(ConsumerNode));
    //重新申请空间定义一个list
    if (consumerNode == NULL) {
    
    
        return EC_NOMEMORY;
    }

    UtilsListInit(&consumerNode->node); //初始化
    consumerNode->consumer = consumer; //开始赋值
    MUTEX_Lock(broadcast->feature->mutex); //开始加锁,对该链表进行操作
    ConsumerNode *head = &relation->callbacks;
    UtilsListAdd(&head->node, &consumerNode->node); //添加一个新节点
    MUTEX_Unlock(broadcast->feature->mutex);
    return EC_SUCCESS;
}
//Consumer的修改。主要是参数中传递一个新的sonsumer对旧的进行更新
static Consumer *ModifyConsumer(IUnknown *iUnknown, const Topic *topic, Consumer *oldConsumer, Consumer *newConsumer)
{
    
    
    if (iUnknown == NULL || topic == NULL || oldConsumer == NULL || newConsumer == NULL) {
    
    
        return NULL;
    }//检查参数

    PubSubImplement *broadcast = GET_OBJECT(iUnknown, PubSubImplement, iUnknown);
    if (broadcast->feature == NULL || broadcast->feature->GetRelation == NULL) {
    
    
        return NULL;
    }
    //对象获取和检查broadcast
    Relation *relation = broadcast->feature->GetRelation(broadcast->feature, topic);
    if (relation == NULL) {
    
    
        return NULL;
    }

    MUTEX_Lock(broadcast->feature->mutex);
    //加锁开始执行修改
    ConsumerNode *item = NULL;
    UTILS_DL_LIST_FOR_EACH_ENTRY(item, &relation->callbacks.node, ConsumerNode, node) {
    
    
        //遍历整个链表,符合条件的consumer进行更新。将参数中的新值替换进去
        if (item->consumer->Equal(item->consumer, oldConsumer)) {
    
    
            Consumer *older = item->consumer;
            item->consumer = newConsumer;
            MUTEX_Unlock(broadcast->feature->mutex);
            //修改成功释放锁,函数退出
            return older;
        }
    }
    MUTEX_Unlock(broadcast->feature->mutex);
    //如果没有符号条件的oldconsumer,函数也得释放锁再退出
    return NULL;
}

static Consumer *Unsubscribe(IUnknown *iUnknown, const Topic *topic, const Consumer *consumer)
{
    
    
    if (iUnknown == NULL || topic == NULL || consumer == NULL) {
    
    
        return NULL;
    }

    PubSubImplement *broadcast = GET_OBJECT(iUnknown, PubSubImplement, iUnknown);
    if (broadcast->feature == NULL || broadcast->feature->GetRelation == NULL) {
    
    
        return NULL;
    }

    Relation *relation = broadcast->feature->GetRelation(broadcast->feature, topic);
    if (relation == NULL) {
    
    
        return NULL;
    }
    MUTEX_Lock(broadcast->feature->mutex);
    ConsumerNode *item = NULL;
    UTILS_DL_LIST_FOR_EACH_ENTRY(item, &relation->callbacks.node, ConsumerNode, node) {
    
    
        if (item->consumer->Equal(item->consumer, consumer)) {
    
    
            UtilsListDelete(&item->node);
            break;
        }
    }
    MUTEX_Unlock(broadcast->feature->mutex);
    if (item == &relation->callbacks || item == NULL) {
    
    
        return NULL;
    }
    Consumer *oldConsumer = item->consumer;
    SAMGR_Free(item);
    return oldConsumer;
}
//bool函数,一个返回值为逻辑值的函数
static BOOL Publish(IUnknown *iUnknown, const Topic *topic, uint8 *data, int16 len)
{
    
    
    PubSubImplement *broadcast = GET_OBJECT(iUnknown, PubSubImplement, iUnknown);
    PubSubFeature *feature = broadcast->feature;
    if (feature == NULL) {
    
    
        return FALSE;
    }
    //检查参数
    Request request = {
    
    MSG_PUBLISH, 0, NULL, *(uint32 *)topic};
    //定义一个请求变量
    if (data != NULL && len > 0) {
    
    
        request.data = (uint8 *)SAMGR_Malloc(len);
        if (request.data == NULL) {
    
    
            return FALSE;
        }
        //检查数据域是否合法
        request.len = len; //输入数据长度和输出一致
        // There is no problem, the request.data length is equal the input data length.
        (void)memcpy_s(request.data, request.len, data, len);
    }

    if (!ImmediatelyPublish(feature, topic, &request)) {
    
    
        //即时提交函数执行失败
        (void)SAMGR_Free(request.data);
        request.data = NULL;
        request.len = 0;
        return FALSE;
    }
    return TRUE;
}
//即时提交
static BOOL ImmediatelyPublish(PubSubFeature *feature, const Topic *topic, const Request *request)
{
    
    
    if (feature->GetRelation == NULL) {
    
    
        return FALSE;
    }

    Relation *relation = feature->GetRelation(feature, topic);
    if (relation == NULL) {
    
    
        return FALSE;
    }

    if (UtilsListEmpty(&relation->callbacks.node)) {
    
    
        return FALSE;
    }
    //前三个主要来检查相关参数
    BOOL needAync = FALSE;
    ConsumerNode *item = NULL;
    uint32 *token = NULL;
    //一些变量的初始化
    MUTEX_Lock(feature->mutex);
    //这里开始申请互斥锁,开始执行操作
    UTILS_DL_LIST_FOR_EACH_ENTRY(item, &relation->callbacks.node, ConsumerNode, node) {
    
    
        if (item->consumer->identity == NULL) {
    
    
        //遍历链表,如果有consumer的身份为空,开始下一次循环遍历
            needAync = TRUE;
            continue;
        }

        Response response = {
    
    item->consumer, 0};
        int ret = SAMGR_SendSharedDirectRequest(item->consumer->identity, request, &response, &token, DefaultHandle);
        //对身份非空的节点执行函数。
        //函数介绍:向特性线程发送调用者的请求和响应。处理程序是直接的调用来处理请求和响应,而不使用消息处理函数。
        if (ret != EC_SUCCESS) {
    
    
            needAync = FALSE;
            break;
        }
    }
    if (needAync) {
    
    
        //对needAync的真假值进行判断
        token = SAMGR_SendSharedRequest(&feature->identity, request, token, NULL);
        //向多个服务或特性发送请求以节省内存
    }
    MUTEX_Unlock(feature->mutex);
    return (token != NULL);
}
//对请求的默认处理函数
//参数传递一个请求和一个响应
static void DefaultHandle(const Request *request, const Response *response)
{
    
    
    Consumer *consumer = (Consumer *)response->data;
    if (consumer == NULL || consumer->Notify == NULL || g_pubSubImplement.feature == NULL) {
    
    
        return;
    }
    //等待即使提交结束
    // wait ImmediatelyPublish finished.
    MUTEX_Lock(g_pubSubImplement.feature->mutex);
    MUTEX_Unlock(g_pubSubImplement.feature->mutex);
    Topic topic = request->msgValue;
    consumer->Notify(consumer, &topic, request);
}

感谢阅读和点赞

猜你喜欢

转载自blog.csdn.net/m0_46976252/article/details/120185003