/******************************************************************************* -- -- -- CedarX Multimedia Framework -- -- -- -- the Multimedia Framework for Linux/Android System -- -- -- -- This software is confidential and proprietary and may be used -- -- only as expressly authorized by a licensing agreement from -- -- Softwinner Products. -- -- -- -- (C) COPYRIGHT 2011 SOFTWINNER PRODUCTS -- -- ALL RIGHTS RESERVED -- -- -- -- The entire notice above must be reproduced -- -- on all copies and should not be removed. -- -- -- *******************************************************************************/ //#define LOG_NDEBUG 0 #define LOG_TAG "tmessage" #include #include #include #include #include #include "tmessage.h" #include "SystemBase.h" #include static int TMessageDeepCopyMessage(message_t *pDesMsg, message_t *pSrcMsg) { pDesMsg->command = pSrcMsg->command; pDesMsg->para0 = pSrcMsg->para0; pDesMsg->para1 = pSrcMsg->para1; pDesMsg->mpData = NULL; pDesMsg->mDataSize = 0; if(pSrcMsg->mpData && pSrcMsg->mDataSize>=0) { pDesMsg->mpData = malloc(pSrcMsg->mDataSize); if(pDesMsg->mpData) { pDesMsg->mDataSize = pSrcMsg->mDataSize; memcpy(pDesMsg->mpData, pSrcMsg->mpData, pSrcMsg->mDataSize); } else { aloge(" fatal error! malloc MessageData fail!"); return -1; } } pDesMsg->pReply = pSrcMsg->pReply; return 0; } static int TMessageSetMessage(message_t *pDesMsg, message_t *pSrcMsg) { pDesMsg->command = pSrcMsg->command; pDesMsg->para0 = pSrcMsg->para0; pDesMsg->para1 = pSrcMsg->para1; pDesMsg->mpData = pSrcMsg->mpData; pDesMsg->mDataSize = pSrcMsg->mDataSize; pDesMsg->pReply = pSrcMsg->pReply; return 0; } static int TMessageIncreaseIdleMessageList(message_queue_t* pThiz) { int ret = 0; message_t *pMsg; int i; for(i=0;imList, &pThiz->mIdleMessageList); } return ret; } MessageReply *ConstructMessageReply() { MessageReply *pReply = (MessageReply*)malloc(sizeof(MessageReply)); if(NULL == pReply) { aloge("fatal error! malloc fail."); } memset(pReply, 0, sizeof(MessageReply)); int ret = cdx_sem_init(&pReply->ReplySem, 0); if(ret != 0) { aloge("fatal error! cdx sem ini fail:%d", ret); } return pReply; } void DestructMessageReply(MessageReply *pReply) { if(pReply) { if(pReply->pReplyExtra) { free(pReply->pReplyExtra); pReply->pReplyExtra = NULL; pReply->nReplyExtraSize = 0; } cdx_sem_deinit(&pReply->ReplySem); free(pReply); } else { aloge("fatal error! reply is null"); } } int InitMessage(message_t *pMsg) { memset(pMsg, 0, sizeof(message_t)); return 0; } int message_create(message_queue_t* msg_queue) { //int i; int ret; alogv("msg create\n"); ret = pthread_mutex_init(&msg_queue->mutex, NULL); if (ret!=0) { return -1; } pthread_condattr_t condAttr; pthread_condattr_init(&condAttr); //#if defined(__LP64__) pthread_condattr_setclock(&condAttr, CLOCK_MONOTONIC); //#endif ret = pthread_cond_init(&msg_queue->mCondMessageQueueChanged, &condAttr); if(ret!=0) { aloge("[%s] fatal error! pthread cond init fail", strrchr(__FILE__, '/')+1); goto _err0; } msg_queue->mWaitMessageFlag = 0; //INIT_LIST_HEAD(&msg_queue->mMessageBufList); INIT_LIST_HEAD(&msg_queue->mIdleMessageList); INIT_LIST_HEAD(&msg_queue->mReadyMessageList); if(0!=TMessageIncreaseIdleMessageList(msg_queue)) { goto _err1; } msg_queue->message_count = 0; return 0; _err1: pthread_cond_destroy(&msg_queue->mCondMessageQueueChanged); _err0: pthread_mutex_destroy(&msg_queue->mutex); return -1; } void message_destroy(message_queue_t* msg_queue) { pthread_mutex_lock(&msg_queue->mutex); if(!list_empty(&msg_queue->mReadyMessageList)) { message_t *pEntry, *pTmp; list_for_each_entry_safe(pEntry, pTmp, &msg_queue->mReadyMessageList, mList) { alogd(" msg destroy: cmd[%x]mpData[%p]size[%d]", pEntry->command, pEntry->mpData, pEntry->mDataSize); if(pEntry->mpData) { free(pEntry->mpData); pEntry->mpData = NULL; } if(pEntry->pReply) { aloge("fatal error! MessageReply[%p] is not destroy? It should be destroyed out. check code!", pEntry->pReply); } pEntry->mDataSize = 0; list_move_tail(&pEntry->mList, &msg_queue->mIdleMessageList); msg_queue->message_count--; } } if(msg_queue->message_count != 0) { aloge(" fatal error! msg count[%d]!=0", msg_queue->message_count); } int cnt = 0; if(!list_empty(&msg_queue->mIdleMessageList)) { message_t *pEntry, *pTmp; list_for_each_entry_safe(pEntry, pTmp, &msg_queue->mIdleMessageList, mList) { list_del(&pEntry->mList); free(pEntry); cnt++; } } INIT_LIST_HEAD(&msg_queue->mIdleMessageList); INIT_LIST_HEAD(&msg_queue->mReadyMessageList); pthread_mutex_unlock(&msg_queue->mutex); pthread_cond_destroy(&msg_queue->mCondMessageQueueChanged); pthread_mutex_destroy(&msg_queue->mutex); } void flush_message(message_queue_t* msg_queue) { pthread_mutex_lock(&msg_queue->mutex); if(!list_empty(&msg_queue->mReadyMessageList)) { message_t *pEntry, *pTmp; list_for_each_entry_safe(pEntry, pTmp, &msg_queue->mReadyMessageList, mList) { alogd(" msg destroy: cmd[%x]mpData[%p]size[%d]", pEntry->command, pEntry->mpData, pEntry->mDataSize); if(pEntry->mpData) { free(pEntry->mpData); pEntry->mpData = NULL; } pEntry->mDataSize = 0; list_move_tail(&pEntry->mList, &msg_queue->mIdleMessageList); msg_queue->message_count--; } } if(msg_queue->message_count != 0) { aloge(" fatal error! msg count[%d]!=0", msg_queue->message_count); } pthread_mutex_unlock(&msg_queue->mutex); } /******************************************************************************* Function name: put_message Description: Do not accept mpData when call this function. Parameters: Return: Time: 2015/3/6 *******************************************************************************/ int put_message(message_queue_t* msg_queue, message_t *msg_in) { message_t message; memset(&message, 0, sizeof(message_t)); message.command = msg_in->command; message.para0 = msg_in->para0; message.para1 = msg_in->para1; message.mpData = NULL; message.mDataSize = 0; return putMessageWithData(msg_queue, &message); } int get_message(message_queue_t* msg_queue, message_t *msg_out) { pthread_mutex_lock(&msg_queue->mutex); if(list_empty(&msg_queue->mReadyMessageList)) { pthread_mutex_unlock(&msg_queue->mutex); return -1; } message_t *pMessageEntry = list_first_entry(&msg_queue->mReadyMessageList, message_t, mList); TMessageSetMessage(msg_out, pMessageEntry); list_move_tail(&pMessageEntry->mList, &msg_queue->mIdleMessageList); msg_queue->message_count--; pthread_mutex_unlock(&msg_queue->mutex); return 0; } int putMessageWithData(message_queue_t* msg_queue, message_t *msg_in) { int ret = 0; pthread_mutex_lock(&msg_queue->mutex); if(list_empty(&msg_queue->mIdleMessageList)) { alogw("idleMessageList are all used, malloc more, msgcmd:%d!", msg_in->command); //dumpCallStack("TMsg"); if(0!=TMessageIncreaseIdleMessageList(msg_queue)) { pthread_mutex_unlock(&msg_queue->mutex); return -1; } } message_t *pMessageEntry = list_first_entry(&msg_queue->mIdleMessageList, message_t, mList); if(0==TMessageDeepCopyMessage(pMessageEntry, msg_in)) { list_move_tail(&pMessageEntry->mList, &msg_queue->mReadyMessageList); msg_queue->message_count++; alogv(" new msg command[%d], para[%d][%d] pData[%p]size[%d]", pMessageEntry->command, pMessageEntry->para0, pMessageEntry->para1, pMessageEntry->mpData, pMessageEntry->mDataSize); if(msg_queue->mWaitMessageFlag) { pthread_cond_signal(&msg_queue->mCondMessageQueueChanged); } } else { ret = -1; } pthread_mutex_unlock(&msg_queue->mutex); return ret; } int get_message_count(message_queue_t* msg_queue) { int message_count; pthread_mutex_lock(&msg_queue->mutex); message_count = msg_queue->message_count; pthread_mutex_unlock(&msg_queue->mutex); return message_count; } int TMessage_WaitQueueNotEmpty(message_queue_t* msg_queue, unsigned int timeout) { int message_count; pthread_mutex_lock(&msg_queue->mutex); msg_queue->mWaitMessageFlag = 1; if(timeout <= 0) { while(list_empty(&msg_queue->mReadyMessageList)) { pthread_cond_wait(&msg_queue->mCondMessageQueueChanged, &msg_queue->mutex); } } else { if(list_empty(&msg_queue->mReadyMessageList)) { int ret = pthread_cond_wait_timeout(&msg_queue->mCondMessageQueueChanged, &msg_queue->mutex, timeout); if(ETIMEDOUT == ret) { //alogd(" pthread cond timeout np timeout[%d]", ret); } else if(0 == ret) { } else { aloge(" fatal error! pthread cond timeout np[%d]", ret); } } } msg_queue->mWaitMessageFlag = 0; message_count = msg_queue->message_count; pthread_mutex_unlock(&msg_queue->mutex); return message_count; }