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 
26 
32 
33 #include <IceUtil/UUID.h>
34 #include <Ice/ObjectAdapter.h>
35 #include <Ice/Connection.h>
36 
37 
38 namespace memoryx
39 {
40 
42  {
43  }
44 
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 
57  {
58  std::unique_lock lock(tokenMutex);
59 
60  if (!lockToken.empty() && c.ctx.count("token") > 0 && c.ctx.at("token") == lockToken)
61  {
62  return ScopedUniqueLockPtr();
63  }
64  return ScopedUniqueLockPtr(new ScopedUniqueLock(segmentMutex));
65  }
66 
67  std::string SegmentUtilImplementations::getJSONEntityById(const std::string& id, const Ice::Current&) const
68  {
69  EntityBasePtr entity = getEntityById(id);
70  if (!entity)
71  {
72  throw EntityNotFoundException();
73  }
75  json->setIceObject("entity", entity);
76  return json->asString(true);
77  }
78 
79  EntityBaseList SegmentUtilImplementations::getEntityWithChildrenById(const std::string& id, bool includeMetaEntities, const Ice::Current& c) const
80  {
81  auto comp = [](const EntityBasePtr & e1, const EntityBasePtr & e2)
82  {
83  return e1->getId() < e2->getId();
84  };
85 
86  std::set<EntityBasePtr, decltype(comp)> result(comp);
87  std::set<EntityBasePtr, decltype(comp)> searchList(comp);
88  EntityPtr root = EntityPtr::dynamicCast(getEntityById(id, c));
89  searchList.insert(root);
90  result.insert(root);
91  auto all = getAllEntities(c);
92  std::string attribName = "parentEntityRefs";
93 
94  while (!searchList.empty())
95  {
96  EntityPtr curParent = EntityPtr::dynamicCast(*searchList.begin());
97  auto curParentRef = getEntityRefById(curParent->getId(), c);
98  searchList.erase(searchList.begin());
99  for (EntityBasePtr& entity : all)
100  {
101  if (!entity->hasAttribute(attribName, c))
102  {
103  continue;
104  }
105  auto attr = entity->getAttribute(attribName, c);
106  for (int i = 0; i < attr->size(); ++i)
107  {
108  memoryx::EntityRefPtr ref = armarx::VariantPtr::dynamicCast(attr->getValueAt(i, c))->get<EntityRef>();
109  if (ref->equals(curParentRef))
110  {
111  ARMARX_INFO_S << ref->entityName << " is parent of " << entity->getName();
112  if (result.count(entity) == 0) // if already in result list, this item was already in search list
113  {
114  searchList.insert(entity);
115  }
116  result.insert(entity);
117  }
118  }
119  }
120  }
121 
122  if (!includeMetaEntities)
123  {
124  EntityBaseList filteredResult;
125  std::copy_if(result.begin(), result.end(), std::back_inserter(filteredResult),
126  [](const EntityBasePtr & entity)
127  {
128  return !entity->isMetaEntity();
129  });
130  return filteredResult;
131  }
132  return EntityBaseList(result.begin(), result.end());
133 
134  }
135 
136  EntityBaseList SegmentUtilImplementations::getEntityWithChildrenByName(const std::string& entityName, bool includeMetaEntities, const Ice::Current& c) const
137  {
138  auto entity = getEntityByName(entityName);
139  if (entity)
140  {
141  return getEntityWithChildrenById(entity->getId(), includeMetaEntities);
142  }
143  else
144  {
145  return EntityBaseList();
146  }
147  }
148 
149  SegmentLockBasePtr SegmentUtilImplementations::lockSegment(const Ice::Current& c)
150  {
152  SegmentLockBasePtr lock = new SegmentLock(!c.con);
153  {
154  std::unique_lock mutexLock(tokenMutex);
155  lockToken = lock->token = IceUtil::generateUUID();
156  }
157  ARMARX_CHECK_EXPRESSION(c.adapter) << "Ice::Current must not be empty";
158  lock->segment = EntityMemorySegmentInterfacePrx::uncheckedCast(c.adapter->createProxy(c.id));
159  if (keepAliveCheckTask)
160  {
161  keepAliveCheckTask->stop();
162  }
163  keepAliveCheckTask = new armarx::PeriodicTask<SegmentUtilImplementations>(this, &SegmentUtilImplementations::keepAliveCheck, lock->keepAliveIntervalMs * 2, false, "KeepAliveChecker", false);
164  {
165  std::unique_lock lock(keepAliveTimestampMutex);
167  }
168  keepAliveCheckTask->start();
169 
170  return lock;
171  }
172 
173  bool SegmentUtilImplementations::keepLockAlive(const std::string& token, const Ice::Current&)
174  {
175  {
176  std::unique_lock lock(tokenMutex);
177  if (token != lockToken)
178  {
179  throw InvalidLockTokenException();
180  }
181  }
182 
183  if (writeLock)
184  {
185  std::unique_lock lock(keepAliveTimestampMutex);
187  return true;
188  }
189 
190  return false;
191  }
192 
193  bool SegmentUtilImplementations::unlockSegment(const SegmentLockBasePtr& lock, const Ice::Current& c)
194  {
195  std::unique_lock mutexLock(tokenMutex);
196 
197  if (lock->token != lockToken)
198  {
199  throw InvalidLockTokenException();
200  }
201  if (!writeLock)
202  {
203  return false;
204  }
205  writeLock.reset();
206  lockToken.clear();
207  return true;
208  }
209 
210 
211 
212  bool SegmentUtilImplementations::unlockSegmentWithToken(const std::string& token, const Ice::Current& c)
213  {
214  std::unique_lock mutexLock(tokenMutex);
215 
216  if (token != lockToken)
217  {
218  throw InvalidLockTokenException();
219  }
220  if (!writeLock)
221  {
222  return false;
223  }
224  writeLock.reset();
225  lockToken.clear();
226  return true;
227  }
228 
230  {
231  std::unique_lock lock(keepAliveTimestampMutex);
232 
233  auto age = (IceUtil::Time::now() - keepAliveTimestamp);
234  if (age.toMilliSeconds() > keepAliveCheckTask->getInterval() && writeLock)
235  {
236  writeLock.reset();
237 
238  {
239  std::unique_lock mutexLock(tokenMutex);
240  lockToken.clear();
241  }
242 
243  ARMARX_WARNING_S << "Segment lock of segment '" << getSegmentName() << "' did not receive keep-alive in time (" << age.toMilliSecondsDouble() << " ms, interval: " << keepAliveCheckTask->getInterval() << " ) - unlocking segment";
244  }
245  }
246 
248  {
249  if (keepAliveTask)
250  {
251  unlock();
252  keepAliveTask->stop();
253  }
254  }
255 
256  SegmentLock::SegmentLock(bool start_watchdog)
257  {
258  if (start_watchdog)
259  {
260  startWatchdog();
261  }
262  }
263 
264  void SegmentLock::unlock(const Ice::Current& c)
265  {
266  try
267  {
268  if (keepAliveTask)
269  {
270  keepAliveTask->stop();
271  }
272 
273  segment->unlockSegmentWithToken(this->token);
274  }
275  catch (...)
276  {
277 
278  }
279  }
280 
282  {
283  keepAliveTask = new armarx::PeriodicTask<SegmentLock>(this, &SegmentLock::keepAlive, keepAliveIntervalMs, false, "KeepAliveTask", false);
284  keepAliveTask->start();
285  }
286 
288  {
289  startWatchdog();
290  }
291 
293  {
294  try
295  {
296  segment->keepLockAlive(this->token);
297  }
298  catch (...)
299  {
300  }
301  }
302 
303 } // namespace memoryx
memoryx::SegmentUtilImplementations::getJSONEntityById
std::string getJSONEntityById(const std::string &id, const Ice::Current &) const override
Definition: SegmentUtilImplementations.cpp:67
armarx::ScopedUniqueLock
boost::unique_lock< boost::shared_mutex > ScopedUniqueLock
Definition: Synchronization.h:153
JSONObject.h
memoryx::SegmentLock::ice_postUnmarshal
void ice_postUnmarshal() override
Definition: SegmentUtilImplementations.cpp:287
ArmarXManager.h
memoryx::SegmentUtilImplementations::unlockSegment
bool unlockSegment(const SegmentLockBasePtr &lock, const Ice::Current &c) override
Definition: SegmentUtilImplementations.cpp:193
memoryx::SegmentUtilImplementations::getReadLock
ScopedSharedLockPtr getReadLock(const Ice::Current &c) const
Definition: SegmentUtilImplementations.cpp:45
memoryx::SegmentUtilImplementations::SegmentUtilImplementations
SegmentUtilImplementations()
Definition: SegmentUtilImplementations.cpp:41
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:88
memoryx::SegmentUtilImplementations::keepAliveCheckTask
armarx::PeriodicTask< SegmentUtilImplementations >::pointer_type keepAliveCheckTask
Definition: SegmentUtilImplementations.h:91
memoryx
VirtualRobot headers.
Definition: CommonPlacesTester.cpp:48
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
memoryx::SegmentUtilImplementations::segmentMutex
std::shared_mutex segmentMutex
Definition: SegmentUtilImplementations.h:86
memoryx::SegmentUtilImplementations::keepAliveCheck
void keepAliveCheck()
Definition: SegmentUtilImplementations.cpp:229
memoryx::EntityRef
The EntityRef class is used to store references to Entities as values in other Entity instances.
Definition: EntityRef.h:45
IceInternal::Handle< JSONObject >
EntityRef.h
memoryx::SegmentUtilImplementations::keepAliveTimestampMutex
std::mutex keepAliveTimestampMutex
Definition: SegmentUtilImplementations.h:87
armarx::armem::client::query_fns::all
auto all()
Definition: query_fns.h:10
armarx::ScopedSharedLockPtr
std::shared_ptr< ScopedSharedLock > ScopedSharedLockPtr
Definition: Synchronization.h:157
memoryx::SegmentUtilImplementations::lockToken
std::string lockToken
Definition: SegmentUtilImplementations.h:90
memoryx::SegmentUtilImplementations::ScopedUniqueLock
std::unique_lock< std::shared_mutex > ScopedUniqueLock
Definition: SegmentUtilImplementations.h:63
memoryx::SegmentUtilImplementations::lockSegment
SegmentLockBasePtr lockSegment(const Ice::Current &c) override
Definition: SegmentUtilImplementations.cpp:149
memoryx::SegmentUtilImplementations::tokenMutex
std::mutex tokenMutex
Definition: SegmentUtilImplementations.h:89
memoryx::SegmentUtilImplementations::getWriteLock
ScopedUniqueLockPtr getWriteLock(const Ice::Current &c) const
Definition: SegmentUtilImplementations.cpp:56
memoryx::SegmentLock::keepAliveTask
armarx::PeriodicTask< SegmentLock >::pointer_type keepAliveTask
Definition: SegmentUtilImplementations.h:50
memoryx::SegmentUtilImplementations::getEntityWithChildrenByName
EntityBaseList getEntityWithChildrenByName(const std::string &, bool includeMetaEntities, const Ice::Current &c=Ice::emptyCurrent) const override
Definition: SegmentUtilImplementations.cpp:136
memoryx::SegmentLock
Definition: SegmentUtilImplementations.h:35
SegmentUtilImplementations.h
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:206
memoryx::SegmentLock::~SegmentLock
~SegmentLock() override
Definition: SegmentUtilImplementations.cpp:247
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:85
memoryx::SegmentUtilImplementations::ScopedUniqueLockPtr
std::unique_ptr< ScopedSharedLock > ScopedUniqueLockPtr
Definition: SegmentUtilImplementations.h:64
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:154
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:281
ARMARX_INFO_S
#define ARMARX_INFO_S
Definition: Logging.h:195
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:79
armarx::ScopedUniqueLockPtr
std::shared_ptr< ScopedUniqueLock > ScopedUniqueLockPtr
Definition: Synchronization.h:156
memoryx::SegmentUtilImplementations::ScopedSharedLockPtr
std::unique_ptr< ScopedSharedLock > ScopedSharedLockPtr
Definition: SegmentUtilImplementations.h:62
Variant.h
memoryx::SegmentLock::unlock
void unlock(const Ice::Current &c=Ice::emptyCurrent) override
Definition: SegmentUtilImplementations.cpp:264
memoryx::SegmentUtilImplementations::unlockSegmentWithToken
bool unlockSegmentWithToken(const std::string &token, const Ice::Current &c) override
Definition: SegmentUtilImplementations.cpp:212
memoryx::SegmentLock::SegmentLock
SegmentLock(bool start_watchdog=false)
Definition: SegmentUtilImplementations.cpp:256
memoryx::SegmentUtilImplementations::keepLockAlive
bool keepLockAlive(const std::string &token, const Ice::Current &) override
Definition: SegmentUtilImplementations.cpp:173
memoryx::SegmentLock::keepAlive
void keepAlive()
Definition: SegmentUtilImplementations.cpp:292