// gfaipc.cpp // #ifdef _WIN32 #define _CRT_SECURE_NO_WARNINGS #include #endif // _WIN32 #include #include #include "defines.h" #include "uuid.h" #include "shmrot.h" ///////////////////////////////////////////////////////////////////////////// CShmHandleMap::CShmHandleMap(void) { memset(m_handles, 0, sizeof(m_handles)); } CShmHandleMap::~CShmHandleMap(void) { for(size_t i = 0; i < _IPCSHM_MAX_HANDLES; i++) { } } HSHM CShmHandleMap::AcquireHandle(CShm *pShm) { HSHM hShm = NULL; for(int i = 0; i < _IPCSHM_MAX_HANDLES; i++) { if(!m_handles[i].pShm) { m_handles[i].pShm = pShm; hShm = &m_handles[i]; break; } } return hShm; } void CShmHandleMap::ReleaseHandle(HSHM hShm) { for(int i = 0; i < _IPCSHM_MAX_HANDLES; i++) { if(&m_handles[i] == hShm) { m_handles[i].pShm = NULL; break; } } } CShm* CShmHandleMap::LookupShm(const uuid_t &uuid) { for(int i = 0; i < _IPCSHM_MAX_HANDLES; i++) { if(m_handles[i].pShm) { const uuid_t &uuid2 = m_handles[i].pShm->Uuid(); if(!_uuid_compare(&uuid, &uuid2)) return m_handles[i].pShm; } } return NULL; } ///////////////////////////////////////////////////////////////////////////// static CShmROT g_shmRot; static CShmHandleMap g_shmHandleMap; __attribute__ ((constructor)) void _OnSoLoad(void) { TRACE("Loading Module GfaIpc.\n"); } __attribute__ ((destructor)) void _OnSoUnload(void) { TRACE("Unloading Module GfaIpc.\n"); } ///////////////////////////////////////////////////////////////////////////// void GfaIpcForceReleaseMutex(void) { g_shmRot.ForceReleaseMutex(); } HSHM GfaIpcAcquireSHM(const char *pszUuid, size_t nSizeElement, size_t nCntElements, const char *pszDescName) { HSHM hShm = NULL; if(!g_shmRot.Created()) { if(!g_shmRot.Create()) { TRACE("GfaIpcAcquireSHM: Failed to create ROT!\n"); return NULL; } } g_shmRot.Lock(); CShm *pShm = g_shmRot.AcquireShm(pszUuid, nSizeElement, nCntElements, pszDescName); if(pShm) { hShm = g_shmHandleMap.AcquireHandle(pShm); if(!hShm) { TRACE("GfaIpcAcquireSHM: Failed to acquire handle!\n"); g_shmRot.ReleaseShm(pShm); } } g_shmRot.Unlock(); return hShm; } ///////////////////////////////////////////////////////////////////////////// void GfaIpcReleaseSHM(HSHM hShm) { if(hShm) { LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm; if(!ph->pShm) { TRACE("GfaIpcReleaseSHM: Invalid Handle!\n"); return; } g_shmRot.Lock(); g_shmRot.ReleaseShm(ph->pShm); g_shmHandleMap.ReleaseHandle(hShm); g_shmRot.Unlock(); } } ///////////////////////////////////////////////////////////////////////////// void* GfaIpcAcquirePointer(HSHM hShm) { if(hShm) { LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm; if(!ph->pShm) { TRACE("GfaIpcAcquirePointer: Invalid Handle!\n"); return NULL; } return ph->pShm->Attach(); } TRACE("GfaIpcAcquirePointer: Invalid Handle!\n"); return NULL; } ///////////////////////////////////////////////////////////////////////////// void GfaIpcReleasePointer(HSHM hShm, const void *p) { if(!hShm) { TRACE("GfaIpcReleasePointer: Invalid Handle!\n"); return; } LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm; if(!ph->pShm) { TRACE("GfaIpcReleasePointer: Invalid Handle!\n"); return; } ph->pShm->Detach(p); } ///////////////////////////////////////////////////////////////////////////// void GfaIpcLockSHM(HSHM hShm) { if(!hShm) { TRACE("GfaIpcLockSHM: Invalid Handle!\n"); return; } LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm; if(!ph->pShm) { TRACE("GfaIpcLockSHM: Invalid Handle!\n"); return; } ph->pShm->Lock(); } ///////////////////////////////////////////////////////////////////////////// int GfaIpcTryLockSHM(HSHM hShm) { if(!hShm) { TRACE("GfaIpcTryLockSHM: Invalid Handle!\n"); return 0; } LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm; if(!ph->pShm) { TRACE("GfaIpcTryLockSHM: Invalid Handle!\n"); return 0; } return ph->pShm->TryLock(); } ///////////////////////////////////////////////////////////////////////////// void GfaIpcUnlockSHM(HSHM hShm) { if(!hShm) { TRACE("GfaIpcUnlockSHM: Invalid Handle!\n"); return; } LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm; if(!ph->pShm) { TRACE("GfaIpcUnlockSHM: Invalid Handle!\n"); return; } ph->pShm->Unlock(); } ///////////////////////////////////////////////////////////////////////////// int GfaIpcLockSHMAndSigBlock(HSHM hShm, sigset_t *pss) { if(!hShm) { TRACE("GfaIpcLockSHMAndSigBlock: Invalid Handle!\n"); return 0; } LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm; if(!ph->pShm) { TRACE("GfaIpcLockSHMAndSigBlock: Invalid Handle!\n"); return 0; } return ph->pShm->LockAndSigBlock(pss); } ///////////////////////////////////////////////////////////////////////////// int GfaIpcUnlockSHMAndSigUnblock(HSHM hShm, sigset_t *pss) { if(!hShm) { TRACE("GfaIpcLockSHMAndSigBlock: Invalid Handle!\n"); return 0; } LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm; if(!ph->pShm) { TRACE("GfaIpcLockSHMAndSigBlock: Invalid Handle!\n"); return 0; } return ph->pShm->UnlockAndSigUnblock(pss); } ///////////////////////////////////////////////////////////////////////////// void GfaIpcDumpSHMROT(void) { if(!g_shmRot.Created()) { if(!g_shmRot.Create()) { TRACE("GfaIpcDumpSHMROT: Failed to create ROT!\n"); return; } } g_shmRot.DumpEntries(g_shmHandleMap); } ///////////////////////////////////////////////////////////////////////////// long GfaIpcInterlockedIncrement(HSHM hShm, volatile long *pl) { if(!hShm) { TRACE("GfaIpcInterlockedIncrement: Invalid Handle!\n"); return 0; } LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm; if(!ph->pShm) { TRACE("GfaIpcInterlockedIncrement: Invalid Handle!\n"); return 0; } return ph->pShm->InterlockedIncrement(pl); } ///////////////////////////////////////////////////////////////////////////// long GfaIpcInterlockedDecrement(HSHM hShm, volatile long *pl) { if(!hShm) { TRACE("GfaIpcInterlockedDecrement: Invalid Handle!\n"); return 0; } LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm; if(!ph->pShm) { TRACE("GfaIpcInterlockedDecrement: Invalid Handle!\n"); return 0; } return ph->pShm->InterlockedDecrement(pl); } ///////////////////////////////////////////////////////////////////////////// long GfaIpcInterlockedCompare(HSHM hShm, volatile long *pl, long comparand) { if(!hShm) { TRACE("GfaIpcInterlockedCompare: Invalid Handle!\n"); return 0; } LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm; if(!ph->pShm) { TRACE("GfaIpcInterlockedCompare: Invalid Handle!\n"); return 0; } return ph->pShm->InterlockedCompare(pl, comparand); } ///////////////////////////////////////////////////////////////////////////// long GfaIpcInterlockedSet(HSHM hShm, volatile long *pl, long val) { if(!hShm) { TRACE("GfaIpcInterlockedSet: Invalid Handle!\n"); return 0; } LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm; if(!ph->pShm) { TRACE("GfaIpcInterlockedSet: Invalid Handle!\n"); return 0; } return ph->pShm->InterlockedSet(pl, val); } ///////////////////////////////////////////////////////////////////////////// long GfaIpcInterlockedClear(HSHM hShm, volatile long *pl) { if(!hShm) { TRACE("GfaIpcInterlockedSet: Invalid Handle!\n"); return 0; } LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm; if(!ph->pShm) { TRACE("GfaIpcInterlockedClear: Invalid Handle!\n"); return 0; } return ph->pShm->InterlockedClear(pl); }