SharedStorage/core/SharedMemoryManager.cpp
2025-04-27 16:32:10 +00:00

123 lines
3.4 KiB
C++

//
// Created by Kirill Zhukov on 20.04.2025.
//
#include "SharedMemoryManager.h"
#include <iostream>
namespace usub::core
{
SharedMemoryManager::SharedMemoryManager(const std::string& name, size_t size, bool create_new) :
shm_name("/" + name), shm_size(size), shm_fd(-1), shm_ptr(nullptr)
{
if (create_new)
{
create();
}
else
{
open();
}
}
SharedMemoryManager::~SharedMemoryManager()
{
if (this->shm_ptr != nullptr)
{
munmap(this->shm_ptr, shm_size);
}
if (this->shm_fd != -1)
{
close(this->shm_fd);
}
}
void* SharedMemoryManager::base_ptr() const noexcept
{
return this->shm_ptr;
}
size_t SharedMemoryManager::size() const noexcept
{
return this->shm_size;
}
const std::string& SharedMemoryManager::name() const noexcept
{
return this->shm_name;
}
void SharedMemoryManager::destroy()
{
munmap(this->shm_ptr, this->shm_size);
close(this->shm_fd);
shm_unlink(this->shm_name.c_str());
this->shm_ptr = nullptr;
this->shm_fd = -1;
}
bool SharedMemoryManager::exists(const std::string& name)
{
int fd = shm_open(("/" + name).c_str(), O_RDWR, 0600);
if (fd == -1)
return false;
close(fd);
return true;
}
bool SharedMemoryManager::needs_init() const noexcept
{
const auto* base = reinterpret_cast<const uint8_t*>(this->shm_ptr);
for (size_t i = 0; i < sizeof(uint64_t); ++i)
{
if (base[i] != 0)
return false;
}
return true;
}
void SharedMemoryManager::create()
{
::shm_unlink((this->shm_name).c_str());
this->shm_fd = ::shm_open(this->shm_name.c_str(), O_CREAT | O_RDWR | O_EXCL, 0600);
if (this->shm_fd == -1)
{
throw std::runtime_error("Failed to create shared memory: " + shm_name);
}
if (::ftruncate(this->shm_fd, this->shm_size) == -1)
{
::close(this->shm_fd);
::shm_unlink(this->shm_name.c_str());
throw std::runtime_error("Failed to set size for shared memory: " + this->shm_name);
}
this->shm_ptr = ::mmap(nullptr, this->shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, this->shm_fd, 0);
if (this->shm_ptr == MAP_FAILED)
{
::close(this->shm_fd);
::shm_unlink(this->shm_name.c_str());
throw std::runtime_error("Failed to mmap shared memory: " + this->shm_name);
}
std::memset(this->shm_ptr, 0, this->shm_size);
}
void SharedMemoryManager::open()
{
this->shm_fd = ::shm_open(this->shm_name.c_str(), O_RDWR, 0600);
if (this->shm_fd == -1)
{
throw std::runtime_error("Failed to open shared memory: " + this->shm_name);
}
else
{
std::cout << "[shm_open] name: " << this->shm_name << ", fd: " << this->shm_fd << '\n';
}
this->shm_ptr = ::mmap(nullptr, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, this->shm_fd, 0);
if (this->shm_ptr == MAP_FAILED)
{
::close(this->shm_fd);
throw std::runtime_error("Failed to mmap shared memory: " + this->shm_name);
}
}
}