#ifndef MSG_CONSTANT_H
#define MSG_CONSTANT_H
#define MAX_MSG_PARA_SIZE 2048 /*訊息參數大小*/
#define MAX_QUEUE_LENGTH 3000 /*隊列限制長度*/
#define EVENTMSG_QUIT 100 /*退出*/
#define RW_SUCCESS 0
#define EMPTY_QUE 1
#define RW_ERROR_QUE -1
#define FULL_QUE -2
#define LOCK_ERROR -3
#define UNLOCK_ERROR -4
#define REALESE_LOCK_ERROR -5
#define UN_INI -6
#define PER_BUFF_LENGTH 1000 /*訊息輸入緩衝區大小(條)*/
/*!
*
* 定義訊息映射段內項目的宏 參考MFC 訊息映射機制
*/
/*訊息處理函數調用時,加上this,必須是訊息機的成員函數*/
#define MSG_MAP_FUN(MSG_CODE,MSG_ACTION_FUN) case MSG_CODE:this->MSG_ACTION_FUN(msg);break;
/*實現訊息轉寄到其他訊息處理對象指標,用於某些訊息需要長時間處理的情況,接受對象必須為msg_machine的子類*/
#define MSG_MAP_OBJ(MSG_CODE,MSG_ACTION_OBJ) case MSG_CODE:SendMessage(msg,MSG_ACTION_OBJ);break;
/*!訊息映射宏
*
* BEGIN_MSG_MAP為定義訊息映射段開始的宏
* 訊息映射段必須出現在類體內,不是實現部分
*形式如下
* BEGIN_MSG_MAP
* MSG_MAP_FUN(message code ,member function that must return void and have a Msg type parameter)
* MSG_MAP_OBJ(message code ,message machine class instance)
* END_MSG_MAP
*/
#define BEGIN_MSG_MAP virtual void Dispatch(struct Msg msg) \
{ \
\
unsigned int msg_code; \
msg_code=msg.msg_code; \
switch(msg_code) \
{
/*!
*
* 定義訊息映射段結束的宏
*/
#define END_MSG_MAP(base) default: \
base::Dispatch(msg); \
break; \
}\
}
#endif
- #ifndef MESSAGE_STRUCT_H
- #define MESSAGE_STRUCT_H
- #ifdef _cplusplus
- extern "C"
- {
- #include <pthread.h>
- #include <semaphore.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- }
- #endif //_cplusplus
- #include "msg_macro.h"
- typedef unsigned char u_char;
- struct Msg
- {
- unsigned int msg_code; // Message Code
- u_char msg_para[MAX_MSG_PARA_SIZE]; // Message Parameter
- };
- class Msg_queue
- {
- public:
- Msg_queue(){ initialized=false; };
- ~Msg_queue();
- int Initialize();
- int GetHead(struct Msg *p_msg);
- int AddTail(struct Msg *p_msg);
- private:
- pthread_mutex_t mutex_wr;
- bool initialized;
- int msg_count;
- int head;
- int tail;
- struct Msg msg_array[MAX_QUEUE_LENGTH];
- };
- #endif // MESSAGE_STRUCT_H
複製代碼
- #include "msg.h"
- extern "C"
- {
- #include <error.h>
- #include <errno.h>
- }
- int Msg_queue::Initialize()
- {
- int error;
- if(initialized)return 0;
- error=pthread_mutex_init(&mutex_wr,NULL);
- switch(error){
- case EAGAIN: initialized=false; return -1;
- case ENOMEM: initialized=false; return -2;
- case EPERM: initialized=false; return -3;
- }
- initialized=true;
- msg_count=0;
- head=0;
- tail=0;
- memset(msg_array,0,sizeof(msg_array));
- return 0;
- }
- int Msg_queue::GetHead(struct Msg *p_msg)
- {
- int result;
- int error;
- if(!initialized)return UN_INI;
- if(p_msg==NULL) return RW_ERROR_QUE;
- if(error=pthread_mutex_lock(&mutex_wr))
- return -3;//取鎖失敗
- if(msg_count>0)
- {
- memcpy((void*)p_msg,(void*)&msg_array[head],sizeof(struct Msg));
- memset((void*)&msg_array[head],0,sizeof(struct Msg));
- head++;
- if(head==MAX_QUEUE_LENGTH)head=0;
- msg_count--;
- result= RW_SUCCESS;
- }
- else
- {
- p_msg->msg_code=EMPTY_QUE;
- result=EMPTY_QUE;
- }
- if(error=pthread_mutex_unlock(&mutex_wr))
- return -4;//解鎖失敗
- return result;
- }
- int Msg_queue::AddTail(struct Msg *p_msg)
- {
- int ilock;
- int result;
- int error;
- if(p_msg==NULL)return RW_ERROR_QUE;
- if(!initialized)return UN_INI;
- if(error=pthread_mutex_lock(&mutex_wr))
- return -3;
- if(msg_count<MAX_QUEUE_LENGTH)
- {
- memcpy((void*)&msg_array[tail],(void*)p_msg,sizeof(struct Msg));
- tail++;
- if(tail==MAX_QUEUE_LENGTH)
- tail=0;
- msg_count++;
- result=RW_SUCCESS;
- }
- else
- result=FULL_QUE;
- if(error=pthread_mutex_unlock(&mutex_wr))
- result=-4;
- return result;
- }
- Msg_queue::~Msg_queue()
- {
- pthread_mutex_destroy(&mutex_wr);
- }
複製代碼
- #ifndef MSGMACHINE_H
- #define MSGMACHINE_H
- #include "msg.h"
- #include "msg_macro.h"
- #include "msg_input_buf.h"
- #ifdef _cplusplus
- extern "C"
- {
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <signal.h>
- #include <unistd.h>
- }
- #endif //_cplusplus
- //-----------------------------------------------------------------------------
-
- class MsgMachine
- {
- public:
- bool cmd_run;
- MsgMachine();
- virtual ~MsgMachine();
- void Msg_Deal_Loop();
- /*從各一緩衝區讀訊息到訊息佇列,非同步檢查某個緩衝區是否可讀*/
- int ReadInputBuf(InputBuff *pbuff) ;
- /*!
- *啟動訊息迴圈處理線程
- *字類如果改寫Execute,必須調用父類的Execute才能啟動訊息處理迴圈
- */
- virtual void Dispatch(struct Msg msg)
- {
- unsigned int msg_code;
- msg_code=msg.msg_code;
- switch(msg_code)
- {
- default:break;
- }
- }
- private:
- bool DetectorActive;
- Msg_queue *pMsg_que;
-
- };
-
- #endif // MSGMACHINE_H
複製代碼
- #include "msg_machine.h"
- MsgMachine::~MsgMachine()
- {
- delete pMsg_que;
- }
- MsgMachine::MsgMachine()
- {
- pMsg_que=new Msg_queue;
- if(pMsg_que->Initialize()==-1)
- {
- delete pMsg_que;
- //printf("Initialize message queue error!\n");
- //u_log("Initialize message queue error!\n");
- exit(-1);
- }
- DetectorActive=true;
- }
- void MsgMachine::Msg_Deal_Loop()
- {
- struct Msg msg;
- while(cmd_run)
- {
-
- if(pMsg_que->GetHead(&msg)==0)
- {
- if(msg.msg_code==EVENTMSG_QUIT)
- break;
- Dispatch(msg);
- }
- else
- continue;
- }
- }
- int MsgMachine::ReadInputBuf(InputBuff *pbuff)
- {
- struct Msg msg;
-
- if(pbuff->Read(&msg)==0)
- {
- if(pMsg_que->AddTail(&msg)==RW_SUCCESS)
- {
- return 0;
- }
- else
- return -1;
- }
- else
- {
- return -1;
- }
- }
複製代碼
以上是偶們的某個項目(Redhat Linux下C++開發實現與某Portal Server的基於UDP訊息的介面
的daemon,參考MFC的訊息映射機制,目前已經實現,上述代碼給大家參考,請多多指教