/************** Begin of sharedmemory.c *******************************************/
#if defined(linux)  && defined(HAVE_SHM)
/***************************************************************************
|saharedmemory.c|  -  saharedmemory共享内存对象 自己定义的一些操作函数的实现文件
-------------------
begin                : |03-6-20|
modify               : |03-6-20|
copyright            : (C) |YEAR| by |wenhm(jesse)|
email                : |EMAIL|
***************************************************************************/
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <errno.h>
#include <string.h>
///#include "sharedmemory.h"

//创建或关键字为Key的含有大小为size的共享内存对象，并将共享内存对象id放于shmid中返回。
//若共享内存对象已存在则取得该对象
int create_sharedmemory(key_t key, int size)
{
	int shmid;

	printf("Attempting to create new sharde memory object whose size is %d\n",size);

	//int shmget(key_t key,int size,int shmflg); 
	if((shmid = shmget(key,size,IPC_CREAT|0666)) == -1)
	{
		fprintf(stderr, "shared memory object apply error:%s!\n",strerror(errno));
	}

	return shmid;
}

//创建关键字Key为IPC_PRIVATE(即关键字由系统选定)的含有大小为size的共享内存对象，并将共享内存对象id放于shmid中返回。
//因使用IPC_PRIVATE创建的共享内存的key都一样，所以key就不要了。
int create_sharedmemory_private(int size)
{
	int shmid;
	struct shmid_ds buf;

	printf("Attempting to create new sharde memory object whose size is %d\n",size);

	//int shmget(key_t key,int size,int shmflg); 
	if((shmid = shmget(IPC_PRIVATE,size,IPC_CREAT|0666)) == -1)
	{
		fprintf(stderr, "sharde memory object already exists!\n");
	}

	if(shmctl(shmid,IPC_STAT, &buf) == -1)
	{
		fprintf(stderr, "shmctl(shmid, IPC_STAT, buf) error!\n");//int shmget(key_t key,int size,int shmflg); 
	};

	return shmid;
}

//将共享内存attach到进程自己得空间内，函数返回指向映射内存的指针。
void *attach_sharedmemory(int shmid )
{
	return(shmat(shmid, 0, 0));
}

//将共享内存disattach，唯一的参数是共享内存映射的指针
//返回值： -1 on error: errno = EINVAL (Invalid attach address passed)
int disattach_sharedmemory(void* shm)
{
	return(shmdt((char*)shm));
}

//获取共享内存对象shmid的大小
int getsize_sharedmemory(int shmid)
{
	struct shmid_ds buf;

	if(shmctl(shmid,IPC_STAT, &buf) == -1)
	{
		fprintf(stderr, "shmctl(shmid, IPC_STAT, buf) error!\n");
	};

	return buf.shm_segsz;    
}

//删除共享内存对象
int del_sharedmemory(int shmid)
{ 
	/* 共享内存对象并不随程序的结束而被删除,如果我们没删除的话(将1改为0) 
	可以用ipcs命令查看到信号灯,用ipcrm可以删除共享内存对象的*/ 
	return shmctl(shmid,IPC_RMID,0); 
} 
#endif
/** 获取模块使用次数
@return long.
*/
long GetModuleUsage()
{
	long lModuleUsage = -1;
#if defined(linux ) && defined(HAVE_SHM)
	//以8个8来作为共享内存的key
#define  MODULE_USAGE_SHMKEY    88888888
	gs_iModuleUsage_shmid = create_sharedmemory(MODULE_USAGE_SHMKEY, sizeof(long));
	void *ptrModuleUsageBuffer = attach_sharedmemory(gs_iModuleUsage_shmid);

	if (NULL != ptrModuleUsageBuffer)
	{
		lModuleUsage = *(long *)ptrModuleUsageBuffer;

		///释放共享内存
		disattach_sharedmemory(ptrModuleUsageBuffer);
		///del_sharedmemory(gs_iModuleUsage_shmid);
	}		
#endif
	return lModuleUsage;
}

/** 设置模块使用次数
@return void.
*/
void SetModuleUsage(long lModuleUsage)
{
#if defined(linux ) && defined(HAVE_SHM)
	gs_iModuleUsage_shmid = create_sharedmemory(MODULE_USAGE_SHMKEY, sizeof(long));
	void *ptrModuleUsageBuffer = attach_sharedmemory(gs_iModuleUsage_shmid);

	if (NULL != ptrModuleUsageBuffer)
	{
		*(long *)ptrModuleUsageBuffer = lModuleUsage;

		///释放共享内存
		disattach_sharedmemory(ptrModuleUsageBuffer);
		///del_sharedmemory(gs_iModuleUsage_shmid);
	}
#endif
}

/** 释放使用的共享内存
@return void.
*/
void ReleaseModuleUsage()
{
#if defined(linux ) && defined(HAVE_SHM)
	long lModuleUsage = 0;
	gs_iModuleUsage_shmid = create_sharedmemory(MODULE_USAGE_SHMKEY, sizeof(long));
	void *ptrModuleUsageBuffer = attach_sharedmemory(gs_iModuleUsage_shmid);

	if (NULL != ptrModuleUsageBuffer)
	{
		lModuleUsage = *(long *)ptrModuleUsageBuffer;

		///释放共享内存
		disattach_sharedmemory(ptrModuleUsageBuffer);

		if (lModuleUsage == 0)
		{
			del_sharedmemory(gs_iModuleUsage_shmid);
		}
	}
#endif
}
/************** Begin of sharedmemory.c *******************************************/