fw4spl
SlotConnection.hxx
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2017.
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 #ifndef __FWCOM_SLOTCONNECTION_HXX__
8 #define __FWCOM_SLOTCONNECTION_HXX__
9 
10 #ifndef __FWCOM_SLOTCONNECTION_HPP__
11 #error fwCom/SlotConnection.hpp not included
12 #endif
13 
14 #include "fwCom/SlotRun.hpp"
15 
16 namespace fwCom
17 {
18 
19 //------------------------------------------------------------------------------
20 
21 template < typename ... A >
22 inline std::shared_ptr< SlotConnection< void (A ...) > > SlotConnection< void (A ...) >::New(
23  const SignalSptrType& signal,
24  const SlotRunSptrType& slot
25  )
26 {
27  return std::make_shared< SelfType >(signal, slot);
28 }
29 
30 //-----------------------------------------------------------------------------
31 
32 template < typename ... A >
33 inline std::shared_ptr< SlotConnection< void (A ...) > > SlotConnection< void (A ...) >::New(
34  const SignalSptrType& signal,
35  const SlotBase::sptr& slot,
36  const SlotWrapperSptrType& slotWrapper
37  )
38 {
39  return std::make_shared< SelfType >(signal, slot, slotWrapper);
40 }
41 
42 //-----------------------------------------------------------------------------
43 
44 template < typename ... A >
45 inline SlotConnection< void (A ...) >::SlotConnection(const SignalSptrType& signal,
46  const SlotRunSptrType& slot) :
47  m_signal(signal),
48  m_connectedSlot(slot),
49  m_pair(true, slot.get())
50 {
51 }
52 
53 //-----------------------------------------------------------------------------
54 
55 template < typename ... A >
56 inline SlotConnection< void (A ...) >::SlotConnection(
57  const SignalSptrType& signal,
58  const SlotBase::sptr& slot,
59  const SlotWrapperSptrType& slotWrapper
60  ) :
61  m_signal(signal),
62  m_connectedSlot(slot),
63  m_slotWrapper(slotWrapper),
64  m_pair(true, slotWrapper.get())
65 {
66 }
67 
68 //-----------------------------------------------------------------------------
69 
70 template < typename ... A >
71 inline SlotConnection< void (A ...) >::~SlotConnection()
72 {
73  this->disconnect();
74 }
75 
76 //-----------------------------------------------------------------------------
77 
78 template < typename ... A >
79 inline void SlotConnection< void (A ...) >::connectNoLock()
80 {
81  SignalSptrType sig(m_signal);
82  sig->m_slots.push_back( &m_pair );
83 }
84 
85 //-----------------------------------------------------------------------------
86 
87 template < typename ... A >
88 inline void SlotConnection< void (A ...) >::disconnectSignalNoLock(const SignalSptrType& sig)
89 {
90  sig->m_slots.remove( &m_pair );
91  sig->m_connections.erase(m_connectedSlot);
92 }
93 
94 //-----------------------------------------------------------------------------
95 
96 template < typename ... A >
97 inline void SlotConnection< void (A ...) >::disconnectSlotNoLock(const SlotBase::sptr& slot)
98 {
99  try
100  {
101  std::shared_ptr< const SlotConnection< void (A ...) > > thisSptr =
102  std::dynamic_pointer_cast< const SlotConnection< void (A ...) > > ( this->shared_from_this() );
103  slot->m_connections.erase( thisSptr );
104  }
105  catch(const ::boost::bad_weak_ptr&)
106  {
107  // SlotConnection destruction is under way, no need to remove
108  // shared_ptr from connections
109  }
110 }
111 
112 //-----------------------------------------------------------------------------
113 
114 template < typename ... A >
115 inline void SlotConnection< void (A ...) >::disconnect()
116 {
117  ::fwCore::mt::WriteLock lock(m_mutex);
118 
119  SignalSptrType sig(m_signal.lock());
120  SlotBase::sptr slot(m_connectedSlot.lock());
121 
122  if(sig)
123  {
124  ::fwCore::mt::WriteLock lock(sig->m_connectionsMutex);
125  this->disconnectSignalNoLock(sig);
126  }
127 
128  m_slotWrapper.reset();
129 
130  if(slot)
131  {
132  ::fwCore::mt::WriteLock lock(slot->m_connectionsMutex);
133  this->disconnectSlotNoLock(slot);
134  }
135 
136  m_signal.reset();
137  m_connectedSlot.reset();
138 }
139 
140 //-----------------------------------------------------------------------------
141 
142 template < typename ... A >
143 inline void SlotConnection< void (A ...) >::disconnectWeakLock()
144 {
145  ::fwCore::mt::WriteLock lock(m_mutex);
146 
147  SignalSptrType sig(m_signal.lock());
148  SlotBase::sptr slot(m_connectedSlot.lock());
149 
150  if(sig)
151  {
152  this->disconnectSignalNoLock(sig);
153  }
154 
155  m_slotWrapper.reset();
156 
157  if(slot)
158  {
159  ::fwCore::mt::WriteLock lock(slot->m_connectionsMutex);
160  this->disconnectSlotNoLock(slot);
161  }
162 
163  m_signal.reset();
164  m_connectedSlot.reset();
165 }
166 
167 //-----------------------------------------------------------------------------
168 
169 template < typename ... A >
170 inline SlotConnectionBase::BlockerSptrType SlotConnection< void (A ...) >::getBlocker()
171 {
172  ::fwCore::mt::ReadToWriteLock lock(m_mutex);
173 
174  SlotConnectionBase::BlockerSptrType blocker(m_weakBlocker.lock());
175  if( !blocker )
176  {
177  ::fwCore::mt::UpgradeToWriteLock writeLock(lock);
178 
179  blocker = m_weakBlocker.lock();
180 
181  if(!blocker)
182  {
183  blocker = SlotConnectionBase::BlockerSptrType(
184  (void*)NULL,
185  std::bind( &SlotConnection< void (A ...) >::unblock, this )
186  );
187  m_weakBlocker = blocker;
188 
189  // signal has to be locked : signal got a pointer on m_pair
190  SignalSptrType sig(m_signal);
191  ::fwCore::mt::ReadLock lock(sig->m_connectionsMutex);
192  m_pair.first = false;
193  }
194  }
195  return blocker;
196 }
197 
198 //-----------------------------------------------------------------------------
199 
200 template < typename ... A >
201 inline void SlotConnection< void (A ...) >::unblock()
202 {
203  ::fwCore::mt::WriteLock lock(m_mutex);
204  // signal has to be locked : signal got a pointer on m_pair
205  SignalSptrType sig(m_signal);
206  ::fwCore::mt::ReadLock connectionLock(sig->m_connectionsMutex);
207  m_pair.first = true;
208 }
209 
210 //-----------------------------------------------------------------------------
211 
212 } // namespace fwCom
213 
214 #endif /* __FWCOM_SLOTCONNECTION_HXX__ */
215 
::boost::upgrade_lock< ReadWriteMutex > ReadToWriteLock
Defines an upgradable lock type for read/write mutex.
::boost::upgrade_to_unique_lock< ReadWriteMutex > UpgradeToWriteLock
Defines a write lock upgraded from ReadToWriteLock.
Namespace containing fw4spl communication tools.
Definition: DumpEditor.hpp:30
::boost::unique_lock< ReadWriteMutex > WriteLock
Defines a lock of write type for read/write mutex.
::boost::shared_lock< ReadWriteMutex > ReadLock
Defines a lock of read type for read/write mutex.