123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 |
- #ifdef _WIN32
- #define _CRT_SECURE_NO_WARNINGS
- #define _CRT_NONSTDC_NO_WARNINGS
- #include <windows.h>
- #include <io.h>
- #include "../Win32/w32def.h"
- #endif // _WIN32
- #include <stdio.h>
- #include <string.h>
- #include <errno.h>
- #include <unistd.h>
- #ifdef __linux__
- #include <sys/file.h>
- #include <sys/ipc.h>
- #include <sys/sem.h>
- #include <linux/limits.h>
- #include <sys/shm.h>
- #endif // __linux__
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include "defines.h"
- #include "shmrot.h"
- /////////////////////////////////////////////////////////////////////////////
- #define _FILES_DIRECTORY "/tmp"
- /////////////////////////////////////////////////////////////////////////////
- #define _SHMROT_ENTRY_FLAG_VALID 0x00000001
- /////////////////////////////////////////////////////////////////////////////
- // {99df2b86-f904-425d-9fcc-c83c329d0937}
- DEFINE_UUID(GUID_SHMROT, 0x99df2b86, 0xf904, 0x425d, 0x9f, 0xcc, 0xc8, 0x3c, 0x32, 0x9d, 0x09, 0x37);
- /////////////////////////////////////////////////////////////////////////////
- CShmROT::CShmROT(void) : m_pTable(NULL)
- {
- }
- CShmROT::~CShmROT(void)
- {
- Release();
- }
- bool CShmROT::Create(void)
- {
- TRACE("CShmROT::Create!\n");
- int nRet = m_shmRot.Create(GUID_SHMROT, sizeof(SHMROT));
- if( nRet >= 0 &&
- (m_pTable = (LPSHMROT)m_shmRot.Attach()))
- {
- if(nRet == 1)
- {
- m_pTable->version = _ROT_CURRENT_VERSION;
- m_pTable->maxEntries = _ROT_MAX_TABLE_ENTRIES;
- m_pTable->entrySize = (uint32_t)sizeof(SHMROT_ENTRY);
- }
- else if(nRet == 0)
- {
- if(m_pTable->version != _ROT_CURRENT_VERSION)
- {
- // ...
- }
- }
- return true;
- }
- return false;
- }
- void CShmROT::Release(void)
- {
- if(m_pTable)
- {
- TRACE("CShmROT::Release!\n");
- m_shmRot.Detach(m_pTable);
- m_shmRot.Release();
- m_pTable = NULL;
- }
- }
- void CShmROT::ForceReleaseMutex(void)
- {
- m_shmRot.ForceReleaseMutex();
- }
- CShm* CShmROT::AcquireShm(const char *pszUuid, size_t nSizeElement, size_t nCntElements, const char *pszDescName)
- {
- if(!m_pTable)
- {
- TRACE("CShmROT::AcquireShm: ROT not initialized!\n");
- return NULL;
- }
- uuid_t uuid;
- CShm *pShm = NULL;
- if(!_uuid_parse(pszUuid, &uuid))
- {
- TRACE("CShmROT::AcquireShm: invalid uuid!\n");
- return NULL;
- }
- int nIndexFound = -1;
- int nFirstUnusedIndex = -1;
- for(int i = 0; i < (int)m_pTable->maxEntries; i++)
- {
- SHMROT_ENTRY &re = m_pTable->rot[i];
- if(re.flags & _SHMROT_ENTRY_FLAG_VALID)
- {
- if(!_uuid_compare(&re.uuid, &uuid))
- {
- nIndexFound = i;
- break;
- }
- }
- else if(nFirstUnusedIndex == -1)
- {
- nFirstUnusedIndex = i;
- }
- }
- if(nIndexFound >= 0) // found existing entry
- {
- SHMROT_ENTRY &re = m_pTable->rot[nIndexFound];
- bool bMatch = (re.nSizeElement == nSizeElement) && (re.nCntElements == nCntElements);
- if(bMatch)
- {
- TRACE("CShmROT::AcquireShm: Found matching SHM entry!\n");
- if((pShm = new CShm))
- {
- if(pShm->Create(uuid, nSizeElement * nCntElements) < 0)
- {
- pShm->Release();
- delete pShm;
- pShm = NULL;
- TRACE("CShmROT::AcquireShm: Failed to create new CShm!\n");
- }
- else
- {
- re.nCntHandles++;
- }
- }
- else
- {
- TRACE("CShmROT::AcquireShm: Failed to allocate new CShm!\n");
- }
- }
- else
- {
- TRACE("CShmROT::AcquireShm: SHM uuid exists, but size does not match!\n");
- }
- }
- else if(nFirstUnusedIndex >= 0) // next free slot
- {
- TRACE("CShmROT::AcquireShm: Create new SHM entry!\n");
- SHMROT_ENTRY &re = m_pTable->rot[nFirstUnusedIndex];
- if((pShm = new CShm))
- {
- if(pShm->Create(uuid, nSizeElement * nCntElements) < 0)
- {
- pShm->Release();
- delete pShm;
- pShm = NULL;
- TRACE("CShmROT::AcquireShm: Failed to create new CShm!\n");
- }
- else
- {
- re.flags = _SHMROT_ENTRY_FLAG_VALID;
- re.nSizeElement = (uint32_t)nSizeElement;
- re.nCntElements = (uint32_t)nCntElements;
- re.nCntHandles = 1;
- _uuid_copy(&re.uuid, &uuid);
- memset(re.szDescName, 0, sizeof(re.szDescName));
- if(pszDescName)
- {
- size_t nLen = strlen(pszDescName);
- if(nLen > 0)
- {
- if(nLen >= _ROT_MAX_ENTRY_NAME)
- nLen = _ROT_MAX_ENTRY_NAME - 1;
- memcpy(re.szDescName, pszDescName, nLen);
- re.szDescName[nLen] = '\0';
- }
- }
- }
- }
- else
- {
- TRACE("CShmROT::AcquireShm: Failed to allocate new CShm!\n");
- }
- }
- else
- {
- TRACE("CShmROT::AcquireShm: SHM uuid not found and no slot available!\n");
- }
- return pShm;
- }
- void CShmROT::ReleaseShm(CShm *pShm)
- {
- if(pShm)
- {
- const uuid_t &ruuid = pShm->Uuid();
- for(int i = 0; i < (int)m_pTable->maxEntries; i++)
- {
- SHMROT_ENTRY &re = m_pTable->rot[i];
- if(!_uuid_compare(&re.uuid, &ruuid))
- {
- if(re.flags & _SHMROT_ENTRY_FLAG_VALID)
- {
- if(re.nCntHandles > 0)
- --re.nCntHandles;
-
- if(re.nCntHandles == 0)
- re.flags &= ~_SHMROT_ENTRY_FLAG_VALID;
- }
- break;
- }
- }
- pShm->Release();
- delete pShm;
- }
- }
- int CShmROT::Lock(void)
- {
- return m_shmRot.Lock();
- }
- int CShmROT::Unlock(void)
- {
- return m_shmRot.Unlock();
- }
- void CShmROT::DumpEntries(CShmHandleMap &map)
- {
- if(!m_pTable)
- {
- printf("CShmROT::DumpEntries: ROT not initialized!\n");
- return;
- }
- char szUuid[_UUID_STRING_LEN + 1];
- Lock();
- for(int i = 0; i < (int)m_pTable->maxEntries; i++)
- {
- SHMROT_ENTRY &re = m_pTable->rot[i];
- if(re.flags & _SHMROT_ENTRY_FLAG_VALID)
- {
- unsigned long nAttached = 0;
- _uuid_unparse(&re.uuid, szUuid, sizeof(szUuid));
- if(re.nCntHandles > 0)
- {
- CShm *pShm = map.LookupShm(re.uuid);
- if(pShm)
- nAttached = pShm->GetNumAttached();
- }
- printf( "uuid: '%s',\n" \
- " flags: 0x%08x,\n" \
- " size of element: %u,\n" \
- " number of elements: %u,\n" \
- " name: '%s',\n" \
- " number of handles: %u,\n" \
- " number of pointers: %lu\n",
- szUuid,
- re.flags,
- re.nSizeElement,
- re.nCntElements,
- re.szDescName,
- re.nCntHandles,
- nAttached);
- fflush(stdout);
- }
- }
- Unlock();
- }
|