CLAM-Development
1.1
|
00001 /* 00002 * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG) 00003 * UNIVERSITAT POMPEU FABRA 00004 * 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 * 00020 */ 00021 00022 #include "Mutex.hxx" 00023 #include "Assert.hxx" 00024 #include "xtime.hxx" 00025 #include "ErrSystem.hxx" 00026 00027 namespace CLAM 00028 { 00029 00030 Mutex::Mutex() 00031 { 00032 int res = 0; 00033 00034 res = pthread_mutex_init( &mMutex, 0 ); 00035 00036 CLAM_ASSERT( res == 0, "Not able to initialize mutex" ); 00037 } 00038 00039 Mutex::~Mutex() 00040 { 00041 int res = 0; 00042 00043 res = pthread_mutex_destroy( &mMutex ); 00044 00045 CLAM_ASSERT( res == 0, "Not able to destroy mutex" ); 00046 } 00047 00048 void Mutex::DoLock() 00049 { 00050 int res = 0; 00051 00052 res = pthread_mutex_lock( &mMutex ); 00053 00054 if ( res == EDEADLK ) 00055 throw LockError(); // What is EDEADLK???? 00056 00057 CLAM_ASSERT( res == 0, "Not able to lock the mutex" ); 00058 } 00059 00060 void Mutex::DoUnlock() 00061 { 00062 int res = 0; 00063 00064 res = pthread_mutex_unlock( &mMutex ); 00065 00066 if ( res == EPERM ) 00067 throw LockError(); // What is EPERM????? 00068 00069 CLAM_ASSERT( res == 0, "Not able to Unlock the mutex" ); 00070 } 00071 00072 void Mutex::DoLock( ConditionVar& state ) 00073 { 00074 // Does nothing 00075 } 00076 00077 void Mutex::DoUnlock( ConditionVar& state ) 00078 { 00079 state.pmutex = &mMutex; 00080 } 00081 00082 TryMutex::TryMutex() 00083 { 00084 int res = 0; 00085 00086 res = pthread_mutex_init( &mMutex, 0 ); 00087 00088 CLAM_ASSERT( res == 0, "Not able to initialize mutex" ); 00089 00090 } 00091 00092 TryMutex::~TryMutex() 00093 { 00094 int res = 0; 00095 00096 res = pthread_mutex_destroy( &mMutex ); 00097 00098 CLAM_ASSERT( res == 0, "Not able to destroy mutex" ); 00099 00100 } 00101 00102 void TryMutex::DoLock() 00103 { 00104 int res = 0; 00105 res = pthread_mutex_lock( &mMutex ); 00106 if ( res == EDEADLK ) 00107 throw LockError(); 00108 00109 CLAM_ASSERT( res == 0, "Not able to lock mutex" ); 00110 } 00111 00112 bool TryMutex::DoTryLock() 00113 { 00114 int res = 0; 00115 00116 res = pthread_mutex_trylock(&mMutex ); 00117 00118 if ( res == EDEADLK ) 00119 throw LockError(); 00120 00121 CLAM_ASSERT ( (res == 0) || (res == EBUSY), "Not able to try-lock the mutex" ); 00122 00123 return res == 0; 00124 } 00125 00126 void TryMutex::DoUnlock() 00127 { 00128 int res = 0; 00129 00130 res = pthread_mutex_unlock( &mMutex ); 00131 00132 if ( res == EPERM ) 00133 throw LockError(); // What is EPERM????? 00134 00135 CLAM_ASSERT( res == 0, "Not able to Unlock the mutex" ); 00136 } 00137 00138 void TryMutex::DoLock( ConditionVar& state ) 00139 { 00140 // Does nothing 00141 } 00142 00143 void TryMutex::DoUnlock( ConditionVar& state ) 00144 { 00145 state.pmutex = &mMutex; 00146 } 00147 00148 TimedMutex::TimedMutex() 00149 : mLocked( false ) 00150 { 00151 int res = 0; 00152 00153 res = pthread_mutex_init( &mMutex, 0 ); 00154 00155 CLAM_ASSERT( res==0, "Not able to initilize the mutex" ); 00156 00157 res = pthread_cond_init( &mCondition, 0 ); 00158 00159 if ( res!= 0 ) 00160 { 00161 pthread_mutex_destroy( &mMutex ); 00162 throw ThreadResourceError("Unable to initialize Condition " ); 00163 } 00164 } 00165 00166 TimedMutex::~TimedMutex() 00167 { 00168 CLAM_ASSERT( !mLocked, "Mutex was locked while attempting to destroy it!" ); 00169 00170 int res = 0; 00171 00172 res = pthread_mutex_destroy(&mMutex ); 00173 00174 CLAM_ASSERT( res == 0, "Unable to destroy the mutex!" ); 00175 00176 res = pthread_cond_destroy( &mCondition ); 00177 00178 CLAM_ASSERT( res == 0, "Unable to destroy the Condition variable" ); 00179 } 00180 00181 void TimedMutex::DoLock( ) 00182 { 00183 int res = 0; 00184 00185 res = pthread_mutex_lock( &mMutex ); 00186 CLAM_ASSERT( res == 0, "Unable to lock mutex (already locked) " ); 00187 00188 while( mLocked ) 00189 { 00190 res = pthread_cond_wait( &mCondition, &mMutex ); 00191 CLAM_ASSERT( res == 0, "Wait failed" ); 00192 } 00193 00194 CLAM_ASSERT( !mLocked, "Spurious value for loop condition" ); 00195 mLocked = true; 00196 00197 res = pthread_mutex_unlock( &mMutex ); 00198 CLAM_ASSERT( res ==0, "Unable to unlock the mutex" ); 00199 } 00200 00201 bool TimedMutex::DoTryLock() 00202 { 00203 int res = 0; 00204 00205 res = pthread_mutex_lock( &mMutex ); 00206 00207 CLAM_ASSERT( res == 0, "Unable to lock the mutex" ); 00208 00209 bool ret = false; 00210 00211 if ( !mLocked ) 00212 { 00213 mLocked = true; 00214 ret = true; 00215 } 00216 00217 res = pthread_mutex_unlock( &mMutex ); 00218 CLAM_ASSERT( res==0, "Unable to unlock the mutex" ); 00219 00220 return ret; 00221 } 00222 00223 bool TimedMutex::DoTimedLock( const xtime& xt ) 00224 { 00225 int res = 0; 00226 res = pthread_mutex_lock( &mMutex ); 00227 CLAM_ASSERT( res == 0, "Unable to lock the mutex" ); 00228 00229 timespec ts; 00230 to_timespec(xt, ts); 00231 00232 while (mLocked) 00233 { 00234 res = pthread_cond_timedwait(&mCondition, &mMutex, &ts); 00235 CLAM_ASSERT(res == 0 || res == ETIMEDOUT, "Low level error"); 00236 00237 if (res == ETIMEDOUT) 00238 break; 00239 } 00240 00241 bool ret = false; 00242 if (!mLocked) 00243 { 00244 mLocked = true; 00245 ret = true; 00246 } 00247 00248 res = pthread_mutex_unlock(&mMutex); 00249 CLAM_ASSERT(res == 0, "Something low level failed!"); 00250 return ret; 00251 } 00252 00253 void TimedMutex::DoUnlock() 00254 { 00255 int res = 0; 00256 res = pthread_mutex_lock(&mMutex); 00257 CLAM_ASSERT(res == 0, "Unable to lock the mutex"); 00258 00259 CLAM_ASSERT(mLocked, "No condition spurious value change"); 00260 mLocked = false; 00261 00262 res = pthread_cond_signal(&mCondition); 00263 CLAM_ASSERT(res == 0, "Not able to change the condition var value"); 00264 00265 res = pthread_mutex_unlock(&mMutex); 00266 CLAM_ASSERT(res == 0, "Unable to unlock the mutex"); 00267 } 00268 00269 void TimedMutex::DoLock(ConditionVar& v) 00270 { 00271 int res = 0; 00272 while (mLocked) 00273 { 00274 res = pthread_cond_wait(&mCondition, &mMutex); 00275 CLAM_ASSERT(res == 0, "pthread_cond_wait call failed!"); 00276 } 00277 00278 CLAM_ASSERT(!mLocked, "Spurious value change"); 00279 mLocked = true; 00280 00281 res = pthread_mutex_unlock(&mMutex); 00282 CLAM_ASSERT(res == 0, "pthread_mutex_unlock call failed!"); 00283 } 00284 00285 void TimedMutex::DoUnlock(ConditionVar& state) 00286 { 00287 int res = 0; 00288 res = pthread_mutex_lock(&mMutex); 00289 CLAM_ASSERT(res == 0, "pthread_mutex_lock call failed"); 00290 00291 CLAM_ASSERT(mLocked, "Spurious value change!"); 00292 mLocked = false; 00293 00294 res = pthread_cond_signal(&mCondition); 00295 CLAM_ASSERT(res == 0, "pthread_cond_signal call failed!"); 00296 00297 state.pmutex = &mMutex; 00298 } 00299 00300 } // end of namespace CLAM 00301