memmappedfile-fix (#115)

Co-authored-by: Metehan Tuncbilek <mtuncbilek95@gmail.com>
Reviewed-by: Georg Hagen <georg.hagen@madvoxel.com>
Co-authored-by: mtuncbilek <metehan.tuncbilek@madvoxel.com>
Co-committed-by: mtuncbilek <metehan.tuncbilek@madvoxel.com>
This commit is contained in:
mtuncbilek
2024-09-21 14:46:39 +02:00
committed by Georg Hagen
parent f6c48edac6
commit 95ddd4b23f
11 changed files with 801 additions and 114 deletions

View File

@@ -6,121 +6,15 @@
#include "MemMappedFile.hpp"
#include "Base/Logger.hpp"
#ifdef _MSC_VER
#include <windows.h>
#else
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#endif
#include "MemMappedFileInternal.hpp"
namespace OpenVulkano
{
class MemMappedFile::Internal final
{
public:
void* address = nullptr;
size_t size = 0;
#ifdef _MSC_VER
HANDLE fileHandle;
HANDLE fileMappingHandle;
Internal(const char* file, FileMode fileMode)
{ //TODO handle other file modes than read
fileHandle = CreateFile(
TEXT(file), // file to open
GENERIC_READ, // open for reading
0, // do not share
NULL, // default security
OPEN_EXISTING, // existing file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attribute template
if (fileHandle == INVALID_HANDLE_VALUE)
{
Logger::FILESYS->critical("Failed to open file: {}", file);
return;
}
LARGE_INTEGER fileSize;
if (!GetFileSizeEx(fileHandle, &fileSize))
{
Logger::FILESYS->critical("Failed to get size of file: {}", file);
CloseHandle(fileHandle);
return;
}
size = fileSize.QuadPart;
fileMappingHandle = CreateFileMapping(
fileHandle,
NULL, // default security
PAGE_READONLY, // read-only access
0, // maximum object size (high-order)
0, // maximum object size (low-order)
NULL); // name of the mapping object
if (fileMappingHandle == 0)
{
Logger::FILESYS->critical("Failed to create file mapping handle: {}", file);
CloseHandle(fileHandle);
size = 0;
return;
}
address = MapViewOfFile(
fileMappingHandle, // handle to the map object
FILE_MAP_READ, // read access
0, // max. object size
0, // size of the hFile
0); // map the entire file
if (address == nullptr)
{
Logger::FILESYS->critical("Failed to create file mapping: {}", file);
CloseHandle(fileMappingHandle);
CloseHandle(fileHandle);
size = 0;
}
}
~Internal()
{
UnmapViewOfFile(address);
CloseHandle(fileMappingHandle);
CloseHandle(fileHandle);
}
#else
int fileHandle;
struct stat fileStat;
Internal(const char* file, FileMode fileMode)
{
fileHandle = open(file, fileMode);
if (fstat(fileHandle, &fileStat) == -1)
{
Logger::FILESYS->critical("Failed to query stats for file: {}", file);
return;
}
address = mmap(nullptr, fileStat.st_size, fileMode + 1, MAP_PRIVATE, fileHandle, 0);
if (address == MAP_FAILED)
{
Logger::FILESYS->critical("Failed to memory map file: {}", file);
address = nullptr;
}
size = fileStat.st_size;
}
~Internal()
{
munmap(address, fileStat.st_size);
close(fileHandle);
}
#endif
};
MemMappedFile::MemMappedFile(const std::filesystem::path& path, FileMode fileMode)
: m_data(nullptr), m_size(0)
{
m_internal = std::make_shared<Internal>(path.string().c_str(), fileMode);
std::string file = path.string();
m_internal = std::make_shared<MemMappedFileInternal>(file.c_str(), fileMode);
m_data = m_internal->address;
m_size = (m_data) ? m_internal->size : 0;
}