64,648
社区成员
发帖
与我相关
我的任务
分享
#define MMSGQ_FLAG "MMSG"
#define MAX_MSG_SIZE (1024*1024*16) //最大消息长度为4M
#define MSGQ_OFFSET 10000
#include "hrx_thread.h"
#include "Memery.h"
/*
MMSGBlock Msg的总块数 每块512个字节 512M = 512*1024 块 50万块
MMSGQ 消息队列 消息队列的块数,起始块,末端块,消息队列的起始,消息队列的数量
*/
#define MAX_MSGQ_CNT 256 //消息队列数量
#define MAX_BLOCK_SIZE 1024 //每块大小
typedef struct
{
void * m_NextBlock; //Next block, 0 means the last block
unsigned int m_MsgFlag; //MsgFlag编号
unsigned int m_InTime; //Insert time
unsigned int m_MsgLength; //Length of the message
unsigned int m_DataLength; //The data length in this block
void * m_Data; //message body
}MMSG;
typedef struct
{
MMSG * m_FirstBlock; //第一个块
MMSG * m_LastBlock; //最后一个块
unsigned int m_BlockCount; //块的数量
unsigned int m_freeCount; //空闲块的数量
}MsgBlockInfo;
typedef struct
{
LOCK_INFOS m_Lock;
char m_Name[128];
unsigned int m_Status;
unsigned int m_QID; //每个消息队列的ID,在MsgQs[MAX_MSGQ_CNT]中的槽位
unsigned int m_CreateTime; //消息队列创建的时间
MsgBlockInfo m_Msginfo; //消息存储容器
MMSG * m_ReadCurrent; //当前读取的消息位置
MMSG * m_WriteCurrent; //当前写入的消息位置
unsigned int m_MsgCount; //本消息队列的中消息的条数
unsigned int m_MsgQSize; //消息队列大小
}MMSGQ;
typedef struct
{
LOCK_INFOS m_Lock;
char m_Flags[4]; //"MMSG"
char m_Name[128];
unsigned int m_Version;
unsigned int m_SysTime;
unsigned int m_TimeTicks;
unsigned int m_CreateTime;
MsgBlockInfo m_DBBlock;
MMSGQ m_MsgQs[MAX_MSGQ_CNT]; //消息队列区,最多可以创建MAX_MSGQ_CNT个消息队列
}MMSGQ_DCB; //MessageQ device control block
#define ERROR_MSGQ_NO1 -100 //内存没有建立或者容量不够
#define ERROR_MSGQ_NO2 -101 //初始化内存锁失败
#define ERROR_MSGQ_NO3 -102 //初始化消息队列锁失败
#define ERROR_MSGQ_NO4 -103 //枷锁失败
#define ERROR_MSGQ_NO5 -104 //消息队列已用完,初始化失败
#define ERROR_MSGQ_NO6 -105 //查找内容不在范围之内,或者传入的参数错误
#define ERROR_MSGQ_NO7 -106 //查找的内容已经作废
#define ERROR_MSGQ_NO8 -107 //消息队列味初始化
#define ERROR_MSGQ_NO9 -108 //消息队列已满
#define ERROR_MSGQ_N10 -109 //接收的容量不够
#define ERROR_MSGQ_N11 -110 //严重错误,数据已经混乱
static char* ERRORINFO[] = {
"内存没有建立或者容量不够",
"初始化内存锁失败",
"初始化消息队列锁失败",
"枷锁失败",
"消息队列已用完,初始化失败",
"查找内容不在范围之内,或者传入的参数错误",
"查找的内容已经作废",
"消息队列味初始化",
"消息队列已满",
"接收的容量不够",
"严重错误,数据已经混乱"
};
[code=c]
class HMMsgQ : public ShareMemery
{
public:
HMMsgQ(){};
~HMMsgQ(){};
//初始化MsgQ
int InitMsgQ()
{
char * sptr = (char*)GetPtr();
int size = GetSize();
if( sptr == NULL || size < 1024 + sizeof(MMSGQ_DCB) )
{
return ERROR_MSGQ_NO1; //内存没有建立或者容量不够
}
#ifdef HRX_LINUX
pthread_mutexattr_t mutexattr;
pthread_mutexattr_init(&mutexattr);
pthread_mutexattr_setpshared(&mutexattr,PTHREAD_PROCESS_SHARED);
#endif
MMSGQ_DCB * pp = (MMSGQ_DCB *)sptr;
char * data = sptr;
data += sizeof(MMSGQ_DCB);
data += MAX_BLOCK_SIZE;
int datalen = size - sizeof(MMSGQ_DCB) - MAX_BLOCK_SIZE;
int bcnt = datalen/(MAX_BLOCK_SIZE+sizeof(MMSG));
#ifdef HRX_NO_MEMERY
InitializeCriticalSection(&(pp->m_Lock.mutex));
#endif
#ifdef HRX_LINUX
if( pthread_mutex_init( &(pp->m_Lock.mutex), &mutexattr ) < 0 )
{
return ERROR_MSGQ_NO2; //初始化锁失败
}
#endif
pp->m_DBBlock.m_BlockCount = bcnt;
pp->m_DBBlock.m_freeCount = bcnt;
pp->m_DBBlock.m_FirstBlock = (MMSG*)data;
pp->m_DBBlock.m_LastBlock = (MMSG*)data;
data += sizeof(MMSG);
pp->m_DBBlock.m_FirstBlock->m_DataLength = 0;
pp->m_DBBlock.m_FirstBlock->m_MsgFlag = 0;
pp->m_DBBlock.m_FirstBlock->m_MsgLength = MAX_BLOCK_SIZE;
pp->m_DBBlock.m_FirstBlock->m_NextBlock = pp->m_DBBlock.m_FirstBlock;
pp->m_DBBlock.m_FirstBlock->m_InTime = 0;
pp->m_DBBlock.m_FirstBlock->m_Data = (void*)data;
data += MAX_BLOCK_SIZE;
MMSG * prev = pp->m_DBBlock.m_LastBlock;
for( int i = 1; i < bcnt; i++ )
{
MMSG * fp = (MMSG*)data;
data += sizeof(MMSG);
fp->m_DataLength = 0;
fp->m_MsgFlag = i;
fp->m_MsgLength = MAX_BLOCK_SIZE;
fp->m_NextBlock = pp->m_DBBlock.m_FirstBlock;
fp->m_InTime = 0;
fp->m_Data = (void*)data;
data += MAX_BLOCK_SIZE;
prev->m_NextBlock = (void*)fp;
prev = fp;
pp->m_DBBlock.m_LastBlock = fp;
}
for( int i = 0; i < MAX_MSGQ_CNT; i++ )
{
memset(pp->m_MsgQs[i].m_Name,0,sizeof(pp->m_MsgQs[i].m_Name));
pp->m_MsgQs[i].m_CreateTime = 0;
pp->m_MsgQs[i].m_Lock;
pp->m_MsgQs[i].m_MsgCount = 0;
pp->m_MsgQs[i].m_MsgQSize = 0;
pp->m_MsgQs[i].m_QID = i;
pp->m_MsgQs[i].m_Status = 0;
pp->m_MsgQs[i].m_Msginfo.m_BlockCount = 0;
pp->m_MsgQs[i].m_Msginfo.m_FirstBlock = NULL;
pp->m_MsgQs[i].m_Msginfo.m_freeCount = 0;
pp->m_MsgQs[i].m_Msginfo.m_LastBlock = NULL;
pp->m_MsgQs[i].m_ReadCurrent = NULL;
pp->m_MsgQs[i].m_WriteCurrent = NULL;
#ifdef HRX_NO_MEMERY
InitializeCriticalSection(&(pp->m_MsgQs[i].m_Lock.mutex));
#endif
#ifdef HRX_LINUX
if( pthread_mutex_init( &(pp->m_MsgQs[i].m_Lock.mutex), &mutexattr ) < 0 )
{
return ERROR_MSGQ_NO3; //初始化锁失败
}
#endif
}
return 0;
};
int InitMsgQ( char* name,int msgcnt )
{
char * sptr = (char*)GetPtr();
int size = GetSize();
if( sptr == NULL || size < 1024 + sizeof(MMSGQ_DCB) )
{
return ERROR_MSGQ_NO1;
}
MMSGQ_DCB * pp = (MMSGQ_DCB *)sptr;
#ifdef HRX_MEMERY
HrxTLockx_Event mksk( GetEventHandle(),200);
if( mksk.Lock() < 0 ) return ERROR_MSGQ_NO4;
#else
FUNCTION_LOCK slock(&(pp->m_Lock));
#endif
for( int i = 0; i < MAX_MSGQ_CNT; i++ )
{
if( pp->m_MsgQs[i].m_Status == 0 )
{
pp->m_MsgQs[i].m_CreateTime = time(0);
strcpy(pp->m_MsgQs[i].m_Name,name);
pp->m_MsgQs[i].m_MsgCount = 0;
pp->m_MsgQs[i].m_MsgQSize = msgcnt;
pp->m_MsgQs[i].m_QID = i;
pp->m_MsgQs[i].m_Status = 1;
pp->m_MsgQs[i].m_Msginfo.m_BlockCount = msgcnt;
pp->m_MsgQs[i].m_Msginfo.m_freeCount = msgcnt;
pp->m_MsgQs[i].m_Status = 1;
for(int j = 0; j < msgcnt; j++ )
{
MMSG * vp = NULL;
if( GetMMSG(&(pp->m_DBBlock),vp) < 0 ) break;
SetMMSG(&(pp->m_MsgQs[i].m_Msginfo),vp);
}
pp->m_MsgQs[i].m_ReadCurrent = pp->m_MsgQs[i].m_Msginfo.m_FirstBlock;
pp->m_MsgQs[i].m_WriteCurrent = pp->m_MsgQs[i].m_Msginfo.m_FirstBlock;
return i;
}
}
return ERROR_MSGQ_NO5;
};
int GetMMSG( MsgBlockInfo* pp,MMSG *& vp )
{
if( pp->m_BlockCount <= 0 ) return -1;
if( pp->m_freeCount <= 0 ) return -1;
vp = pp->m_FirstBlock;
MMSG * sp = (MMSG *)(pp->m_FirstBlock->m_NextBlock);
pp->m_FirstBlock = sp;
vp->m_NextBlock = NULL;
pp->m_freeCount -- ;
if( pp->m_freeCount == 0 )
{
pp->m_FirstBlock = NULL;
pp->m_LastBlock = NULL;
}
else
{
pp->m_LastBlock->m_NextBlock = pp->m_FirstBlock;
}
return 0;
};
int SetMMSG( MsgBlockInfo* pp,MMSG * vp )
{
if( pp->m_BlockCount == 0 )
{
pp->m_FirstBlock = vp;
pp->m_LastBlock = vp;
vp->m_NextBlock = pp->m_FirstBlock;
}
else
{
pp->m_LastBlock->m_NextBlock = vp;
pp->m_LastBlock = vp;
vp->m_NextBlock = pp->m_FirstBlock;
}
pp->m_BlockCount ++;
pp->m_freeCount ++;
return 0;
};
int GetMMSGID( char* name, int & id)
{
char * sptr = (char*)GetPtr();
int size = GetSize();
if( sptr == NULL || size < 1024 + sizeof(MMSGQ_DCB) )
{
return ERROR_MSGQ_NO1;
}
MMSGQ_DCB * pp = (MMSGQ_DCB *)sptr;
#ifdef HRX_MEMERY
HrxTLockx_Event mksk( GetEventHandle(),200);
if( mksk.Lock() < 0 ) return ERROR_MSGQ_NO4;
#else
FUNCTION_LOCK slock(&(pp->m_Lock));
#endif
for( int i = 0; i < MAX_MSGQ_CNT; i++ )
{
if( pp->m_MsgQs[i].m_Status != 0 && strcmp(pp->m_MsgQs[i].m_Name,name) == 0 )
{
id = i;
return i;
}
}
return ERROR_MSGQ_NO6;
};
int PrushBackMMSG( int MsgQid, char* buff, int len ) //放入消息队列
{
if( MsgQid < 0 || MsgQid >= MAX_MSGQ_CNT || buff == NULL ) return ERROR_MSGQ_NO6;
char * sptr = (char*)GetPtr();
int size = GetSize();
if( sptr == NULL || size < 1024 + sizeof(MMSGQ_DCB) )
{
return ERROR_MSGQ_NO1;
}
MMSGQ_DCB * pp = (MMSGQ_DCB *)sptr;
#ifdef HRX_MEMERY
HrxTLockx_Event mksk( GetEventHandle(),200);
if( mksk.Lock() < 0 ) return ERROR_MSGQ_NO4;
#else
FUNCTION_LOCK slock(&(pp->m_MsgQs[MsgQid].m_Lock));
#endif
if( pp->m_MsgQs[MsgQid].m_Status == 0 ) return ERROR_MSGQ_NO7;
if( pp->m_MsgQs[MsgQid].m_WriteCurrent == NULL ) return ERROR_MSGQ_NO8;
int cnt = len/MAX_BLOCK_SIZE+1;
if( pp->m_MsgQs[MsgQid].m_Msginfo.m_freeCount < cnt ) return ERROR_MSGQ_NO9;
int clen = len;
char * cbuff = buff;
for( int i = 0; i < cnt; i++ )
{
MMSG * curt = pp->m_MsgQs[MsgQid].m_WriteCurrent;
if( clen > MAX_BLOCK_SIZE )
{
memcpy( curt->m_Data, cbuff, MAX_BLOCK_SIZE);
curt->m_DataLength = MAX_BLOCK_SIZE;
curt->m_InTime = time(0);
curt->m_MsgFlag = cnt - i; //1 2 3
cbuff += MAX_BLOCK_SIZE;
clen -= MAX_BLOCK_SIZE;
}
else
{
memcpy( curt->m_Data, cbuff, clen);
curt->m_DataLength = clen;
curt->m_InTime = time(0);
curt->m_MsgFlag = cnt - i;
cbuff += clen;
clen -= clen;
}
pp->m_MsgQs[MsgQid].m_WriteCurrent = (MMSG *)curt->m_NextBlock;
pp->m_MsgQs[MsgQid].m_Msginfo.m_freeCount --;
}
return 1;
};
int PopFrontMMSG( int MsgQid, char* buff, int Maxlen ) //取出消息
{
if( MsgQid < 0 || MsgQid >= MAX_MSGQ_CNT || buff == NULL ) return ERROR_MSGQ_NO6;
char * sptr = (char*)GetPtr();
int size = GetSize();
if( sptr == NULL || size < 1024 + sizeof(MMSGQ_DCB) )
{
return ERROR_MSGQ_NO1;
}
MMSGQ_DCB * pp = (MMSGQ_DCB *)sptr;
#ifdef HRX_MEMERY
HrxTLockx_Event mksk( GetEventHandle(),200);
if( mksk.Lock() < 0 ) return ERROR_MSGQ_NO4;
#else
FUNCTION_LOCK slock(&(pp->m_MsgQs[MsgQid].m_Lock));
#endif
if( pp->m_MsgQs[MsgQid].m_Status == 0 ) return ERROR_MSGQ_NO7;
if( pp->m_MsgQs[MsgQid].m_ReadCurrent == NULL ) return ERROR_MSGQ_NO8;
if( pp->m_MsgQs[MsgQid].m_ReadCurrent->m_MsgFlag == 0 ) return 0; //没有消息
int cnt = pp->m_MsgQs[MsgQid].m_ReadCurrent->m_MsgFlag;
char * cbuff = buff;
int plen = 0;
for( int i = 0; i < cnt; i++ )
{
MMSG * curt = pp->m_MsgQs[MsgQid].m_ReadCurrent;
if( plen + curt->m_DataLength > Maxlen ) return ERROR_MSGQ_N10; //Maxlen 不够
if( curt->m_MsgFlag != cnt - i ) return ERROR_MSGQ_N11; //数据已经混乱
memcpy( cbuff, curt->m_Data, curt->m_DataLength );
cbuff += curt->m_DataLength;
plen += curt->m_DataLength;
pp->m_MsgQs[MsgQid].m_ReadCurrent = (MMSG *)curt->m_NextBlock;
pp->m_MsgQs[MsgQid].m_Msginfo.m_freeCount ++;
}
return 1;
};
char* GetErrInfo(int err)
{
return ERRORINFO[-err-100];
};
};
[/code]