mutex_pos.hpp
Go to the documentation of this file.
1 
8 /*****************************************************************************
9 ** Ifdefs
10 *****************************************************************************/
11 
12 #ifndef ECL_THREADS_MUTEX_POS_HPP_
13 #define ECL_THREADS_MUTEX_POS_HPP_
14 
15 /*****************************************************************************
16 ** Platform Check
17 *****************************************************************************/
18 
19 #include <ecl/config/ecl.hpp>
20 #if defined(ECL_IS_POSIX)
21 
22 /*****************************************************************************
23 ** Includes
24 *****************************************************************************/
25 
26 #include <errno.h>
27 #include <cstring> // strerror function
28 #include <string>
29 #include <pthread.h>
30 #include <sstream>
31 #include <ecl/config/macros.hpp>
34 #include <ecl/time/duration.hpp>
35 
36 
37 /*****************************************************************************
38 ** Namespaces
39 *****************************************************************************/
40 
41 namespace ecl {
42 
43 /*****************************************************************************
44 ** Typedefs
45 *****************************************************************************/
46 
47 typedef pthread_mutex_t RawMutex;
49 /*****************************************************************************
50 ** Class Mutex
51 *****************************************************************************/
80 class Mutex {
81 public:
92  Mutex(const bool locked = false);
98  virtual ~Mutex();
99 
105  void unlock();
111  void lock();
125  bool trylock(Duration &duration);
136  bool trylock();
146  unsigned int locks() { return number_locks; }
147 
154  RawMutex& rawType() { return mutex; }
155 
156 private:
157  RawMutex mutex;
158  unsigned int number_locks;
159 
160 };
161 
162 }; // namespace ecl
163 
164 /*****************************************************************************
165 ** Interface [Exceptions]
166 *****************************************************************************/
167 
168 #if defined(ECL_HAS_EXCEPTIONS)
169 namespace ecl {
170 namespace threads {
171 
172 /*****************************************************************************
173 ** Interface [Mutex Exceptions]
174 *****************************************************************************/
175 
184 inline StandardException ECL_LOCAL throwMutexAttrException(const char* loc, int error_result) {
185  switch (error_result) {
186  case ( EINVAL ) : return StandardException(loc, InvalidInputError, "The specified mutex attribute was invalid.");
187  case ( ENOMEM ) : return StandardException(loc, MemoryError, "There is insufficient memory for initialisation of the mutex attribute.");
188  default :
189  {
190  std::ostringstream ostream;
191  ostream << "Unknown posix error " << error_result << ": " << strerror(error_result) << ".";
192  return StandardException(loc, UnknownError, ostream.str());
193  }
194  }
195 }
204 inline StandardException ECL_LOCAL throwMutexInitException(const char* loc, int error_result) {
205  switch (error_result) {
206  case ( EINVAL ) : return StandardException(loc, InvalidInputError, "The specified mutex was invalid.");
207  case ( EBUSY ) : return StandardException(loc, InvalidInputError, "The mutex object has already been initialised and not yet destroyed.");
208  case ( EAGAIN ) : return StandardException(loc, MemoryError, "The mutex object has already been initialised and not yet destroyed.");
209  case ( ENOMEM ) : return StandardException(loc, MemoryError, "There is insufficient memory for initialisation of the mutex.");
210  case ( EPERM ) : return StandardException(loc, PermissionsError, "The user does not have the privilege to perform the operation.");
211  default :
212  {
213  std::ostringstream ostream;
214  ostream << "Unknown posix error " << error_result << ": " << strerror(error_result) << ".";
215  return StandardException(loc, UnknownError, ostream.str());
216  }
217  }
218 }
227 inline StandardException ECL_LOCAL throwMutexDestroyException(const char* loc, int error_result) {
228  switch (error_result) {
229  case ( EINVAL ) : return StandardException(loc, DestructorError, "The specified mutex is invalid (for some reason or other).");
230  case ( EBUSY ) : return StandardException(loc, DestructorError, "Attempted to destroy the mutex while it was locked.");
231  default : return StandardException(loc, UnknownError, "Unknown error.");
232  }
233 }
242 inline StandardException ECL_LOCAL throwMutexTimedLockException(const char* loc, int error_result) {
243  switch (error_result) {
244  case ( EDEADLK ): return StandardException(loc, UsageError, "DEADLOCK! The current thread already owns the mutex.");
245  // These aren't relevant to us (EBUSY is normal operation for trylock, EINVAL can't happen because of RAII, and EAGAIN because our mutex isn't RECURSIVE)
246  case ( EINVAL ) : return StandardException(loc, UsageError, "The mutex is not initialised or it is priority protected and the calling thread's priority is higher than the mutex' current priority ceiling.");
247  case ( EAGAIN ) : return StandardException(loc, OutOfRangeError, "The mutex could not be acquired because the maximum number of recursive locks for the mutex has been exceeded.");
248  default : return StandardException(loc, UnknownError, "Unknown error.");
249  }
250 }
259 inline StandardException ECL_LOCAL throwMutexLockException(const char* loc, int error_result) {
260  switch (error_result) {
261  case ( EDEADLK ): return StandardException(loc, UsageError, "DEADLOCK! The mutex has already been locked by this thread, it now has to wait on itself.");
262  // These aren't relevant to us (EBUSY is normal operation for trylock, EINVAL can't happen because of RAII, and EAGAIN because our mutex isn't RECURSIVE)
263  case ( EBUSY ) : return StandardException(loc, ConfigurationError, "The try lock failed because it was already locked (normal operation really, not really an error).");
264  case ( EINVAL ) : return StandardException(loc, InvalidInputError, "The mutex does not refer to an initialised mutex.");
265  case ( EAGAIN ) : return StandardException(loc, OutOfRangeError, "The mutex could not be acquired because the maximum number of recursive locks for the mutex has been exceeded.");
266  default : return StandardException(loc, PosixError, "Unknown error.");
267  }
268 }
277 inline StandardException ECL_LOCAL throwMutexUnLockException(const char* loc, int error_result) {
278  switch (error_result) {
279  case ( EINVAL ) : return StandardException(loc, InvalidInputError, "The mutex does not refer to an initialised mutex.");
280  case ( EAGAIN ) : return StandardException(loc, OutOfRangeError, "The mutex could not be acquired because the maximum number of recursive locks for the mutex has been exceeded.");
281  case ( EPERM ) : return StandardException(loc, PermissionsError, "The user does not have the privilege to perform the operation.");
282  default : return StandardException(loc, UnknownError, "Unknown error.");
283  }
284 }
285 
286 
287 }; // namespace threads
288 } // namespace ecl
289 
290 #endif /* ECL_HAS_EXCEPTIONS */
291 #endif /* ECL_IS_POSIX */
292 #endif /* ECL_THREADS_MUTEX_POS_HPP_ */
ecl::InvalidInputError
InvalidInputError
ecl::UsageError
UsageError
ECL_LOCAL
#define ECL_LOCAL
ecl::MemoryError
MemoryError
ecl::DestructorError
DestructorError
ecl::PosixError
PosixError
mutex
ecl::Mutex mutex
Definition: examples/mutex.cpp:25
Duration
TimeStamp Duration
ecl::PermissionsError
PermissionsError
standard_exception.hpp
ecl::UnknownError
UnknownError
macros.hpp
ecl::OutOfRangeError
OutOfRangeError
ecl
Embedded control libraries.
duration.hpp
ecl::ConfigurationError
ConfigurationError


ecl_threads
Author(s): Daniel Stonier
autogenerated on Wed Mar 2 2022 00:16:43