📄 shmobjqueue.cpp
字号:
/*
* this file provide obj queue in share memory realization
* composed by antony
* 2003-3-17
* copyright reserved
*/
/*
*m_ppObjLast modified 2003-3-18
*still need to add code to maintain shm consistent
*/
//modified by antony 2003-03-23
//change shm create mode
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include "shmobjqueue.h"
#include "mylog.h"
template <class st > shmobjqueue<st>::shmobjqueue(int ipckey,int num)
{
m_ipckey = ipckey;
mylog("init queue shmobjqueue key=%x", ipckey);
this->m_iObjSize = sizeof(st);
//m_pShm = this->shmcreate(shmfilename, proj_id, num*this->m_iObjSize +sizeof(int)*4);
m_pShm = this->shmcreate(ipckey, num);
if(m_pShm == NULL)
{
assert(0);
}
this->m_piMaxPoolSize = (int *)m_pShm;
if(*this->m_piMaxPoolSize != num)
{
mylog("pool size actual size:%d,reques size:%d",*this->m_piMaxPoolSize,num);
assert(0);
}
this->m_piPoolSize = (int *)((char *)this->m_piMaxPoolSize+sizeof(this->m_piMaxPoolSize));
this->m_ppObjFirst = (st **)((char *)this->m_piPoolSize+sizeof(this->m_piPoolSize));
this->m_ppObjLast = (st **)((char *)this->m_ppObjFirst+sizeof(this->m_ppObjFirst));
this->m_pMemStart = (st *)((char *)this->m_ppObjLast+ sizeof(this->m_ppObjLast));
this->m_pMemEnd = (st *)(this->m_pMemStart + *(this->m_piMaxPoolSize));
this->asynInit(ipckey);
}
template <class st > shmobjqueue<st>::~shmobjqueue()
{
mylog("destruct[%x]",m_ipckey);
this->detach();
}
template <class st > char* shmobjqueue<st>::shmcreate(int ipckey, unsigned long num)
{
int shmid = 0;
int size;
key_t shmkey;
if(num != 0)
size = num*this->m_iObjSize +sizeof(int)*4;
else
size = 0;
shmkey = ipckey;
shmid = shmget( shmkey, size, 0640 );
if( shmid < 0 ) {
shmid = shmget( shmkey, size, IPC_CREAT | 0640);
if( shmid < 0 )
return NULL;
m_pShm = (char *) shmat( shmid, NULL, 0 );
if( m_pShm == (char *)-1 )
return NULL;
memset( m_pShm, 0, size );
*(int *)m_pShm = num;
*(int *)((int)m_pShm+sizeof(int)) = 0;
*(void **)((int)m_pShm+sizeof(int)*2) = (void *)((int)m_pShm + sizeof(int)*4);
*(void **)((int)m_pShm+sizeof(int)*3) = (void *)((int)m_pShm + sizeof(int)*4);
} else {
mylog("attaching shm");
m_pShm = (char *) shmat( shmid, NULL, 0 );
if( m_pShm == (void *)-1 )
{
mylog("error:%s",strerror(errno));
return NULL;
}
}
return m_pShm;
}
template <class st > bool shmobjqueue<st>::get(st *p_st)
{
bool ret;
this->asynStart();
mylog("before get,pool size=%d",*this->m_piPoolSize);
if( *this->m_piPoolSize <0)
{
ret = false;
mylog("m_piPoolSize error:%d", *this->m_piPoolSize);
//force to clearup;
this->clearup();
}
else if(*this->m_piPoolSize == 0)
{
ret = false;
mylog("pool is empty");
if(*this->m_ppObjFirst != *this->m_ppObjLast )
{
mylog("consistent error");
}
}
else
{
ret = true;
(*this->m_piPoolSize)--;
memcpy(p_st, *this->m_ppObjFirst, sizeof(st));
*this->m_ppObjFirst = (st *)((char *)*this->m_ppObjFirst+this->m_iObjSize );
//reach m_pMemEnd,loop to m_pMemStart point
if(*this->m_ppObjFirst == this->m_pMemEnd)
*this->m_ppObjFirst = this->m_pMemStart;
if(*this->m_ppObjFirst == *this->m_ppObjLast)
{
*this->m_piPoolSize = 0;
}
}
mylog("after get,pool size=%d",*this->m_piPoolSize);
this->asynEnd();
return ret;
}
template <class st > bool shmobjqueue<st>::put(st *p_st)
{
bool ret;
this->asynStart();
mylog("before put,pool size=%d",*this->m_piPoolSize);
if(*this->m_piPoolSize >*this->m_piMaxPoolSize)
{
mylog("pool size error,max size:%d,actual size:%d",
*this->m_piMaxPoolSize,*this->m_piPoolSize);
ret = false;
}
else if(*this->m_piPoolSize ==*this->m_piMaxPoolSize)
{
ret = false;
mylog("pool is full,max size:%d",*this->m_piMaxPoolSize);
if(*this->m_ppObjFirst != *this->m_ppObjLast )
{
mylog("consistent error");
}
}
else
{
ret = true;
memcpy(*this->m_ppObjLast,p_st, sizeof(st));
*this->m_ppObjLast = (st *)((char *)*this->m_ppObjLast+this->m_iObjSize );
if(*this->m_ppObjLast == this->m_pMemEnd)
*this->m_ppObjLast = this->m_pMemStart;
(*this->m_piPoolSize)++;
}
mylog("after put,pool size=%d",*this->m_piPoolSize);
this->asynEnd();
return ret;
}
template <class st > void shmobjqueue<st>::clearup()
{
this->asynStart();
*this->m_ppObjFirst = this->m_pMemStart;
*this->m_ppObjLast = this->m_pMemStart;
*this->m_piPoolSize = 0;
this->asynEnd();
}
template <class st > void shmobjqueue<st>::asynInit(int ipckey)
{
key_t semkey;
int value;
semkey = ipckey;
m_iSemid = semget(semkey, 0, 0640);
if(m_iSemid <0)
{
m_iSemid = semget(semkey, 1, IPC_CREAT|0640);
if(m_iSemid<0)
{
mylog("error:%s",strerror( errno ));
}
arg.val = 1;
value = semctl(m_iSemid,0, SETVAL, arg);
mylog("create sem value=%d",value);
return;
}
else
{
value = semctl(m_iSemid,0, GETVAL, arg);
mylog("sem exist,value=%d",value);
return;
}
}
template <class st > void shmobjqueue<st>::asynStart()
{
struct sembuf sops;
int value;
sops.sem_num=0;
sops.sem_op=-1;
sops.sem_flg=0;
// value=semctl(m_iSemid,sops.sem_num,GETVAL,0);
// mylog("before AsyStart %d", value);
value = semop(m_iSemid,&sops,1);
// mylog("after AsyStart %d", value);
return;
}
template <class st > void shmobjqueue<st>::asynEnd()
{
struct sembuf sops;
int value;
sops.sem_num=0;
sops.sem_op=1;
sops.sem_flg=0;
// value=semctl(m_iSemid,sops.sem_num,GETVAL,0);
// mylog("before AsyEnd %d", value);
value = semop(m_iSemid,&sops,1);
// value=semctl(m_iSemid,sops.sem_num,GETVAL,0);
// mylog("after AsyEnd %d", value);
return;
}
template <class st > void shmobjqueue<st>::detach()
{
if(m_pShm > (void *)0)
shmdt(m_pShm);
mylog("ipckey=%x", m_ipckey);
}
template <class st > bool shmobjqueue<st>::isEmpty()
{
if(*(this->m_piPoolSize) == 0)
return true;
else
return false;
}
template <class st > int shmobjqueue<st>::getSize()
{
int l_size;
asynStart();
l_size = *m_piPoolSize;
asynEnd();
return l_size;
}
template <class st > bool shmobjqueue<st>::isFull()
{
bool l_bRet;
asynStart();
l_bRet = (*m_piPoolSize == *m_piMaxPoolSize);
asynEnd();
return l_bRet;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -