legatt 32f4597c4d Base frontend module
- Naming style migrated to camel-case
- P7lib logger sources added
- Vcpkg manifest, CMake presets and build moved to root
- SDL2, Vulkan and RmlUi dependencies added
- Logger LOG macro added
- Logger  configuration
- SDL2 window configuration
- Vulkan configuration
- RmlUi configuration
- SDL event loop
2025-08-08 00:07:32 +03:00

640 lines
16 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// /
// 2012-2020 (c) Baical /
// /
// This library is free software; you can redistribute it and/or /
// modify it under the terms of the GNU Lesser General Public /
// License as published by the Free Software Foundation; either /
// version 3.0 of the License, or (at your option) any later version. /
// /
// This library is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
// Lesser General Public License for more details. /
// /
// You should have received a copy of the GNU Lesser General Public /
// License along with this library. /
// /
////////////////////////////////////////////////////////////////////////////////
#ifndef PSHARED_H
#define PSHARED_H
////////////////////////////////////////////////////////////////////////////////
//Headers dependencies:
#include <unistd.h>
#include <fcntl.h> // For O_* constants
#include <semaphore.h>
#include <sys/mman.h>
#include <sys/stat.h> // For mode constants
#define SHARED_NAME_FORMAT_STRING "/P7_Type%d_PID%d_Text%s"
#define SHARED_NAME_LEN (strlen(SHARED_NAME_FORMAT_STRING) + 64)
#define SHARED_SEM_NULL SEM_FAILED
////////////////////////////////////////////////////////////////////////////////
//CShared
class CShared
{
struct sShared
{
int iMFD;
sem_t *hSemaphore;
size_t szName;
char *pName;
char *pSemName;
char *pMemName;
};
enum eType
{
ETYPE_MUTEX = 0,
ETYPE_FILE ,
ETYPE_MAX
};
public:
typedef sShared *hShared;
typedef sem_t *hSem;
enum eLock
{
E_OK ,
E_TIMEOUT ,
E_ERROR ,
E_NOT_EXISTS
};
////////////////////////////////////////////////////////////////////////////
//CShared::Create
static tBOOL Create(CShared::hShared *o_pHandle,
const tXCHAR *i_pName,
const tUINT8 *i_pData,
tUINT16 i_wSize
)
{
hShared l_pShared = NULL;
tBOOL l_bResult = TRUE;
tBOOL l_bRelease = FALSE;
void *l_pBuffer = NULL;
if ( (NULL == i_pName)
|| (NULL == i_pData)
|| (0 >= i_wSize)
|| (NULL == o_pHandle)
)
{
l_bResult = FALSE;
goto l_lblExit;
}
l_pShared = (hShared)malloc(sizeof(sShared));
if (NULL == l_pShared)
{
l_bResult = FALSE;
goto l_lblExit;
}
memset(l_pShared, 0, sizeof(sShared));
l_pShared->hSemaphore = SHARED_SEM_NULL;
l_pShared->iMFD = -1;
l_pShared->szName = strlen(i_pName) + SHARED_NAME_LEN;
l_pShared->pName = strdup(i_pName);
l_pShared->pSemName = (char*)malloc(l_pShared->szName);
l_pShared->pMemName = (char*)malloc(l_pShared->szName);
if ( (NULL == l_pShared->pSemName)
|| (NULL == l_pShared->pMemName)
|| (NULL == l_pShared->pName)
)
{
l_bResult = FALSE;
goto l_lblExit;
}
////////////////////////////////////////////////////////////////////////
//create ssemaphore and own it
Create_Name(l_pShared->pSemName, l_pShared->szName, ETYPE_MUTEX, i_pName);
l_pShared->hSemaphore = sem_open(l_pShared->pSemName, O_CREAT | O_EXCL, 0666, 0);
if (SHARED_SEM_NULL == l_pShared->hSemaphore)
{
l_bResult = FALSE;
goto l_lblExit;
}
l_bRelease = TRUE;
////////////////////////////////////////////////////////////////////////
//share memory
Create_Name(l_pShared->pMemName, l_pShared->szName, ETYPE_FILE, i_pName);
l_pShared->iMFD = shm_open(l_pShared->pMemName,
O_RDWR | O_CREAT | O_EXCL,
0666
);
if (0 > l_pShared->iMFD)
{
l_bResult = FALSE;
goto l_lblExit;
}
if (0 != ftruncate(l_pShared->iMFD, (off_t)i_wSize))
{
l_bResult = FALSE;
goto l_lblExit;
}
l_pBuffer = mmap(0,
(size_t)i_wSize,
PROT_READ | PROT_WRITE,
MAP_SHARED,
l_pShared->iMFD,
0
);
if ( (NULL == l_pBuffer)
|| (MAP_FAILED == l_pBuffer)
)
{
l_bResult = FALSE;
goto l_lblExit;
}
*o_pHandle = (CShared::hShared)l_pShared;
memcpy(l_pBuffer, i_pData, (size_t)i_wSize);
if (0 != munmap(l_pBuffer, (size_t)i_wSize))
{
}
l_lblExit:
if (l_bRelease)
{
sem_post(l_pShared->hSemaphore);
}
if (FALSE == l_bResult)
{
Close(l_pShared);
l_pShared = NULL;
if (o_pHandle)
{
*o_pHandle = NULL;
}
}
return l_bResult;
}//CShared::Create
////////////////////////////////////////////////////////////////////////////
//Read
static tBOOL Read(const tXCHAR *i_pName,
void *o_pData,
tUINT16 i_wSize
)
{
tBOOL l_bResult = TRUE;
size_t l_szName = 0;
char *l_pName = NULL;
void *l_pBuffer = NULL;
int l_iMFD = -1;
struct stat l_sStat;
if ( (NULL == i_pName)
|| (NULL == o_pData)
|| (0 >= i_wSize)
)
{
l_bResult = FALSE;
goto l_lblExit;
}
l_szName = strlen(i_pName) + SHARED_NAME_LEN;
l_pName = (char*)malloc(l_szName);
if (NULL == l_pName)
{
l_bResult = FALSE;
goto l_lblExit;
}
////////////////////////////////////////////////////////////////////////////
//open shared memory object
Create_Name(l_pName, l_szName, ETYPE_FILE, i_pName);
l_iMFD = shm_open(l_pName, O_RDONLY, 0444);
if (0 > l_iMFD)
{
l_bResult = FALSE;
goto l_lblExit;
}
memset(&l_sStat, 0, sizeof(l_sStat));
if (-1 == fstat(l_iMFD, &l_sStat))
{
l_bResult = FALSE;
goto l_lblExit;
}
if ((size_t)l_sStat.st_size > (size_t)i_wSize)
{
l_bResult = FALSE;
goto l_lblExit;
}
l_pBuffer = mmap(0,
(size_t)l_sStat.st_size,
PROT_READ,
MAP_SHARED,
l_iMFD,
0
);
if ( (NULL == l_pBuffer)
|| (MAP_FAILED == l_pBuffer)
)
{
l_bResult = FALSE;
goto l_lblExit;
}
memcpy(o_pData, l_pBuffer, (size_t)l_sStat.st_size);
if (0 == munmap(l_pBuffer, (size_t)l_sStat.st_size))
{
l_pBuffer = NULL;
}
l_lblExit:
if (l_pName)
{
free(l_pName);
l_pName = NULL;
}
if (0 <= l_iMFD)
{
close(l_iMFD);
l_iMFD = -1;
}
return l_bResult;
}//Read
////////////////////////////////////////////////////////////////////////////
//Write
static tBOOL Write(const tXCHAR *i_pName,
const tUINT8 *i_pData,
tUINT16 i_wSize
)
{
tBOOL l_bResult = TRUE;
size_t l_szName = 0;
char *l_pName = NULL;
void *l_pBuffer = NULL;
int l_iMFD = -1;
struct stat l_sStat;
if ( (NULL == i_pName)
|| (NULL == i_pData)
|| (0 >= i_wSize)
)
{
l_bResult = FALSE;
goto l_lblExit;
}
l_szName = strlen(i_pName) + SHARED_NAME_LEN;
l_pName = (char*)malloc(l_szName);
if (NULL == l_pName)
{
l_bResult = FALSE;
goto l_lblExit;
}
////////////////////////////////////////////////////////////////////////////
//open shared memory object
Create_Name(l_pName, l_szName, ETYPE_FILE, i_pName);
l_iMFD = shm_open(l_pName, O_RDWR, 0666);
if (0 > l_iMFD)
{
l_bResult = FALSE;
goto l_lblExit;
}
memset(&l_sStat, 0, sizeof(l_sStat));
if (-1 == fstat(l_iMFD, &l_sStat))
{
l_bResult = FALSE;
goto l_lblExit;
}
if ((size_t)l_sStat.st_size < (size_t)i_wSize)
{
l_bResult = FALSE;
goto l_lblExit;
}
l_pBuffer = mmap(0,
(size_t)l_sStat.st_size,
PROT_READ | PROT_WRITE,
MAP_SHARED,
l_iMFD,
0
);
if ( (NULL == l_pBuffer)
|| (MAP_FAILED == l_pBuffer)
)
{
l_bResult = FALSE;
goto l_lblExit;
}
memcpy(l_pBuffer, i_pData, (size_t)i_wSize);
if (0 == munmap(l_pBuffer, (size_t)l_sStat.st_size))
{
l_pBuffer = NULL;
}
l_lblExit:
if (l_pName)
{
free(l_pName);
l_pName = NULL;
}
if (0 <= l_iMFD)
{
close(l_iMFD);
l_iMFD = -1;
}
return l_bResult;
}//Write
////////////////////////////////////////////////////////////////////////////
//Lock
static eLock Lock(const tXCHAR *i_pName, CShared::hSem &o_rSem, tUINT32 i_dwTimeout_ms)
{
eLock l_eReturn = CShared::E_TIMEOUT;
size_t l_szName = 0;
char *l_pName = NULL;
const int l_i1ms = 1000;
tINT64 l_llWait = (tINT64)i_dwTimeout_ms * 1000LL;
sem_t *l_hSem = SHARED_SEM_NULL;
o_rSem = SHARED_SEM_NULL;
if (NULL == i_pName)
{
l_eReturn = CShared::E_ERROR;
goto l_lblExit;
}
l_szName = strlen(i_pName) + SHARED_NAME_LEN;
l_pName = (char*)malloc(l_szName);
if (NULL == l_pName)
{
l_eReturn = CShared::E_ERROR;
goto l_lblExit;
}
////////////////////////////////////////////////////////////////////////
//open semaphore
Create_Name(l_pName, l_szName, ETYPE_MUTEX, i_pName);
l_hSem = sem_open(l_pName, 0);
if (SHARED_SEM_NULL == l_hSem)
{
l_eReturn = CShared::E_NOT_EXISTS;
goto l_lblExit;
}
l_eReturn = CShared::E_TIMEOUT;
while (0 < l_llWait)
{
if (0 == sem_trywait(l_hSem))
{
l_eReturn = CShared::E_OK;
break;
}
else
{
usleep(l_i1ms); //10 ms
l_llWait -= l_i1ms;
}
}
l_lblExit:
if (l_pName)
{
free(l_pName);
l_pName = NULL;
}
if (SHARED_SEM_NULL != l_hSem)
{
if (CShared::E_OK == l_eReturn)
{
o_rSem = l_hSem;
}
else
{
sem_close(l_hSem);
l_hSem = SHARED_SEM_NULL;
}
}
return l_eReturn;
}//Lock
////////////////////////////////////////////////////////////////////////////
//UnLock
static eLock UnLock(CShared::hSem &io_rSem)
{
eLock l_eReturn = CShared::E_ERROR;
if (SHARED_SEM_NULL == io_rSem)
{
l_eReturn = CShared::E_NOT_EXISTS;
goto l_lblExit;
}
if (0 == sem_post(io_rSem))
{
l_eReturn = CShared::E_OK;
}
sem_close(io_rSem);
io_rSem = SHARED_SEM_NULL;
l_lblExit:
return l_eReturn;
}//UnLock
////////////////////////////////////////////////////////////////////////////
//GetSemName
static const tXCHAR* GetName(hShared i_pShared)
{
if (NULL == i_pShared)
{
return FALSE;
}
return i_pShared->pName;
}
////////////////////////////////////////////////////////////////////////////
//Close
static tBOOL Close(hShared i_pShared)
{
if (NULL == i_pShared)
{
return FALSE;
}
//if (SHARED_SEM_NULL != i_pShared->hSemaphore)
//{
// sem_wait(i_pShared->hSemaphore);
//}
if (0 <= i_pShared->iMFD)
{
close(i_pShared->iMFD);
i_pShared->iMFD = -1;
}
if (i_pShared->pMemName)
{
shm_unlink(i_pShared->pMemName);
}
if (SHARED_SEM_NULL != i_pShared->hSemaphore)
{
int l_iRes = -1;
l_iRes = sem_close(i_pShared->hSemaphore);
i_pShared->hSemaphore = SHARED_SEM_NULL;
UNUSED_ARG(l_iRes);
}
if (i_pShared->pSemName)
{
sem_unlink(i_pShared->pSemName);
free(i_pShared->pSemName);
i_pShared->pSemName = NULL;
}
if (i_pShared->pMemName)
{
free(i_pShared->pMemName);
i_pShared->pMemName = NULL;
}
if (i_pShared->pName)
{
free(i_pShared->pName);
i_pShared->pName = NULL;
}
i_pShared->szName = 0;
free(i_pShared);
i_pShared = NULL;
return TRUE;
}//Close
////////////////////////////////////////////////////////////////////////////
//UnLink
static tBOOL UnLink(const tXCHAR *i_pName)
{
tBOOL l_bReturn = TRUE;
size_t l_szName = 0;
char *l_pName = NULL;
if (NULL == i_pName)
{
l_bReturn = FALSE;
goto l_lblExit;
}
l_szName = strlen(i_pName) + SHARED_NAME_LEN;
l_pName = (char*)malloc(l_szName);
if (NULL == l_pName)
{
l_bReturn = FALSE;
goto l_lblExit;
}
Create_Name(l_pName, l_szName, ETYPE_MUTEX, i_pName);
if (0 != sem_unlink(l_pName))
{
l_bReturn = FALSE;
}
Create_Name(l_pName, l_szName, ETYPE_FILE, i_pName);
if (0 != shm_unlink(l_pName))
{
l_bReturn = FALSE;
}
l_lblExit:
if (l_pName)
{
free(l_pName);
l_pName = NULL;
}
return l_bReturn;
}//UnLink
private:
////////////////////////////////////////////////////////////////////////////
//Create_Name
static tBOOL Create_Name(tXCHAR *o_pName,
size_t i_szName,
eType i_eType,
const tXCHAR *i_pPostfix
)
{
if ( (NULL == o_pName)
|| (16 >= i_szName)
|| (ETYPE_MAX <= i_eType)
|| (NULL == i_pPostfix)
)
{
return FALSE;
}
snprintf(o_pName, i_szName, SHARED_NAME_FORMAT_STRING, i_eType, getpid(), i_pPostfix);
return TRUE;
}//Create_Name
};
#endif //PSHARED_H