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