System: Gracefully handle memory allocaion failure

This commit is contained in:
Stenzek
2024-02-25 18:20:34 +10:00
parent 9ac9fc0a1e
commit c1381cfda6
11 changed files with 92 additions and 39 deletions

View File

@ -1,10 +1,12 @@
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#include "memmap.h"
#include "align.h"
#include "assert.h"
#include "error.h"
#include "log.h"
#include "small_string.h"
#include "string_util.h"
#include "fmt/format.h"
@ -47,11 +49,15 @@ std::string MemMap::GetFileMappingName(const char* prefix)
return fmt::format("{}_{}", prefix, pid);
}
void* MemMap::CreateSharedMemory(const char* name, size_t size)
void* MemMap::CreateSharedMemory(const char* name, size_t size, Error* error)
{
return static_cast<void*>(CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
static_cast<DWORD>(size >> 32), static_cast<DWORD>(size),
StringUtil::UTF8StringToWideString(name).c_str()));
const HANDLE mapping =
static_cast<void*>(CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, static_cast<DWORD>(size >> 32),
static_cast<DWORD>(size), StringUtil::UTF8StringToWideString(name).c_str()));
if (!mapping)
Error::SetWin32(error, "CreateFileMappingW() failed: ", GetLastError());
return mapping;
}
void MemMap::DestroySharedMemory(void* ptr)
@ -299,24 +305,33 @@ std::string MemMap::GetFileMappingName(const char* prefix)
#endif
}
void* MemMap::CreateSharedMemory(const char* name, size_t size)
void* MemMap::CreateSharedMemory(const char* name, size_t size, Error* error)
{
const int fd = shm_open(name, O_CREAT | O_EXCL | O_RDWR, 0600);
if (fd < 0)
{
Log_ErrorPrintf("shm_open failed: %d\n", errno);
Error::SetErrno(error, "shm_open failed: ", errno);
return nullptr;
}
// we're not going to be opening this mapping in other processes, so remove the file
shm_unlink(name);
// use fallocate() to ensure we don't SIGBUS later on.
#ifdef __linux__
if (fallocate(fd, 0, 0, static_cast<off_t>(size)) < 0)
{
Error::SetErrno(error, TinyString::from_format("fallocate({}) failed: ", size), errno);
return nullptr;
}
#else
// ensure it's the correct size
if (ftruncate(fd, static_cast<off_t>(size)) < 0)
{
Log_ErrorPrintf("ftruncate(%zu) failed: %d\n", size, errno);
Error::SetErrno(error, TinyString::from_format("ftruncate({}) failed: ", size), errno);
return nullptr;
}
#endif
return reinterpret_cast<void*>(static_cast<intptr_t>(fd));
}

View File

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#pragma once
@ -34,9 +34,11 @@ enum class PageProtect : u32
#endif
class Error;
namespace MemMap {
std::string GetFileMappingName(const char* prefix);
void* CreateSharedMemory(const char* name, size_t size);
void* CreateSharedMemory(const char* name, size_t size, Error* error);
void DestroySharedMemory(void* ptr);
void* MapSharedMemory(void* handle, size_t offset, void* baseaddr, size_t size, PageProtect mode);
void UnmapSharedMemory(void* baseaddr, size_t size);