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

608 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. /
// /
////////////////////////////////////////////////////////////////////////////////
#pragma once
#define SHARED_SEM_NULL NULL
////////////////////////////////////////////////////////////////////////////////
//CShared
class CShared
{
struct sShared
{
HANDLE hMemory;
HANDLE hMutex;
tXCHAR *pName;
};
enum eType
{
ETYPE_MUTEX = 0,
ETYPE_FILE ,
ETYPE_MAX
};
public:
typedef sShared *hShared;
typedef HANDLE 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
)
{
sShared *l_pShared = NULL;
tBOOL l_bReturn = TRUE;
DWORD l_dwLen = 0;
wchar_t *l_pName = NULL;
BOOL l_bRelease = FALSE;
tUINT8 *l_pBuffer = NULL;
if ( (NULL == i_pName)
|| (NULL == i_pData)
|| (0 >= i_wSize)
|| (NULL == o_pHandle)
)
{
l_bReturn = FALSE;
goto l_lblExit;
}
l_pShared = new sShared;
if (NULL == l_pShared)
{
l_bReturn = FALSE;
goto l_lblExit;
}
memset(l_pShared, 0, sizeof(sShared));
l_dwLen = (DWORD)wcslen(i_pName) + 128;
l_pName = (wchar_t*)malloc(sizeof(wchar_t) * l_dwLen);
l_pShared->pName = PStrDub(i_pName);
if ( (NULL == l_pName)
|| (NULL == l_pShared->pName)
)
{
l_bReturn = FALSE;
goto l_lblExit;
}
////////////////////////////////////////////////////////////////////////////
//create mutex and own it
Create_Name(l_pName, l_dwLen, ETYPE_MUTEX, i_pName);
l_pShared->hMutex = CreateMutexW(NULL, TRUE, l_pName);
if ( (NULL == l_pShared->hMutex)
|| (ERROR_ALREADY_EXISTS == GetLastError())
)
{
l_bReturn = FALSE;
goto l_lblExit;
}
l_bRelease = TRUE;
////////////////////////////////////////////////////////////////////////////
//create shared memory object
Create_Name(l_pName, l_dwLen, ETYPE_FILE, i_pName);
l_pShared->hMemory = CreateFileMappingW(INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // maximum object size (high-order tUINT32)
i_wSize, // maximum object size (low-order tUINT32)
l_pName // name of mapping object
);
if ( (NULL == l_pShared->hMemory)
|| (ERROR_ALREADY_EXISTS == GetLastError())
)
{
l_bReturn = FALSE;
goto l_lblExit;
}
l_pBuffer = (tUINT8*)MapViewOfFile(l_pShared->hMemory,
FILE_MAP_ALL_ACCESS,
0,
0,
i_wSize
);
if (NULL == l_pBuffer)
{
l_bReturn = FALSE;
goto l_lblExit;
}
*o_pHandle = (CShared::hShared)l_pShared;
__try
{
memcpy(l_pBuffer, i_pData, i_wSize);
}
__except ( GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR
? EXCEPTION_EXECUTE_HANDLER
: EXCEPTION_CONTINUE_SEARCH
)
{
l_bReturn = FALSE;
goto l_lblExit;
}
l_lblExit:
if (l_pName)
{
free(l_pName);
l_pName = NULL;
}
if (l_pBuffer)
{
UnmapViewOfFile(l_pBuffer);
l_pBuffer = NULL;
}
if (l_bRelease)
{
ReleaseMutex(l_pShared->hMutex);
}
if (FALSE == l_bReturn)
{
Close((hShared)l_pShared);
l_pShared = NULL;
if (o_pHandle)
{
*o_pHandle = NULL;
}
}
return l_bReturn;
}//Shared_Create
////////////////////////////////////////////////////////////////////////////
//Read
static tBOOL Read(const tXCHAR *i_pName,
tUINT8 *o_pData,
tUINT16 i_wSize
)
{
HANDLE l_hMemory = NULL;
tBOOL l_bReturn = TRUE;
DWORD l_dwLen = 0;
wchar_t *l_pName = NULL;
tUINT8 *l_pBuffer = NULL;
if ( (NULL == i_pName)
|| (NULL == o_pData)
|| (0 >= i_wSize)
)
{
l_bReturn = FALSE;
goto l_lblExit;
}
l_dwLen = (DWORD)wcslen(i_pName) + 128;
l_pName = (wchar_t*)malloc(sizeof(wchar_t) * l_dwLen);
if (NULL == l_pName)
{
l_bReturn = FALSE;
goto l_lblExit;
}
////////////////////////////////////////////////////////////////////////
//open shared memory object
Create_Name(l_pName, l_dwLen, ETYPE_FILE, i_pName);
l_hMemory = OpenFileMappingW(FILE_MAP_ALL_ACCESS, // read/write access
FALSE, // do not inherit the name
l_pName // name of mapping object
);
if (NULL == l_hMemory)
{
l_bReturn = FALSE;
goto l_lblExit;
}
l_pBuffer = (tUINT8*)MapViewOfFile(l_hMemory,
FILE_MAP_READ,
0,
0,
i_wSize
);
if (NULL == l_pBuffer)
{
l_bReturn = FALSE;
goto l_lblExit;
}
__try
{
memcpy(o_pData, l_pBuffer, i_wSize);
}
__except ( (GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR)
? EXCEPTION_EXECUTE_HANDLER
: EXCEPTION_CONTINUE_SEARCH
)
{
l_bReturn = FALSE;
goto l_lblExit;
}
l_lblExit:
if (l_pName)
{
free(l_pName);
l_pName = NULL;
}
if (l_pBuffer)
{
UnmapViewOfFile(l_pBuffer);
l_pBuffer = NULL;
}
if (l_hMemory)
{
CloseHandle(l_hMemory);
l_hMemory = NULL;
}
return l_bReturn;
}//Read
////////////////////////////////////////////////////////////////////////////
//Write
static tBOOL Write(const tXCHAR *i_pName,
const tUINT8 *i_pData,
tUINT16 i_wSize
)
{
HANDLE l_hMemory = NULL;
tBOOL l_bReturn = TRUE;
DWORD l_dwLen = 0;
wchar_t *l_pName = NULL;
tUINT8 *l_pBuffer = NULL;
if ( (NULL == i_pName)
|| (NULL == i_pData)
|| (0 >= i_wSize)
)
{
l_bReturn = FALSE;
goto l_lblExit;
}
l_dwLen = (DWORD)wcslen(i_pName) + 128;
l_pName = (wchar_t*)malloc(sizeof(wchar_t) * l_dwLen);
if (NULL == l_pName)
{
l_bReturn = FALSE;
goto l_lblExit;
}
////////////////////////////////////////////////////////////////////////
//open shared memory object
Create_Name(l_pName, l_dwLen, ETYPE_FILE, i_pName);
l_hMemory = OpenFileMappingW(FILE_MAP_ALL_ACCESS, // read/write access
FALSE, // do not inherit the name
l_pName // name of mapping object
);
if (NULL == l_hMemory)
{
l_bReturn = FALSE;
goto l_lblExit;
}
l_pBuffer = (tUINT8*)MapViewOfFile(l_hMemory,
FILE_MAP_WRITE,
0,
0,
i_wSize
);
if (NULL == l_pBuffer)
{
l_bReturn = FALSE;
goto l_lblExit;
}
__try
{
memcpy(l_pBuffer, i_pData, i_wSize);
}
__except ( (GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR)
? EXCEPTION_EXECUTE_HANDLER
: EXCEPTION_CONTINUE_SEARCH
)
{
l_bReturn = FALSE;
goto l_lblExit;
}
l_lblExit:
if (l_pName)
{
free(l_pName);
l_pName = NULL;
}
if (l_pBuffer)
{
UnmapViewOfFile(l_pBuffer);
l_pBuffer = NULL;
}
if (l_hMemory)
{
CloseHandle(l_hMemory);
l_hMemory = NULL;
}
return l_bReturn;
}//Write
////////////////////////////////////////////////////////////////////////////
//Lock
static eLock Lock(const tXCHAR *i_pName, CShared::hSem &o_rSem, tUINT32 i_dwTimeout_ms)
{
HANDLE l_hMutex = NULL;
eLock l_eReturn = CShared::E_OK;
DWORD l_dwLen = 0;
wchar_t *l_pName = NULL;
o_rSem = SHARED_SEM_NULL;
if (NULL == i_pName)
{
l_eReturn = CShared::E_ERROR;
goto l_lblExit;
}
l_dwLen = (DWORD)wcslen(i_pName) + 128;
l_pName = (wchar_t*)malloc(sizeof(wchar_t) * l_dwLen);
if (NULL == l_pName)
{
l_eReturn = CShared::E_ERROR;
goto l_lblExit;
}
////////////////////////////////////////////////////////////////////////
//open mutex and own it
Create_Name(l_pName, l_dwLen, ETYPE_MUTEX, i_pName);
l_hMutex = OpenMutexW(MUTEX_ALL_ACCESS, FALSE, l_pName);
if (NULL == l_hMutex)
{
l_eReturn = CShared::E_NOT_EXISTS;
goto l_lblExit;
}
if (WAIT_OBJECT_0 != WaitForSingleObject(l_hMutex, i_dwTimeout_ms))
{
l_eReturn = CShared::E_TIMEOUT;
goto l_lblExit;
}
l_lblExit:
if (l_pName)
{
free(l_pName);
l_pName = NULL;
}
if (SHARED_SEM_NULL != l_hMutex)
{
if (CShared::E_OK == l_eReturn)
{
o_rSem = l_hMutex;
}
else
{
CloseHandle(l_hMutex);
l_hMutex = SHARED_SEM_NULL;
}
}
return l_eReturn;
}//Lock
////////////////////////////////////////////////////////////////////////////
//UnLock
static eLock UnLock(CShared::hSem &io_rSem)
{
HANDLE l_hMutex = NULL;
eLock l_eReturn = CShared::E_ERROR;
if (SHARED_SEM_NULL == io_rSem)
{
l_eReturn = CShared::E_NOT_EXISTS;
goto l_lblExit;
}
ReleaseMutex(io_rSem);
l_lblExit:
if (io_rSem)
{
CloseHandle(io_rSem);
io_rSem = SHARED_SEM_NULL;
}
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_hShared)
{
if (NULL == i_hShared)
{
return FALSE;
}
//if (i_hShared->hMutex)
//{
// WaitForSingleObject(i_hShared->hMutex, 3000);
//}
if (i_hShared->hMemory)
{
CloseHandle(i_hShared->hMemory);
i_hShared->hMemory = NULL;
}
if (i_hShared->hMutex)
{
CloseHandle(i_hShared->hMutex);
i_hShared->hMutex = NULL;
}
if (i_hShared->pName)
{
PStrFreeDub(i_hShared->pName);
i_hShared->pName = NULL;
}
delete i_hShared;
return TRUE;
}//Shared_Close
////////////////////////////////////////////////////////////////////////////
//UnLink - linux required it due to fact that life time of shared object is
//almost infinit, and cleanup should be done manually
static tBOOL UnLink(const tXCHAR *i_pName)
{
UNUSED_ARG(i_pName);
return TRUE;
}//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;
}
FILETIME l_tProcess_Time = {0};
FILETIME l_tStub_01 = {0};
FILETIME l_tStub_02 = {0};
FILETIME l_tStub_03 = {0};
GetProcessTimes(GetCurrentProcess(),
&l_tProcess_Time,
&l_tStub_01,
&l_tStub_02,
&l_tStub_03
);
if (ETYPE_MUTEX == i_eType)
{
swprintf_s(o_pName,
i_szName,
L"Local\\m%d%d%d%s",
GetCurrentProcessId(),
l_tProcess_Time.dwHighDateTime,
l_tProcess_Time.dwLowDateTime,
i_pPostfix
);
}
else if (ETYPE_FILE == i_eType)
{
swprintf_s(o_pName,
i_szName,
L"Local\\f%d%d%d%s",
GetCurrentProcessId(),
l_tProcess_Time.dwHighDateTime,
l_tProcess_Time.dwLowDateTime,
i_pPostfix
);
}
return TRUE;
}//Create_Name
};