perThreadRef.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef EQBASE_PERTHREADREF_H
00019 #define EQBASE_PERTHREADREF_H
00020
00021 #include <eq/base/base.h>
00022 #include <eq/base/debug.h>
00023 #include <eq/base/refPtr.h>
00024
00025 namespace eq
00026 {
00027 namespace base
00028 {
00029 class PerThreadRefPrivate;
00030
00032 template< typename T > class PerThreadRef : public NonCopyable
00033 {
00034 public:
00036 PerThreadRef();
00038 ~PerThreadRef();
00039
00041 PerThreadRef<T>& operator = ( RefPtr< T > data );
00043 PerThreadRef<T>& operator = ( const PerThreadRef<T>& rhs );
00044
00046 RefPtr< const T > get() const;
00048 RefPtr< T > get();
00049
00051 T* getPointer();
00053 T* operator->();
00055 const T* operator->() const;
00056
00058 bool operator == ( const PerThreadRef& rhs ) const
00059 { return ( get() == rhs.get( )); }
00061 bool operator == ( const RefPtr< T >& rhs ) const
00062 { return ( get()==rhs ); }
00064 bool operator != ( const RefPtr< T >& rhs ) const
00065 { return ( get()!=rhs ); }
00066
00068 bool operator ! () const;
00069
00071 bool isValid() const;
00072
00073 private:
00074 PerThreadRefPrivate* _data;
00075 };
00076
00077
00078
00079
00080
00081
00082
00083 #ifdef PTHREAD_MUTEX_INITIALIZER
00084 # ifndef HAVE_PTHREAD_H
00085 # define HAVE_PTHREAD_H
00086 # endif
00087 #endif
00088
00089
00090
00091
00092
00093 #ifdef HAVE_PTHREAD_H
00094
00095 class PerThreadRefPrivate
00096 {
00097 public:
00098 pthread_key_t key;
00099 };
00100
00101 template< typename T >
00102 PerThreadRef<T>::PerThreadRef()
00103 : _data( new PerThreadRefPrivate )
00104 {
00105 const int error = pthread_key_create( &_data->key, 0 );
00106 if( error )
00107 {
00108 EQERROR << "Can't create thread-specific key: "
00109 << strerror( error ) << std::endl;
00110 EQASSERT( !error );
00111 }
00112 }
00113
00114 template< typename T >
00115 PerThreadRef<T>::~PerThreadRef()
00116 {
00117 RefPtr< T > object = get();
00118
00119 pthread_key_delete( _data->key );
00120 delete _data;
00121 _data = 0;
00122
00123 object.unref();
00124 }
00125
00126 template< typename T >
00127 PerThreadRef<T>& PerThreadRef<T>::operator = ( RefPtr< T > data )
00128 {
00129 data.ref();
00130
00131 RefPtr< T > object = get();
00132 pthread_setspecific( _data->key, static_cast<const void*>( data.get( )));
00133
00134 object.unref();
00135 return *this;
00136 }
00137
00138 template< typename T >
00139 PerThreadRef<T>& PerThreadRef<T>::operator = ( const PerThreadRef<T>& rhs )
00140 {
00141 RefPtr< T > newObject = rhs.get();
00142 newObject.ref();
00143
00144 RefPtr< T > object = get();
00145 pthread_setspecific( _data->key, pthread_getspecific( rhs._data->key ));
00146
00147 object.unref();
00148 return *this;
00149 }
00150
00151 template< typename T >
00152 RefPtr< const T > PerThreadRef<T>::get() const
00153 {
00154 return static_cast< const T* >( pthread_getspecific( _data->key ));
00155 }
00156
00157 template< typename T >
00158 RefPtr< T > PerThreadRef<T>::get()
00159 {
00160 return static_cast< T* >( pthread_getspecific( _data->key ));
00161 }
00162
00163 template< typename T >
00164 T* PerThreadRef<T>::getPointer()
00165 {
00166 return static_cast< T* >( pthread_getspecific( _data->key ));
00167 }
00168
00169 template< typename T >
00170 T* PerThreadRef<T>::operator->()
00171 {
00172 EQASSERT( pthread_getspecific( _data->key ));
00173 return static_cast< T* >( pthread_getspecific( _data->key ));
00174 }
00175
00176 template< typename T >
00177 const T* PerThreadRef<T>::operator->() const
00178 {
00179 EQASSERT( pthread_getspecific( _data->key ));
00180 return static_cast< const T* >( pthread_getspecific( _data->key ));
00181 }
00182
00183 template< typename T >
00184 bool PerThreadRef<T>::operator ! () const
00185 {
00186 return pthread_getspecific( _data->key ) == 0;
00187 }
00188
00189 template< typename T >
00190 bool PerThreadRef<T>::isValid() const
00191 {
00192 return pthread_getspecific( _data->key ) != 0;
00193 }
00194
00195 #endif // HAVE_PTHREAD_H
00196 }
00197
00198 }
00199 #endif //EQBASE_PERTHREADREF_H