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:
125
openVulkanoCpp/IO/MemMappedFileInternal.cpp
Normal file
125
openVulkanoCpp/IO/MemMappedFileInternal.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "MemMappedFileInternal.hpp"
|
||||
|
||||
#include "Base/Logger.hpp"
|
||||
#include "Host/Windows/ErrorUtils.hpp"
|
||||
|
||||
namespace OpenVulkano
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
MemMappedFileInternal::MemMappedFileInternal(const char* file, MemMappedFile::FileMode fileMode)
|
||||
: size(0), fileHandle(nullptr), fileMappingHandle(nullptr)
|
||||
{
|
||||
DWORD openMode { 0 }, mapMode { 0 }, viewMode { 0 };
|
||||
|
||||
switch (fileMode)
|
||||
{
|
||||
case MemMappedFile::FileMode::READ_ONLY:
|
||||
openMode = GENERIC_READ;
|
||||
mapMode = PAGE_READONLY;
|
||||
viewMode = FILE_MAP_READ;
|
||||
break;
|
||||
case MemMappedFile::FileMode::WRITE_ONLY:
|
||||
openMode = GENERIC_WRITE;
|
||||
mapMode = PAGE_READWRITE;
|
||||
viewMode = FILE_MAP_WRITE;
|
||||
break;
|
||||
case MemMappedFile::FileMode::READ_WRITE:
|
||||
openMode = GENERIC_ALL;
|
||||
mapMode = PAGE_READWRITE;
|
||||
viewMode = FILE_MAP_ALL_ACCESS;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
fileHandle = CreateFileA(file, // file to open
|
||||
openMode, // open for switch case
|
||||
NULL, // share mode
|
||||
NULL, // default security
|
||||
OPEN_ALWAYS, // always
|
||||
FILE_ATTRIBUTE_NORMAL, // normal file
|
||||
NULL); // no attribute template
|
||||
|
||||
if (fileHandle == INVALID_HANDLE_VALUE || fileHandle == NULL)
|
||||
{
|
||||
Logger::FILESYS->critical("Failed to open file: {}.", ErrorUtils::GetLastErrorMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
LARGE_INTEGER fileSize;
|
||||
if (!GetFileSizeEx(fileHandle, &fileSize))
|
||||
{
|
||||
Logger::FILESYS->critical("Failed to get size of file: {}", ErrorUtils::GetLastErrorMessage());
|
||||
CloseHandle(fileHandle);
|
||||
return;
|
||||
}
|
||||
size = fileSize.QuadPart;
|
||||
|
||||
fileMappingHandle = CreateFileMappingA(fileHandle,
|
||||
NULL, // default security
|
||||
mapMode, // mod for switch case
|
||||
0, // maximum object size (high-order)
|
||||
0, // maximum object size (low-order)
|
||||
NULL); // name of the mapping object
|
||||
if (fileMappingHandle == INVALID_HANDLE_VALUE || fileMappingHandle == NULL)
|
||||
{
|
||||
Logger::FILESYS->critical("Failed to create file mapping handle: {}", ErrorUtils::GetLastErrorMessage());
|
||||
CloseHandle(fileHandle);
|
||||
size = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
address = MapViewOfFile(fileMappingHandle, // handle to the map object
|
||||
viewMode, // access for switch case
|
||||
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: {}", ErrorUtils::GetLastErrorMessage());
|
||||
CloseHandle(fileMappingHandle);
|
||||
CloseHandle(fileHandle);
|
||||
size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
MemMappedFileInternal::~MemMappedFileInternal()
|
||||
{
|
||||
UnmapViewOfFile(address);
|
||||
CloseHandle(fileMappingHandle);
|
||||
CloseHandle(fileHandle);
|
||||
}
|
||||
#else
|
||||
MemMappedFileInternal::MemMappedFileInternal(const char* file, MemMappedFile::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_SHARED, fileHandle, 0);
|
||||
if (address == MAP_FAILED)
|
||||
{
|
||||
Logger::FILESYS->critical("Failed to memory map file: {}", file);
|
||||
address = nullptr;
|
||||
}
|
||||
size = fileStat.st_size;
|
||||
}
|
||||
|
||||
MemMappedFileInternal::~MemMappedFileInternal()
|
||||
{
|
||||
munmap(address, fileStat.st_size);
|
||||
close(fileHandle);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user