This commit is contained in:
2026-06-11 12:40:43 +05:30
parent 603ed9c60e
commit adf74e2427
@@ -1,6 +1,34 @@
#include "SharedMemory.h"
#include "Config.h"
/*
Function: invalidateMapping
Description: Releases all mapping resources and resets the mapping to an invalid state.
Parameters:
- mapping: MappingInfo&, mapping information and handles
Returns:
- None
*/
static void invalidateMapping(MappingInfo& mapping)
{
if (mapping.mappedView != nullptr)
{
UnmapViewOfFile(mapping.mappedView);
mapping.mappedView = nullptr;
}
if (mapping.mappingHandle != NULL)
{
CloseHandle(mapping.mappingHandle);
mapping.mappingHandle = NULL;
}
if (mapping.fileHandle != INVALID_HANDLE_VALUE)
{
CloseHandle(mapping.fileHandle);
mapping.fileHandle = INVALID_HANDLE_VALUE;
}
mapping.mappedCapacity = 0;
}
/*
Function: createOrOpenMapping
Description: Creates or opens a file mapping and maps it into the process address space.
@@ -31,8 +59,7 @@ bool SharedMemory::createOrOpenMapping(MappingInfo& mapping)
LARGE_INTEGER fileSize;
if (!GetFileSizeEx(mapping.fileHandle, &fileSize))
{
CloseHandle(mapping.fileHandle);
mapping.fileHandle = INVALID_HANDLE_VALUE;
invalidateMapping(mapping);
return false;
}
bool isNewFile = (fileSize.QuadPart == 0);
@@ -43,14 +70,12 @@ bool SharedMemory::createOrOpenMapping(MappingInfo& mapping)
newSize.QuadPart = sizeof(FileHeader) + initialCapacity * mapping.recordSize;
if (!SetFilePointerEx(mapping.fileHandle, newSize, NULL, FILE_BEGIN))
{
CloseHandle(mapping.fileHandle);
mapping.fileHandle = INVALID_HANDLE_VALUE;
invalidateMapping(mapping);
return false;
}
if (!SetEndOfFile(mapping.fileHandle))
{
CloseHandle(mapping.fileHandle);
mapping.fileHandle = INVALID_HANDLE_VALUE;
invalidateMapping(mapping);
return false;
}
}
@@ -64,8 +89,7 @@ bool SharedMemory::createOrOpenMapping(MappingInfo& mapping)
NULL);
if (mapping.mappingHandle == NULL)
{
CloseHandle(mapping.fileHandle);
mapping.fileHandle = INVALID_HANDLE_VALUE;
invalidateMapping(mapping);
return false;
}
mapping.mappedView =
@@ -77,13 +101,15 @@ bool SharedMemory::createOrOpenMapping(MappingInfo& mapping)
0);
if (mapping.mappedView == nullptr)
{
CloseHandle(mapping.mappingHandle);
CloseHandle(mapping.fileHandle);
mapping.mappingHandle = NULL;
mapping.fileHandle = INVALID_HANDLE_VALUE;
invalidateMapping(mapping);
return false;
}
FileHeader* header = getHeader(mapping);
if (header == nullptr)
{
invalidateMapping(mapping);
return false;
}
FileHeader* header = reinterpret_cast<FileHeader*>(mapping.mappedView);
if (isNewFile)
{
header->recordCount = 0;
@@ -103,22 +129,7 @@ Returns:
*/
void SharedMemory::closeMapping(MappingInfo& mapping)
{
if (mapping.mappedView != nullptr)
{
UnmapViewOfFile(mapping.mappedView);
mapping.mappedView = nullptr;
}
if (mapping.mappingHandle != NULL)
{
CloseHandle(mapping.mappingHandle);
mapping.mappingHandle = NULL;
}
if (mapping.fileHandle != INVALID_HANDLE_VALUE)
{
CloseHandle(mapping.fileHandle);
mapping.fileHandle = INVALID_HANDLE_VALUE;
}
mapping.mappedCapacity = 0;
invalidateMapping(mapping);
}
/*
@@ -135,7 +146,6 @@ FileHeader* SharedMemory::getHeader(MappingInfo& mapping)
{
return nullptr;
}
return reinterpret_cast<FileHeader*>(mapping.mappedView);
}
@@ -229,3 +239,92 @@ size_t SharedMemory::getCapacity(MappingInfo& mapping)
}
return header->capacity;
}
/*
Function: resizeMapping
Description: Resizes the file mapping to the specified capacity.
Parameters:
- mapping: MappingInfo&, mapping information and handles
- newCapacity: size_t, new mapping capacity
Returns:
- bool: True if the resize succeeded, otherwise false
*/
bool SharedMemory::resizeMapping(MappingInfo& mapping, size_t newCapacity)
{
FileHeader* header = getHeader(mapping);
if (header == nullptr)
{
invalidateMapping(mapping);
return false;
}
header->capacity = newCapacity;
if (!FlushViewOfFile(mapping.mappedView, sizeof(FileHeader)))
{
return false;
}
if (!UnmapViewOfFile(mapping.mappedView))
{
return false;
}
mapping.mappedView = nullptr;
CloseHandle(mapping.mappingHandle);
mapping.mappingHandle = NULL;
LARGE_INTEGER newSize;
newSize.QuadPart = sizeof(FileHeader) + newCapacity * mapping.recordSize;
if (!SetFilePointerEx(mapping.fileHandle, newSize, NULL, FILE_BEGIN))
{
invalidateMapping(mapping);
return false;
}
if (!SetEndOfFile(mapping.fileHandle))
{
invalidateMapping(mapping);
return false;
}
mapping.mappingHandle =
CreateFileMappingA(
mapping.fileHandle,
NULL,
PAGE_READWRITE,
0,
0,
NULL);
if (mapping.mappingHandle == NULL)
{
invalidateMapping(mapping);
return false;
}
mapping.mappedView =
MapViewOfFile(
mapping.mappingHandle,
FILE_MAP_ALL_ACCESS,
0,
0,
0);
if (mapping.mappedView == nullptr)
{
invalidateMapping(mapping);
return false;
}
mapping.mappedCapacity = newCapacity;
return true;
}
/*
Function: ensureCapacityForInsert
Description: Ensures that the mapping has space for at least one additional record, growing it if necessary.
Parameters:
- mapping: MappingInfo&, mapping information and handles
Returns:
- bool: True if capacity is available, otherwise false
*/
bool SharedMemory::ensureCapacityForInsert(MappingInfo& mapping)
{
size_t recordCount = getRecordCount(mapping);
size_t capacity = getCapacity(mapping);
if (recordCount < capacity)
{
return true;
}
return resizeMapping(mapping, capacity * 2);
}