📄 shmobjlinkeq.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 "shmobjlinkeq.h"
#include "mylog.h"
template <class st, class eq> shmobjlinkeq<st, eq>::shmobjlinkeq(int ipckey,unsigned int count)
{
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);
}
this->asynInit(ipckey);
}
template <class st, class eq> shmobjlinkeq<st, eq>::~shmobjlinkeq()
{
this->detach();
}
template <class st, class eq> char* shmobjlinkeq<st, eq>::shmcreate(int ipckey, unsigned int count)
{
int shmid = 0;
char *l_pShm = NULL;
key_t shmkey;
unsigned int size = sizeof(shmHead)+count*sizeof(container);
shmkey = ipckey;
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;
/* m_pShm 未赋值 */
m_pShm = l_pShm;
this->clearup();
} else {
mylog("attaching shm");
l_pShm = (char *) shmat( shmid, NULL, 0 );
if( l_pShm == (char *)-1 )
return NULL;
}
return l_pShm;
}
template <class st, class eq> bool shmobjlinkeq<st, eq>::get(st *p_st)
{
bool ret = false;
container *l_pCurContainer;
this->asynStart();
l_pCurContainer = m_pShmHead->first;
if( m_pShmHead->actPoolSize> 0)
{
ret = true;
memcpy(p_st, &l_pCurContainer->obj,sizeof(st));
l_pCurContainer->status = false;
m_pShmHead->first = l_pCurContainer->next;
m_pShmHead->last->next = m_pShmHead->first;
m_pShmHead->actPoolSize--;
}
else
{
mylog("error,pool size %d", m_pShmHead->actPoolSize);
}
this->asynEnd();
return ret;
}
template <class st, class eq> bool shmobjlinkeq<st, eq>::get(st *p_st, st *p_stIndext)
{
unsigned int loop;
bool ret = false;
container *l_pFirstContainer;
this->asynStart();
l_pFirstContainer = m_pShmHead->first;
for(loop=0;loop<m_pShmHead->actPoolSize;loop++)
{
if((m_pShmHead->first->obj) == *p_stIndext)
{
ret = true;
memcpy(p_st, &(m_pShmHead->first->obj),sizeof(st));
m_pShmHead->first->status = false;
m_pShmHead->first = m_pShmHead->first->next;
m_pShmHead->last->next = m_pShmHead->first;
m_pShmHead->actPoolSize--;
break;
}
this->moveNext();
}
this->asynEnd();
return ret;
}
template <class st, class eq> bool shmobjlinkeq<st, eq>::search(st *p_stIndext)
{
unsigned int loop;
bool ret = false;
container *l_pFirstContainer;
this->asynStart();
l_pFirstContainer = m_pShmHead->first;
for(loop=0;loop<m_pShmHead->actPoolSize;loop++)
{
if((m_pShmHead->first->obj) == *p_stIndext)
{
ret = true;
break;
}
this->moveNext();
}
this->asynEnd();
return ret;
}
template <class st, class eq> bool shmobjlinkeq<st, eq>::put(st *p_st)
{
bool ret = false;
container *l_pCrusingContainer = m_pShmHead->first;
this->asynStart();
if(m_pShmHead->actPoolSize< m_pShmHead->maxPoolSize)
{
while(l_pCrusingContainer != m_pShmHead->shmEnd )
{
if(l_pCrusingContainer->status == false)
break;
l_pCrusingContainer = l_pCrusingContainer ++;
}
if(l_pCrusingContainer != m_pShmHead->shmEnd)
{
ret = true;
l_pCrusingContainer->status = true;
memcpy(&(l_pCrusingContainer->obj), p_st, sizeof(st));
l_pCrusingContainer->next = m_pShmHead->first;
m_pShmHead->first = l_pCrusingContainer;
m_pShmHead->last->next = m_pShmHead->first;
m_pShmHead->actPoolSize ++;
mylog("after put,size %d", m_pShmHead->actPoolSize);
}
else
{
mylog("reach no space found");
}
}
else
{
mylog("pool is full");
}
this->asynEnd();
return ret;
}
template <class st, class eq> void shmobjlinkeq<st, eq>::clearup()
{
shmHead *l_pShmHead = (shmHead *)this->m_pShm;
container *l_pCrusingContainer = (container *)(this->m_pShm+sizeof(shmHead));
this->asynStart();
l_pShmHead->actPoolSize = 0;
l_pShmHead->shmStart = (container *)(this->m_pShm+sizeof(shmHead));
l_pShmHead->first = l_pShmHead->shmStart;
l_pShmHead->last = l_pShmHead->shmStart;
l_pShmHead->shmEnd = l_pShmHead->shmStart+l_pShmHead->maxPoolSize;
while(l_pCrusingContainer != l_pShmHead->shmEnd)
{
l_pCrusingContainer->status = false;
l_pCrusingContainer->next = NULL;
l_pCrusingContainer = l_pCrusingContainer++;
}
this->asynEnd();
}
template <class st, class eq> bool shmobjlinkeq<st, eq>::moveNext()
{
bool ret = false;
shmHead *l_pShmHead = (shmHead *)m_pShm;
//this->asynStart();
if(l_pShmHead->first->next != NULL)
{
ret = true;
l_pShmHead->last = l_pShmHead->first;
l_pShmHead->first = l_pShmHead->last->next;
}
//this->asynEnd();
return ret;
}
template <class st, class eq> void shmobjlinkeq<st, eq>::delCur()
{
}
template <class st, class eq> void shmobjlinkeq<st, eq>::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, class eq> void shmobjlinkeq<st, eq>::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, class eq> void shmobjlinkeq<st, eq>::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, class eq> void shmobjlinkeq<st, eq>::detach()
{
if(m_pShm > (void *)0)
shmdt(m_pShm);
}
template <class st, class eq> bool shmobjlinkeq<st, eq>::isEmpty()
{
if(m_pShmHead->actPoolSize == 0)
return true;
else
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -