mutex_pos.hpp
Go to the documentation of this file.
00001 
00008 /*****************************************************************************
00009 ** Ifdefs
00010 *****************************************************************************/
00011 
00012 #ifndef ECL_THREADS_MUTEX_POS_HPP_
00013 #define ECL_THREADS_MUTEX_POS_HPP_
00014 
00015 /*****************************************************************************
00016 ** Platform Check
00017 *****************************************************************************/
00018 
00019 #include <ecl/config/ecl.hpp>
00020 #if defined(ECL_IS_POSIX)
00021 
00022 /*****************************************************************************
00023 ** Includes
00024 *****************************************************************************/
00025 
00026 #include <errno.h>
00027 #include <cstring> // strerror function
00028 #include <string>
00029 #include <pthread.h>
00030 #include <sstream>
00031 #include <ecl/config/macros.hpp>
00032 #include <ecl/exceptions/macros.hpp>
00033 #include <ecl/exceptions/standard_exception.hpp>
00034 #include <ecl/time/duration.hpp>
00035 
00036 
00037 /*****************************************************************************
00038 ** Namespaces
00039 *****************************************************************************/
00040 
00041 namespace ecl {
00042 
00043 /*****************************************************************************
00044 ** Typedefs
00045 *****************************************************************************/
00046 
00047 typedef pthread_mutex_t RawMutex; 
00049 /*****************************************************************************
00050 ** Class Mutex
00051 *****************************************************************************/
00080 class Mutex {
00081 public:
00092         Mutex(const bool locked = false) ecl_assert_throw_decl(StandardException);
00098         virtual ~Mutex();
00099 
00105         void unlock() ecl_assert_throw_decl(StandardException);
00111         void lock() ecl_assert_throw_decl(StandardException);
00125         bool trylock(Duration &duration) ecl_assert_throw_decl(StandardException);
00136         bool trylock() ecl_assert_throw_decl(StandardException);
00146         unsigned int locks() { return number_locks; }
00147 
00154         RawMutex& rawType() { return mutex; }
00155 
00156 private:
00157         RawMutex mutex;
00158         unsigned int number_locks;
00159 
00160 };
00161 
00162 }; // namespace ecl
00163 
00164 /*****************************************************************************
00165 ** Interface [Exceptions]
00166 *****************************************************************************/
00167 
00168 #if defined(ECL_HAS_EXCEPTIONS)
00169 namespace ecl {
00170 namespace threads {
00171 
00172 /*****************************************************************************
00173 ** Interface [Mutex Exceptions]
00174 *****************************************************************************/
00175 
00184 inline StandardException ECL_LOCAL throwMutexAttrException(const char* loc, int error_result) {
00185         switch (error_result) {
00186                 case ( EINVAL ) : return StandardException(loc, InvalidInputError, "The specified mutex attribute was invalid.");
00187                 case ( ENOMEM ) : return StandardException(loc, MemoryError, "There is insufficient memory for initialisation of the mutex attribute.");
00188                 default         :
00189                 {
00190                         std::ostringstream ostream;
00191                         ostream << "Unknown posix error " << error_result << ": " << strerror(error_result) << ".";
00192                         return StandardException(loc, UnknownError, ostream.str());
00193                 }
00194         }
00195 }
00204 inline StandardException ECL_LOCAL throwMutexInitException(const char* loc, int error_result) {
00205         switch (error_result) {
00206                 case ( EINVAL ) : return StandardException(loc, InvalidInputError, "The specified mutex was invalid.");
00207                 case ( EBUSY )  : return StandardException(loc, InvalidInputError, "The mutex object has already been initialised and not yet destroyed.");
00208                 case ( EAGAIN ) : return StandardException(loc, MemoryError, "The mutex object has already been initialised and not yet destroyed.");
00209                 case ( ENOMEM ) : return StandardException(loc, MemoryError, "There is insufficient memory for initialisation of the mutex.");
00210                 case ( EPERM )  : return StandardException(loc, PermissionsError, "The user does not have the privilege to perform the operation.");
00211                 default         :
00212                 {
00213                         std::ostringstream ostream;
00214                         ostream << "Unknown posix error " << error_result << ": " << strerror(error_result) << ".";
00215                         return StandardException(loc, UnknownError, ostream.str());
00216                 }
00217         }
00218 }
00227 inline StandardException ECL_LOCAL throwMutexDestroyException(const char* loc, int error_result) {
00228         switch (error_result) {
00229                 case ( EINVAL ) : return StandardException(loc, DestructorError, "The specified mutex is invalid (for some reason or other).");
00230                 case ( EBUSY )  : return StandardException(loc, DestructorError, "Attempted to destroy the mutex while it was locked.");
00231                 default         : return StandardException(loc, UnknownError, "Unknown error.");
00232         }
00233 }
00242 inline StandardException ECL_LOCAL throwMutexTimedLockException(const char* loc, int error_result) {
00243         switch (error_result) {
00244                 case ( EDEADLK ): return StandardException(loc, UsageError, "DEADLOCK! The current thread already owns the mutex.");
00245                 // 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)
00246                 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.");
00247                 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.");
00248                 default         : return StandardException(loc, UnknownError, "Unknown error.");
00249         }
00250 }
00259 inline StandardException ECL_LOCAL throwMutexLockException(const char* loc, int error_result) {
00260         switch (error_result) {
00261                 case ( EDEADLK ): return StandardException(loc, UsageError, "DEADLOCK! The mutex has already been locked by this thread, it now has to wait on itself.");
00262                 // 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)
00263                 case ( EBUSY )  : return StandardException(loc, ConfigurationError, "The try lock failed because it was already locked (normal operation really, not really an error).");
00264                 case ( EINVAL ) : return StandardException(loc, InvalidInputError, "The mutex does not refer to an initialised mutex.");
00265                 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.");
00266                 default         : return StandardException(loc, PosixError, "Unknown error.");
00267         }
00268 }
00277 inline StandardException ECL_LOCAL throwMutexUnLockException(const char* loc, int error_result) {
00278         switch (error_result) {
00279                 case ( EINVAL ) : return StandardException(loc, InvalidInputError, "The mutex does not refer to an initialised mutex.");
00280                 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.");
00281                 case ( EPERM )  : return StandardException(loc, PermissionsError, "The user does not have the privilege to perform the operation.");
00282                 default         : return StandardException(loc, UnknownError, "Unknown error.");
00283         }
00284 }
00285 
00286 
00287 }; // namespace threads
00288 } // namespace ecl
00289 
00290 #endif /* ECL_HAS_EXCEPTIONS */
00291 #endif /* ECL_IS_POSIX */
00292 #endif /* ECL_THREADS_MUTEX_POS_HPP_ */


ecl_threads
Author(s): Daniel Stonier (d.stonier@gmail.com)
autogenerated on Thu Jan 2 2014 11:12:47