csutil/threading/pthread_mutex.h
00001 /* 00002 Copyright (C) 2006 by Marten Svanfeldt 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Lesser General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public 00015 License along with this library; if not, write to the Free 00016 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00017 */ 00018 00019 #ifndef __CS_CSUTIL_THREADING_PTHREAD_MUTEX_H__ 00020 #define __CS_CSUTIL_THREADING_PTHREAD_MUTEX_H__ 00021 00022 #ifndef DOXYGEN_RUN 00023 00024 #include <pthread.h> 00025 00026 namespace CS 00027 { 00028 namespace Threading 00029 { 00030 namespace Implementation 00031 { 00032 class ConditionBase; 00033 00037 class MutexBase 00038 { 00039 public: 00040 void Initialize () 00041 { 00042 pthread_mutex_init (&mutex, 0); 00043 } 00044 00045 void Destroy () 00046 { 00047 pthread_mutex_destroy (&mutex); 00048 } 00049 00050 bool Lock () 00051 { 00052 int status = pthread_mutex_lock (&mutex); 00053 return status == 0; 00054 } 00055 00056 bool TryLock () 00057 { 00058 int status = pthread_mutex_trylock (&mutex); 00059 return status == 0; 00060 } 00061 00062 void Unlock () 00063 { 00064 pthread_mutex_unlock (&mutex); 00065 } 00066 00067 protected: 00068 friend class ConditionBase; 00069 00070 pthread_mutex_t mutex; 00071 }; 00072 00073 00077 #ifdef CS_PTHREAD_MUTEX_RECURSIVE 00078 class RecursiveMutexBase : public MutexBase 00079 { 00080 public: 00081 void Initialize () 00082 { 00083 // Use different initialization 00084 pthread_mutexattr_t attr; 00085 pthread_mutexattr_init (&attr); 00086 pthread_mutexattr_settype (&attr, CS_PTHREAD_MUTEX_RECURSIVE); 00087 pthread_mutex_init (&mutex, &attr); 00088 } 00089 }; 00090 #else 00091 00092 // Recursive mutex when native recursive mutex isn't supported by pthread 00093 // Emulate it 00094 class RecursiveMutexBase : public MutexBase 00095 { 00096 public: 00097 void Initialize () 00098 { 00099 MutexBase::Initialize (); 00100 00101 recursionCount = 0; 00102 validID = false; 00103 pthread_cond_init (&unlockedCond, 0); 00104 } 00105 00106 void Destroy () 00107 { 00108 MutexBase::Destroy (); 00109 pthread_cond_destroy (&unlockedCond); 00110 } 00111 00112 bool Lock () 00113 { 00114 MutexBase::Lock (); 00115 00116 pthread_t tid = pthread_self (); 00117 if (validID && pthread_equal (threadID, tid)) 00118 { 00119 ++recursionCount; 00120 } 00121 else 00122 { 00123 while (validID) 00124 { 00125 pthread_cond_wait (&unlockedCond, &mutex); 00126 } 00127 00128 threadID = tid; 00129 validID = true; 00130 recursionCount = 1; 00131 } 00132 00133 MutexBase::Unlock (); 00134 } 00135 00136 bool TryLock () 00137 { 00138 bool ret = false; 00139 MutexBase::Lock (); 00140 00141 pthread_t tid = pthread_self (); 00142 if (validID && pthread_equal (threadID, tid)) 00143 { 00144 ++recursionCount; 00145 ret = true; 00146 } 00147 else if (!validID) 00148 { 00149 threadID = tid; 00150 validID = true; 00151 recursionCount = 1; 00152 ret = true; 00153 } 00154 00155 MutexBase::Unlock (); 00156 return ret; 00157 } 00158 00159 void Unlock () 00160 { 00161 MutexBase::Lock (); 00162 pthread_t tid = pthread_self (); 00163 if (validID && !pthread_equal (threadID, tid)) 00164 { 00165 MutexBase::Unlock (); 00166 return; 00167 } 00168 00169 if (--recursionCount == 0) 00170 { 00171 validID = false; 00172 pthread_cond_signal (&unlockedCond); 00173 } 00174 00175 MutexBase::Unlock (); 00176 } 00177 00178 protected: 00179 pthread_cond_t unlockedCond; 00180 pthread_t threadID; 00181 int32 recursionCount; 00182 bool validID; 00183 }; 00184 00185 #endif 00186 00187 } // namespace Implementation 00188 } // namespace Threading 00189 } // namespace CS 00190 00191 #endif // DOXYGEN_RUN 00192 00193 #endif // __CS_CSUTIL_THREADING_PTHREAD_MUTEX_H__
Generated for Crystal Space 2.0 by doxygen 1.6.1