IceSharedMemoryProvider.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 ArmarX::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#include <Ice/Initialize.h>
28#include <Ice/ObjectAdapter.h>
29
35#include <ArmarXCore/interface/core/SharedMemory.h>
36
37// exceptions
39
40namespace armarx
41{
42 /**
43 * \class IceSharedMemoryProvider
44 * \ingroup SharedMemory
45 * The IceSharedMemoryProvider provides data via Ice or shared memory. Whether Ice or shared memory is used for data
46 * transfer is determined based on the hardware id of the machine. The provider should be constructed in the onInit method
47 * and started in the onStart method. <br/>
48 * Use the getScopedWriteLock() or lock() / unlock() methods before writing to the memory.
49 */
50 template <class MemoryObject, class MemoryObjectMetaInfo = MetaInfoSizeBase>
52 virtual public HardwareIdentifierProvider,
53 virtual public SharedMemoryProviderInterface
54 {
55 public:
56 /**
57 * Creates an ice shared memory provider which transparentely communicates using shared memory
58 * on local machines and using Ice on remote machines.
59 *
60 * @param component pointer to component
61 * @param numberElements number of elements of type MemoryObject stored in the memory
62 *
63 * @throw SharedMemoryException
64 */
66 int size,
67 int capacity = 0,
68 std::string nameSuffix = "")
69 {
70
71 memoryName = object->getName() + "Memory" + nameSuffix;
72
73 this->object = object;
74
75 typename MemoryObjectMetaInfo::PointerType info = new MemoryObjectMetaInfo();
76 info->size = size;
77
78 if (capacity > size)
79 {
80 info->capacity = capacity;
81 }
82 else
83 {
84 info->capacity = size;
85 }
86
87 // init shared memory
88 initSharedMemory(object, info);
89 }
90
92 typename MemoryObjectMetaInfo::PointerType info,
93 std::string nameSuffix = "")
94 {
95 memoryName = object->getName() + "Memory" + nameSuffix;
96
97 this->object = object;
98
99 // init shared memory
100
101 initSharedMemory(object, info);
102 }
103
104 protected:
106 {
107 ARMARX_VERBOSE_S << "~IceSharedMemoryProvider " << VAROUT(memoryName);
108 stop();
109 }
110
111 public:
112 /**
113 * Starts the memory provider. The component needs to be connected, otherwise method will fail.
114 *
115 * @throw SharedMemoryException
116 */
117 void
119 {
120 if (object->getState() < eManagedIceObjectStarting)
121 {
123 memoryName,
124 "Started IceSharedMemoryProvider before component is in connected state.");
125 }
126
127 initIce(object);
128 }
129
130 /**
131 * @brief Removes this object from Ice. Call this if you want to use a sharedmemory with the same name again.
132 */
133 void
135 {
136 if (memoryAdapter)
137 {
138 ARMARX_VERBOSE_S << "Remvoing shared memory " << memoryName << " from Ice";
139 ::Ice::Identity id = Ice::stringToIdentity(memoryName);
140 memoryAdapter->remove(id);
141 object->getIceManager()->getIceGridSession()->getAdmin()->removeObject(id);
142 memoryAdapter->destroy();
143 memoryAdapter = NULL;
144 }
145 }
146
147 /**
148 * Retrieve pointer to buffer. This buffer should only be used for writing.
149 * Before writing do not forget to lock the provider using either lock() and unlock()
150 * or getScopedLock()
151 *
152 * @return pointer to the shared memory segment
153 */
154 MemoryObject*
156 {
157 return sharedMemoryProvider->getMemory();
158 }
159
160 /**
161 * Retrieve scoped lock for writing to the memory.
162 *
163 * @return the scoped lock
164 */
167 {
168 auto prov = sharedMemoryProvider;
169 if (prov)
170 {
171 return sharedMemoryProvider->getScopedWriteLock();
172 }
173 else
174 {
176 }
177 }
178
181 {
182 auto prov = sharedMemoryProvider;
183 if (prov)
184 {
185 return sharedMemoryProvider->getScopedReadLock();
186 }
187 else
188 {
190 }
191 }
192
193 /**
194 * lock memory for writing
195 */
196 void
198 {
199 sharedMemoryProvider->lock();
200 }
201
202 /**
203 * unlock memory after writing
204 */
205 void
207 {
208 sharedMemoryProvider->unlock();
209 }
210
211 /**
212 * return data via ice.
213 */
214 Blob
215 getData(MetaInfoSizeBasePtr& info, const Ice::Current& c = Ice::emptyCurrent) override
216 {
217 auto lock = getScopedReadLock();
218
219 info = new MemoryObjectMetaInfo(*sharedMemoryProvider->getMetaInfo());
220
221 if (info->size)
222 {
223 memcpy(buffer.data(), getBuffer(), info->size);
224 }
225
226 return buffer;
227 }
228
229 Blob
231 {
232 auto lock = getScopedReadLock();
233
234 if (sharedMemoryProvider->getMetaInfo()->size)
235 {
236 memcpy(buffer.data(), getBuffer(), sharedMemoryProvider->getMetaInfo()->size);
237 }
238
239 return buffer;
240 }
241
242 void
243 setMetaInfo(const typename MemoryObjectMetaInfo::PointerType& info, bool threadSafe = true)
244 {
246 if (threadSafe)
247 {
249 }
250 sharedMemoryProvider->setMetaInfo(info);
251
252 buffer.resize(info->size);
253 }
254
255 /**
256 * @brief getMetaInfo returns a copy of the memory object information
257 */
258 typename MemoryObjectMetaInfo::PointerType
259 getMetaInfo(bool threadSafe = true) const
260 {
262 if (threadSafe)
263 {
265 }
266 return new MemoryObjectMetaInfo(*sharedMemoryProvider->getMetaInfo());
267 }
268
269 /**
270 * @brief getMetaInfo returns a copy of the memory object information
271 */
272 MetaInfoSizeBasePtr
273 getMetaInfo(const Ice::Current& c) const override
274 {
275 return getMetaInfo();
276 }
277
278 /**
279 * return memory size via ice.
280 */
281 int
282 getSize(const Ice::Current& c = Ice::emptyCurrent) override
283 {
284 return sharedMemoryProvider->getSize();
285 }
286
287 /**
288 * pointer type for convenience.
289 */
292
293 private:
294 // register shared memory object to ice and init ice buffer
295 void
296 initIce(ManagedIceObject* object)
297 {
298 if (!memoryAdapter)
299 {
300
301 Ice::ObjectPrx thisProxy =
302 object->getIceManager()->getIceGridSession()->registerObjectWithNewAdapter(
303 this, memoryName, memoryAdapter);
304 }
305 buffer.resize(sharedMemoryProvider->getSize());
306 }
307
308 // register shared memory provider shared memory and init shared memory buffer
309 void
310 initSharedMemory(ManagedIceObject* object, typename MemoryObjectMetaInfo::PointerType info)
311 {
312 // might throw
313 sharedMemoryProvider.reset(
315 }
316
317 std::string memoryName;
318
319 // data
320 Blob buffer;
321
322 // component
323 ManagedIceObject* object;
324 Ice::ObjectAdapterPtr memoryAdapter;
325
326
327 // pointer type
329 sharedMemoryProvider;
330 };
331
332} // namespace armarx
#define VAROUT(x)
constexpr T c
to retreive a unique Hardware identifier
MetaInfoSizeBasePtr getMetaInfo(const Ice::Current &c) const override
getMetaInfo returns a copy of the memory object information
MemoryObjectMetaInfo::PointerType getMetaInfo(bool threadSafe=true) const
getMetaInfo returns a copy of the memory object information
int getSize(const Ice::Current &c=Ice::emptyCurrent) override
return memory size via ice.
void setMetaInfo(const typename MemoryObjectMetaInfo::PointerType &info, bool threadSafe=true)
IceUtil::Handle< IceSharedMemoryProvider< MemoryObject, MemoryObjectMetaInfo > > pointer_type
pointer type for convenience.
SharedMemoryScopedReadLockPtr getScopedReadLock() const
void start()
Starts the memory provider.
SharedMemoryScopedWriteLockPtr getScopedWriteLock() const
Retrieve scoped lock for writing to the memory.
IceSharedMemoryProvider(ManagedIceObject *object, int size, int capacity=0, std::string nameSuffix="")
Creates an ice shared memory provider which transparentely communicates using shared memory on local ...
void stop()
Removes this object from Ice.
void unlock()
unlock memory after writing
void lock()
lock memory for writing
Blob getData(MetaInfoSizeBasePtr &info, const Ice::Current &c=Ice::emptyCurrent) override
return data via ice.
IceSharedMemoryProvider(ManagedIceObject *object, typename MemoryObjectMetaInfo::PointerType info, std::string nameSuffix="")
MemoryObject * getBuffer()
Retrieve pointer to buffer.
The ManagedIceObject is the base class for all ArmarX objects.
The SharedMemoryProvider creates a shared memory segment for writing.
std::shared_ptr< SharedMemoryProvider< MemoryObject, MemoryObjectMetaInfo > > pointer_type
Pointer type for convenience.
#define ARMARX_VERBOSE_S
Definition Logging.h:207
::IceInternal::Handle<::Ice::ObjectAdapter > ObjectAdapterPtr
Definition IceManager.h:52
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::shared_ptr< SharedMemoryScopedWriteLock > SharedMemoryScopedWriteLockPtr
std::shared_ptr< SharedMemoryScopedReadLock > SharedMemoryScopedReadLockPtr