/************** 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 *******************************************/