(gps)gps消息队列解析

gps从loc_api层到loc eng层用到了消息队列,大致格式是:sendMsg(new xxx),这个msg最终会发送到message queue中,在loopMain中读取出来然后分别调用msg的log()和proc()来处理相应的message,因此有必要了解一下这个message queue的大致flow

gps message queue进程间通信分为发送端和接收端,我们分开来看一下。

发送端的api: hardware/qcom/gps/utils/msg_q.c

msq_q_err_type msg_q_snd(void* msg_q_data, void* msg_obj, void (*dealloc)(void*)){ msq_q_err_type rv; if( msg_q_data == NULL ) {LOC_LOGE(“%s: Invalid msg_q_data parameter!\n”, __FUNCTION__);return eMSG_Q_INVALID_HANDLE; } if( msg_obj == NULL ) {LOC_LOGE(“%s: Invalid msg_obj parameter!\n”, __FUNCTION__);return eMSG_Q_INVALID_PARAMETER; } //前面两个是判断param的合法性//把msg_q_data转换为msg queue相同的类型msg_q* msg_q* p_msg_q = (msg_q*)msg_q_data;//锁定p_msg_q的mutex,pthread_mutex_lock跟pthread_cond_xxx系列函数一般是成对出现的,防止多线程的pthread_cond_xxx系列函数之间竞争 pthread_mutex_lock(&p_msg_q->list_mutex);LOC_LOGD(“%s: Sending message with handle = 0x%08X\n”, __FUNCTION__, msg_obj);if( p_msg_q->unblocked ) {//如果不是锁定的,说明该msg是不可用的LOC_LOGE(“%s: Message queue has been unblocked.\n”, __FUNCTION__);pthread_mutex_unlock(&p_msg_q->list_mutex);return eMSG_Q_UNAVAILABLE_RESOURCE; }//linked_list_add,从名字来看应该是链表的插入动作 rv = convert_linked_list_err_type(linked_list_add(p_msg_q->msg_list, msg_obj, dealloc));/* Show data is in the message queue. */ //唤醒message queue的条件变量,rcv端被这个条件变量block住了哦,具体用法可请参见manpage pthread_cond_signal(&p_msg_q->list_cond);//解锁message queue的mutex,rcv端才可以从message queue中取出数据 pthread_mutex_unlock(&p_msg_q->list_mutex);LOC_LOGD(“%s: Finished Sending message with handle = 0x%08X\n”, __FUNCTION__, msg_obj);return rv;}

message queue,顾名思义message会插入到queue中,下面就是插入的动作: hardware/qcom/gps/utils/linked_list.c

linked_list_err_type linked_list_add(void* list_data, void *data_obj, void (*dealloc)(void*)){ LOC_LOGD(“%s: Adding to list data_obj = 0x%08X\n”, __FUNCTION__, data_obj); if( list_data == NULL ) {LOC_LOGE(“%s: Invalid list parameter!\n”, __FUNCTION__);return eLINKED_LIST_INVALID_HANDLE; }if( data_obj == NULL ) {LOC_LOGE(“%s: Invalid input parameter!\n”, __FUNCTION__);return eLINKED_LIST_INVALID_PARAMETER; } //前面两个是判断param的合法性//list_data是能确认msg queue的指针 list_state* p_list = (list_state*)list_data; list_element* elem = (list_element*)malloc(sizeof(list_element)); if( elem == NULL ) {LOC_LOGE(“%s: Memory allocation failed\n”, __FUNCTION__);return eLINKED_LIST_FAILURE_GENERAL; }/* Copy data to newly created element */ //填充elem,传入的data_obj参数封装到elem结点,然后插入到msg queue elem->data_ptr = data_obj; elem->next = NULL; elem->prev = NULL; elem->dealloc_func = dealloc;/* Replace head element */ //保存list的head结点到tmp list_element* tmp = p_list->p_head; //list的head结点指向elem p_list->p_head = elem; /* Point next to the previous head element */ //list的head结点的next结点指向tmp,也就是以前的head,这样子elem就成了新的head结点 p_list->p_head->next = tmp;if( tmp != NULL ) {//如果tmp结点,就是以前的head结点不是null,那么以前head结点的prev指针指向elem(新的head结点),这也说明了以前的head结点成了现在head结点的下一个结点tmp->prev = p_list->p_head; } else {//如果tmp结点是null,,也就是以前就是一个空的双向链表,现在新插入的elem结点(p_list->p_head = elem)既是head结点,也是tail结点p_list->p_tail = p_list->p_head; }return eLINKED_LIST_SUCCESS;}

从函数名来看,应该是把链表的返回值转换成message queue的返回值: hardware/qcom/gps/utils/linked_list.c

static msq_q_err_type convert_linked_list_err_type(linked_list_err_type linked_list_val){ switch( linked_list_val ) { case eLINKED_LIST_SUCCESS:return eMSG_Q_SUCCESS; case eLINKED_LIST_INVALID_PARAMETER:return eMSG_Q_INVALID_PARAMETER; case eLINKED_LIST_INVALID_HANDLE:return eMSG_Q_INVALID_HANDLE; case eLINKED_LIST_UNAVAILABLE_RESOURCE:return eMSG_Q_UNAVAILABLE_RESOURCE; case eLINKED_LIST_INSUFFICIENT_BUFFER:return eMSG_Q_INSUFFICIENT_BUFFER;case eLINKED_LIST_FAILURE_GENERAL: default:return eMSG_Q_FAILURE_GENERAL; }}生活中最基本的技巧是交流,最可依赖的品质是耐心,

(gps)gps消息队列解析

相关文章:

你感兴趣的文章:

标签云: