Mutex.cxx

Go to the documentation of this file.
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 
Generated by  doxygen 1.6.3