RecursiveMutex.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 "RecursiveMutex.hxx"
00023 #include "xtime.hxx"
00024 #include "Assert.hxx"
00025 #include <pthread.h>
00026 #include <errno.h>
00027 
00028 namespace CLAM
00029 {
00030 
00031 
00032         RecursiveMutex::RecursiveMutex()
00033                 : mCount(0), mValidID( false )
00034         {
00035                 pthread_mutexattr_t attr;
00036 
00037                 int res = 0;
00038 
00039                 res = pthread_mutexattr_init( &attr );
00040                 CLAM_ASSERT( res == 0, "pthread_mutexattr_init failed" );
00041 
00042                 res = pthread_mutex_init( &mMutex, &attr );
00043                 CLAM_ASSERT( res == 0, "pthread_mutex_init failed");
00044 
00045                 res = pthread_cond_init( &mUnlocked, 0 );
00046 
00047                 if ( res!= 0 )
00048                         {
00049                                 pthread_mutex_destroy( &mMutex );
00050                                 throw ThreadResourceError("pthread_cond_init failed");
00051                         }       
00052         }
00053 
00054         RecursiveMutex::~RecursiveMutex()
00055         {
00056                 int res = 0;
00057                 res = pthread_mutex_destroy( &mMutex );
00058 
00059                 CLAM_ASSERT( res == 0, "pthread_mutex_destroy failed" );
00060 
00061                 res = pthread_cond_destroy( &mUnlocked );
00062 
00063                 CLAM_ASSERT( res == 0, "pthread_cond_destroy failed" );
00064         }
00065 
00066 
00067         void RecursiveMutex::DoLock()
00068         {
00069                 int res = 0;
00070 
00071                 res = pthread_mutex_lock( &mMutex );
00072 
00073                 pthread_t tid = pthread_self();
00074 
00075                 if ( mValidID && pthread_equal( mThreadID, tid ) )
00076                         ++ mCount;
00077                 else
00078                         {
00079                                 while ( mValidID )
00080                                         {
00081                                                 res = pthread_cond_wait( &mUnlocked, &mMutex );
00082                                                 CLAM_ASSERT( res == 0, "pthread_cond_wait failed" );
00083                                         }
00084 
00085                                 mThreadID = tid;
00086                                 mValidID = true;
00087                                 mCount = 1;
00088                         }
00089                 
00090                 res = pthread_mutex_unlock( &mMutex );
00091                 CLAM_ASSERT( res == 0, "pthread_mutex_unlock failed" );
00092         }
00093 
00094         void RecursiveMutex::DoUnlock( )
00095         {
00096                 int res = 0;
00097                 res = pthread_mutex_lock( &mMutex );
00098                 CLAM_ASSERT( res == 0, "pthread_mutex_lock failed" );
00099 
00100                 pthread_t tid = pthread_self();
00101 
00102                 if ( mValidID && !pthread_equal( mThreadID, tid ) )
00103                         {
00104                                 res = pthread_mutex_unlock( &mMutex );
00105                                 CLAM_ASSERT( res == 0, "pthread_mutex_unlock failed" );
00106                         }
00107                 
00108                 if ( --mCount == 0 )
00109                         {
00110                                 CLAM_ASSERT( mValidID, "Spurious value change!" );
00111                                 mValidID = false;
00112                                 
00113                                 res = pthread_cond_signal( &mUnlocked );
00114                                 CLAM_ASSERT( res==0, "pthread_cond_signal failed" );
00115                         }
00116 
00117                 res = pthread_mutex_unlock( &mMutex );
00118                 CLAM_ASSERT( res == 0, "pthread_mutex_unlock failed" );
00119         }
00120 
00121         void RecursiveMutex::DoLock( ConditionVar& state )
00122         {
00123                 int res = 0;
00124                 
00125                 while ( mValidID )
00126                         {
00127                                 res = pthread_cond_wait( &mUnlocked, &mMutex );
00128                                 CLAM_ASSERT( res == 0, "pthread_cond_wait failed!" );
00129                         }
00130 
00131                 mThreadID = pthread_self();
00132                 mValidID = true;
00133                 mCount = state.count;
00134 
00135                 res = pthread_mutex_unlock( &mMutex );
00136                 CLAM_ASSERT( res == 0, "pthread_mutex_unlock failed" );
00137         }
00138 
00139         void RecursiveMutex::DoUnlock( ConditionVar& state )
00140         {
00141                 int res = 0;
00142 
00143                 res = pthread_mutex_lock( &mMutex );
00144                 CLAM_ASSERT( res == 0, "pthread_mutex_lock failed" );
00145 
00146                 CLAM_ASSERT( mValidID, "Spurious value change!" );
00147                 mValidID = false;
00148 
00149                 res = pthread_cond_signal( &mUnlocked );
00150                 CLAM_ASSERT( res == 0, "pthread_cond_signal failed!" );
00151 
00152                 state.pmutex = &mMutex;
00153                 state.count = mCount;
00154         }
00155 
00156         RecursiveTryMutex::RecursiveTryMutex()
00157                 : mCount(0), mValidID( false )
00158         {
00159                 pthread_mutexattr_t attr;
00160 
00161                 int res = 0;
00162 
00163                 res = pthread_mutexattr_init( &attr );
00164                 CLAM_ASSERT( res == 0, "pthread_mutexattr_init failed" );
00165 
00166                 res = pthread_mutex_init( &mMutex, &attr );
00167                 CLAM_ASSERT( res == 0, "pthread_mutex_init failed");
00168 
00169                 res = pthread_cond_init( &mUnlocked, 0 );
00170 
00171                 if ( res!= 0 )
00172                         {
00173                                 pthread_mutex_destroy( &mMutex );
00174                                 throw ThreadResourceError("pthread_cond_init failed");
00175                         }       
00176         }
00177 
00178         RecursiveTryMutex::~RecursiveTryMutex()
00179         {
00180                 int res = 0;
00181                 res = pthread_mutex_destroy( &mMutex );
00182 
00183                 CLAM_ASSERT( res == 0, "pthread_mutex_destroy failed" );
00184 
00185                 res = pthread_cond_destroy( &mUnlocked );
00186 
00187                 CLAM_ASSERT( res == 0, "pthread_cond_destroy failed" );
00188         }
00189 
00190 
00191         void RecursiveTryMutex::DoLock()
00192         {
00193                 int res = 0;
00194 
00195                 res = pthread_mutex_lock( &mMutex );
00196 
00197                 pthread_t tid = pthread_self();
00198 
00199                 if ( mValidID && pthread_equal( mThreadID, tid ) )
00200                         ++ mCount;
00201                 else
00202                         {
00203                                 while ( mValidID )
00204                                         {
00205                                                 res = pthread_cond_wait( &mUnlocked, &mMutex );
00206                                                 CLAM_ASSERT( res == 0, "pthread_cond_wait failed" );
00207                                         }
00208 
00209                                 mThreadID = tid;
00210                                 mValidID = true;
00211                                 mCount = 1;
00212                         }
00213                 
00214                 res = pthread_mutex_unlock( &mMutex );
00215                 CLAM_ASSERT( res == 0, "pthread_mutex_unlock failed" );
00216         }
00217 
00218         bool RecursiveTryMutex::DoTryLock()
00219         {
00220                 int res = 0;
00221                 
00222                 res = pthread_mutex_lock( &mMutex );
00223                 CLAM_ASSERT( res == 0, " pthread_mutex_lock failed " );
00224 
00225                 bool ret = false;
00226 
00227                 pthread_t tid = pthread_self();
00228                 
00229                 if (mValidID && pthread_equal(mThreadID, tid ) )
00230                         {
00231                                 ++mCount;
00232                                 ret = true;
00233                         }
00234                 else if ( !mValidID )
00235                         {
00236                                 mThreadID = tid;
00237                                 mValidID = true;
00238                                 mCount = 1;
00239                                 ret = true;
00240                         }
00241 
00242                 res = pthread_mutex_unlock(&mMutex );
00243                 CLAM_ASSERT( res==0, "pthread_mutex_unlock failed" );
00244                 
00245                 return ret;
00246         }
00247 
00248         void RecursiveTryMutex::DoUnlock( )
00249         {
00250                 int res = 0;
00251                 res = pthread_mutex_lock( &mMutex );
00252                 CLAM_ASSERT( res == 0, "pthread_mutex_lock failed" );
00253 
00254                 pthread_t tid = pthread_self();
00255 
00256                 if ( mValidID && !pthread_equal( mThreadID, tid ) )
00257                         {
00258                                 res = pthread_mutex_unlock( &mMutex );
00259                                 CLAM_ASSERT( res == 0, "pthread_mutex_unlock failed" );
00260                         }
00261                 
00262                 if ( --mCount == 0 )
00263                         {
00264                                 CLAM_ASSERT( mValidID, "Spurious value change!" );
00265                                 mValidID = false;
00266                                 
00267                                 res = pthread_cond_signal( &mUnlocked );
00268                                 CLAM_ASSERT( res==0, "pthread_cond_signal failed" );
00269                         }
00270 
00271                 res = pthread_mutex_unlock( &mMutex );
00272                 CLAM_ASSERT( res == 0, "pthread_mutex_unlock failed" );
00273         }
00274 
00275         void RecursiveTryMutex::DoLock( ConditionVar& state )
00276         {
00277                 int res = 0;
00278                 
00279                 while ( mValidID )
00280                         {
00281                                 res = pthread_cond_wait( &mUnlocked, &mMutex );
00282                                 CLAM_ASSERT( res == 0, "pthread_cond_wait failed!" );
00283                         }
00284 
00285                 mThreadID = pthread_self();
00286                 mValidID = true;
00287                 mCount = state.count;
00288 
00289                 res = pthread_mutex_unlock( &mMutex );
00290                 CLAM_ASSERT( res == 0, "pthread_mutex_unlock failed" );
00291         }
00292 
00293         void RecursiveTryMutex::DoUnlock( ConditionVar& state )
00294         {
00295                 int res = 0;
00296 
00297                 res = pthread_mutex_lock( &mMutex );
00298                 CLAM_ASSERT( res == 0, "pthread_mutex_lock failed" );
00299 
00300                 CLAM_ASSERT( mValidID, "Spurious value change!" );
00301                 mValidID = false;
00302 
00303                 res = pthread_cond_signal( &mUnlocked );
00304                 CLAM_ASSERT( res == 0, "pthread_cond_signal failed!" );
00305 
00306                 state.pmutex = &mMutex;
00307                 state.count = mCount;
00308         }
00309 
00310 
00311         RecursiveTimedMutex::RecursiveTimedMutex()
00312                 : mCount(0), mValidID( false )
00313         {
00314                 pthread_mutexattr_t attr;
00315 
00316                 int res = 0;
00317 
00318                 res = pthread_mutexattr_init( &attr );
00319                 CLAM_ASSERT( res == 0, "pthread_mutexattr_init failed" );
00320 
00321 
00322                 res = pthread_mutex_init( &mMutex, &attr );
00323                 CLAM_ASSERT( res == 0, "pthread_mutex_init failed");
00324 
00325                 res = pthread_cond_init( &mUnlocked, 0 );
00326 
00327                 if ( res!= 0 )
00328                         {
00329                                 pthread_mutex_destroy( &mMutex );
00330                                 throw ThreadResourceError("pthread_cond_init failed");
00331                         }       
00332         }
00333 
00334         RecursiveTimedMutex::~RecursiveTimedMutex()
00335         {
00336                 int res = 0;
00337                 res = pthread_mutex_destroy( &mMutex );
00338 
00339                 CLAM_ASSERT( res == 0, "pthread_mutex_destroy failed" );
00340 
00341                 res = pthread_cond_destroy( &mUnlocked );
00342 
00343                 CLAM_ASSERT( res == 0, "pthread_cond_destroy failed" );
00344         }
00345 
00346 
00347         void RecursiveTimedMutex::DoLock()
00348         {
00349                 int res = 0;
00350 
00351                 res = pthread_mutex_lock( &mMutex );
00352 
00353                 pthread_t tid = pthread_self();
00354 
00355                 if ( mValidID && pthread_equal( mThreadID, tid ) )
00356                         ++ mCount;
00357                 else
00358                         {
00359                                 while ( mValidID )
00360                                         {
00361                                                 res = pthread_cond_wait( &mUnlocked, &mMutex );
00362                                                 CLAM_ASSERT( res == 0, "pthread_cond_wait failed" );
00363                                         }
00364 
00365                                 mThreadID = tid;
00366                                 mValidID = true;
00367                                 mCount = 1;
00368                         }
00369                 
00370                 res = pthread_mutex_unlock( &mMutex );
00371                 CLAM_ASSERT( res == 0, "pthread_mutex_unlock failed" );
00372         }
00373 
00374         bool RecursiveTimedMutex::DoTryLock()
00375         {
00376                 int res = 0;
00377                 
00378                 res = pthread_mutex_lock( &mMutex );
00379                 CLAM_ASSERT( res == 0, " pthread_mutex_lock failed " );
00380 
00381                 bool ret = false;
00382 
00383                 pthread_t tid = pthread_self();
00384                 
00385                 if (mValidID && pthread_equal(mThreadID, tid ) )
00386                         {
00387                                 ++mCount;
00388                                 ret = true;
00389                         }
00390                 else if ( !mValidID )
00391                         {
00392                                 mThreadID = tid;
00393                                 mValidID = true;
00394                                 mCount = 1;
00395                                 ret = true;
00396                         }
00397 
00398                 res = pthread_mutex_unlock(&mMutex );
00399                 CLAM_ASSERT( res==0, "pthread_mutex_unlock failed" );
00400                 
00401                 return ret;
00402         }
00403 
00404         bool RecursiveTimedMutex::DoTimedLock( const xtime& xt )
00405         {
00406                 int res = 0;
00407 
00408                 res = pthread_mutex_lock( &mMutex );
00409                 CLAM_ASSERT( res == 0 , "pthread_mutex_lock failed" );
00410 
00411                 bool ret = false;
00412 
00413                 pthread_t tid = pthread_self();
00414 
00415                 if ( mValidID && pthread_equal( mThreadID, tid ) )
00416                         {
00417                                 ++mCount;
00418                                 ret = true;
00419                         }
00420                 else
00421                         {
00422                                 timespec ts;
00423                                 
00424                                 to_timespec( xt, ts );
00425 
00426                                 while( mValidID )
00427                                         {
00428                                                 res = pthread_cond_timedwait( &mUnlocked, &mMutex, &ts );
00429                                                 if ( res == ETIMEDOUT )
00430                                                         break;
00431                                                 CLAM_ASSERT( res==0, "pthread_cond_timedwait failed" );
00432                                         }
00433 
00434                                 if ( !mValidID )
00435                                         {
00436                                                 mThreadID = tid;
00437                                                 mValidID = true;
00438                                                 mCount = 1;
00439                                                 ret = true;
00440                                         }
00441                         }
00442 
00443                 res = pthread_mutex_unlock( &mMutex );
00444                 CLAM_ASSERT( res==0, "pthread_mutex_unlock failed" );
00445 
00446                 return ret;
00447         }
00448 
00449         void RecursiveTimedMutex::DoUnlock( )
00450         {
00451                 int res = 0;
00452                 res = pthread_mutex_lock( &mMutex );
00453                 CLAM_ASSERT( res == 0, "pthread_mutex_lock failed" );
00454 
00455                 pthread_t tid = pthread_self();
00456 
00457                 if ( mValidID && !pthread_equal( mThreadID, tid ) )
00458                         {
00459                                 res = pthread_mutex_unlock( &mMutex );
00460                                 CLAM_ASSERT( res == 0, "pthread_mutex_unlock failed" );
00461                         }
00462                 
00463                 if ( --mCount == 0 )
00464                         {
00465                                 CLAM_ASSERT( mValidID, "Spurious value change!" );
00466                                 mValidID = false;
00467                                 
00468                                 res = pthread_cond_signal( &mUnlocked );
00469                                 CLAM_ASSERT( res == 0, "pthread_cond_signal failed" );
00470                         }
00471 
00472                 res = pthread_mutex_unlock( &mMutex );
00473                 CLAM_ASSERT( res == 0, "pthread_mutex_unlock failed" );
00474         }
00475 
00476         void RecursiveTimedMutex::DoLock( ConditionVar& state )
00477         {
00478                 int res = 0;
00479                 
00480                 while ( mValidID )
00481                         {
00482                                 res = pthread_cond_wait( &mUnlocked, &mMutex );
00483                                 CLAM_ASSERT( res == 0, "pthread_cond_wait failed!" );
00484                         }
00485 
00486                 mThreadID = pthread_self();
00487                 mValidID = true;
00488                 mCount = state.count;
00489 
00490                 res = pthread_mutex_unlock( &mMutex );
00491                 CLAM_ASSERT( res == 0, "pthread_mutex_unlock failed" );
00492         }
00493 
00494         void RecursiveTimedMutex::DoUnlock( ConditionVar& state )
00495         {
00496                 int res = 0;
00497 
00498                 res = pthread_mutex_lock( &mMutex );
00499                 CLAM_ASSERT( res == 0, "pthread_mutex_lock failed" );
00500 
00501                 CLAM_ASSERT( mValidID, "Spurious value change!" );
00502                 mValidID = false;
00503 
00504                 res = pthread_cond_signal( &mUnlocked );
00505                 CLAM_ASSERT( res == 0, "pthread_cond_signal failed!" );
00506 
00507                 state.pmutex = &mMutex;
00508                 state.count = mCount;
00509         }
00510 
00511 
00512 } // end of namespace CLAM
00513 
Generated by  doxygen 1.6.3