timedLock.cpp

00001 
00002 /* Copyright (c) 2005-2006, Stefan Eilemann <eile@equalizergraphics.com> 
00003  *
00004  * This library is free software; you can redistribute it and/or modify it under
00005  * the terms of the GNU Lesser General Public License version 2.1 as published
00006  * by the Free Software Foundation.
00007  *  
00008  * This library is distributed in the hope that it will be useful, but WITHOUT
00009  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00010  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00011  * details.
00012  * 
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this library; if not, write to the Free Software Foundation, Inc.,
00015  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00016  */
00017 
00018 #include "timedLock.h"
00019 
00020 #include <eq/base/debug.h>
00021 
00022 #include <pthread.h>
00023 #include <errno.h>
00024 #include <string.h>
00025 #include <sys/timeb.h>
00026 
00027 #ifdef WIN32_API
00028 #  define timeb _timeb
00029 #  define ftime _ftime
00030 #endif
00031 
00032 using namespace std;
00033 
00034 namespace eq
00035 {
00036 namespace base
00037 {
00038 class TimedLockPrivate
00039 {
00040 public:
00041     pthread_mutex_t mutex;
00042     pthread_cond_t  cond;
00043 };
00044 
00045 TimedLock::TimedLock()
00046         : _data( new TimedLockPrivate )
00047         , _locked( false )
00048 {
00049     int error = pthread_mutex_init( &_data->mutex, 0 );
00050     if( error )
00051     {
00052         EQERROR << "Error creating pthread mutex: " << strerror(error) << endl;
00053         return;
00054     }
00055     error = pthread_cond_init( &_data->cond, 0 );
00056     if( error )
00057     {
00058         EQERROR << "Error creating pthread condition: " << strerror( error )
00059                 << endl;
00060         pthread_mutex_destroy( &_data->mutex );
00061         return;
00062     }
00063 }
00064 
00065 TimedLock::~TimedLock()
00066 {
00067     pthread_mutex_destroy( &_data->mutex );
00068     pthread_cond_destroy( &_data->cond );
00069     delete _data;
00070     _data = 0;
00071 }
00072 
00073 bool TimedLock::set( const uint32_t timeout )
00074 {
00075     pthread_mutex_lock( &_data->mutex );
00076 
00077     bool acquired = true;
00078     while( _locked )
00079     {
00080         if( timeout )
00081         {
00082             timespec ts = { 0, 0 };
00083             if( timeout > 0 )
00084             {
00085                 ts.tv_sec  = static_cast<int>( timeout / 1000 );
00086                 ts.tv_nsec = (timeout - ts.tv_sec*1000) * 1000000;
00087             }
00088 
00089             timeb tb;
00090             ftime( &tb );
00091             ts.tv_sec  += tb.time;
00092             ts.tv_nsec += tb.millitm * 1000000;
00093             
00094             int error = pthread_cond_timedwait( &_data->cond, &_data->mutex, &ts );
00095             if( error == ETIMEDOUT )
00096             {
00097                 acquired = false;
00098                 break;
00099             }
00100         }
00101         else
00102             pthread_cond_wait( &_data->cond, &_data->mutex );
00103     }
00104 
00105     if( acquired )
00106     {
00107         EQASSERT( !_locked );
00108         _locked = true;
00109     }
00110 
00111     pthread_mutex_unlock( &_data->mutex );
00112     return acquired;
00113 }
00114 
00115 void TimedLock::unset()
00116 {
00117     pthread_mutex_lock( &_data->mutex );
00118     _locked = false;
00119     pthread_cond_signal( &_data->cond );
00120     pthread_mutex_unlock( &_data->mutex );
00121 }
00122 
00123 
00124 bool TimedLock::trySet()
00125 {
00126     pthread_mutex_lock( &_data->mutex );
00127     
00128     bool acquired = false;
00129     if( _locked )
00130     {
00131         _locked  = true;
00132         acquired = true;
00133     }
00134 
00135     pthread_mutex_unlock( &_data->mutex );
00136     return acquired;
00137 }
00138 
00139 
00140 bool TimedLock::test()
00141 {
00142     return _locked;
00143 }
00144 }
00145 }
Generated on Mon Aug 10 18:58:41 2009 for Equalizer 0.9 by  doxygen 1.5.8