⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shmobjvector.cpp

📁 uclinux的进程间通信例子
💻 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 + -