123 lines
3.4 KiB
C++
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);
|
|
}
|
|
}
|
|
}
|