Synchronization.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 ArmarXCore::core
19 * @author Jan Issac (jan dot issac at gmx dot de)
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 
27 #include <boost/thread/condition_variable.hpp>
28 #include <boost/thread/locks.hpp>
29 #include <boost/thread/mutex.hpp>
30 #include <boost/thread/recursive_mutex.hpp>
31 #include <boost/thread/shared_mutex.hpp>
32 
34 
35 #define MUTEX_TIMEOUT_MSEC 10000
36 
38 {
39  /**
40  * @struct MutexTimeoutException
41  * @ingroup Threads
42  * @brief The MutexTimeoutException struct
43  */
44  struct MutexTimeoutException : LocalException
45  {
46  MutexTimeoutException(int timeoutDelayMs, std::string mutexName = "")
47  {
48  std::stringstream reason;
49  reason << "A Thread failed to get a mutex '" + mutexName + "' after "
50  << timeoutDelayMs * 0.001 << " seconds!";
51  setReason(reason.str());
52  }
53 
54  std::string
55  name() const override
56  {
57  return "armarx::exceptions::local::MutexTimeoutException";
58  }
59  };
60 
61  struct MutexDestructionException : LocalException
62  {
63  MutexDestructionException(std::string mutexName = "") :
64  LocalException("A mutex '" + mutexName +
65  "' was not already unlocked in the destructor!")
66  {
67  }
68 
69  std::string
70  name() const override
71  {
72  return "armarx::exceptions::local::MutexDestructionException";
73  }
74  };
75 } // namespace armarx::exceptions::local
76 
77 namespace armarx
78 {
79  /**
80  * @class HiddenTimedMutex
81  * @defgroup Threads
82  * @brief The HiddenTimedMutex class is a mutex, that has a normal boost::mutex
83  * interface, but will timeout after fixed (defined in MUTEX_TIMEOUT_MSEC)
84  * interval and throw a MutexTimeoutException, if it could not aquire the
85  * mutex in that time.<br/>
86  * This way, the stacktrace to the deadlock can be easily retrieved.
87  */
89  {
90  boost::timed_mutex timedMutex;
91  int timeoutDelayMs;
92  std::string mutexName;
93 
94  public:
95  HiddenTimedMutex(int timeout = MUTEX_TIMEOUT_MSEC, std::string mutexName = "") :
96  timeoutDelayMs(timeout), mutexName(mutexName)
97  {
98  }
99 
101  {
102  if (!try_lock())
103  {
104  // throw exceptions::local::MutexDestructionException();
105  std::cout << "A mutex ('" << mutexName
106  << "') was still locked in the destructor! Fix Application!\nBacktrace:\n"
107  << LocalException::generateBacktrace() << std::endl;
108  }
109  else
110  {
111  unlock();
112  }
113  }
114 
115  void
117  {
118  boost::system_time timeout =
119  boost::get_system_time() + boost::posix_time::milliseconds(timeoutDelayMs);
120 
121  if (!timedMutex.timed_lock(timeout))
122  {
123  throw exceptions::local::MutexTimeoutException(timeoutDelayMs, mutexName);
124  }
125  }
126 
127  bool
129  {
130  return timedMutex.try_lock();
131  }
132 
133  void
135  {
136  timedMutex.unlock();
137  }
138 
139  using ScopedLock = boost::unique_lock<HiddenTimedMutex>;
140  using ScopedTryLock = boost::detail::try_lock_wrapper<HiddenTimedMutex>;
141  };
142 
143  /**
144  \addtogroup Threads
145  @{
146  */
147 
148 
149  using Mutex = boost::mutex;
150  using ScopedLock = Mutex::scoped_lock;
151  using ScopedLockPtr = std::shared_ptr<ScopedLock>;
152  using ScopedTryLock = Mutex::scoped_try_lock;
153 
154  using TimedMutex = boost::timed_mutex;
155  using ScopedTimedMutex = TimedMutex::scoped_lock;
156  using ScopedTimedMutexPtr = std::shared_ptr<ScopedTimedMutex>;
157  using ScopedTimedTryMutex = TimedMutex::scoped_try_lock;
158 
159  using RecursiveMutex = boost::recursive_mutex;
160  using ScopedRecursiveLock = RecursiveMutex::scoped_lock;
161  using ScopedRecursiveLockPtr = std::shared_ptr<ScopedRecursiveLock>;
162  using ScopedRecursiveTryLock = RecursiveMutex::scoped_try_lock;
163 
164  using TimedRecursiveMutex = boost::recursive_timed_mutex;
165  using ScopedTimedRecursiveLock = TimedRecursiveMutex::scoped_lock;
166  using ScopedTimedRecursiveLockPtr = std::shared_ptr<ScopedTimedRecursiveLock>;
167  using ScopedTimedRecursiveTryLock = TimedRecursiveMutex::scoped_try_lock;
168 
169  using SharedMutex = boost::shared_mutex;
170 
171  using ScopedUniqueLock = boost::unique_lock<boost::shared_mutex>;
172  using ScopedSharedLock = boost::shared_lock<boost::shared_mutex>;
173 
174  using ScopedUniqueLockPtr = std::shared_ptr<ScopedUniqueLock>;
175  using ScopedSharedLockPtr = std::shared_ptr<ScopedSharedLock>;
176 
177  using ConditionalVariable = boost::condition_variable;
178  /*
179  @}
180  */
181 } // namespace armarx
MUTEX_TIMEOUT_MSEC
#define MUTEX_TIMEOUT_MSEC
Definition: Synchronization.h:35
armarx::ScopedUniqueLock
boost::unique_lock< boost::shared_mutex > ScopedUniqueLock
Definition: Synchronization.h:171
armarx::HiddenTimedMutex::ScopedTryLock
boost::detail::try_lock_wrapper< HiddenTimedMutex > ScopedTryLock
Definition: Synchronization.h:140
armarx::exceptions::local::MutexTimeoutException
The MutexTimeoutException struct.
Definition: Synchronization.h:44
armarx::HiddenTimedMutex::try_lock
bool try_lock()
Definition: Synchronization.h:128
armarx::ScopedTimedMutex
TimedMutex::scoped_lock ScopedTimedMutex
Definition: Synchronization.h:155
armarx::TimedMutex
boost::timed_mutex TimedMutex
Definition: Synchronization.h:154
armarx::HiddenTimedMutex
Definition: Synchronization.h:88
armarx::HiddenTimedMutex::lock
void lock()
Definition: Synchronization.h:116
armarx::ScopedLock
Mutex::scoped_lock ScopedLock
Definition: Synchronization.h:150
armarx::ScopedTimedTryMutex
TimedMutex::scoped_try_lock ScopedTimedTryMutex
Definition: Synchronization.h:157
armarx::exceptions::local::MutexTimeoutException::MutexTimeoutException
MutexTimeoutException(int timeoutDelayMs, std::string mutexName="")
Definition: Synchronization.h:46
armarx::ConditionalVariable
boost::condition_variable ConditionalVariable
Definition: Synchronization.h:177
armarx::ScopedSharedLockPtr
std::shared_ptr< ScopedSharedLock > ScopedSharedLockPtr
Definition: Synchronization.h:175
armarx::exceptions::local
Definition: DynamicLibraryException.h:31
armarx::exceptions::local::MutexTimeoutException::name
std::string name() const override
Definition: Synchronization.h:55
armarx::ScopedRecursiveLock
RecursiveMutex::scoped_lock ScopedRecursiveLock
Definition: Synchronization.h:160
armarx::ScopedTimedRecursiveLockPtr
std::shared_ptr< ScopedTimedRecursiveLock > ScopedTimedRecursiveLockPtr
Definition: Synchronization.h:166
armarx::ScopedLockPtr
std::shared_ptr< ScopedLock > ScopedLockPtr
Definition: Synchronization.h:151
armarx::ScopedTimedRecursiveTryLock
TimedRecursiveMutex::scoped_try_lock ScopedTimedRecursiveTryLock
Definition: Synchronization.h:167
armarx::ScopedTryLock
Mutex::scoped_try_lock ScopedTryLock
Definition: Synchronization.h:152
armarx::SharedMutex
boost::shared_mutex SharedMutex
Definition: Synchronization.h:169
armarx::HiddenTimedMutex::~HiddenTimedMutex
~HiddenTimedMutex()
Definition: Synchronization.h:100
armarx::ScopedSharedLock
boost::shared_lock< boost::shared_mutex > ScopedSharedLock
Definition: Synchronization.h:172
armarx::ScopedRecursiveTryLock
RecursiveMutex::scoped_try_lock ScopedRecursiveTryLock
Definition: Synchronization.h:162
armarx::Mutex
boost::mutex Mutex
Definition: Synchronization.h:149
armarx::TimedRecursiveMutex
boost::recursive_timed_mutex TimedRecursiveMutex
Definition: Synchronization.h:164
armarx::ScopedRecursiveLockPtr
std::shared_ptr< ScopedRecursiveLock > ScopedRecursiveLockPtr
Definition: Synchronization.h:161
armarx::HiddenTimedMutex::HiddenTimedMutex
HiddenTimedMutex(int timeout=MUTEX_TIMEOUT_MSEC, std::string mutexName="")
Definition: Synchronization.h:95
armarx::HiddenTimedMutex::ScopedLock
boost::unique_lock< HiddenTimedMutex > ScopedLock
Definition: Synchronization.h:139
armarx::ScopedUniqueLockPtr
std::shared_ptr< ScopedUniqueLock > ScopedUniqueLockPtr
Definition: Synchronization.h:174
armarx::HiddenTimedMutex::unlock
void unlock()
Definition: Synchronization.h:134
armarx::ScopedTimedMutexPtr
std::shared_ptr< ScopedTimedMutex > ScopedTimedMutexPtr
Definition: Synchronization.h:156
armarx::RecursiveMutex
boost::recursive_mutex RecursiveMutex
Definition: Synchronization.h:159
armarx::exceptions::local::MutexDestructionException::MutexDestructionException
MutexDestructionException(std::string mutexName="")
Definition: Synchronization.h:63
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::exceptions::local::MutexDestructionException
Definition: Synchronization.h:61
Exception.h
armarx::exceptions::local::MutexDestructionException::name
std::string name() const override
Definition: Synchronization.h:70
armarx::ScopedTimedRecursiveLock
TimedRecursiveMutex::scoped_lock ScopedTimedRecursiveLock
Definition: Synchronization.h:165