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

📄 shmobjlinkeq.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 "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 + -