SharedMemoryConsumer.h
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package VisionX::Core
19  * @author Kai Welke (kai dot welke at kit dot edu)
20  * @date 2012
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 
25 #pragma once
26 
27 // boost
28 #include <memory>
29 #ifndef Q_MOC_RUN
30 #include <boost/interprocess/managed_shared_memory.hpp>
31 #include <boost/interprocess/sync/interprocess_upgradable_mutex.hpp>
32 #include <boost/interprocess/sync/sharable_lock.hpp>
33 #endif
34 
35 // exceptions
36 #include <iostream>
37 
39 #include <ArmarXCore/interface/core/SharedMemory.h>
40 
41 namespace armarx
42 {
44  boost::interprocess::sharable_lock<boost::interprocess::interprocess_upgradable_mutex>;
45  using SharedMemoryScopedReadLockPtr = std::shared_ptr<SharedMemoryScopedReadLock>;
46 
47  /**
48  * \class SharedMemoryConsumer
49  * \ingroup SharedMemory
50  * The SharedMemoryConsumer opens an existing shared memory segment for reading. It provides synchronized read access to the
51  * shared data. The memory content is an array of objects, where the object type is specified as template parameter.
52  * The SharedMemoryConsumer needs to be constructed, after a SharedMemoryProvider has been created.
53  */
54  template <class MemoryObject, class MemoryObjectMetaInfo = MetaInfoSizeBase>
56  {
57  public:
58  class Wrapper : public MemoryObjectMetaInfo
59  {
60  public:
62  {
63  }
64 
65  Wrapper(const MemoryObjectMetaInfo& source) : MemoryObjectMetaInfo(source)
66  {
67  }
68  };
69 
70  /**
71  * Creates a shared memory consumer.
72  *
73  * @param memoryName name of the memory as set in the SharedMemoryProvider
74  *
75  * @throw SharedMemoryConnectionFailure
76  */
77  SharedMemoryConsumer(std::string newMemoryName)
78  {
79 
80  this->memoryName = newMemoryName;
81  auto env_c_str = getenv("USER");
82  std::string userName = env_c_str ? env_c_str : "";
83 
84  if (!userName.empty())
85  {
86  this->memoryName += userName;
87  }
88 
89  // create shared memory segment
90  try
91  {
92  sharedMemorySegment = new boost::interprocess::managed_shared_memory(
93  boost::interprocess::open_only, memoryName.c_str());
94  }
95  catch (const boost::interprocess::interprocess_exception& e)
96  {
97  std::string reason = "Error opening shared memory segment for reading: ";
99  reason + e.what());
100  }
101 
102  info = sharedMemorySegment->find<Wrapper>("Info").first;
103 
104  if (!info)
105  {
107  memoryName, "Error opening memory size for reading");
108  }
109 
110  // get or create the shared image mutex
111  memoryMutex =
112  sharedMemorySegment
113  ->find<boost::interprocess::interprocess_upgradable_mutex>("SharedMutex")
114  .first;
115 
116  if (!memoryMutex)
117  {
119  memoryName, "Error opening shared mutex for reading");
120  }
121 
122  // create the managed image memory object
123  data = sharedMemorySegment->find<MemoryObject>("Data").first;
124 
125  if (!data)
126  {
128  memoryName, "Error opening shared data for reading");
129  }
130 
131  condSizeChanged =
132  sharedMemorySegment
133  ->find<boost::interprocess::interprocess_condition>("CondSizeChanged")
134  .first;
135 
136  if (!data)
137  {
139  memoryName, "Error opening condition variable for reading");
140  }
141  }
142 
143  /**
144  * Destructs the shared memory consumer.
145  */
147  {
148  // removing of shared memory disabled since otherwise reopening fails
149  //boost::interprocess::shared_memory_object::remove(memoryName.c_str());
150  }
151 
152  /**
153  * Retrieve size of usable shared memory.
154  *
155  * @return size in bytes
156  */
157  int
158  getSize() const
159  {
161  if (!info)
162  {
164  memoryName, "Error opening shared mutex for reading");
165  }
166 
167  return info->size;
168  }
169 
170  typename MemoryObjectMetaInfo::PointerType
171  getMetaInfo(bool threadSafe = true) const
172  {
174  if (threadSafe)
175  {
177  }
178  if (info)
179  {
180  return new Wrapper(*info);
181  }
182  else
183  {
184  return NULL;
185  }
186  }
187 
188  /**
189  * Retrieve pointer to shared memory. Use getScopedReadLock() or lock() / unlock() before reading from the memory.
190  *
191  * @return pointer to the shared memory with type MemoryObject
192  */
193  MemoryObject*
195  {
196  return data;
197  }
198 
199  /**
200  * Retrieve scoped lock to the shared memory for reading.
201  *
202  * @return scoped lock to shared memory
203  */
206  {
208 
209  if (memoryMutex)
210  {
211  lock.reset(new SharedMemoryScopedReadLock(*memoryMutex));
212  }
213 
214  return lock;
215  }
216 
217  /**
218  * Lock shared memory for reading.
219  */
220  void
222  {
223  if (memoryMutex)
224  {
225  memoryMutex->lock_sharable();
226  }
227  }
228 
229  /**
230  * Unlock shared memory after reading.
231  */
232  void
234  {
235  if (memoryMutex)
236  {
237  memoryMutex->unlock_sharable();
238  }
239  }
240 
241  /**
242  * Pointer type for convenience.
243  */
244  using pointer_type =
245  std::shared_ptr<SharedMemoryConsumer<MemoryObject, MemoryObjectMetaInfo>>;
246 
247  private:
248  /**
249  * Name of memory segment
250  */
251  std::string memoryName;
252 
253  /**
254  * Managed shared memory segment
255  */
256  boost::interprocess::managed_shared_memory* sharedMemorySegment;
257 
258  /**
259  * Upgradable data mutex
260  */
261  mutable boost::interprocess::interprocess_upgradable_mutex* memoryMutex;
262 
263  /**
264  * @brief condSizeChanged whether the size was changed
265  */
266  boost::interprocess::interprocess_condition* condSizeChanged;
267 
268  /**
269  * the data
270  */
271  MemoryObject* data;
272 
273  MemoryObjectMetaInfo* info;
274  };
275 } // namespace armarx
armarx::SharedMemoryConsumer
Definition: SharedMemoryConsumer.h:55
armarx::SharedMemoryConsumer::unlock
void unlock()
Unlock shared memory after reading.
Definition: SharedMemoryConsumer.h:233
armarx::SharedMemoryConsumer::SharedMemoryConsumer
SharedMemoryConsumer(std::string newMemoryName)
Creates a shared memory consumer.
Definition: SharedMemoryConsumer.h:77
armarx::SharedMemoryConsumer::Wrapper::Wrapper
Wrapper(const MemoryObjectMetaInfo &source)
Definition: SharedMemoryConsumer.h:65
armarx::SharedMemoryScopedReadLockPtr
std::shared_ptr< SharedMemoryScopedReadLock > SharedMemoryScopedReadLockPtr
Definition: SharedMemoryConsumer.h:45
armarx::SharedMemoryConsumer::Wrapper
Definition: SharedMemoryConsumer.h:58
armarx::exceptions::local::SharedMemoryConnectionFailure
Definition: SharedMemoryExceptions.h:53
armarx::SharedMemoryConsumer::getMemory
MemoryObject * getMemory()
Retrieve pointer to shared memory.
Definition: SharedMemoryConsumer.h:194
armarx::SharedMemoryConsumer::pointer_type
std::shared_ptr< SharedMemoryConsumer< MemoryObject, MemoryObjectMetaInfo > > pointer_type
Pointer type for convenience.
Definition: SharedMemoryConsumer.h:245
armarx::SharedMemoryConsumer::getMetaInfo
MemoryObjectMetaInfo::PointerType getMetaInfo(bool threadSafe=true) const
Definition: SharedMemoryConsumer.h:171
boost::source
Vertex source(const detail::edge_base< Directed, Vertex > &e, const PCG &)
Definition: point_cloud_graph.h:661
armarx::SharedMemoryConsumer::getSize
int getSize() const
Retrieve size of usable shared memory.
Definition: SharedMemoryConsumer.h:158
armarx::SharedMemoryScopedReadLock
boost::interprocess::sharable_lock< boost::interprocess::interprocess_upgradable_mutex > SharedMemoryScopedReadLock
Definition: SharedMemoryConsumer.h:44
SharedMemoryExceptions.h
armarx::SharedMemoryConsumer::getScopedReadLock
SharedMemoryScopedReadLockPtr getScopedReadLock() const
Retrieve scoped lock to the shared memory for reading.
Definition: SharedMemoryConsumer.h:205
armarx::SharedMemoryConsumer::~SharedMemoryConsumer
~SharedMemoryConsumer()
Destructs the shared memory consumer.
Definition: SharedMemoryConsumer.h:146
armarx::SharedMemoryConsumer::Wrapper::Wrapper
Wrapper()
Definition: SharedMemoryConsumer.h:61
armarx::SharedMemoryConsumer::lock
void lock()
Lock shared memory for reading.
Definition: SharedMemoryConsumer.h:221
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27