www.pudn.com > tvctrl.rar > shmem.c


#include   
#include   
#include   
#include   
  
#include   
#include   
  
#include "tvmisc.h"  
  
#define SHMEMCTRL_TAG "SHMEMCTRL_TAG"  
  
typedef struct tagShareMemCtrlHead  
{  
	char 	tag[16] ;  
	int		usercount ;  
	int		status ;  
	int		memoff ;  
	int		memsize ;  
} ShareMemCtrlHead_t, *pShareMemCtrlHead_t ;  
  
typedef struct tagShareMemCtrl  
{  
	char 	tag[16] ;  
	int		key ;  
	int		size ;  
	int		shmid ;  
	void	*shmem ;  
} ShareMemCtrl_t, *pShareMemCtrl_t ;  
  
static int TagValid(char *tag) ;  
  
static int TagValid(char *tag)  
{  
	int result = 0 ;  
	  
	if (tag  
		&& strncmp(tag, SHMEMCTRL_TAG) == 0  
		)  
		result = 1 ;  
		  
	return (result) ;  
}  
  
int ShareMemOpen(int key, size_t size, char *tag, int *status)  
{  
	int result = 0 ;  
	int shmid ;  
	size_t sizehead = sizeof(ShareMemCtrlHead_t) ;  
	ShareMemCtrl_t *p ;  
	ShareMemCtrlHead_t *ph ;  
	  
	if (key > 0  
		&& size > 0  
		)  
	{  
		shmid = shmget(key, size+sizehead, IPC_CREAT|IPC_EXCL) ;  
		if (shmid == -1  
			&& errno == EEXIST  
			&& ((shmid = shmget(key, size+sizehead, 0)) != -1)  
			&& (ph = (ShareMemCtrlHead_t *)shmat(shmid, 0, 0))  
			)  
		{  
#ifdef __DEBUG__  
			printf("share memory already exist \n") ;  
#endif  
			p = (ShareMemCtrl_t *)malloc(sizeof(ShareMemCtrl_t)) ;  
			if (p)  
			{  
				memset(p, 0x00, sizeof(ShareMemCtrl_t)) ;  
				strncpy(p->tag, SHMEMCTRL_TAG, sizeof(p->tag)-1) ;  
				p->key = key ;  
				p->size = ph->memsize ;  
				p->shmid = shmid ;  
				p->shmem = (void *)ph ;  
				ph->usercount++ ;  
				if (status) *status = ph->usercount ;  
				result = (int)p ;  
			}  
		}  
		else if (shmid != -1  
					&& (ph = (ShareMemCtrlHead_t *)shmat(shmid, 0, 0))  
					) /* created share memory */  
		{  
#ifdef __DEBUG__  
			printf("now created share memory() \n") ;  
#endif  
			p = (ShareMemCtrl_t *)malloc(sizeof(ShareMemCtrl_t)) ;  
			if (p)  
			{  
				memset(ph, 0x00, sizeof(ShareMemCtrlHead_t)) ;  
				if (tag) strncpy(ph->tag, tag, sizeof(ph->tag)-1) ;  
				ph->memoff = sizeof(ShareMemCtrlHead_t) ;  
				ph->memsize = (int)size ;  
				  
				memset(p, 0x00, sizeof(ShareMemCtrl_t)) ;  
				strncpy(p->tag, SHMEMCTRL_TAG, sizeof(p->tag)-1) ;  
				p->key = key ;  
				p->size = ph->memsize ;  
				p->shmid = shmid ;  
				p->shmem = (void *)ph ;  
				ph->usercount++ ;  
				if (status) *status = ph->usercount ;  
				result = (int)p ;  
			}  
		}  
		else  
		{  
#ifdef __DEBUG__  
			printf("ShareMemOpen() error \n") ;  
#endif  
		}  
	}  
	  
	return (result) ;  
}  
  
int ShareMemClose(int handle)  
{  
	int result = -1 ;  
	ShareMemCtrl_t *p = (ShareMemCtrl_t *)handle ;  
	  
	if (p  
		&& TagValid(p->tag)  
		&& p->shmem  
		)  
	{  
		ShareMemCtrlHead_t *ph = (ShareMemCtrlHead_t *)p->shmem ;  
		  
		if (ph->usercount > 0)  
		{  
			ph->usercount-- ;  
			/* ÊͷʲÏíÄÚ´æ */  
			if (ph->usercount <= 0)  
			{  
				shmdt((void *)p->shmem) ;  
				shmctl(p->shmid, IPC_RMID, NULL) ;  
			}	  
		}  
		memset(p, 0x00, sizeof(ShareMemCtrl_t)) ;  
		free(p) ;  
		result = 0 ;  
	}  
	  
	return (result) ;  
}  
  
int ShareMemGetSize(handle)  
{  
	int result = 0 ;  
	ShareMemCtrl_t *p = (ShareMemCtrl_t *)handle ;  
	  
	if (p  
		&& TagValid(p->tag)  
		&& p->shmem  
		)  
	{  
		result = p->size ;	  
	}  
	  
	return (result) ;  
}  
  
void *ShareMemGetStartAddr(int handle)  
{  
	void *result = NULL ;  
	ShareMemCtrl_t *p = (ShareMemCtrl_t *)handle ;  
	  
	if (p  
		&& TagValid(p->tag)  
		&& p->shmem  
		)  
	{  
		ShareMemCtrlHead_t *ph = (ShareMemCtrlHead_t *)p->shmem ;  
		  
		result = (void *)((char *)p->shmem + ph->memoff) ;  
	}  
	  
	return (result) ;  
}