123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- #include "libsharememory.h"
- #include "inner_log.h"
- #include <stdio.h>
- #include <errno.h>
- #include <string.h>
- #ifndef _WIN32
- #include <fcntl.h>
- #include <sys/mman.h>
- #include <unistd.h>
- #include <sys/stat.h>
- #define sprintf_s snprintf
- #endif //NOT _WIN32
- class sharememory_impl4sdk
- {
- protected:
- unsigned int m_dwBytes;
- bool m_bLocked;
- void* m_pData;
- #if defined(_MSC_VER)
- HANDLE m_hFileMap;
- HANDLE m_hMutex;
- #else
- int m_shid;
- sem_t* m_semt;
- char m_strsemname[MAX_PATH];
- char m_strshmname[MAX_PATH];
- #endif //_MSC_VER
- public:
- sharememory_impl4sdk()
- {
- #if defined(_MSC_VER)
- m_hMutex = NULL;
- m_hFileMap = NULL;
- #else
- m_shid = -1;
- m_semt = SEM_FAILED;
- memset(m_strsemname, 0, MAX_PATH);
- memset(m_strshmname, 0, MAX_PATH);
- #endif //_MSC_VER
- m_dwBytes = 0;
- m_pData = NULL;
- m_bLocked = false;
- }
- ~sharememory_impl4sdk()
- {
- CloseShareMem();
- }
- #ifndef _WIN32
- bool CreateShareMemLinux(const char* szName, unsigned int dwBytes)
- {
- bool bRet = false;
- if (szName != NULL && dwBytes > 0) {
- sprintf_s(m_strshmname, MAX_PATH, "%s", szName);
- sprintf_s(m_strsemname, MAX_PATH, "/mutex.%s", szName);
- mode_t fm = umask(0);
- m_shid = shm_open(m_strshmname, O_CREAT | O_TRUNC | O_RDWR, 0777);
- umask(fm);
- if (m_shid >= 0) {
- aos_debug_log((LB, "shm_open O_CREAT | O_TRUNC | O_RDWR, 0777) success and share memory %s and size is %d", m_strshmname, dwBytes));
- } else {
- aos_error_log((LB, "shm_open O_CREAT | O_TRUNC | O_RDWR, 0777) %s failed for %s, and errno is %d", m_strshmname, strerror(errno), errno));
- if (EEXIST == errno) {
- //m_shid = shm_open(m_strshmname, O_RDWR, 0);
- }
- }
- if (m_shid != -1) {
- ftruncate(m_shid, dwBytes);
- m_pData = mmap(NULL, dwBytes, PROT_READ | PROT_WRITE, MAP_SHARED, m_shid, 0);
- if (MAP_FAILED != m_pData) {
- *((unsigned int*)m_pData) = dwBytes;
- m_dwBytes = dwBytes;
- m_semt = sem_open(m_strsemname, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, 1);
- if (SEM_FAILED == m_semt && EEXIST == errno) {
- aos_warn_log((LB, "sem has been existed!"));
- m_semt = sem_open(m_strsemname, 0);
- sem_init(m_semt, 32, 1);
- int ivalue = -1;
- sem_getvalue(m_semt, &ivalue);
- aos_debug_log((LB, "sem get value return %d", ivalue));
- bRet = true;
- } else if (SEM_FAILED != m_semt) {
- int ivalue = -1;
- sem_getvalue(m_semt, &ivalue);
- aos_debug_log((LB, "sem get value return %d", ivalue));
- bRet = true;
- } else {
- aos_error_log((LB, "sem_open failed %s(%d)", strerror(errno), errno));
- }
- } else {
- aos_error_log((LB, "mmap failed %s(%d)", strerror(errno), errno));
- }
- }
- if (!bRet) {
- CloseShareMem();
- }
- }
- return bRet;
- }
- //创建共享内存区
- bool CreateShareMem(const char* szName, unsigned int dwBytes)
- {
- return CreateShareMemLinux(szName, dwBytes);
- }
- //打开已有的共享内存区
- bool OpenShareMem(const char* szName, unsigned int dwBytes)
- {
- bool T = false;
- if (szName != NULL) {
- sprintf_s(m_strshmname, MAX_PATH, "%s", szName);
- sprintf_s(m_strsemname, MAX_PATH, "/mutex.%s", szName);
- mode_t fm = umask(0);
- m_shid = shm_open(m_strshmname, O_RDWR, 0777);
- umask(fm);
- if (m_shid != -1) {
- m_semt = sem_open(m_strsemname, 0);
- if (SEM_FAILED != m_semt) {
- int ivalue = -1;
- sem_getvalue(m_semt, &ivalue);
- aos_debug_log((LB, "sem get value return %d", ivalue));
- lseek(m_shid, 0, SEEK_SET);
- m_pData = mmap(NULL, dwBytes, PROT_READ | PROT_WRITE, MAP_SHARED, m_shid, 0);
- if (MAP_FAILED != m_pData) {
- if (LockShareMem()) {
- m_dwBytes = *((unsigned int*)m_pData);
- aos_debug_log((LB, "data byte: %u vs %u", m_dwBytes, dwBytes));
- UnlockShareMem();
- if (m_dwBytes > 0) {
- T = true;
- }
- }
- } else {
- aos_error_log((LB, "mmap failed %s(%d)", strerror(errno), errno));
- }
- } else {
- aos_error_log((LB, "sem_open failed %s, %s(%d)", m_strsemname, strerror(errno), errno));
- }
- } else {
- aos_error_log((LB, "shm_open failed %s, %s(%d)", m_strshmname, strerror(errno), errno));
- }
- if (!T) {
- CloseShareMem();
- }
- }
- return T;
- }
- #else
- //创建共享内存区
- BOOL CreateShareMem(LPCTSTR szName, DWORD dwBytes)
- {
- BOOL T = FALSE;
- char szBuf[MAX_PATH];
- LPCTSTR 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(DWORD) + 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();
- }
- }
- }
- return T;
- }
- //打开已有的共享内存区
- BOOL OpenShareMem(LPCTSTR szName, unsigned int dwNoUse)
- {
- BOOL T = FALSE;
- 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();
- }
- }
- return T;
- }
- #endif //_WIN32
- //释放共享内存区
- void CloseShareMem()
- {
- aos_debug_log((LB, "close share memory"));
- if (m_bLocked){
- UnlockShareMem();
- }
- #if defined(_MSC_VER)
- 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;
- }
- #else
- if (SEM_FAILED != m_semt) {
- sem_unlink(m_strsemname);
- m_semt = SEM_FAILED;
- }
- if (m_pData != NULL) {
- munmap(m_pData, m_dwBytes);
- }
- if (m_shid >= 0) {
- shm_unlink(m_strshmname);
- m_shid = -1;
- }
- #endif //_MSC_VER
- m_dwBytes = 0;
- }
- //获取共享内存区大小
- unsigned int GetShareMemBytes()
- {
- return m_dwBytes;
- }
- //是否有可用的内存区
- bool IsShareMemValid()
- {
- #if defined(_MSC_VER)
- return (m_hFileMap != NULL && m_hMutex != NULL);
- #else
- return (m_shid != -1 && m_semt != NULL);
- #endif //_MSC_VER
- }
- //锁定访问内存区
- void* LockShareMem(unsigned int dwWaitTimeout=INFINITE)
- {
- void* pData=NULL;
- if (IsShareMemValid() && m_pData != NULL && !m_bLocked)
- {
- #if defined(_MSC_VER)
- if (WaitForSingleObject(m_hMutex, dwWaitTimeout) != WAIT_TIMEOUT) {
- m_bLocked = true;
- }
- if (m_bLocked) {
- pData = (LPVOID)((LPDWORD)m_pData + 1);
- }
- #else
- 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;
- }
- #endif //_MSC_VER
- if (m_bLocked) {
- pData = (void*)((unsigned int*)m_pData + 1);
- }
- }
- return pData;
- }
- //内存区是否互斥锁定
- bool IsShareMemLocked()
- {
- return m_bLocked;
- }
- //解锁内存区
- void UnlockShareMem()
- {
- if (m_bLocked)
- {
- #if defined(_MSC_VER)
- ReleaseMutex(m_hMutex);
- #else
- sem_post(m_semt);
- #endif //_MSC_VER
- m_bLocked = false;
- }
- }
- };
- // 这是已导出类的构造函数。
- // 有关类定义的信息,请参阅 libsharememory.h
- Clibsharememory4SDK::Clibsharememory4SDK()
- {
- m_pImpl = new sharememory_impl4sdk;
- return;
- }
- Clibsharememory4SDK::~Clibsharememory4SDK()
- {
- delete m_pImpl;
- }
- void Clibsharememory4SDK::Unlock()
- {
- m_pImpl->UnlockShareMem();
- return;
- }
- bool Clibsharememory4SDK::IsLocked()
- {
- bool bRst = m_pImpl->IsShareMemLocked();
- return bRst;
- }
- void* Clibsharememory4SDK::Lock(unsigned int dwWaitTimeout)
- {
- void* lpVoid = m_pImpl->LockShareMem(dwWaitTimeout);
- return lpVoid;
- }
- bool Clibsharememory4SDK::IsValid()
- {
- bool bRst = m_pImpl->IsShareMemValid();
- return bRst;
- }
- unsigned int Clibsharememory4SDK::GetBytes()
- {
- unsigned int TotalBytes = m_pImpl->GetShareMemBytes();
- return TotalBytes;
- }
- void Clibsharememory4SDK::Close()
- {
- m_pImpl->CloseShareMem();
- return;
- }
- bool Clibsharememory4SDK::Open(const char* szName, unsigned int dwBytes)
- {
- return m_pImpl->OpenShareMem(szName, dwBytes);
- }
- bool Clibsharememory4SDK::Create(const char* szName, unsigned int dwBytes)
- {
- return m_pImpl->CreateShareMem(szName,dwBytes);
- }
|