SegmentUtilImplementations.cpp
Go to the documentation of this file.
1 /*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package ArmarX
17 * @author Mirko Waechter( mirko.waechter at kit dot edu)
18 * @date 2016
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
23 
24 #include <Ice/Connection.h>
25 #include <Ice/ObjectAdapter.h>
26 #include <IceUtil/UUID.h>
27 
33 
36 
37 namespace memoryx
38 {
39 
41  {
42  }
43 
44  auto
46  {
47  std::unique_lock lock(tokenMutex);
48 
49  if (!lockToken.empty() && c.ctx.count("token") > 0 && c.ctx.at("token") == lockToken)
50  {
51  return ScopedSharedLockPtr();
52  }
53  return ScopedSharedLockPtr(new ScopedSharedLock(segmentMutex));
54  }
55 
56  auto
58  {
59  std::unique_lock lock(tokenMutex);
60 
61  if (!lockToken.empty() && c.ctx.count("token") > 0 && c.ctx.at("token") == lockToken)
62  {
63  return ScopedUniqueLockPtr();
64  }
65  return ScopedUniqueLockPtr(new ScopedUniqueLock(segmentMutex));
66  }
67 
68  std::string
69  SegmentUtilImplementations::getJSONEntityById(const std::string& id, const Ice::Current&) const
70  {
71  EntityBasePtr entity = getEntityById(id);
72  if (!entity)
73  {
74  throw EntityNotFoundException();
75  }
77  json->setIceObject("entity", entity);
78  return json->asString(true);
79  }
80 
81  EntityBaseList
83  bool includeMetaEntities,
84  const Ice::Current& c) const
85  {
86  auto comp = [](const EntityBasePtr& e1, const EntityBasePtr& e2)
87  { return e1->getId() < e2->getId(); };
88 
89  std::set<EntityBasePtr, decltype(comp)> result(comp);
90  std::set<EntityBasePtr, decltype(comp)> searchList(comp);
91  EntityPtr root = EntityPtr::dynamicCast(getEntityById(id, c));
92  searchList.insert(root);
93  result.insert(root);
94  auto all = getAllEntities(c);
95  std::string attribName = "parentEntityRefs";
96 
97  while (!searchList.empty())
98  {
99  EntityPtr curParent = EntityPtr::dynamicCast(*searchList.begin());
100  auto curParentRef = getEntityRefById(curParent->getId(), c);
101  searchList.erase(searchList.begin());
102  for (EntityBasePtr& entity : all)
103  {
104  if (!entity->hasAttribute(attribName, c))
105  {
106  continue;
107  }
108  auto attr = entity->getAttribute(attribName, c);
109  for (int i = 0; i < attr->size(); ++i)
110  {
112  armarx::VariantPtr::dynamicCast(attr->getValueAt(i, c))->get<EntityRef>();
113  if (ref->equals(curParentRef))
114  {
115  ARMARX_INFO_S << ref->entityName << " is parent of " << entity->getName();
116  if (result.count(entity) ==
117  0) // if already in result list, this item was already in search list
118  {
119  searchList.insert(entity);
120  }
121  result.insert(entity);
122  }
123  }
124  }
125  }
126 
127  if (!includeMetaEntities)
128  {
129  EntityBaseList filteredResult;
130  std::copy_if(result.begin(),
131  result.end(),
132  std::back_inserter(filteredResult),
133  [](const EntityBasePtr& entity) { return !entity->isMetaEntity(); });
134  return filteredResult;
135  }
136  return EntityBaseList(result.begin(), result.end());
137  }
138 
139  EntityBaseList
141  bool includeMetaEntities,
142  const Ice::Current& c) const
143  {
144  auto entity = getEntityByName(entityName);
145  if (entity)
146  {
147  return getEntityWithChildrenById(entity->getId(), includeMetaEntities);
148  }
149  else
150  {
151  return EntityBaseList();
152  }
153  }
154 
155  SegmentLockBasePtr
157  {
159  SegmentLockBasePtr lock = new SegmentLock(!c.con);
160  {
161  std::unique_lock mutexLock(tokenMutex);
162  lockToken = lock->token = IceUtil::generateUUID();
163  }
164  ARMARX_CHECK_EXPRESSION(c.adapter) << "Ice::Current must not be empty";
165  lock->segment =
166  EntityMemorySegmentInterfacePrx::uncheckedCast(c.adapter->createProxy(c.id));
167  if (keepAliveCheckTask)
168  {
169  keepAliveCheckTask->stop();
170  }
172  this,
174  lock->keepAliveIntervalMs * 2,
175  false,
176  "KeepAliveChecker",
177  false);
178  {
179  std::unique_lock lock(keepAliveTimestampMutex);
181  }
182  keepAliveCheckTask->start();
183 
184  return lock;
185  }
186 
187  bool
188  SegmentUtilImplementations::keepLockAlive(const std::string& token, const Ice::Current&)
189  {
190  {
191  std::unique_lock lock(tokenMutex);
192  if (token != lockToken)
193  {
194  throw InvalidLockTokenException();
195  }
196  }
197 
198  if (writeLock)
199  {
200  std::unique_lock lock(keepAliveTimestampMutex);
202  return true;
203  }
204 
205  return false;
206  }
207 
208  bool
209  SegmentUtilImplementations::unlockSegment(const SegmentLockBasePtr& lock, const Ice::Current& c)
210  {
211  std::unique_lock mutexLock(tokenMutex);
212 
213  if (lock->token != lockToken)
214  {
215  throw InvalidLockTokenException();
216  }
217  if (!writeLock)
218  {
219  return false;
220  }
221  writeLock.reset();
222  lockToken.clear();
223  return true;
224  }
225 
226  bool
228  const Ice::Current& c)
229  {
230  std::unique_lock mutexLock(tokenMutex);
231 
232  if (token != lockToken)
233  {
234  throw InvalidLockTokenException();
235  }
236  if (!writeLock)
237  {
238  return false;
239  }
240  writeLock.reset();
241  lockToken.clear();
242  return true;
243  }
244 
245  void
247  {
248  std::unique_lock lock(keepAliveTimestampMutex);
249 
250  auto age = (IceUtil::Time::now() - keepAliveTimestamp);
251  if (age.toMilliSeconds() > keepAliveCheckTask->getInterval() && writeLock)
252  {
253  writeLock.reset();
254 
255  {
256  std::unique_lock mutexLock(tokenMutex);
257  lockToken.clear();
258  }
259 
260  ARMARX_WARNING_S << "Segment lock of segment '" << getSegmentName()
261  << "' did not receive keep-alive in time ("
262  << age.toMilliSecondsDouble()
263  << " ms, interval: " << keepAliveCheckTask->getInterval()
264  << " ) - unlocking segment";
265  }
266  }
267 
269  {
270  if (keepAliveTask)
271  {
272  unlock();
273  keepAliveTask->stop();
274  }
275  }
276 
277  SegmentLock::SegmentLock(bool start_watchdog)
278  {
279  if (start_watchdog)
280  {
281  startWatchdog();
282  }
283  }
284 
285  void
286  SegmentLock::unlock(const Ice::Current& c)
287  {
288  try
289  {
290  if (keepAliveTask)
291  {
292  keepAliveTask->stop();
293  }
294 
295  segment->unlockSegmentWithToken(this->token);
296  }
297  catch (...)
298  {
299  }
300  }
301 
302  void
304  {
306  this, &SegmentLock::keepAlive, keepAliveIntervalMs, false, "KeepAliveTask", false);
307  keepAliveTask->start();
308  }
309 
310  void
312  {
313  startWatchdog();
314  }
315 
316  void
318  {
319  try
320  {
321  segment->keepLockAlive(this->token);
322  }
323  catch (...)
324  {
325  }
326  }
327 
328 } // namespace memoryx
memoryx::SegmentUtilImplementations::getJSONEntityById
std::string getJSONEntityById(const std::string &id, const Ice::Current &) const override
Definition: SegmentUtilImplementations.cpp:69
armarx::ScopedUniqueLock
boost::unique_lock< boost::shared_mutex > ScopedUniqueLock
Definition: Synchronization.h:171
JSONObject.h
memoryx::SegmentLock::ice_postUnmarshal
void ice_postUnmarshal() override
Definition: SegmentUtilImplementations.cpp:311
ArmarXManager.h
memoryx::SegmentUtilImplementations::unlockSegment
bool unlockSegment(const SegmentLockBasePtr &lock, const Ice::Current &c) override
Definition: SegmentUtilImplementations.cpp:209
memoryx::SegmentUtilImplementations::getReadLock
ScopedSharedLockPtr getReadLock(const Ice::Current &c) const
Definition: SegmentUtilImplementations.cpp:45
memoryx::SegmentUtilImplementations::SegmentUtilImplementations
SegmentUtilImplementations()
Definition: SegmentUtilImplementations.cpp:40
armarx::JSONObject
The JSONObject class is used to represent and (de)serialize JSON objects.
Definition: JSONObject.h:43
memoryx::SegmentUtilImplementations::keepAliveTimestamp
IceUtil::Time keepAliveTimestamp
Definition: SegmentUtilImplementations.h:98
memoryx::SegmentUtilImplementations::keepAliveCheckTask
armarx::PeriodicTask< SegmentUtilImplementations >::pointer_type keepAliveCheckTask
Definition: SegmentUtilImplementations.h:101
memoryx
VirtualRobot headers.
Definition: CommonPlacesTester.cpp:48
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
memoryx::SegmentUtilImplementations::segmentMutex
std::shared_mutex segmentMutex
Definition: SegmentUtilImplementations.h:96
memoryx::SegmentUtilImplementations::keepAliveCheck
void keepAliveCheck()
Definition: SegmentUtilImplementations.cpp:246
memoryx::EntityRef
The EntityRef class is used to store references to Entities as values in other Entity instances.
Definition: EntityRef.h:46
IceInternal::Handle< JSONObject >
EntityRef.h
memoryx::SegmentUtilImplementations::keepAliveTimestampMutex
std::mutex keepAliveTimestampMutex
Definition: SegmentUtilImplementations.h:97
armarx::ScopedSharedLockPtr
std::shared_ptr< ScopedSharedLock > ScopedSharedLockPtr
Definition: Synchronization.h:175
armarx::armem::client::query_fns::all
auto all()
Definition: query_fns.h:9
memoryx::SegmentUtilImplementations::lockToken
std::string lockToken
Definition: SegmentUtilImplementations.h:100
memoryx::SegmentUtilImplementations::ScopedUniqueLock
std::unique_lock< std::shared_mutex > ScopedUniqueLock
Definition: SegmentUtilImplementations.h:67
memoryx::SegmentUtilImplementations::lockSegment
SegmentLockBasePtr lockSegment(const Ice::Current &c) override
Definition: SegmentUtilImplementations.cpp:156
memoryx::SegmentUtilImplementations::tokenMutex
std::mutex tokenMutex
Definition: SegmentUtilImplementations.h:99
memoryx::SegmentUtilImplementations::getWriteLock
ScopedUniqueLockPtr getWriteLock(const Ice::Current &c) const
Definition: SegmentUtilImplementations.cpp:57
memoryx::SegmentLock::keepAliveTask
armarx::PeriodicTask< SegmentLock >::pointer_type keepAliveTask
Definition: SegmentUtilImplementations.h:56
memoryx::SegmentUtilImplementations::getEntityWithChildrenByName
EntityBaseList getEntityWithChildrenByName(const std::string &, bool includeMetaEntities, const Ice::Current &c=Ice::emptyCurrent) const override
Definition: SegmentUtilImplementations.cpp:140
memoryx::SegmentLock
Definition: SegmentUtilImplementations.h:41
SegmentUtilImplementations.h
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:213
memoryx::SegmentLock::~SegmentLock
~SegmentLock() override
Definition: SegmentUtilImplementations.cpp:268
armarx::TimeUtil::GetTime
static IceUtil::Time GetTime(TimeMode timeMode=TimeMode::VirtualTime)
Get the current time.
Definition: TimeUtil.cpp:42
ExpressionException.h
memoryx::SegmentUtilImplementations::writeLock
ScopedUniqueLockPtr writeLock
Definition: SegmentUtilImplementations.h:95
memoryx::SegmentUtilImplementations::ScopedUniqueLockPtr
std::unique_ptr< ScopedSharedLock > ScopedUniqueLockPtr
Definition: SegmentUtilImplementations.h:68
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
TimeUtil.h
armarx::ScopedSharedLock
boost::shared_lock< boost::shared_mutex > ScopedSharedLock
Definition: Synchronization.h:172
set
set(LIBS ArmarXCoreInterfaces ${CMAKE_THREAD_LIBS_INIT} ${dl_LIBRARIES} ${rt_LIBRARIES} ${QT_LIBRARIES} ${Boost_LIBRARIES} BoostAssertionHandler ArmarXCPPUtility SimoxUtility) set(LIB_FILES ArmarXManager.cpp ArmarXMultipleObjectsScheduler.cpp ArmarXObjectScheduler.cpp ManagedIceObject.cpp ManagedIceObjectPlugin.cpp Component.cpp ComponentPlugin.cpp IceGridAdmin.cpp ArmarXObjectObserver.cpp IceManager.cpp PackagePath.cpp RemoteReferenceCount.cpp logging/LoggingUtil.cpp logging/Logging.cpp logging/LogSender.cpp logging/ArmarXLogBuf.cpp system/ArmarXDataPath.cpp system/DynamicLibrary.cpp system/ProcessWatcher.cpp system/FactoryCollectionBase.cpp system/cmake/CMakePackageFinder.cpp system/cmake/CMakePackageFinderCache.cpp system/cmake/ArmarXPackageToolInterface.cpp system/RemoteObjectNode.cpp services/sharedmemory/HardwareId.cpp services/tasks/RunningTask.cpp services/tasks/ThreadList.cpp services/tasks/ThreadPool.cpp services/profiler/Profiler.cpp services/profiler/FileLoggingStrategy.cpp services/profiler/IceLoggingStrategy.cpp application/Application.cpp application/ApplicationOptions.cpp application/ApplicationProcessFacet.cpp application/ApplicationNetworkStats.cpp application/properties/PropertyUser.cpp application/properties/Property.cpp application/properties/PropertyDefinition.cpp application/properties/PropertyDefinitionContainer.cpp application/properties/PropertyDefinitionHelpFormatter.cpp application/properties/PropertyDefinitionConfigFormatter.cpp application/properties/PropertyDefinitionBriefHelpFormatter.cpp application/properties/PropertyDefinitionXmlFormatter.cpp application/properties/PropertyDefinitionDoxygenFormatter.cpp application/properties/PropertyDefinitionDoxygenComponentPagesFormatter.cpp application/properties/PropertyDefinitionContainerBriefHelpFormatter.cpp application/properties/IceProperties.cpp exceptions/Exception.cpp exceptions/local/UnexpectedEnumValueException.cpp util/FileSystemPathBuilder.cpp util/StringHelpers.cpp util/IceReportSkipper.cpp util/Throttler.cpp util/distributed/AMDCallbackCollection.cpp util/distributed/RemoteHandle/ClientSideRemoteHandleControlBlock.cpp util/distributed/RemoteHandle/RemoteHandle.cpp util/distributed/RemoteHandle/RemoteHandleControlBlock.cpp time/ice_conversions.cpp time/json_conversions.cpp time/CallbackWaitLock.cpp time/Clock.cpp time/ClockType.cpp time/ClockTypeNames.cpp time/CycleUtil.cpp time/DateTime.cpp time/Duration.cpp time/Frequency.cpp time/LocalTimeServer.cpp time/Metronome.cpp time/ScopedStopWatch.cpp time/StopWatch.cpp time/Timer.cpp time/TimeKeeper.cpp time/TimeUtil.cpp csv/CsvWriter.cpp csv/CsvReader.cpp eigen/conversions.cpp eigen/ice_conversions.cpp) set(LIB_HEADERS ArmarXManager.h ArmarXDummyManager.h ArmarXMultipleObjectsScheduler.h ArmarXObjectObserver.h ArmarXObjectScheduler.h ArmarXFwd.h Component.h ComponentPlugin.h ComponentFactories.h CoreObjectFactories.h IceGridAdmin.h IceManager.h IceManagerImpl.h json_conversions.h ManagedIceObject.h ManagedIceObjectPlugin.h ManagedIceObjectImpl.h ManagedIceObjectDependency.h ManagedIceObjectRegistryInterface.h PackagePath.h RemoteReferenceCount.h system/ImportExport.h system/ImportExportComponent.h system/AbstractFactoryMethod.h system/FactoryCollectionBase.h system/Synchronization.h system/ArmarXDataPath.h system/DynamicLibrary.h system/ProcessWatcher.h system/ConditionSynchronization.h system/cmake/CMakePackageFinder.h system/cmake/CMakePackageFinderCache.h system/cmake/FindPackageX.cmake system/cmake/ArmarXPackageToolInterface.h system/RemoteObjectNode.h logging/LoggingUtil.h logging/LogSender.h logging/Logging.h logging/ArmarXLogBuf.h logging/SpamFilterData.h services/tasks/RunningTask.h services/tasks/PeriodicTask.h services/tasks/ThreadList.h services/tasks/TaskUtil.h services/tasks/ThreadPool.h services/sharedmemory/SharedMemoryProvider.h services/sharedmemory/SharedMemoryConsumer.h services/sharedmemory/IceSharedMemoryProvider.h services/sharedmemory/IceSharedMemoryConsumer.h services/sharedmemory/HardwareIdentifierProvider.h services/sharedmemory/HardwareId.h services/sharedmemory/exceptions/SharedMemoryExceptions.h services/profiler/Profiler.h services/profiler/LoggingStrategy.h services/profiler/FileLoggingStrategy.h services/profiler/IceLoggingStrategy.h application/Application.h application/ApplicationOptions.h application/ApplicationProcessFacet.h application/ApplicationNetworkStats.h application/properties/forward_declarations.h application/properties/Properties.h application/properties/Property.h application/properties/PluginEigen.h application/properties/PluginEnumNames.h application/properties/PluginCfgStruct.h application/properties/PluginAll.h application/properties/PropertyUser.h application/properties/PropertyDefinition.h application/properties/PropertyDefinition.hpp application/properties/PropertyDefinitionInterface.h application/properties/PropertyDefinitionContainer.h application/properties/PropertyDefinitionFormatter.h application/properties/PropertyDefinitionContainerFormatter.h application/properties/PropertyDefinitionConfigFormatter.h application/properties/PropertyDefinitionHelpFormatter.h application/properties/PropertyDefinitionBriefHelpFormatter.h application/properties/PropertyDefinitionXmlFormatter.h application/properties/PropertyDefinitionDoxygenFormatter.h application/properties/PropertyDefinitionDoxygenComponentPagesFormatter.h application/properties/PropertyDefinitionContainerBriefHelpFormatter.h application/properties/ProxyPropertyDefinition.h application/properties/IceProperties.h exceptions/Exception.h exceptions/LocalException.h exceptions/local/DynamicLibraryException.h exceptions/local/ExpressionException.h exceptions/local/FileIOException.h exceptions/local/InvalidPropertyValueException.h exceptions/local/MissingRequiredPropertyException.h exceptions/local/PropertyInheritanceCycleException.h exceptions/local/ProxyNotInitializedException.h exceptions/local/UnexpectedEnumValueException.h exceptions/local/UnmappedValueException.h exceptions/local/ValueRangeExceededException.h exceptions/user/NotImplementedYetException.h rapidxml/rapidxml.hpp rapidxml/rapidxml_print.hpp rapidxml/rapidxml_iterators.hpp rapidxml/rapidxml_utils.hpp rapidxml/wrapper/RapidXmlReader.h rapidxml/wrapper/RapidXmlWriter.h rapidxml/wrapper/DefaultRapidXmlReader.h rapidxml/wrapper/MultiNodeRapidXMLReader.h util/IceBlobToObject.h util/ObjectToIceBlob.h util/FileSystemPathBuilder.h util/FiniteStateMachine.h util/StringHelpers.h util/StringHelperTemplates.h util/algorithm.h util/OnScopeExit.h util/Predicates.h util/Preprocessor.h util/PropagateConst.h util/Registrar.h util/TemplateMetaProgramming.h util/TripleBuffer.h util/IceReportSkipper.h util/Throttler.h util/distributed/AMDCallbackCollection.h util/distributed/RemoteHandle/ClientSideRemoteHandleControlBlock.h util/distributed/RemoteHandle/RemoteHandle.h util/distributed/RemoteHandle/RemoteHandleControlBlock.h util/SimpleStatemachine.h time.h time_minimal.h time/forward_declarations.h time/ice_conversions.h time/json_conversions.h time/CallbackWaitLock.h time/Clock.h time/ClockType.h time/ClockTypeNames.h time/CycleUtil.h time/DateTime.h time/Duration.h time/Frequency.h time/LocalTimeServer.h time/Metronome.h time/ScopedStopWatch.h time/StopWatch.h time/Timer.h time/TimeUtil.h time/TimeKeeper.h csv/CsvWriter.h csv/CsvReader.h eigen/conversions.h eigen/ice_conversions.h ice_conversions.h ice_conversions/ice_conversions_boost_templates.h ice_conversions/ice_conversions_templates.h ice_conversions/ice_conversions_templates.tpp $
Definition: CMakeLists.txt:12
Entity.h
memoryx::SegmentLock::startWatchdog
void startWatchdog()
Definition: SegmentUtilImplementations.cpp:303
ARMARX_INFO_S
#define ARMARX_INFO_S
Definition: Logging.h:202
armarx::PeriodicTask
Definition: ArmarXManager.h:70
memoryx::SegmentUtilImplementations::getEntityWithChildrenById
EntityBaseList getEntityWithChildrenById(const std::string &id, bool includeMetaEntities, const Ice::Current &c=Ice::emptyCurrent) const override
Definition: SegmentUtilImplementations.cpp:82
armarx::ScopedUniqueLockPtr
std::shared_ptr< ScopedUniqueLock > ScopedUniqueLockPtr
Definition: Synchronization.h:174
memoryx::SegmentUtilImplementations::ScopedSharedLockPtr
std::unique_ptr< ScopedSharedLock > ScopedSharedLockPtr
Definition: SegmentUtilImplementations.h:66
Variant.h
memoryx::SegmentLock::unlock
void unlock(const Ice::Current &c=Ice::emptyCurrent) override
Definition: SegmentUtilImplementations.cpp:286
memoryx::SegmentUtilImplementations::unlockSegmentWithToken
bool unlockSegmentWithToken(const std::string &token, const Ice::Current &c) override
Definition: SegmentUtilImplementations.cpp:227
memoryx::SegmentLock::SegmentLock
SegmentLock(bool start_watchdog=false)
Definition: SegmentUtilImplementations.cpp:277
memoryx::SegmentUtilImplementations::keepLockAlive
bool keepLockAlive(const std::string &token, const Ice::Current &) override
Definition: SegmentUtilImplementations.cpp:188
memoryx::SegmentLock::keepAlive
void keepAlive()
Definition: SegmentUtilImplementations.cpp:317