Cheetah Software  1.0
SharedMemoryObject< T > Class Template Reference

#include <SharedMemory.h>

+ Inheritance diagram for SharedMemoryObject< T >:
+ Collaboration diagram for SharedMemoryObject< T >:

Public Member Functions

 SharedMemoryObject ()=default
 
bool createNew (const std::string &name, bool allowOverwrite=false)
 
void attach (const std::string &name)
 
void closeNew ()
 
void detach ()
 
T * get ()
 
T & operator() ()
 

Private Attributes

T * _data = nullptr
 
std::string _name
 
size_t _size
 
int _fd
 

Detailed Description

template<typename T>
class SharedMemoryObject< T >

A container class for an object which is stored in shared memory. This object can then be viewed in multiple processes or programs. Note that there is significant overhead when creating a shared memory object, so it is recommended that two programs that communicate should have one single large SharedMemoryObject instead of many small ones.

A name string is used to identify shared objects across different programs

Before a shared memory object can be used, you must either allocate new memory, or connect it to an existing shared memory object.

Creating/deleting the memory can be done with createNew/closeNew. Viewing an existing object allocated with createNew can be done with attach/detach

For an example, see test_sharedMemory.cpp

Definition at line 112 of file SharedMemory.h.

Constructor & Destructor Documentation

template<typename T>
SharedMemoryObject< T >::SharedMemoryObject ( )
default

Member Function Documentation

template<typename T>
void SharedMemoryObject< T >::attach ( const std::string &  name)
inline

Attach to an existing shared memory object.

Definition at line 191 of file SharedMemory.h.

191  {
192  assert(!_data);
193  _name = name;
194  _size = sizeof(T);
195  printf("[Shared Memory] open existing %s size %ld bytes\n", name.c_str(),
196  _size);
197  _fd = shm_open(name.c_str(), O_RDWR,
198  S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP | S_IROTH);
199  if (_fd == -1) {
200  printf("[ERROR] SharedMemoryObject::attach shm_open(%s) failed: %s\n",
201  _name.c_str(), strerror(errno));
202  throw std::runtime_error("Failed to create shared memory!");
203  return;
204  }
205 
206  struct stat s;
207  if (fstat(_fd, &s)) {
208  printf("[ERROR] SharedMemoryObject::attach(%s) stat: %s\n", name.c_str(),
209  strerror(errno));
210  throw std::runtime_error("Failed to create shared memory!");
211  return;
212  }
213 
214  if ((size_t)s.st_size != _size) {
215  printf(
216  "[ERROR] SharedMemoryObject::attach(%s) on something that was "
217  "incorrectly "
218  "sized (size is %ld bytes, should be %ld)\n",
219  _name.c_str(), s.st_size, _size);
220  throw std::runtime_error("Failed to create shared memory!");
221  return;
222  }
223 
224  void* mem =
225  mmap(nullptr, _size, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0);
226  if (mem == MAP_FAILED) {
227  printf("[ERROR] SharedMemory::attach(%s) mmap fail: %s\n", _name.c_str(),
228  strerror(errno));
229  throw std::runtime_error("Failed to create shared memory!");
230  return;
231  }
232 
233  _data = (T*)mem;
234  }
std::string _name
Definition: SharedMemory.h:318

+ Here is the caller graph for this function:

template<typename T>
void SharedMemoryObject< T >::closeNew ( )
inline

Free memory associated with the current open shared memory object. The object could have been opened with either attach or createNew. After calling this, no process can use this shared object

Definition at line 241 of file SharedMemory.h.

241  {
242  assert(_data);
243  // first, unmap
244  if (munmap((void*)_data, _size)) {
245  printf("[ERROR] SharedMemoryObject::closeNew (%s) munmap %s\n",
246  _name.c_str(), strerror(errno));
247  throw std::runtime_error("Failed to create shared memory!");
248  return;
249  }
250 
251  _data = nullptr;
252 
253  if (shm_unlink(_name.c_str())) {
254  printf("[ERROR] SharedMemoryObject::closeNew (%s) shm_unlink %s\n",
255  _name.c_str(), strerror(errno));
256  throw std::runtime_error("Failed to create shared memory!");
257  return;
258  }
259 
260  // close fd
261  if (close(_fd)) {
262  printf("[ERROR] SharedMemoryObject::closeNew (%s) close %s\n",
263  _name.c_str(), strerror(errno));
264  throw std::runtime_error("Failed to create shared memory!");
265  return;
266  }
267 
268  _fd = 0;
269  }
std::string _name
Definition: SharedMemory.h:318

+ Here is the caller graph for this function:

template<typename T>
bool SharedMemoryObject< T >::createNew ( const std::string &  name,
bool  allowOverwrite = false 
)
inline

Allocate memory for the shared memory object and attach to it. If allowOverwrite is true, and there's already an object with this name, the old object is overwritten Note that if this happens, the object may be initialized in a very weird state.

Otherwise, if an object with the name already exists, throws a std::runtime_error

Definition at line 125 of file SharedMemory.h.

125  {
126  bool hadToDelete = false;
127  assert(!_data);
128  _name = name;
129  _size = sizeof(T);
130  printf("[Shared Memory] open new %s, size %ld bytes\n", name.c_str(),
131  _size);
132 
133  _fd = shm_open(name.c_str(), O_RDWR | O_CREAT,
134  S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP | S_IROTH);
135  if (_fd == -1) {
136  printf("[ERROR] SharedMemoryObject shm_open failed: %s\n",
137  strerror(errno));
138  throw std::runtime_error("Failed to create shared memory!");
139  return false;
140  }
141 
142  struct stat s;
143  if (fstat(_fd, &s)) {
144  printf("[ERROR] SharedMemoryObject::createNew(%s) stat: %s\n",
145  name.c_str(), strerror(errno));
146  throw std::runtime_error("Failed to create shared memory!");
147  return false;
148  }
149 
150  if (s.st_size) {
151  printf(
152  "[Shared Memory] SharedMemoryObject::createNew(%s) on something that "
153  "wasn't new (size is %ld bytes)\n",
154  _name.c_str(), s.st_size);
155  hadToDelete = true;
156  if (!allowOverwrite)
157  throw std::runtime_error(
158  "Failed to create shared memory - it already exists.");
159  printf("\tusing existing shared memory!\n");
160  // return false;
161  }
162 
163  if (ftruncate(_fd, _size)) {
164  printf("[ERROR] SharedMemoryObject::createNew(%s) ftruncate(%ld): %s\n",
165  name.c_str(), _size, strerror(errno));
166  throw std::runtime_error("Failed to create shared memory!");
167  return false;
168  }
169 
170  void* mem =
171  mmap(nullptr, _size, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0);
172  if (mem == MAP_FAILED) {
173  printf("[ERROR] SharedMemory::createNew(%s) mmap fail: %s\n",
174  _name.c_str(), strerror(errno));
175  throw std::runtime_error("Failed to create shared memory!");
176  return false;
177  }
178 
179  // there is a chance that the shared memory is not zeroed if we are reusing
180  // old memory. this causes all sorts of weird issues, especially if the
181  // layout of the object in memory has changed.
182  memset(mem, 0, _size);
183 
184  _data = (T*)mem;
185  return hadToDelete;
186  }
std::string _name
Definition: SharedMemory.h:318

+ Here is the caller graph for this function:

template<typename T>
void SharedMemoryObject< T >::detach ( )
inline

Close this view of the currently opened shared memory object. The object can be opened with either attach or createNew. After calling this, this process can no longer use this shared object, but other processes still can.

Definition at line 277 of file SharedMemory.h.

277  {
278  assert(_data);
279  // first, unmap
280  if (munmap((void*)_data, _size)) {
281  printf("[ERROR] SharedMemoryObject::detach (%s) munmap %s\n",
282  _name.c_str(), strerror(errno));
283  throw std::runtime_error("Failed to create shared memory!");
284  return;
285  }
286 
287  _data = nullptr;
288 
289  // close fd
290  if (close(_fd)) {
291  printf("[ERROR] SharedMemoryObject::detach (%s) close %s\n",
292  _name.c_str(), strerror(errno));
293  throw std::runtime_error("Failed to create shared memory!");
294  return;
295  }
296 
297  _fd = 0;
298  }
std::string _name
Definition: SharedMemory.h:318

+ Here is the caller graph for this function:

template<typename T>
T* SharedMemoryObject< T >::get ( )
inline

Get the shared memory object.

Definition at line 303 of file SharedMemory.h.

303  {
304  assert(_data);
305  return _data;
306  }

+ Here is the caller graph for this function:

template<typename T>
T& SharedMemoryObject< T >::operator() ( )
inline

Get the shared memory object.

Definition at line 311 of file SharedMemory.h.

311  {
312  assert(_data);
313  return *_data;
314  }

Member Data Documentation

template<typename T>
T* SharedMemoryObject< T >::_data = nullptr
private

Definition at line 317 of file SharedMemory.h.

template<typename T>
int SharedMemoryObject< T >::_fd
private

Definition at line 320 of file SharedMemory.h.

template<typename T>
std::string SharedMemoryObject< T >::_name
private

Definition at line 318 of file SharedMemory.h.

template<typename T>
size_t SharedMemoryObject< T >::_size
private

Definition at line 319 of file SharedMemory.h.


The documentation for this class was generated from the following file: