00001 #ifndef NO_GUICAST 00002 #include "bcsignals.h" 00003 #endif 00004 #include "mutex.h" 00005 00006 Mutex::Mutex(char *title, int recursive) 00007 { 00008 this->title = title; 00009 pthread_mutexattr_t attr; 00010 pthread_mutexattr_init(&attr); 00011 pthread_mutex_init(&mutex, &attr); 00012 pthread_mutex_init(&recursive_lock, &attr); 00013 count = 0; 00014 this->recursive = recursive; 00015 thread_id = 0; 00016 thread_id_valid = 0; 00017 } 00018 00019 Mutex::~Mutex() 00020 { 00021 pthread_mutex_destroy(&mutex); 00022 pthread_mutex_destroy(&recursive_lock); 00023 #ifndef NO_GUICAST 00024 UNSET_ALL_LOCKS(this); 00025 #endif 00026 } 00027 00028 int Mutex::lock(char *location) 00029 { 00030 // Test recursive owner and give up if we already own it 00031 if(recursive) 00032 { 00033 pthread_mutex_lock(&recursive_lock); 00034 if(thread_id_valid && pthread_self() == thread_id) 00035 { 00036 count++; 00037 pthread_mutex_unlock(&recursive_lock); 00038 return 0; 00039 } 00040 pthread_mutex_unlock(&recursive_lock); 00041 } 00042 00043 00044 #ifndef NO_GUICAST 00045 SET_LOCK(this, title, location); 00046 #endif 00047 if(pthread_mutex_lock(&mutex)) perror("Mutex::lock"); 00048 00049 00050 00051 // Update recursive status for the first lock 00052 if(recursive) 00053 { 00054 pthread_mutex_lock(&recursive_lock); 00055 count = 1; 00056 thread_id = pthread_self(); 00057 thread_id_valid = 1; 00058 pthread_mutex_unlock(&recursive_lock); 00059 } 00060 else 00061 { 00062 count = 1; 00063 } 00064 00065 00066 #ifndef NO_GUICAST 00067 SET_LOCK2 00068 #endif 00069 return 0; 00070 } 00071 00072 int Mutex::unlock() 00073 { 00074 // Remove from recursive status 00075 if(recursive) 00076 { 00077 pthread_mutex_lock(&recursive_lock); 00078 count--; 00079 // Still locked 00080 if(count > 0) 00081 { 00082 pthread_mutex_unlock(&recursive_lock); 00083 return 0; 00084 } 00085 // Not owned anymore 00086 thread_id = 0; 00087 thread_id_valid = 0; 00088 pthread_mutex_unlock(&recursive_lock); 00089 } 00090 else 00091 count = 0; 00092 00093 00094 #ifndef NO_GUICAST 00095 UNSET_LOCK(this); 00096 #endif 00097 00098 if(pthread_mutex_unlock(&mutex)) perror("Mutex::unlock"); 00099 return 0; 00100 } 00101 00102 int Mutex::trylock() 00103 { 00104 return pthread_mutex_trylock(&mutex); 00105 } 00106 00107 int Mutex::is_locked() 00108 { 00109 return count; 00110 } 00111 00112 int Mutex::reset() 00113 { 00114 pthread_mutex_destroy(&mutex); 00115 pthread_mutexattr_t attr; 00116 pthread_mutexattr_init(&attr); 00117 pthread_mutex_init(&mutex, &attr); 00118 count = 0; 00119 thread_id = 0; 00120 thread_id_valid = 0; 00121 #ifndef NO_GUICAST 00122 UNSET_ALL_LOCKS(this) 00123 #endif 00124 return 0; 00125 }
1.5.5