fw4spl
RecursiveLock.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2018.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #include "fwDataCamp/visitor/RecursiveLock.hpp"
8 
9 #include "fwDataCamp/exception/NullPointer.hpp"
10 #include "fwDataCamp/exception/ObjectNotFound.hpp"
11 
12 #include <fwCore/mt/types.hpp>
13 
14 #include <fwData/camp/mapper.hpp>
15 #include <fwData/Object.hpp>
16 
17 #include <fwMemory/BufferObject.hpp>
18 
19 namespace fwDataCamp
20 {
21 
22 namespace visitor
23 {
24 
25 struct LockVisitor : public camp::ValueVisitor< void >
26 {
28 
30  m_locks(locks)
31  {
32  }
33 
34  //------------------------------------------------------------------------------
35 
36  void operator()(camp::NoType value)
37  {
38  }
39 
40  //------------------------------------------------------------------------------
41 
42  void operator()(bool value)
43  {
44  }
45 
46  //------------------------------------------------------------------------------
47 
48  void operator()(long value)
49  {
50  }
51 
52  //------------------------------------------------------------------------------
53 
54  void operator()(double value)
55  {
56  }
57 
58  //------------------------------------------------------------------------------
59 
60  void operator()(const std::string& value)
61  {
62  }
63 
64  //------------------------------------------------------------------------------
65 
66  void operator()(const camp::EnumObject& value)
67  {
68  }
69 
70  //------------------------------------------------------------------------------
71 
72  void operator()(const camp::UserObject& value)
73  {
74  const camp::Class& metaclass = value.getClass();
75  if ( value.pointer() )
76  {
77  OSLM_DEBUG( "visit class= '" << metaclass.name() << "' ( classname = '"<< value.call("classname") <<"' )" );
78  if( metaclass.hasFunction("is_a") )
79  {
80  if( value.call("is_a", ::camp::Args("::fwData::Object")).to<bool>() )
81  {
82  ::fwData::Object* ptr = value.get< ::fwData::Object* >();
83  ::fwData::Object::sptr obj = ptr->getSptr();
84  ::fwDataCamp::visitor::RecursiveLock visitor( obj, m_locks );
85  }
86  else if( value.call("is_a", ::camp::Args("::fwMemory::BufferObject")).to<bool>() )
87  {
89  ::fwMemory::BufferObject::sptr bo = ptr->getSptr();
91  = SPTR(::fwCore::mt::ReadLock)(new ::fwCore::mt::ReadLock(bo->getMutex()));
92  m_locks->push_back(lock);
93  }
94  }
95  }
96  }
97 };
98 
99 //-----------------------------------------------------------------------------
100 
101 RecursiveLock::RecursiveLock( ::fwData::Object::csptr object, SPTR(LockVectType)locks ) :
102  m_object(object),
103  m_locks(locks)
104 {
105  SPTR(::fwCore::mt::ReadLock) lock
106  = SPTR(::fwCore::mt::ReadLock)(new ::fwCore::mt::ReadLock(m_object->getMutex()));
107  m_locks->push_back(lock);
108  m_campObj = camp::UserObject( *object );
109  this->lock();
110 }
111 
112 //-----------------------------------------------------------------------------
113 
114 RecursiveLock::~RecursiveLock()
115 {
116 }
117 
118 //-----------------------------------------------------------------------------
119 
120 void RecursiveLock::visit(const camp::SimpleProperty& property)
121 {
122 }
123 
124 //-----------------------------------------------------------------------------
125 
126 void RecursiveLock::visit(const camp::EnumProperty& property)
127 {
128 }
129 
130 //-----------------------------------------------------------------------------
131 
132 void RecursiveLock::visit(const camp::MapProperty& property)
133 {
134  const std::string name( property.name() );
135  const size_t size = property.getSize( m_campObj );
136 
137  std::pair< ::camp::Value, ::camp::Value > value;
138  ::camp::Value first;
139  ::camp::Value second;
140 
141  for (size_t var = 0; var < size; ++var)
142  {
143  value = property.getElement(m_campObj, var);
144 
145  first = value.first;
146  second = value.second;
147 
148  SLM_ASSERT("Not managed type for map key.",
149  first.type() == ::camp::stringType ||
150  first.type() == ::camp::intType ||
151  first.type() == ::camp::realType );
152 
153  if ( second.type() == ::camp::userType )
154  {
155  LockVisitor visitor(m_locks);
156  second.visit( visitor );
157  }
158  }
159 }
160 
161 //-----------------------------------------------------------------------------
162 
163 void RecursiveLock::visit(const camp::ArrayProperty& property)
164 {
165  const std::string name( property.name() );
166  const size_t size = property.size( m_campObj );
167 
168  ::camp::Value value;
169 
170  for (size_t var = 0; var < size; ++var)
171  {
172  value = property.get(m_campObj, var);
173 
174  if ( value.type() == ::camp::userType )
175  {
176  LockVisitor visitor(m_locks);
177  value.visit( visitor );
178  }
179  }
180 }
181 
182 //-----------------------------------------------------------------------------
183 
184 void RecursiveLock::visit(const camp::UserProperty& property)
185 {
186  SLM_TRACE_FUNC();
187  const std::string name( property.name() );
188 
189  ::camp::Value elemValue = property.get( m_campObj );
190  LockVisitor visitor(m_locks);
191  elemValue.visit( visitor );
192 }
193 
194 //-----------------------------------------------------------------------------
195 
196 void RecursiveLock::visit(const camp::Function& function)
197 {
198 }
199 
200 //-----------------------------------------------------------------------------
201 
202 void RecursiveLock::lock()
203 {
204  const camp::Class& camClass = ::camp::classByName( m_object->getClassname() );
205  camClass.visit( *this );
206 }
207 
208 //-----------------------------------------------------------------------------
209 
210 } // visitor
211 
212 } // fwDataCamp
#define SPTR(_cls_)
#define SLM_TRACE_FUNC()
Trace contextual function signature.
Definition: spyLog.hpp:329
FWDATACAMP_API RecursiveLock(std::shared_ptr< const ::fwData::Object >object, std::shared_ptr< LockVectType >locks=std::shared_ptr< LockVectType >(new LockVectType()))
Constructor. Creates a recursive lock onto the given object and recursively locks it...
This namespace contains data object descriptions used for introspection.
#define SLM_ASSERT(message, cond)
work like &#39;assert&#39; from &#39;cassert&#39;, with in addition a message logged by spylog (with FATAL loglevel) ...
Definition: spyLog.hpp:308
std::vector< std::shared_ptr< ::fwCore::mt::ReadLock > > LockVectType
Container definition dedicated to object locks storage.
::boost::shared_lock< ReadWriteMutex > ReadLock
Defines a lock of read type for read/write mutex.
This class is an helper to lock an object and all its children recursively.
Base class for each data object.
Define Base class for FW4SPL buffers.
#define OSLM_DEBUG(message)
Definition: spyLog.hpp:241