17 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
21 #elif defined(_WIN32) || defined(_WIN64)
29 class SharedMemory::Impl
32 Impl(
const std::string&
name,
size_t size)
34 assert(!
name.empty() &&
"Shared memory buffer name must not be empty!");
35 assert((
size > 0) &&
"Shared memory buffer size must be greater than zero!");
37 size_t total = SHARED_MEMORY_HEADER_SIZE +
size;
38 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
43 _shared = shm_open(_name.c_str(), (O_CREAT | O_EXCL | O_RDWR), (S_IRUSR | S_IWUSR));
47 _shared = shm_open(_name.c_str(), (O_CREAT | O_RDWR), (S_IRUSR | S_IWUSR));
49 throwex SystemException(
"Failed to create or open a shared memory handler!");
56 int result = ftruncate(_shared, total);
58 throwex SystemException(
"Failed to truncate a shared memory handler!");
62 _ptr = mmap(
nullptr, total, (PROT_READ | PROT_WRITE), MAP_SHARED, _shared, 0);
63 if (_ptr == MAP_FAILED)
66 shm_unlink(_name.c_str());
67 throwex SystemException(
"Failed to map a shared memory buffer!");
69 #elif defined(_WIN32) || defined(_WIN64)
70 _name =
"Global\\" +
name;
74 _shared = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, _name.c_str());
75 if (_shared ==
nullptr)
78 _shared = CreateFileMappingA(INVALID_HANDLE_VALUE,
nullptr, PAGE_READWRITE, 0, (DWORD)total, _name.c_str());
79 if (_shared ==
nullptr)
80 throwex SystemException(
"Failed to create or open a shared memory handler!");
86 _ptr = MapViewOfFile(_shared, FILE_MAP_ALL_ACCESS, 0, 0, total);
90 throwex SystemException(
"Failed to map a shared memory buffer!");
93 static const char* SHARED_MEMORY_HEADER_PREFIX =
"SHMM";
99 std::memcpy(((SharedMemoryHeader*)_ptr)->prefix, SHARED_MEMORY_HEADER_PREFIX, 4 );
100 ((SharedMemoryHeader*)_ptr)->size =
size;
105 bool is_valid_prefix = (std::strncmp(((SharedMemoryHeader*)_ptr)->prefix, SHARED_MEMORY_HEADER_PREFIX, 4) == 0);
106 bool is_valid_size = (((SharedMemoryHeader*)_ptr)->size ==
size);
107 if (!is_valid_prefix || !is_valid_size)
109 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
112 #elif defined(_WIN32) || defined(_WIN64)
113 UnmapViewOfFile(_ptr);
114 CloseHandle(_shared);
116 if (!is_valid_prefix)
117 throwex SystemException(
"Invalid shared memory buffer prefix!");
119 throwex SystemException(
"Invalid shared memory buffer size!");
126 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
128 size_t total = ((SharedMemoryHeader*)_ptr)->size + SHARED_MEMORY_HEADER_SIZE;
129 int result = munmap(_ptr, total);
131 fatality(SystemException(
"Failed to unmap a shared memory buffer!"));
134 result = close(_shared);
136 fatality(SystemException(
"Failed to close a shared memory handler!"));
141 result = shm_unlink(_name.c_str());
143 fatality(SystemException(
"Failed to unlink a shared memory handler!"));
145 #elif defined(_WIN32) || defined(_WIN64)
147 if (!UnmapViewOfFile(_ptr))
148 fatality(SystemException(
"Failed to unmap a shared memory buffer!"));
151 if (!CloseHandle(_shared))
152 fatality(SystemException(
"Failed to close a shared memory handler!"));
156 void*
ptr() {
return (uint8_t*)_ptr + SHARED_MEMORY_HEADER_SIZE; }
157 const void*
ptr()
const {
return _ptr; }
158 bool owner()
const {
return _owner; }
162 static const int SHARED_MEMORY_HEADER_SIZE = 64;
165 struct SharedMemoryHeader
176 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
178 #elif defined(_WIN32) || defined(_WIN64)
191 static_assert((StorageSize >=
sizeof(Impl)),
"SharedMemory::StorageSize must be increased!");
192 static_assert(((StorageAlign %
alignof(Impl)) == 0),
"SharedMemory::StorageAlign must be adjusted!");
201 reinterpret_cast<Impl*
>(&_storage)->~Impl();
void * ptr()
Get the shared memory block pointer.
bool owner() const
Get the shared memory owner flag (true if the new one was created, false if the existing one was open...
size_t size() const noexcept
Get the shared memory block size.
SharedMemory(const std::string &name, size_t size)
Create a new or open existing block of shared memory with a given name and size.
const std::string & name() const noexcept
Get the shared memory block name.
Aligned storage validator.
#define throwex
Throw extended exception macro.
Fatal abort execution definition.
#define fatality(...)
Fatal abort execution extended macro.
C++ Common project definitions.
Shared memory manager definition.
Aligned storage validator definition.