$search
00001 00008 /***************************************************************************** 00009 ** Platform Check 00010 *****************************************************************************/ 00011 00012 #include <ecl/config/ecl.hpp> 00013 #if defined(ECL_IS_POSIX) 00014 00015 /***************************************************************************** 00016 ** Includes 00017 *****************************************************************************/ 00018 00019 #include <errno.h> 00020 #include <ecl/exceptions/standard_exception.hpp> 00021 #include "../../include/ecl/threads/mutex.hpp" 00022 00023 /***************************************************************************** 00024 ** Namespaces 00025 *****************************************************************************/ 00026 00027 namespace ecl { 00028 00029 /***************************************************************************** 00030 * Mutex Class Methods 00031 *****************************************************************************/ 00032 00033 Mutex::Mutex(const bool locked) ecl_assert_throw_decl(StandardException) : number_locks(0) { 00034 00035 pthread_mutexattr_t attr; 00036 int result; 00037 00038 result = pthread_mutexattr_init(&attr); 00039 ecl_assert_throw( result == 0, threads::throwMutexAttrException(LOC,result)); 00040 00041 #if defined(NDEBUG) || defined(ECL_NDEBUG) 00042 result = pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_NORMAL); 00043 #else 00044 result = pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_ERRORCHECK); 00045 #endif 00046 ecl_assert_throw( result == 0, threads::throwMutexAttrException(LOC,result)); 00047 00048 if ( result == 0 ) { 00049 result = pthread_mutex_init(&mutex,&attr); 00050 } 00051 ecl_assert_throw( result == 0, threads::throwMutexInitException(LOC,result)); 00052 result = pthread_mutexattr_destroy(&attr); 00053 ecl_assert_throw( result == 0, threads::throwMutexAttrException(LOC,result)); 00054 00055 if ( locked ) { 00056 this->lock(); 00057 } 00058 }; 00059 00060 Mutex::~Mutex() { 00061 pthread_mutex_destroy(&mutex); 00062 // Spank! Destructor exceptions are bad. 00063 // ecl_assert_throw( result == 0, threads::throwMutexDestroyException(LOC,result)); 00064 } 00065 00066 void Mutex::lock() ecl_assert_throw_decl(StandardException) 00067 { 00068 ++number_locks; 00069 int result = pthread_mutex_lock(&mutex); 00070 ecl_assert_throw( result == 0, threads::throwMutexLockException(LOC,result)); 00071 }; 00072 00073 bool Mutex::trylock(Duration &duration) ecl_assert_throw_decl(StandardException) 00074 { 00075 #if defined(_POSIX_TIMEOUTS) && (_POSIX_TIMEOUTS - 200112L) >= 0L 00076 timespec timeout; 00077 timeout.tv_sec = duration.sec(); 00078 timeout.tv_nsec = duration.nsec(); 00079 int result = pthread_mutex_timedlock(&mutex,&timeout); 00080 if ( result == ETIMEDOUT ) { 00081 return false; 00082 } 00083 ecl_assert_throw( result == 0, threads::throwMutexTimedLockException(LOC,result)); 00084 ++number_locks; 00085 #else 00086 return trylock(); // fallback option 00087 #endif 00088 return true; 00089 }; 00090 00091 bool Mutex::trylock() ecl_assert_throw_decl(StandardException) 00092 { 00093 int result = pthread_mutex_trylock(&mutex); 00094 00095 // result will typically be EBUSY if already locked, so filter it from the assert check. 00096 if ( result == EBUSY ) { 00097 return false; 00098 } 00099 00100 ecl_assert_throw( result == 0, threads::throwMutexLockException(LOC,result)); 00101 00102 // If we made it here, it means the attempt locked the mutex. 00103 ++number_locks; 00104 return true; 00105 }; 00106 00107 00108 void Mutex::unlock() ecl_assert_throw_decl(StandardException) 00109 { 00110 --number_locks; 00111 int result = pthread_mutex_unlock(&mutex); 00112 ecl_assert_throw( result == 0, threads::throwMutexUnLockException(LOC,result)); 00113 }; 00114 00115 }; // namespace ecl 00116 00117 #endif /* ECL_IS_POSIX */