📄 shmobjvector.cpp
字号:
/*
* this file provide obj pool realization
* composed by antony
* 2003-3-17
* copyright reserved
*/
/*
*last modified 2003-3-25
*still need to add code to realize search function
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include "shmobjvector.h"
#include "mylog.h"
#include "obj.h"
template <class st > shmobjvector<st>::shmobjvector(int ipckey,unsigned int count)
{
m_pCurContainer = NULL;
m_pShm = this->shmcreate(ipckey, count);
if(m_pShm == NULL)
{
mylog("shm init error");
assert(0);
}
this->m_pShmHead = (shmHead *)this->m_pShm;
if(m_pShmHead->maxPoolSize != count)
{
mylog("max num %d,req count %d",m_pShmHead->maxPoolSize, count);
assert(0);
}
//m_pCurContainer = m_pShmHead->shmStart;
this->asynInit(ipckey);
}
template <class st > shmobjvector<st>::~shmobjvector()
{
this->detach();
}
template <class st > bool shmobjvector<st>::setId(unsigned int id)
{
bool ret = false;
if(m_pShmHead->maxPoolSize >id)
{
ret = true;
m_pCurContainer = m_pShmHead->shmStart+ id;
}
else
{
m_pCurContainer = NULL;
mylog("id error");
}
return ret;
}
template <class st > char* shmobjvector<st>::shmcreate(int ipckey, unsigned int count)
{
int shmid = 0;
unsigned int i;
char *l_pShm = NULL;
container *l_pContainer = NULL;
key_t shmkey;
shmkey = ipckey;
unsigned int size = sizeof(shmHead)+count*sizeof(container);
mylog("shmkey:%d",shmkey);
shmid = shmget( shmkey, size, 0660 );
if( shmid < 0 ) {
shmid = shmget( shmkey, size, IPC_CREAT | 0660);
if( shmid < 0 )
return NULL;
l_pShm = (char *) shmat( shmid, NULL, 0 );
if( l_pShm == (void *)-1 )
return NULL;
((shmHead *)l_pShm)->maxPoolSize = count;
((shmHead *)l_pShm)->actPoolSize = 0;
/* m_pShm 未赋值 */
m_pShm = l_pShm;
((shmHead *)l_pShm)->shmStart =(container *)((char *)l_pShm+sizeof(shmHead));
((shmHead *)l_pShm)->shmEnd =((shmHead *)l_pShm)->shmStart+count;
l_pContainer = ((shmHead *)l_pShm)->shmStart;
for(i=0;i<count;i++)
{
l_pContainer->status = false;
l_pContainer++;
}
} else {
mylog("attaching shm");
l_pShm = (char *) shmat( shmid, NULL, 0 );
if( l_pShm == (char *)-1 )
return NULL;
}
return l_pShm;
}
template <class st > bool shmobjvector<st>::get(st *p_st)
{
bool ret = false;
if(m_pCurContainer != NULL)
{
if(m_pCurContainer->status == true)
{
ret = true;
mylog("get valid status");
this->asynStart();
memcpy( p_st, &m_pCurContainer->obj, sizeof(st));
this->asynEnd();
}
else
mylog("get invalid status");
}
else
{
mylog("init error");
}
return ret;
}
template <class st > bool shmobjvector<st>::put(st *p_st)
{
bool ret = false;
if(m_pCurContainer != NULL)
{
ret = true;
this->asynStart();
if(m_pCurContainer->status == true)
{
mylog("update status");
}
else
{
mylog("init status");
m_pCurContainer->status = true;
}
memcpy(&m_pCurContainer->obj, p_st, sizeof(st));
this->asynEnd();
}
else
{
mylog("init error");
}
return ret;
}
template <class st > void shmobjvector<st>::asynInit(int ipckey)
{
key_t semkey;
int value;
semkey = ipckey;
mylog("semkey=%d",semkey);
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);
value = semctl(m_iSemid,0, GETVAL, 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 shmobjvector<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 shmobjvector<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 shmobjvector<st>::detach()
{
if(m_pShm > (void *)0)
shmdt(m_pShm);
}
template <class st > bool shmobjvector<st>::isEmpty()
{
if(m_pShmHead->actPoolSize == 0)
return true;
else
return false;
}
/*
* just realize the following class
*/
template class shmobjvector<char>;
template class shmobjvector<int>;
template class shmobjvector<testObj>;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -