00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef AMINO_UTIL_LOCK
00023 #define AMINO_UTIL_LOCK
00024
00025 #include <pthread.h>
00026 #include <iostream>
00027 #include <amino/stdatomic.h>
00028
00029 namespace amino {
00030 class condition_variable;
00031
00032 enum LOCK_TYPE {COMMON_LOCK,TRY_LOCK,NO_LOCK};
00033
00034 template <class Mutex> class unique_lock {
00035 public:
00036 friend class condition_variable;
00037
00038 typedef Mutex mutex_type;
00039
00040 unique_lock() {
00041 internal_mut = new mutex_type();
00042 needDel = true;
00043 lock_count = 0;
00044 }
00045
00046 explicit unique_lock(mutex_type& m, LOCK_TYPE t = COMMON_LOCK) {
00047 internal_mut = &m;
00048 needDel = false;
00049 lock_count = 0;
00050 switch (t) {
00051 case COMMON_LOCK:
00052 internal_mut->lock();
00053 ++lock_count;
00054 break;
00055 case TRY_LOCK:
00056 if (internal_mut->try_lock())
00057 ++lock_count;
00058 break;
00059 case NO_LOCK:
00060 break;
00061 default:
00062 throw std::logic_error("Not a valid lock type");
00063 }
00064 }
00065
00066 void lock() {
00067 #ifndef DEBUG
00068
00069 #endif
00070 internal_mut->lock();
00071 lock_count++;
00072 }
00073
00074 bool try_lock() {
00075 if (internal_mut->try_lock()) {
00076 lock_count++;
00077 #ifndef DEBUG
00078
00079 #endif
00080 return true;
00081 }
00082 return false;
00083 }
00084
00085
00086 void unlock() {
00087 lock_count--;
00088 internal_mut->unlock();
00089 #ifndef DEBUG
00090
00091 #endif
00092 }
00093
00094 bool owns_lock() {
00095 return lock_count.load() > 0;
00096 }
00097
00098 mutex_type* mutex() const {
00099 return internal_mut;
00100 }
00101
00102 virtual ~unique_lock() {
00103 #ifndef DEBUG
00104
00105 #endif
00106 while (owns_lock()) {
00107 unlock();
00108 }
00109 if (needDel)
00110 delete internal_mut;
00111 }
00112 private:
00113 bool needDel;
00114 atomic_int lock_count;
00115 mutex_type * internal_mut;
00116 };
00117 }
00118
00119 #endif