123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420 |
- // libsharememory.cpp : 定义 DLL 应用程序的导出函数。
- //
- #include "stdafx.h"
- #include "libsharememory.h"
- #include <stdio.h>
- //#include "SpBase.h"
- //#define TESTSHAREMEM 0
- void Debug(const char* fmt, ...)
- {
- // char strfmt[512] = { 0 };
- // va_list args;
- // va_start(args, fmt);
- // vsprintf(strfmt, fmt, args);
- //#ifdef TESTSHAREMEM
- // printf("%s\n", strfmt);
- //#else
- // Dbg("%s", strfmt);
- //#endif
- // va_end(args);
- // fflush(stdout);
- }
- class libsharememory_impl
- {
- protected:
- unsigned int m_dwBytes;
- bool m_bLocked;
- void* m_pData;
- //HANDLE m_hFile;
- #ifdef RVC_OS_WIN
- HANDLE m_hFileMap;
- HANDLE m_hMutex;
- #else
- //void* m_hFileMap;
- int m_shid;
- sem_t* m_semt;
- char m_strsemname[MAX_PATH];
- char m_strshmname[MAX_PATH];
- #endif // RVC_OS_WIN
- public:
- libsharememory_impl()
- {
- m_pData=NULL;
- m_bLocked = false;
- #ifdef RVC_OS_WIN
- m_hFileMap = NULL;
- m_hMutex = NULL;
- #else
- m_shid = -1;
- m_semt = NULL;
- memset(m_strsemname, 0, MAX_PATH);
- memset(m_strshmname, 0, MAX_PATH);
- #endif // RVC_OS_WIN
- m_dwBytes=0;
- }
- ~libsharememory_impl()
- {
- CloseShareMem();
- }
- #ifdef RVC_OS_WIN
- #else
- bool CreateShareMemLinux(const char* szName, unsigned int dwBytes)
- {
- bool bRet = false;
- if (szName != NULL && dwBytes > 0) {
- char szBuf[MAX_PATH] = {0};
- const char* szFile = tmpnam(szBuf);
- if (szFile != NULL) {
- snprintf(m_strshmname, MAX_PATH, "%s", szName);
- snprintf(m_strsemname, MAX_PATH, "/mutex.%s", szName);
- m_shid = shm_open(szName, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
- if (m_shid >= 0) {
- //Debug("%s:%d shm_open O_CREAT|O_RDWR|O_EXCL success and share memory %s and size is %d", __FUNCTION__, __LINE__, szName, dwBytes);
- }
- else {
- //Debug("%s:%d shm_open O_CREAT|O_RDWR|O_EXCL %s failed for %s, and errno is %d", __FUNCTION__, __LINE__, m_strshmname, strerror(errno), errno);
- if (EEXIST == errno) {
- m_shid = shm_open(szName, O_RDWR, 0);
- }
- }
-
- if (m_shid >= 0){
- if (NULL == m_pData){
- ftruncate(m_shid, dwBytes);
- m_pData = mmap(NULL, dwBytes, PROT_READ | PROT_WRITE, MAP_SHARED, m_shid, 0);
- if (MAP_FAILED != m_pData) {
- *((LPDWORD)m_pData) = dwBytes;
- m_dwBytes = dwBytes;
- sem_t* semt = sem_open(m_strsemname, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, 1);
- if (NULL == semt) {
- if (EEXIST == errno) {
- semt = sem_open(m_strsemname, 0);
- sem_init(semt,32, 1);
- }
- }
- if (NULL != semt) {
- m_semt = semt;
- int ivalue = -1;
- sem_getvalue(m_semt, &ivalue);
- bRet = true;
- }
- }
- }
- }
- }
- }
- return bRet;
- }
- #endif
- //创建共享内存区
- bool CreateShareMem(const char* szName, unsigned int dwBytes)
- {
- bool T =false;
- #ifdef RVC_OS_WIN
- char szBuf[MAX_PATH];
- const char* szFile;
- if (szName != NULL && dwBytes > 0)
- {
- CloseShareMem();
- szFile = tmpnam(szBuf);
- if (szFile != NULL)
- {
- m_hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, dwBytes + sizeof(unsigned int) + sizeof(int), szName);
- if (m_hFileMap != NULL)
- {
- m_dwBytes = dwBytes;
- m_pData = MapViewOfFile(m_hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
- if (m_pData != NULL)
- {
- *((LPDWORD)m_pData) = dwBytes;
- //*((int*)((LPDWORD)m_pData+1))= ++m_nEntityNum;
- sprintf_s(szBuf, "Mutex<%s>", szName);
- m_hMutex = CreateMutex(NULL, false, szBuf);
- if (m_hMutex != NULL)
- {
- if (GetLastError() != ERROR_ALREADY_EXISTS)
- {
- T = true;
- }
- }
- }
- }
- if (!T)
- {
- CloseShareMem();
- }
- }
- }
- #else
- T = CreateShareMemLinux(szName, dwBytes);
- #endif // RVC_OS_WIN
- return T;
- }
- //打开已有的共享内存区
- bool OpenShareMem(const char* szName)
- {
- bool T=false;
- #ifdef RVC_OS_WIN
- char szBuf[MAX_PATH];
- if (szName != NULL)
- {
- CloseShareMem();
- m_hFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, szName);
- if (m_hFileMap != NULL)
- {
- sprintf_s(szBuf, "Mutex<%s>", szName);
- m_hMutex = OpenMutex(MUTEX_ALL_ACCESS, false, szBuf);
- if (m_hMutex != NULL)
- {
- m_pData = MapViewOfFile(m_hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
- if (LockShareMem())
- {
- m_dwBytes = *((LPDWORD)m_pData);
- //m_nEntityNum = *((int*)((LPDWORD)m_pData+1));
- //*((int*)((LPDWORD)m_pData+1)) = ++m_nEntityNum;
- UnlockShareMem();
- if (m_dwBytes > 0)
- {
- T = true;
- }
- }
- }
- }
- if (!T)
- {
- CloseShareMem();
- }
- }
- #else
- if (szName != NULL) {
- int shid = shm_open(szName, O_RDWR, 0);
- if (-1 != shid) {
- m_shid = shid;
- sem_t* semt = sem_open(m_strsemname, 0);
- if (SEM_FAILED != semt){
- m_semt = semt;
- int ivalue = -1;
- sem_getvalue(semt, &ivalue);
- m_pData = mmap(NULL, m_dwBytes, PROT_READ | PROT_WRITE, MAP_SHARED, shid, 0);
- if (MAP_FAILED != m_pData) {
- if (LockShareMem()){
- m_dwBytes = *((LPDWORD)m_pData);
- UnlockShareMem();
- if (m_dwBytes > 0)
- {
- T = true;
- }
- }
- }
- }
- }
-
- if (!T){
- CloseShareMem();
- }
- }
- #endif // RVC_OS_WIN
- return T;
- }
- //释放共享内存区
- void CloseShareMem()
- {
- #ifdef RVC_OS_WIN
- if (m_bLocked)
- {
- UnlockShareMem();
- }
- if (m_pData != NULL)
- {
- UnmapViewOfFile(m_pData);
- m_pData = NULL;
- }
- if (m_hFileMap != NULL)
- {
- CloseHandle(m_hFileMap);
- m_hFileMap = NULL;
- }
- if (m_hMutex != NULL)
- {
- CloseHandle(m_hMutex);
- m_hMutex = NULL;
- }
- m_dwBytes = 0;
- #else
- if (m_bLocked){
- UnlockShareMem();
- }
- if (NULL != m_semt){
- sem_unlink(m_strsemname);
- }
- if (m_pData != NULL){
- munmap(m_pData, m_dwBytes);
- }
- shm_unlink(m_strshmname);
- m_dwBytes = 0;
- #endif // _WIN32
- }
- //获取共享内存区大小
- unsigned int GetShareMemBytes()
- {
- return m_dwBytes;
- }
- //是否有可用的内存区
- bool IsShareMemValid()
- {
- #ifdef RVC_OS_WIN
- return (m_hFileMap != NULL && m_hMutex != NULL);
- #else
- return (m_shid != -1 && m_semt != NULL);
- #endif // RVC_OS_WIN
- }
- //锁定访问内存区
- void* LockShareMem(unsigned int dwWaitTimeout=INFINITE)
- {
- void* pData=NULL;
- #ifdef RVC_OS_WIN
- if (IsShareMemValid() && m_pData != NULL && !m_bLocked)
- {
- if (WaitForSingleObject(m_hMutex, dwWaitTimeout) != WAIT_TIMEOUT)
- {
- m_bLocked = true;
- }
- if (m_bLocked)
- {
- pData = (void*)((LPDWORD)m_pData + 1);
- }
- }
- #else
- //Debug("IsShareMemValid flag is %d, m_pData = 0x%08x, m_bLocked flag is %s.", IsShareMemValid(), m_pData, m_bLocked ? "true" : "false");
- if (IsShareMemValid() && m_pData != NULL && !m_bLocked)
- {
- struct timespec ts;
- clock_gettime(CLOCK_REALTIME, &ts);
- long unsec = ts.tv_nsec + (1000*1000*dwWaitTimeout);
- ts.tv_sec += (unsec / 1000000000);
- ts.tv_nsec = (unsec % 1000000000);
- int ivalue = -1;
- sem_getvalue(m_semt, &ivalue);
- if (0 == sem_timedwait(m_semt,&ts))
- {
- sem_getvalue(m_semt, &ivalue);
- m_bLocked = true;
- }
- if (m_bLocked)
- {
- pData = (void*)((LPDWORD)m_pData + 1);
- }
- }
- #endif // _WIN32
- return pData;
- }
- //内存区是否互斥锁定
- bool IsShareMemLocked()
- {
- return m_bLocked;
- }
- //解锁内存区
- void UnlockShareMem()
- {
- #ifdef RVC_OS_WIN
- if (m_bLocked)
- {
- ReleaseMutex(m_hMutex);
- m_bLocked = false;
- }
- #else
- if (m_bLocked)
- {
- sem_post(m_semt);
- m_bLocked = false;
- }
- #endif // _WIN32
- }
- };
- // 这是已导出类的构造函数。
- // 有关类定义的信息,请参阅 libsharememory.h
- Clibsharememory::Clibsharememory()
- {
- m_pImpl = new libsharememory_impl;
- return;
- }
- Clibsharememory::~Clibsharememory()
- {
- delete m_pImpl;
- }
- void Clibsharememory::Unlock()
- {
- m_pImpl->UnlockShareMem();
- return;
- }
- bool Clibsharememory::IsLocked()
- {
- bool bRst = m_pImpl->IsShareMemLocked();
- return bRst;
- }
- void* Clibsharememory::Lock(unsigned int dwWaitTimeout)
- {
- void* lpVoid = m_pImpl->LockShareMem(dwWaitTimeout);
- return lpVoid;
- }
- bool Clibsharememory::IsValid()
- {
- bool bRst = m_pImpl->IsShareMemValid();
- return bRst;
- }
- unsigned int Clibsharememory::GetBytes()
- {
- unsigned int TotalBytes = m_pImpl->GetShareMemBytes();
- return TotalBytes;
- }
- void Clibsharememory::Close()
- {
- m_pImpl->CloseShareMem();
- return;
- }
- bool Clibsharememory::Open(const char* szName)
- {
- bool bRst = m_pImpl->OpenShareMem(szName);
- return bRst;
- }
- bool Clibsharememory::Create(const char* szName, unsigned int dwBytes)
- {
- bool bRst = m_pImpl->CreateShareMem(szName,dwBytes);
- return bRst;
- }
|