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 "SharedMemory.h"
#include "Config.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 Function: createOrOpenMapping
Description: Creates or opens a file mapping and maps it into the process address space. 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; LARGE_INTEGER fileSize;
if (!GetFileSizeEx(mapping.fileHandle, &fileSize)) if (!GetFileSizeEx(mapping.fileHandle, &fileSize))
{ {
CloseHandle(mapping.fileHandle); invalidateMapping(mapping);
mapping.fileHandle = INVALID_HANDLE_VALUE;
return false; return false;
} }
bool isNewFile = (fileSize.QuadPart == 0); bool isNewFile = (fileSize.QuadPart == 0);
@@ -43,14 +70,12 @@ bool SharedMemory::createOrOpenMapping(MappingInfo& mapping)
newSize.QuadPart = sizeof(FileHeader) + initialCapacity * mapping.recordSize; newSize.QuadPart = sizeof(FileHeader) + initialCapacity * mapping.recordSize;
if (!SetFilePointerEx(mapping.fileHandle, newSize, NULL, FILE_BEGIN)) if (!SetFilePointerEx(mapping.fileHandle, newSize, NULL, FILE_BEGIN))
{ {
CloseHandle(mapping.fileHandle); invalidateMapping(mapping);
mapping.fileHandle = INVALID_HANDLE_VALUE;
return false; return false;
} }
if (!SetEndOfFile(mapping.fileHandle)) if (!SetEndOfFile(mapping.fileHandle))
{ {
CloseHandle(mapping.fileHandle); invalidateMapping(mapping);
mapping.fileHandle = INVALID_HANDLE_VALUE;
return false; return false;
} }
} }
@@ -64,8 +89,7 @@ bool SharedMemory::createOrOpenMapping(MappingInfo& mapping)
NULL); NULL);
if (mapping.mappingHandle == NULL) if (mapping.mappingHandle == NULL)
{ {
CloseHandle(mapping.fileHandle); invalidateMapping(mapping);
mapping.fileHandle = INVALID_HANDLE_VALUE;
return false; return false;
} }
mapping.mappedView = mapping.mappedView =
@@ -77,13 +101,15 @@ bool SharedMemory::createOrOpenMapping(MappingInfo& mapping)
0); 0);
if (mapping.mappedView == nullptr) if (mapping.mappedView == nullptr)
{ {
CloseHandle(mapping.mappingHandle); invalidateMapping(mapping);
CloseHandle(mapping.fileHandle); return false;
mapping.mappingHandle = NULL; }
mapping.fileHandle = INVALID_HANDLE_VALUE; FileHeader* header = getHeader(mapping);
if (header == nullptr)
{
invalidateMapping(mapping);
return false; return false;
} }
FileHeader* header = reinterpret_cast<FileHeader*>(mapping.mappedView);
if (isNewFile) if (isNewFile)
{ {
header->recordCount = 0; header->recordCount = 0;
@@ -103,22 +129,7 @@ Returns:
*/ */
void SharedMemory::closeMapping(MappingInfo& mapping) void SharedMemory::closeMapping(MappingInfo& mapping)
{ {
if (mapping.mappedView != nullptr) invalidateMapping(mapping);
{
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;
} }
/* /*
@@ -135,7 +146,6 @@ FileHeader* SharedMemory::getHeader(MappingInfo& mapping)
{ {
return nullptr; return nullptr;
} }
return reinterpret_cast<FileHeader*>(mapping.mappedView); return reinterpret_cast<FileHeader*>(mapping.mappedView);
} }
@@ -229,3 +239,92 @@ size_t SharedMemory::getCapacity(MappingInfo& mapping)
} }
return header->capacity; 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);
}