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);
}
感谢阅读和点赞