timedLock.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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 }