POSIX Shared Memory Data Structures 1.0
High-performance lock-free data structures for inter-process communication
Loading...
Searching...
No Matches
posix_shm.h
Go to the documentation of this file.
1
16#pragma once
17#include <string>
18#include <stdexcept>
19#include <sys/mman.h>
20#include <sys/stat.h>
21#include <fcntl.h>
22#include <unistd.h>
23#include <cstring>
24#include <atomic>
25#include <cerrno>
26#include "shm_table.h"
27
60template<typename TableType = shm_table>
62{
63private:
68 struct header
69 {
70 std::atomic<int> ref_count;
71 TableType table;
72
74 void inc()
75 {
76 ref_count.fetch_add(1, std::memory_order_relaxed);
77 }
78
81 int dec()
82 {
83 return ref_count.fetch_sub(1, std::memory_order_release) - 1;
84 }
85 };
86
87 void *base_addr;
88 size_t total_size;
89 std::string name;
90 int fd;
91 header *hdr;
92
93public:
121 posix_shm_impl(const std::string &name, size_t size = 0)
122 : name(name), total_size(size + sizeof(header))
123 {
124 bool created = false;
125
126 if (size == 0) {
127 // Size 0 means attach to existing only
128 fd = shm_open(name.c_str(), O_RDWR, 0666);
129 if (fd == -1)
130 {
131 throw std::runtime_error("Failed to open existing shared memory: " + std::string(strerror(errno)));
132 }
133 // Need to get the actual size
134 struct stat sb;
135 if (fstat(fd, &sb) == -1) {
136 close(fd);
137 throw std::runtime_error("Failed to get shared memory size: " + std::string(strerror(errno)));
138 }
139 total_size = sb.st_size;
140 }
141 else {
142 // Size > 0 means create new or attach to existing
143 fd = shm_open(name.c_str(), O_CREAT | O_EXCL | O_RDWR, 0666);
144 if (fd == -1)
145 {
146 if (errno == EEXIST)
147 {
148 fd = shm_open(name.c_str(), O_RDWR, 0666);
149 if (fd == -1)
150 {
151 throw std::runtime_error("Failed to open existing shared memory: " + std::string(strerror(errno)));
152 }
153 }
154 else
155 {
156 throw std::runtime_error("Failed to create shared memory: " + std::string(strerror(errno)));
157 }
158 }
159 else
160 {
161 created = true;
162 }
163 }
164
165 if (created && ftruncate(fd, total_size) == -1)
166 {
167 close(fd);
168 shm_unlink(name.c_str());
169 throw std::runtime_error("Failed to set size of shared memory: " + std::string(strerror(errno)));
170 }
171
172 base_addr = mmap(NULL, total_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
173 if (base_addr == MAP_FAILED)
174 {
175 close(fd);
176 if (created)
177 shm_unlink(name.c_str());
178 throw std::runtime_error("Failed to map shared memory: " + std::string(strerror(errno)));
179 }
180
181 hdr = static_cast<header *>(base_addr);
182 if (created)
183 {
184 // Initialize header with reference count 1 and empty table
185 new (hdr) header{{1}, TableType{}};
186 }
187 else
188 {
189 hdr->inc();
190 }
191 }
192
205 {
206 hdr->dec();
207 munmap(base_addr, total_size);
208 close(fd);
209 }
210
222 void *get_base_addr() const
223 {
224 return &hdr->table;
225 }
226
241 size_t get_total_size() const
242 {
243 return total_size - sizeof(header);
244 }
245
260 TableType* get_table()
261 {
262 return &hdr->table;
263 }
264
272 const TableType* get_table() const
273 {
274 return &hdr->table;
275 }
276
292 int get_ref_count() const
293 {
294 return hdr->ref_count.load(std::memory_order_acquire);
295 }
296
314 bool unlink()
315 {
316 if (shm_unlink(name.c_str()) == -1)
317 {
318 return false;
319 }
320 return true;
321 }
322
325
328
330 using table_type = TableType;
331};
332
340
348
356
POSIX shared memory wrapper with RAII and reference counting.
Definition posix_shm.h:62
posix_shm_impl(const posix_shm_impl &)=delete
Deleted copy constructor (non-copyable)
bool unlink()
Explicitly unlink the shared memory segment.
Definition posix_shm.h:314
int get_ref_count() const
Get current reference count.
Definition posix_shm.h:292
posix_shm_impl & operator=(const posix_shm_impl &)=delete
Deleted copy assignment (non-copyable)
size_t get_total_size() const
Get usable size for data (excluding header)
Definition posix_shm.h:241
TableType table_type
Type alias for the table type parameter.
Definition posix_shm.h:330
TableType * get_table()
Get mutable pointer to metadata table.
Definition posix_shm.h:260
const TableType * get_table() const
Get const pointer to metadata table.
Definition posix_shm.h:272
~posix_shm_impl()
Destructor with automatic cleanup.
Definition posix_shm.h:204
posix_shm_impl(const std::string &name, size_t size=0)
Create or attach to a POSIX shared memory segment.
Definition posix_shm.h:121
void * get_base_addr() const
Get base address for user data (after header)
Definition posix_shm.h:222